Update SHM mode.
For 16bpp pixmaps, we use GL_RGB and GL_UNSIGNED_SHORT_5_6_5 with glTex(Sub)Image2D, which means that SHM mode works with 16bpp X servers. Also, only create one XShmPixmap per damaged pixmap, instead of one per (optimised) damage rectangle. Now we can use GL_RGB textures for 24bpp pixmaps, just like fallback mode does and tfp mode can. svn path=/trunk/KDE/kdebase/workspace/; revision=659274
This commit is contained in:
parent
5feb577369
commit
630f5793dc
2 changed files with 24 additions and 12 deletions
|
@ -126,8 +126,10 @@ OpenGL TODO
|
|||
obscured (makes a difference with many windows open)
|
||||
- http://lists.kde.org/?l=kwin&m=116585618111882&w=2
|
||||
|
||||
+ shm mode needs support for more data formats than GL_BGRA in order to support e.g. 16bpp mode
|
||||
/ shm mode needs support for more data formats than GL_BGRA
|
||||
- http://www.xfree86.org/current/glTexImage2D.3.html
|
||||
- this now works for 16bpp, but maybe not 15bpp or less
|
||||
- endian issues?
|
||||
|
||||
% with current nvidia glXCreatePixmap in tfp mode fails with pixmaps 32x32 and smaller
|
||||
|
||||
|
|
|
@ -827,18 +827,26 @@ bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
|
|||
else if( shm_mode )
|
||||
{ // copy pixmap contents to a texture via shared memory
|
||||
#ifdef HAVE_XSHM
|
||||
GLenum pixfmt, type;
|
||||
if( depth >= 24 )
|
||||
{
|
||||
pixfmt = GL_BGRA;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else
|
||||
{ // depth 16
|
||||
pixfmt = GL_RGB;
|
||||
type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
}
|
||||
findTarget();
|
||||
if( mTexture == None )
|
||||
{
|
||||
glGenTextures( 1, &mTexture );
|
||||
glBindTexture( mTarget, mTexture );
|
||||
y_inverted = false;
|
||||
glTexImage2D( mTarget, 0, GL_RGBA, mSize.width(), mSize.height(),
|
||||
0, GL_BGRA, GL_UNSIGNED_BYTE, NULL );
|
||||
// TODO hasAlpha() ?
|
||||
// glCopyTexImage2D( mTarget, 0,
|
||||
// depth == 32 ? GL_RGBA : GL_RGB,
|
||||
// 0, 0, mSize.width(), mSize.height(), 0 );
|
||||
glTexImage2D( mTarget, 0, depth == 32 ? GL_RGBA : GL_RGB,
|
||||
mSize.width(), mSize.height(), 0,
|
||||
pixfmt, type, NULL );
|
||||
}
|
||||
else
|
||||
glBindTexture( mTarget, mTexture );
|
||||
|
@ -848,19 +856,21 @@ bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
|
|||
xgcv.graphics_exposures = False;
|
||||
xgcv.subwindow_mode = IncludeInferiors;
|
||||
GC gc = XCreateGC( display(), pix, GCGraphicsExposures | GCSubwindowMode, &xgcv );
|
||||
Pixmap p = XShmCreatePixmap( display(), rootWindow(), shm.shmaddr, &shm,
|
||||
mSize.width(), mSize.height(), depth );
|
||||
QRegion damage = optimizeBindDamage( region, 100 * 100 );
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, mSize.width());
|
||||
foreach( QRect r, damage.rects())
|
||||
{ // TODO for small areas it might be faster to not use SHM to avoid the XSync()
|
||||
Pixmap p = XShmCreatePixmap( display(), rootWindow(), shm.shmaddr, &shm,
|
||||
r.width(), r.height(), depth );
|
||||
XCopyArea( display(), pix, p, gc, r.x(), r.y(), r.width(), r.height(), 0, 0 );
|
||||
XSync( display(), False );
|
||||
glXWaitX();
|
||||
glTexSubImage2D( mTarget, 0,
|
||||
r.x(), r.y(), r.width(), r.height(), GL_BGRA, GL_UNSIGNED_BYTE, shm.shmaddr );
|
||||
r.x(), r.y(), r.width(), r.height(),
|
||||
pixfmt, type, shm.shmaddr );
|
||||
glXWaitGL();
|
||||
XFreePixmap( display(), p );
|
||||
}
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
|
||||
XFreePixmap( display(), p );
|
||||
XFreeGC( display(), gc );
|
||||
}
|
||||
y_inverted = true;
|
||||
|
|
Loading…
Reference in a new issue