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:
Philip Falkner 2007-04-29 21:22:49 +00:00
parent 5feb577369
commit 630f5793dc
2 changed files with 24 additions and 12 deletions

View file

@ -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

View file

@ -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;