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

View file

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

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
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
//****************************************

View file

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

View file

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

View file

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

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());
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;
}

View file

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