From 9bfae71d45de64d1f2fb2dca728ae488bf815fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Lu=C5=88=C3=A1k?= Date: Thu, 16 Nov 2006 07:46:39 +0000 Subject: [PATCH] Support for strict binding for AIGLX, although currently not needed. svn path=/branches/work/kwin_composite/; revision=605274 --- COMPOSITE_TODO | 15 +++++++------- scene_opengl.cpp | 52 ++++++++++++++++++++++++++++++++++-------------- scene_opengl.h | 3 +++ 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/COMPOSITE_TODO b/COMPOSITE_TODO index 589bbe0599..18843fffc4 100644 --- a/COMPOSITE_TODO +++ b/COMPOSITE_TODO @@ -130,17 +130,16 @@ OpenGL TODO + - perhaps syncing to vblank will be needed to avoid flicker ! - XCopyArea() should not update the whole screen but only the affected areas -? compiz checks that "GLX_SGIX_fbconfig" extension is present and requires it - -? non-tfp mode creates context everytime it updates the texture in bindTexture() - - otherwise ATI crashes (http://lists.kde.org/?l=kwin&m=116304346330186&w=2, - http://lists.kde.org/?l=kwin&m=116310179311409&w=2) -? - it causes small performance decrease (5-10%), but non-tfp is bound to be slower anyway - - the commit is r603713, maybe it should be checked later and perhaps reverted - + direct vs indirect rendering + - figure out when it is better to enable direct rendering (last argument to glXCreateNewContext()) and figure out how to turn it on safely + ++ strict binding + - there is code to support strict binding as required by AIGLX, but it's disabled, because + copy_buffer in bindTexture() ensures strict binding as a side-effect + - since copy_buffer hack should be removed in the future, strict binding will need to be enabled then + - http://lists.kde.org/?l=kwin&m=116363084129170&w=2 + XRender TODO ============================== diff --git a/scene_opengl.cpp b/scene_opengl.cpp index ee5d482dc2..4e3944ef3f 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -74,6 +74,7 @@ GLXContext SceneOpenGL::ctxbuffer; // the destination drawable where the compositing is done GLXDrawable SceneOpenGL::glxbuffer; bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap) +bool SceneOpenGL::strict_binding; // intended for AIGLX bool SceneOpenGL::db; // destination drawable is double-buffered bool SceneOpenGL::copy_buffer_hack; // workaround for nvidia < 1.0-9xxx drivers bool SceneOpenGL::supports_saturation; @@ -153,6 +154,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws ) if( !hasGLXVersion( 1, 3 ) && !hasGLExtension( "GLX_SGIX_fbconfig" )) return; tfp_mode = ( glXBindTexImageEXT != NULL && glXReleaseTexImageEXT != NULL ); + strict_binding = false; // not needed now // 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 @@ -496,8 +498,8 @@ void SceneOpenGL::Window::bindTexture() { // tfp mode, simply bind the pixmap to texture if( texture == None ) glGenTextures( 1, &texture ); - if( bound_pixmap != None ) - { // release old if needed + if( bound_pixmap != None && !strict_binding ) // release old if needed + { glXReleaseTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT ); glXDestroyGLXPixmap( display(), bound_glxpixmap ); XFreePixmap( display(), bound_pixmap ); @@ -513,7 +515,8 @@ void SceneOpenGL::Window::bindTexture() glXGetFBConfigAttrib( display(), fbcdrawable, GLX_Y_INVERTED_EXT, &value ); texture_y_inverted = value ? true : false; glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); - glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); + if( !strict_binding ) + glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); } else { // non-tfp case, copy pixmap contents to a texture @@ -564,13 +567,37 @@ void SceneOpenGL::Window::bindTexture() XFreePixmap( display(), window_pix ); } +void SceneOpenGL::Window::enableTexture() + { + glEnable( GL_TEXTURE_RECTANGLE_ARB ); + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + if( tfp_mode && strict_binding ) + { + assert( bound_pixmap != None ); + glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); + } + } + +void SceneOpenGL::Window::disableTexture() + { + if( tfp_mode && strict_binding ) + { + assert( bound_pixmap != None ); + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + glXReleaseTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT ); + } + glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 ); + glDisable( GL_TEXTURE_RECTANGLE_ARB ); + } + void SceneOpenGL::Window::discardTexture() { if( texture != 0 ) { if( tfp_mode ) { - glXReleaseTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT ); + if( !strict_binding ) + glXReleaseTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT ); glXDestroyGLXPixmap( display(), bound_glxpixmap ); XFreePixmap( display(), bound_pixmap ); bound_pixmap = None; @@ -653,8 +680,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA ); const float scale_constant[] = { 1.0, 1.0, 1.0, 0.5}; glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, scale_constant ); - glEnable( GL_TEXTURE_RECTANGLE_ARB ); - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + enableTexture(); // Then we take dot product of the result of previous pass and // saturation_constant. This gives us completely unsaturated @@ -670,8 +696,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_CONSTANT ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, saturation_constant ); - glEnable( GL_TEXTURE_RECTANGLE_ARB ); - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + enableTexture(); // Finally we need to interpolate between the original image and the // greyscale image to get wanted level of saturation @@ -691,8 +716,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); // And make primary color contain the wanted opacity glColor4f( data.opacity, data.opacity, data.opacity, data.opacity ); - glEnable( GL_TEXTURE_RECTANGLE_ARB ); - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + enableTexture(); if( toplevel->hasAlpha() || data.brightness != 1.0f ) { @@ -724,8 +748,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS ); glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); } - glEnable( GL_TEXTURE_RECTANGLE_ARB ); - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, texture ); + enableTexture(); } glActiveTexture(GL_TEXTURE0 ); @@ -756,7 +779,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constant ); } } - glEnable( GL_TEXTURE_RECTANGLE_ARB ); + enableTexture(); // actually paint the window glBegin( GL_QUADS ); foreach( QRect r, region.rects()) @@ -793,8 +816,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat } if( !was_blend ) glDisable( GL_BLEND ); - glDisable( GL_TEXTURE_RECTANGLE_ARB ); - glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 ); + disableTexture(); } } // namespace diff --git a/scene_opengl.h b/scene_opengl.h index 5baa7e2ef5..5db49fd543 100644 --- a/scene_opengl.h +++ b/scene_opengl.h @@ -47,6 +47,7 @@ class SceneOpenGL static GLXDrawable glxbuffer; static GLXContext ctxbuffer; static bool tfp_mode; + static bool strict_binding; static bool copy_buffer_hack; static bool supports_saturation; class Window; @@ -61,6 +62,8 @@ class SceneOpenGL::Window virtual void free(); virtual void performPaint( int mask, QRegion region, WindowPaintData data ); void bindTexture(); + void enableTexture(); + void disableTexture(); void discardTexture(); Window() {} // QMap sucks even in Qt4 private: