diff --git a/scene_opengl.cpp b/scene_opengl.cpp index d4dc762612..afd6d9de03 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -147,9 +147,9 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows ) foreach( Window* w2, phase2 ) { Window& w = *w2; + w.bindTexture(); glEnable( GL_BLEND ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - w.bindTexture(); w.draw(); glDisable( GL_BLEND ); } @@ -180,7 +180,6 @@ void SceneOpenGL::windowGeometryShapeChanged( Toplevel* c ) return; // by default Window& w = windows[ c ]; w.discardShape(); - w.discardPixmap(); w.discardTexture(); } @@ -192,7 +191,6 @@ void SceneOpenGL::windowOpacityChanged( Toplevel* ) if( !windows.contains( c )) // this is ok, texture is created return; // on demand Window& w = windows[ c ]; - w.discardPixmap(); w.discardTexture(); #endif } @@ -206,8 +204,7 @@ void SceneOpenGL::updateTransformation( Toplevel* ) SceneOpenGL::Window::Window( Toplevel* c ) : toplevel( c ) - , glxpixmap( None ) - , texture( None ) + , texture( 0 ) , shape_valid( false ) , depth( 0 ) { @@ -219,18 +216,9 @@ SceneOpenGL::Window::~Window() void SceneOpenGL::Window::free() { - discardPixmap(); discardTexture(); } -GLXPixmap SceneOpenGL::Window::glxPixmap() const - { - if( glxpixmap == None ) - glxpixmap = glXCreatePixmap( display(), fbcdrawable, - toplevel->windowPixmap(), NULL ); - return glxpixmap; - } - // for relative window positioning void SceneOpenGL::Window::setDepth( int d ) { @@ -239,7 +227,14 @@ void SceneOpenGL::Window::setDepth( int d ) void SceneOpenGL::Window::bindTexture() { - GLXDrawable pixmap = glxPixmap(); + if( texture != 0 && toplevel->damage().isEmpty()) + { + // texture doesn't need updating, just bind it + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + return; + } + GLXDrawable pixmap = glXCreatePixmap( display(), fbcdrawable, + toplevel->windowPixmap(), NULL ); glXMakeContextCurrent( display(), pixmap, pixmap, context ); glReadBuffer( GL_FRONT ); glDrawBuffer( GL_FRONT ); @@ -264,6 +259,11 @@ void SceneOpenGL::Window::bindTexture() } } } + // the pixmap is no longer needed, the texture will be updated + // only when the window changes anyway, so no need to cache + // the pixmap + glXDestroyPixmap( display(), pixmap ); + toplevel->resetWindowPixmap(); } void SceneOpenGL::Window::discardShape() diff --git a/scene_opengl.h b/scene_opengl.h index f8e91240c7..9c9af29da4 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -60,16 +60,13 @@ class SceneOpenGL::Window void draw(); bool isVisible() const; bool isOpaque() const; - GLXPixmap glxPixmap() const; void bindTexture(); QRegion shape() const; - void discardPixmap(); void discardTexture(); void discardShape(); Window() {} // QMap sucks even in Qt4 private: Toplevel* toplevel; - mutable GLXPixmap glxpixmap; Texture texture; mutable QRegion shape_region; mutable bool shape_valid; @@ -100,20 +97,12 @@ int SceneOpenGL::Window::height() const return toplevel->height(); } -inline -void SceneOpenGL::Window::discardPixmap() - { - if( glxpixmap != None ) - glXDestroyPixmap( display(), glxpixmap ); - glxpixmap = None; - } - inline void SceneOpenGL::Window::discardTexture() { - if( texture != None ) + if( texture != 0 ) glDeleteTextures( 1, &texture ); - texture = None; + texture = 0; } } // namespace diff --git a/toplevel.h b/toplevel.h index 2cebe61415..61ca988a00 100644 --- a/toplevel.h +++ b/toplevel.h @@ -54,6 +54,7 @@ class Toplevel bool isUtility() const; Pixmap windowPixmap() const; + void resetWindowPixmap(); Visual* visual() const; bool shape() const; virtual double opacity() const = 0; @@ -67,7 +68,6 @@ class Toplevel protected: void setHandle( Window id ); void detectShape( Window id ); - void resetWindowPixmap(); void damageNotifyEvent( XDamageNotifyEvent* e ); QRect geom; Visual* vis;