diff --git a/composite.cpp b/composite.cpp index d79ceae029..036cfcac70 100644 --- a/composite.cpp +++ b/composite.cpp @@ -140,6 +140,8 @@ void Workspace::compositeTimeout() windows.append( c ); } scene->paint( damage_region, windows ); + foreach( Toplevel* c, windows ) + c->resetDamage(); damage_region = QRegion(); } diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 687c6b622c..bb65df8240 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -25,6 +25,7 @@ namespace KWinInternal //**************************************** GLXFBConfig SceneOpenGL::fbcdrawable; +GLXContext SceneOpenGL::context; const int root_attrs[] = { @@ -129,22 +130,15 @@ void SceneOpenGL::paint( QRegion, ToplevelList windows ) { assert( this->windows.contains( *it )); Window& w = this->windows[ *it ]; - GLXDrawable pixmap = w.glxPixmap(); - glXMakeContextCurrent( display(), pixmap, pixmap, context ); - glReadBuffer( GL_FRONT ); - glDrawBuffer( GL_FRONT ); - Texture texture = w.texture(); - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); - glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, - 0, 0, (*it)->width(), (*it)->height(), 0 ); + w.bindTexture(); // TODO for double-buffered root glDrawBuffer( GL_BACK ); glXMakeContextCurrent( display(), glxroot, glxroot, context ); glPushMatrix(); // TODO Y axis in opengl grows up apparently - glTranslatef( (*it)->x(), displayHeight() - (*it)->height() - (*it)->y(), 0 ); + glTranslatef( w.glX(), w.glY(), 0 ); glEnable( GL_TEXTURE_RECTANGLE_ARB ); glBegin( GL_QUADS ); - quadDraw( 0, 0, (*it)->width(), (*it)->height()); + quadDraw( 0, 0, w.width(), w.height()); glEnd(); glPopMatrix(); glDisable( GL_TEXTURE_RECTANGLE_ARB ); @@ -175,7 +169,7 @@ void SceneOpenGL::windowDeleted( Toplevel* c ) SceneOpenGL::Window::Window( Toplevel* c ) : toplevel( c ) , glxpixmap( None ) - , gltexture( None ) + , texture( None ) { } @@ -197,11 +191,32 @@ GLXPixmap SceneOpenGL::Window::glxPixmap() const return glxpixmap; } -SceneOpenGL::Texture SceneOpenGL::Window::texture() const +void SceneOpenGL::Window::bindTexture() { - if( gltexture == None ) - glGenTextures( 1, &gltexture ); - return gltexture; + GLXDrawable pixmap = glxPixmap(); + glXMakeContextCurrent( display(), pixmap, pixmap, context ); + glReadBuffer( GL_FRONT ); + glDrawBuffer( GL_FRONT ); + if( texture == None ) + { + glGenTextures( 1, &texture ); + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + glCopyTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, + 0, 0, toplevel->width(), toplevel->height(), 0 ); + } + else + { + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + if( !toplevel->damage().isEmpty()) + { + foreach( QRect r, toplevel->damage().rects()) + { + int gly = height() - r.y() - r.height(); // to opengl coords + glCopyTexSubImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, + r.x(), gly, r.x(), gly, r.width(), r.height()); + } + } + } } } // namespace diff --git a/scene_opengl.h b/scene_opengl.h index cdf996c6a7..1f3f0bb9a5 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -12,6 +12,7 @@ License. See the file "COPYING" for the exact licensing terms. #define KWIN_SCENE_OPENGL_H #include "scene.h" +#include "toplevel.h" #include #include @@ -35,7 +36,7 @@ class SceneOpenGL GLXFBConfig fbcroot; static GLXFBConfig fbcdrawable; GLXPixmap glxroot; - GLXContext context; + static GLXContext context; class Window; QMap< Toplevel*, Window > windows; }; @@ -46,17 +47,45 @@ class SceneOpenGL::Window Window( Toplevel* c ); ~Window(); void free(); // is often copied by value, use manually instead of dtor + int glX() const; // remap to OpenGL coordinates + int glY() const; + int width() const; + int height() const; GLXPixmap glxPixmap() const; - Texture texture() const; + void bindTexture(); Window() {} // QMap sucks even in Qt4 private: void discardPixmap(); void discardTexture(); Toplevel* toplevel; mutable GLXPixmap glxpixmap; - mutable Texture gltexture; + Texture texture; }; +inline +int SceneOpenGL::Window::glX() const + { + return toplevel->x(); + } + +inline +int SceneOpenGL::Window::glY() const + { + return displayHeight() - toplevel->y() - toplevel->height(); + } + +inline +int SceneOpenGL::Window::width() const + { + return toplevel->width(); + } + +inline +int SceneOpenGL::Window::height() const + { + return toplevel->height(); + } + inline void SceneOpenGL::Window::discardPixmap() { @@ -68,9 +97,9 @@ void SceneOpenGL::Window::discardPixmap() inline void SceneOpenGL::Window::discardTexture() { - if( gltexture != None ) - glDeleteTextures( 1, &gltexture ); - gltexture = None; + if( texture != None ) + glDeleteTextures( 1, &texture ); + texture = None; } } // namespace