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
This commit is contained in:
Luboš Luňák 2006-11-24 21:28:00 +00:00
parent cb549777ba
commit 049460fa2e
8 changed files with 24 additions and 39 deletions

View file

@ -112,7 +112,11 @@ OpenGL TODO
- since copy_buffer hack should be removed in the future, strict binding will need to be enabled then - 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 - 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 XRender TODO
============================== ==============================

View file

@ -224,14 +224,10 @@ void Workspace::performCompositing()
else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( children[ i ] ))) else if( Unmanaged* c = findUnmanaged( HandleMatchPredicate( children[ i ] )))
windows.append( c ); windows.append( c );
} }
scene->initPaint(); QRegion damage = damage_region;
scene->paint( damage_region, windows ); // clear all damage, so that post-pass can add damage for the next repaint
// clear all damage
damage_region = QRegion(); damage_region = QRegion();
foreach( Toplevel* c, windows ) scene->paint( damage, windows );
c->resetDamage();
// run post-pass only after clearing the damage
scene->postPaint();
lastCompositePaint.start(); lastCompositePaint.start();
} }
@ -326,9 +322,9 @@ void Toplevel::addDamageFull()
addDamage( rect()); addDamage( rect());
} }
void Toplevel::resetDamage() void Toplevel::resetDamage( const QRect& r )
{ {
damage_region = QRegion(); damage_region -= r;
} }
#endif #endif

View file

@ -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 // returns mask and possibly modified region
void Scene::paintScreen( int* mask, QRegion* region ) void Scene::paintScreen( int* mask, QRegion* region )
{ {
@ -105,6 +99,7 @@ void Scene::paintScreen( int* mask, QRegion* region )
? 0 : PAINT_SCREEN_REGION; ? 0 : PAINT_SCREEN_REGION;
updateTimeDiff(); updateTimeDiff();
// preparation step // preparation step
effects->startPaint();
effects->prePaintScreen( mask, region, time_diff ); effects->prePaintScreen( mask, region, time_diff );
if( *mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED )) if( *mask & ( PAINT_SCREEN_TRANSFORMED | PAINT_WINDOW_TRANSFORMED ))
{ // optimized painting is not possible with transformations { // optimized painting is not possible with transformations
@ -121,6 +116,9 @@ void Scene::paintScreen( int* mask, QRegion* region )
} }
ScreenPaintData data; ScreenPaintData data;
effects->paintScreen( *mask, *region, data ); effects->paintScreen( *mask, *region, data );
effects->postPaintScreen();
foreach( Window* w, stacking_order )
effects->postPaintWindow( w );
} }
// Compute time since the last painting pass. // 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 ); 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 // Scene::Window
//**************************************** //****************************************

View file

@ -30,15 +30,9 @@ class Scene
Scene( Workspace* ws ); Scene( Workspace* ws );
virtual ~Scene() = 0; virtual ~Scene() = 0;
class Window; 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. // Repaints the given screen areas, windows provides the stacking order.
// The entry point for the main part of the painting pass. // The entry point for the main part of the painting pass.
virtual void paint( QRegion damage, ToplevelList windows ) = 0; 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. // Notification function - KWin core informs about changes.
// Used to mainly discard cached data. // Used to mainly discard cached data.

View file

@ -450,6 +450,9 @@ void SceneOpenGL::paint( QRegion damage, ToplevelList toplevels )
glPopMatrix(); glPopMatrix();
flushBuffer( mask, damage ); flushBuffer( mask, damage );
ungrabXServer(); ungrabXServer();
// do cleanup
stacking_order.clear();
checkGLError( "PostPaint" );
} }
// wait for vblank signal before painting // wait for vblank signal before painting
@ -542,12 +545,6 @@ void SceneOpenGL::paintBackground( QRegion )
// TODO? // TODO?
} }
void SceneOpenGL::postPaint()
{
checkGLError( "PostPaint" );
Scene::postPaint();
}
void SceneOpenGL::windowAdded( Toplevel* c ) void SceneOpenGL::windowAdded( Toplevel* c )
{ {
assert( !windows.contains( c )); assert( !windows.contains( c ));
@ -692,6 +689,7 @@ void SceneOpenGL::Window::bindTexture()
// the pixmap // the pixmap
XFreePixmap( display(), pix ); XFreePixmap( display(), pix );
texture_y_inverted = true; texture_y_inverted = true;
toplevel->resetDamage( toplevel->rect());
} }
else if( tfp_mode ) else if( tfp_mode )
{ // tfp mode, simply bind the pixmap to texture { // tfp mode, simply bind the pixmap to texture
@ -716,6 +714,7 @@ void SceneOpenGL::Window::bindTexture()
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
if( !strict_binding ) if( !strict_binding )
glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
toplevel->resetDamage( toplevel->rect());
} }
else else
{ // non-tfp case, copy pixmap contents to a texture { // non-tfp case, copy pixmap contents to a texture
@ -761,6 +760,7 @@ void SceneOpenGL::Window::bindTexture()
glXMakeContextCurrent( display(), glxbuffer, glxbuffer, ctxbuffer ); glXMakeContextCurrent( display(), glxbuffer, glxbuffer, ctxbuffer );
glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture );
texture_y_inverted = false; texture_y_inverted = false;
toplevel->resetDamage( toplevel->rect());
} }
if( copy_buffer ) if( copy_buffer )
XFreePixmap( display(), window_pix ); XFreePixmap( display(), window_pix );

View file

@ -28,7 +28,6 @@ class SceneOpenGL
SceneOpenGL( Workspace* ws ); SceneOpenGL( Workspace* ws );
virtual ~SceneOpenGL(); virtual ~SceneOpenGL();
virtual void paint( QRegion damage, ToplevelList windows ); virtual void paint( QRegion damage, ToplevelList windows );
virtual void postPaint();
virtual void windowGeometryShapeChanged( Toplevel* ); virtual void windowGeometryShapeChanged( Toplevel* );
virtual void windowOpacityChanged( Toplevel* ); virtual void windowOpacityChanged( Toplevel* );
virtual void windowAdded( Toplevel* ); virtual void windowAdded( Toplevel* );

View file

@ -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()); XRenderComposite( display(), PictOpSrc, buffer, None, front, 0, 0, 0, 0, 0, 0, displayWidth(), displayHeight());
XFlush( display()); XFlush( display());
} }
// do cleanup
stacking_order.clear();
} }
void SceneXrender::paintGenericScreen( int mask, ScreenPaintData data ) void SceneXrender::paintGenericScreen( int mask, ScreenPaintData data )
@ -274,6 +276,7 @@ Picture SceneXrender::Window::picture()
if( alpha_clear ) if( alpha_clear )
XFreePixmap( display(), window_pix ); XFreePixmap( display(), window_pix );
#endif #endif
toplevel->resetDamage( toplevel->rect());
} }
return _picture; return _picture;
} }

View file

@ -65,7 +65,7 @@ class Toplevel
void addDamage( int x, int y, int w, int h ); void addDamage( int x, int y, int w, int h );
void addDamageFull(); void addDamageFull();
QRegion damage() const; QRegion damage() const;
void resetDamage(); void resetDamage( const QRect& r );
protected: protected:
void setHandle( Window id ); void setHandle( Window id );
void detectShape( Window id ); void detectShape( Window id );