diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index 1eda965a74..37c14a3026 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -72,3 +72,8 @@ TODO: / design framework for graphical effects - modelling it after compiz seems to make a lot of sense + +* make paintSimpleScreen() clip non-visible parts + - clip parts of lower windows by parts of windows above them, so that those parts + don't need to be painted + - similarly like in scene_xrender.cpp diff --git a/scene_opengl.cpp b/scene_opengl.cpp index bd3aaf4574..0476764304 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -261,7 +261,7 @@ bool SceneOpenGL::findConfig( const int* attrs, GLXFBConfig& config, VisualID vi return false; } -void SceneOpenGL::paint( QRegion, ToplevelList windows ) +void SceneOpenGL::paint( QRegion damage, ToplevelList windows ) { grabXServer(); glXWaitX(); @@ -270,6 +270,50 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows ) glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glScalef( 1, -1, 1 ); glTranslatef( 0, -displayHeight(), 0 ); + if( /*generic case*/false ) + paintGenericScreen( windows ); + else + paintSimpleScreen( damage, windows ); + glPopMatrix(); + if( root_db ) + glXSwapBuffers( display(), glxroot ); + else + { + glFlush(); + glXWaitGL(); + XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 ); + XFlush( display()); + } + ungrabXServer(); + checkGLError( "PostPaint" ); + } + +// the generic drawing code that should eventually handle even +// transformations +void SceneOpenGL::paintGenericScreen( ToplevelList windows ) + { + int depth = 0; + foreach( Toplevel* c, windows ) // bottom to top + { + assert( this->windows.contains( c )); + Window& w = this->windows[ c ]; + w.setDepth( --depth ); + if( !w.isVisible()) + continue; + w.bindTexture(); + if( !w.isOpaque()) + { + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + } + w.draw(); + glDisable( GL_BLEND ); + } + } + +// the optimized case without any transformations at all +void SceneOpenGL::paintSimpleScreen( QRegion, ToplevelList windows ) + { int depth = 0; QList< Window* > phase2; for( int i = windows.count() - 1; // top to bottom @@ -299,18 +343,6 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows ) w.draw(); glDisable( GL_BLEND ); } - glPopMatrix(); - if( root_db ) - glXSwapBuffers( display(), glxroot ); - else - { - glFlush(); - glXWaitGL(); - XCopyArea( display(), buffer, rootWindow(), gcroot, 0, 0, displayWidth(), displayHeight(), 0, 0 ); - XFlush( display()); - } - ungrabXServer(); - checkGLError( "PostPaint" ); } void SceneOpenGL::windowAdded( Toplevel* c ) diff --git a/scene_opengl.h b/scene_opengl.h index 01b4b751f8..f3af780fc2 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -34,6 +34,8 @@ class SceneOpenGL private: void initBuffer(); bool findConfig( const int* attrs, GLXFBConfig& config, VisualID visual = None ); + void paintGenericScreen( ToplevelList windows ); + void paintSimpleScreen( QRegion damage, ToplevelList windows ); typedef GLuint Texture; GC gcroot; Drawable buffer;