From 049460fa2e833d87441e17dd7dfa28cd0402e937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Fri, 24 Nov 2006 21:28:00 +0000 Subject: [PATCH] Reset window damage after updating the damaged areas of the OpenGL texture or Xrender picture, not after every repaint. This also allows removing the confusing initPaint()/postPaint() calls in Scene. svn path=/branches/work/kwin_composite/; revision=607500 --- COMPOSITE_TODO | 6 +++++- composite.cpp | 14 +++++--------- scene.cpp | 19 ++++--------------- scene.h | 6 ------ scene_opengl.cpp | 12 ++++++------ scene_opengl.h | 1 - scene_xrender.cpp | 3 +++ toplevel.h | 2 +- 8 files changed, 24 insertions(+), 39 deletions(-) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index db333ecdeb..930f696da8 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -112,7 +112,11 @@ OpenGL TODO - since copy_buffer hack should be removed in the future, strict binding will need to be enabled then - http://lists.kde.org/?l=kwin&m=116363084129170&w=2 - +% bindTexture() optimize copied areas + - right now bindTexture() updates every damaged area and resets the window damage + - it might make things faster to update only areas that need to be repainted + and keep the rest damaged until needed + XRender TODO ============================== diff --git a/composite.cpp b/composite.cpp index d3948ec8c6..3895b61c97 100644 --- a/composite.cpp +++ b/composite.cpp @@ -224,14 +224,10 @@ void Workspace::performCompositing() else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( children[ i ] ))) windows.append( c ); } - scene->initPaint(); - scene->paint( damage_region, windows ); - // clear all damage + QRegion damage = damage_region; + // clear all damage, so that post-pass can add damage for the next repaint damage_region = QRegion(); - foreach( Toplevel* c, windows ) - c->resetDamage(); - // run post-pass only after clearing the damage - scene->postPaint(); + scene->paint( damage, windows ); lastCompositePaint.start(); } @@ -326,9 +322,9 @@ void Toplevel::addDamageFull() addDamage( rect()); } -void Toplevel::resetDamage() +void Toplevel::resetDamage( const QRect& r ) { - damage_region = QRegion(); + damage_region -= r; } #endif diff --git a/scene.cpp b/scene.cpp index a9b8bd438a..285ffb6d10 100644 --- a/scene.cpp +++ b/scene.cpp @@ -92,12 +92,6 @@ Scene::~Scene() { } -void Scene::initPaint() - { - effects->startPaint(); - // do the rest of prepaint pass together with paint pass - } - // returns mask and possibly modified region void Scene::paintScreen( int* mask, QRegion* region ) { @@ -105,6 +99,7 @@ void Scene::paintScreen( int* mask, QRegion* region ) ? 0 : PAINT_SCREEN_REGION; updateTimeDiff(); // preparation step + effects->startPaint(); effects->prePaintScreen( mask, region, time_diff ); if( *mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED )) { // optimized painting is not possible with transformations @@ -121,6 +116,9 @@ void Scene::paintScreen( int* mask, QRegion* region ) } ScreenPaintData data; effects->paintScreen( *mask, *region, data ); + effects->postPaintScreen(); + foreach( Window* w, stacking_order ) + effects->postPaintWindow( w ); } // Compute time since the last painting pass. @@ -235,15 +233,6 @@ void Scene::finalPaintWindow( Scene::Window* w, int mask, QRegion region, Window w->performPaint( mask, region, data ); } -void Scene::postPaint() - { - effects->postPaintScreen(); - foreach( Window* w, stacking_order ) - effects->postPaintWindow( w ); - // do cleanup - stacking_order.clear(); - } - //**************************************** // Scene::Window //**************************************** diff --git a/scene.h b/scene.h index 7c8057006e..adb39744fd 100644 --- a/scene.h +++ b/scene.h @@ -30,15 +30,9 @@ class Scene Scene( Workspace* ws ); virtual ~Scene() = 0; class Window; - // Called before calling paint() to perform initialization (does not - // do the prepaint pass though) - virtual void initPaint(); // Repaints the given screen areas, windows provides the stacking order. // The entry point for the main part of the painting pass. virtual void paint( QRegion damage, ToplevelList windows ) = 0; - // Called to perform post paint cleanup and for animations to prepare - // for next pass. - virtual void postPaint(); // Notification function - KWin core informs about changes. // Used to mainly discard cached data. diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 44ace7620e..9dc10b4f0f 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -450,6 +450,9 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels ) glPopMatrix(); flushBuffer( mask, damage ); ungrabXServer(); + // do cleanup + stacking_order.clear(); + checkGLError( "PostPaint" ); } // wait for vblank signal before painting @@ -542,12 +545,6 @@ void SceneOpenGL::paintBackground( QRegion ) // TODO? } -void SceneOpenGL::postPaint() - { - checkGLError( "PostPaint" ); - Scene::postPaint(); - } - void SceneOpenGL::windowAdded( Toplevel* c ) { assert( !windows.contains( c )); @@ -692,6 +689,7 @@ void SceneOpenGL::Window::bindTexture() // the pixmap XFreePixmap( display(), pix ); texture_y_inverted = true; + toplevel->resetDamage( toplevel->rect()); } else if( tfp_mode ) { // tfp mode, simply bind the pixmap to texture @@ -716,6 +714,7 @@ void SceneOpenGL::Window::bindTexture() glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); if( !strict_binding ) glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); + toplevel->resetDamage( toplevel->rect()); } else { // non-tfp case, copy pixmap contents to a texture @@ -761,6 +760,7 @@ void SceneOpenGL::Window::bindTexture() glXMakeContextCurrent( display(), glxbuffer, glxbuffer, ctxbuffer ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); texture_y_inverted = false; + toplevel->resetDamage( toplevel->rect()); } if( copy_buffer ) XFreePixmap( display(), window_pix ); diff --git a/scene_opengl.h b/scene_opengl.h index 8644ab84ea..ffe7a5aedb 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -28,7 +28,6 @@ class SceneOpenGL SceneOpenGL( Workspace* ws ); virtual ~SceneOpenGL(); virtual void paint( QRegion damage, ToplevelList windows ); - virtual void postPaint(); virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* ); virtual void windowAdded( Toplevel* ); diff --git a/scene_xrender.cpp b/scene_xrender.cpp index 2c86d8d8c5..546eea0215 100644 --- a/scene_xrender.cpp +++ b/scene_xrender.cpp @@ -123,6 +123,8 @@ void SceneXrender::paint( QRegion damage, ToplevelList toplevels ) XRenderComposite( display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight()); XFlush( display()); } + // do cleanup + stacking_order.clear(); } void SceneXrender::paintGenericScreen( int mask, ScreenPaintData data ) @@ -274,6 +276,7 @@ Picture SceneXrender::Window::picture() if( alpha_clear ) XFreePixmap( display(), window_pix ); #endif + toplevel->resetDamage( toplevel->rect()); } return _picture; } diff --git a/toplevel.h b/toplevel.h index 6b2d507c09..cf655320df 100644 --- a/toplevel.h +++ b/toplevel.h @@ -65,7 +65,7 @@ class Toplevel void addDamage( int x, int y, int w, int h ); void addDamageFull(); QRegion damage() const; - void resetDamage(); + void resetDamage( const QRect& r ); protected: void setHandle( Window id ); void detectShape( Window id );