From fef4dec6e66a479dcff9f6c246fe05dbc713ed11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Sat, 21 Oct 2006 15:23:01 +0000 Subject: [PATCH] Add COPY_BUFFER workaround from glcompmgr that makes this work even with stable 8776 nvidia drivers (the beta ones lock up on me from time to time with multiple X running). svn path=/branches/work/kwin_composite/; revision=597767 --- COMPOSITE_TODO | 7 +------ manage.cpp | 2 +- scene_opengl.cpp | 19 ++++++++++--------- scene_opengl.h | 1 + toplevel.h | 10 ++++++++-- unmanaged.cpp | 2 +- 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index 8b84fee761..db7e2a5867 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -25,12 +25,7 @@ Sources: TODO: * Check/make it work with other gfx cards - - I've tested only with nvidia with the 9625 beta drivers so far - * latest stable nvidia drivers don't quite work, the COPY_BUFFERS - or REFRESH_DRAWABLES workaround from glcompmgr should take care of that - - the COPY_BUFFERS hack, if I'm getting it right, just creates a copy - of the X Pixmap first, so just always using ALPHA_CLEAR_COPY hack - in KWin should do the same + - I've tested only with nvidia with the 9625 beta drivers and 8776 stable drivers so far - I have absolutely no idea about other gfx cards, needs to be tested * ati * intel diff --git a/manage.cpp b/manage.cpp index ea2626616a..c35b09334a 100644 --- a/manage.cpp +++ b/manage.cpp @@ -54,7 +54,7 @@ bool Client::manage( Window w, bool isMapped ) embedClient( w, attr ); vis = attr.visual; - depth = attr.depth; + bit_depth = attr.depth; setupCompositing(); diff --git a/scene_opengl.cpp b/scene_opengl.cpp index d809b6bf4c..c1cf55d3be 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -30,6 +30,7 @@ GLXContext SceneOpenGL::context; GLXPixmap SceneOpenGL::glxroot; bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap) bool SceneOpenGL::root_db; // destination drawable is double-buffered +bool SceneOpenGL::copy_buffer_hack; // workaround for nvidia < 1.0-9xxx drivers typedef void (*glXBindTexImageEXT_func)( Display* dpy, GLXDrawable drawable, int buffer, const int* attrib_list ); @@ -121,6 +122,9 @@ SceneOpenGL::SceneOpenGL( Workspace* ws ) glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" ); glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" ); tfp_mode = ( glXBindTexImageEXT != NULL && glXReleaseTexImageEXT != NULL ); + // use copy buffer hack from glcompmgr (called COPY_BUFFER there) - nvidia drivers older than + // 1.0-9xxx don't update pixmaps properly, so do a copy first + copy_buffer_hack = !tfp_mode; // TODO detect that it's nvidia < 1.0-9xxx driver initBuffer(); if( tfp_mode ) { @@ -380,22 +384,21 @@ void SceneOpenGL::Window::bindTexture() // the alpha for the decoration part is broken for some reason (undefined?). // I wasn't lucky converting KWin to use ARGB visuals for decorations, // so instead simply set alpha in those parts to opaque. - // Without ALPHA_CLEAR_COPY the setting is done directly in the window + // Without alpha_clear_copy the setting is done directly in the window // pixmap, which seems to be ok, but let's not risk trouble right now. // TODO check if this isn't a performance problem and how it can be done better Client* c = dynamic_cast< Client* >( toplevel ); bool alpha_clear = c != NULL && c->hasAlpha() && !c->noBorder(); -#define ALPHA_CLEAR_COPY -#ifdef ALPHA_CLEAR_COPY - if( alpha_clear ) + bool alpha_clear_copy = true; + bool copy_buffer = (( alpha_clear && alpha_clear_copy ) || copy_buffer_hack ); + if( copy_buffer ) { - Pixmap p2 = XCreatePixmap( display(), pix, c->width(), c->height(), 32 ); + Pixmap p2 = XCreatePixmap( display(), pix, c->width(), c->height(), toplevel->depth()); GC gc = XCreateGC( display(), pix, 0, NULL ); XCopyArea( display(), pix, p2, gc, 0, 0, c->width(), c->height(), 0, 0 ); pix = p2; XFreeGC( display(), gc ); } -#endif if( alpha_clear ) { XGCValues gcv; @@ -475,10 +478,8 @@ void SceneOpenGL::Window::bindTexture() glDrawBuffer( GL_BACK ); glXMakeContextCurrent( display(), glxroot, glxroot, context ); } -#ifdef ALPHA_CLEAR_COPY - if( alpha_clear ) + if( copy_buffer ) XFreePixmap( display(), window_pix ); -#endif } void SceneOpenGL::Window::discardTexture() diff --git a/scene_opengl.h b/scene_opengl.h index b865363cd8..9a300d4c65 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -45,6 +45,7 @@ class SceneOpenGL static GLXDrawable glxroot; static GLXContext context; static bool tfp_mode; + static bool copy_buffer_hack; class Window; QMap< Toplevel*, Window > windows; }; diff --git a/toplevel.h b/toplevel.h index 71c8dc2eb0..57d8ace01a 100644 --- a/toplevel.h +++ b/toplevel.h @@ -57,6 +57,7 @@ class Toplevel Visual* visual() const; bool shape() const; virtual double opacity() const = 0; + int depth() const; bool hasAlpha() const; void setupCompositing(); void finishCompositing(); @@ -70,7 +71,7 @@ class Toplevel void damageNotifyEvent( XDamageNotifyEvent* e ); QRect geom; Visual* vis; - int depth; + int bit_depth; virtual void debug( kdbgstream& stream ) const = 0; friend kdbgstream& operator<<( kdbgstream& stream, const Toplevel* ); private: @@ -197,9 +198,14 @@ inline bool Toplevel::shape() const return is_shape; } +inline int Toplevel::depth() const + { + return bit_depth; + } + inline bool Toplevel::hasAlpha() const { - return depth == 32; + return depth() == 32; } #ifdef NDEBUG diff --git a/unmanaged.cpp b/unmanaged.cpp index 9a1a38ac7d..7f090fd1b7 100644 --- a/unmanaged.cpp +++ b/unmanaged.cpp @@ -39,7 +39,7 @@ bool Unmanaged::track( Window w ) setHandle( w ); geom = QRect( attr.x, attr.y, attr.width, attr.height ); vis = attr.visual; - depth = attr.depth; + bit_depth = attr.depth; unsigned long properties[ 2 ]; properties[ NETWinInfo::PROTOCOLS ] = NET::WMWindowType |