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:
parent
daa8f7eccc
commit
fef4dec6e6
6 changed files with 22 additions and 19 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
10
toplevel.h
10
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
|
||||
|
|
|
@ -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 |
|
||||
|
|
Loading…
Reference in a new issue