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
icc-effect-5.14.5
Luboš Luňák 2006-10-21 15:23:01 +00:00
parent daa8f7eccc
commit fef4dec6e6
6 changed files with 22 additions and 19 deletions

View File

@ -25,12 +25,7 @@ Sources:
TODO: TODO:
* Check/make it work with other gfx cards * Check/make it work with other gfx cards
- I've tested only with nvidia with the 9625 beta drivers so far - I've tested only with nvidia with the 9625 beta drivers and 8776 stable 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 have absolutely no idea about other gfx cards, needs to be tested - I have absolutely no idea about other gfx cards, needs to be tested
* ati * ati
* intel * intel

View File

@ -54,7 +54,7 @@ bool Client::manage( Window w, bool isMapped )
embedClient( w, attr ); embedClient( w, attr );
vis = attr.visual; vis = attr.visual;
depth = attr.depth; bit_depth = attr.depth;
setupCompositing(); setupCompositing();

View File

@ -30,6 +30,7 @@ GLXContext SceneOpenGL::context;
GLXPixmap SceneOpenGL::glxroot; GLXPixmap SceneOpenGL::glxroot;
bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap) bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap)
bool SceneOpenGL::root_db; // destination drawable is double-buffered 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, typedef void (*glXBindTexImageEXT_func)( Display* dpy, GLXDrawable drawable,
int buffer, const int* attrib_list ); int buffer, const int* attrib_list );
@ -121,6 +122,9 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" ); glXBindTexImageEXT = (glXBindTexImageEXT_func) getProcAddress( "glXBindTexImageEXT" );
glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" ); glXReleaseTexImageEXT = (glXReleaseTexImageEXT_func) getProcAddress( "glXReleaseTexImageEXT" );
tfp_mode = ( glXBindTexImageEXT != NULL && glXReleaseTexImageEXT != NULL ); 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(); initBuffer();
if( tfp_mode ) if( tfp_mode )
{ {
@ -380,22 +384,21 @@ void SceneOpenGL::Window::bindTexture()
// the alpha for the decoration part is broken for some reason (undefined?). // the alpha for the decoration part is broken for some reason (undefined?).
// I wasn't lucky converting KWin to use ARGB visuals for decorations, // I wasn't lucky converting KWin to use ARGB visuals for decorations,
// so instead simply set alpha in those parts to opaque. // 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. // 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 // TODO check if this isn't a performance problem and how it can be done better
Client* c = dynamic_cast< Client* >( toplevel ); Client* c = dynamic_cast< Client* >( toplevel );
bool alpha_clear = c != NULL && c->hasAlpha() && !c->noBorder(); bool alpha_clear = c != NULL && c->hasAlpha() && !c->noBorder();
#define ALPHA_CLEAR_COPY bool alpha_clear_copy = true;
#ifdef ALPHA_CLEAR_COPY bool copy_buffer = (( alpha_clear && alpha_clear_copy ) || copy_buffer_hack );
if( alpha_clear ) 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 ); GC gc = XCreateGC( display(), pix, 0, NULL );
XCopyArea( display(), pix, p2, gc, 0, 0, c->width(), c->height(), 0, 0 ); XCopyArea( display(), pix, p2, gc, 0, 0, c->width(), c->height(), 0, 0 );
pix = p2; pix = p2;
XFreeGC( display(), gc ); XFreeGC( display(), gc );
} }
#endif
if( alpha_clear ) if( alpha_clear )
{ {
XGCValues gcv; XGCValues gcv;
@ -475,10 +478,8 @@ void SceneOpenGL::Window::bindTexture()
glDrawBuffer( GL_BACK ); glDrawBuffer( GL_BACK );
glXMakeContextCurrent( display(), glxroot, glxroot, context ); glXMakeContextCurrent( display(), glxroot, glxroot, context );
} }
#ifdef ALPHA_CLEAR_COPY if( copy_buffer )
if( alpha_clear )
XFreePixmap( display(), window_pix ); XFreePixmap( display(), window_pix );
#endif
} }
void SceneOpenGL::Window::discardTexture() void SceneOpenGL::Window::discardTexture()

View File

@ -45,6 +45,7 @@ class SceneOpenGL
static GLXDrawable glxroot; static GLXDrawable glxroot;
static GLXContext context; static GLXContext context;
static bool tfp_mode; static bool tfp_mode;
static bool copy_buffer_hack;
class Window; class Window;
QMap< Toplevel*, Window > windows; QMap< Toplevel*, Window > windows;
}; };

View File

@ -57,6 +57,7 @@ class Toplevel
Visual* visual() const; Visual* visual() const;
bool shape() const; bool shape() const;
virtual double opacity() const = 0; virtual double opacity() const = 0;
int depth() const;
bool hasAlpha() const; bool hasAlpha() const;
void setupCompositing(); void setupCompositing();
void finishCompositing(); void finishCompositing();
@ -70,7 +71,7 @@ class Toplevel
void damageNotifyEvent( XDamageNotifyEvent* e ); void damageNotifyEvent( XDamageNotifyEvent* e );
QRect geom; QRect geom;
Visual* vis; Visual* vis;
int depth; int bit_depth;
virtual void debug( kdbgstream& stream ) const = 0; virtual void debug( kdbgstream& stream ) const = 0;
friend kdbgstream& operator<<( kdbgstream& stream, const Toplevel* ); friend kdbgstream& operator<<( kdbgstream& stream, const Toplevel* );
private: private:
@ -197,9 +198,14 @@ inline bool Toplevel::shape() const
return is_shape; return is_shape;
} }
inline int Toplevel::depth() const
{
return bit_depth;
}
inline bool Toplevel::hasAlpha() const inline bool Toplevel::hasAlpha() const
{ {
return depth == 32; return depth() == 32;
} }
#ifdef NDEBUG #ifdef NDEBUG

View File

@ -39,7 +39,7 @@ bool Unmanaged::track( Window w )
setHandle( w ); setHandle( w );
geom = QRect( attr.x, attr.y, attr.width, attr.height ); geom = QRect( attr.x, attr.y, attr.width, attr.height );
vis = attr.visual; vis = attr.visual;
depth = attr.depth; bit_depth = attr.depth;
unsigned long properties[ 2 ]; unsigned long properties[ 2 ];
properties[ NETWinInfo::PROTOCOLS ] = properties[ NETWinInfo::PROTOCOLS ] =
NET::WMWindowType | NET::WMWindowType |