Try to reduce number of roundtrips in SHM mode by merging

region rectangles.


svn path=/branches/work/kwin_composite/; revision=606267
This commit is contained in:
Luboš Luňák 2006-11-19 20:10:25 +00:00
parent 951448b575
commit 6e54bae328
2 changed files with 28 additions and 11 deletions

View file

@ -603,7 +603,8 @@ void SceneOpenGL::Window::bindTexture()
xgcv.graphics_exposures = False;
xgcv.subwindow_mode = IncludeInferiors;
GC gc = XCreateGC( display(), pix, GCGraphicsExposures | GCSubwindowMode, &xgcv );
foreach( QRect r, toplevel->damage().rects())
QRegion damage = optimizeBindDamage( toplevel->damage(), 100 * 100 );
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(), toplevel->depth());
@ -670,17 +671,15 @@ void SceneOpenGL::Window::bindTexture()
else
{
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
if( !toplevel->damage().isEmpty())
QRegion damage = optimizeBindDamage( toplevel->damage(), 30 * 30 );
foreach( QRect r, damage.rects())
{
foreach( QRect r, toplevel->damage().rects())
{
// convert to OpenGL coordinates (this is mapping
// the pixmap to a texture, this is not affected
// by using glOrtho() for the OpenGL scene)
int gly = toplevel->height() - r.y() - r.height();
glCopyTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
r.x(), gly, r.x(), gly, r.width(), r.height());
}
// convert to OpenGL coordinates (this is mapping
// the pixmap to a texture, this is not affected
// by using glOrtho() for the OpenGL scene)
int gly = toplevel->height() - r.y() - r.height();
glCopyTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0,
r.x(), gly, r.x(), gly, r.width(), r.height());
}
}
glXWaitGL();
@ -698,6 +697,23 @@ void SceneOpenGL::Window::bindTexture()
XFreePixmap( display(), window_pix );
}
QRegion SceneOpenGL::Window::optimizeBindDamage( const QRegion& reg, int limit )
{
if( reg.rects().count() <= 1 )
return reg;
// try to reduce the number of rects, as especially with SHM mode every rect
// causes X roundtrip, even for very small areas - so, when the size difference
// between all the areas and the bounding rectangle is small, simply use
// only the bounding rectangle
int size = 0;
foreach( QRect r, reg.rects())
size += r.width() * r.height();
if( reg.boundingRect().width() * reg.boundingRect().height() - size < limit )
return reg.boundingRect();
return reg;
}
void SceneOpenGL::Window::enableTexture()
{
glEnable( GL_TEXTURE_RECTANGLE_ARB );

View file

@ -76,6 +76,7 @@ class SceneOpenGL::Window
void discardTexture();
Window() {} // QMap sucks even in Qt4
private:
QRegion optimizeBindDamage( const QRegion& reg, int limit );
Texture texture;
bool texture_y_inverted; // texture has y inverted
Pixmap bound_pixmap; // the pixmap the texture is bound to, only for tfp_mode