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
This commit is contained in:
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:
* 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

View file

@ -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();

View file

@ -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()

View file

@ -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;
};

View file

@ -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

View file

@ -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 |