--Boundary-00=_zjmvFKzXZP+yCCz Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Monday 29 January 2007 10:21, Lubos Lunak wrote: > On Saturday 27 January 2007 21:26, Philip Falkner wrote: > Fdclock -sta seems to work fine here in fallback mode with either current > svn or with the configs patch (I only get the warning then). > > [...] > > Given fallback's priority I wouldn't bother for now. Okay. I've turned the warning into a comment, since warning on every bind = is=20 annoying. :) > > We could use this in tfp, too, for when there's no fbconfig for that > > window depth. > > I think such case should be very unlikely, if possible at all. =46rom a copy of glxinfo output from fglrx I found on the web, it seems it = only=20 has 24-bit depths in 24-bit mode. A 32-bit window like fdclock -sta might= =20 happen, but it won't work without a compositor anyway (I think), so if we=20 just don't bind the texture in that case (tfp_mode), it shouldn't be so=20 terrible, right? And fglrx is the only driver I've found that may work thi= s=20 way. Attached patch again. I've split initFBConfigs() into initBufferConfigs() = and=20 initDrawableConfigs() for neatness. Since Rivo's problem is something=20 unrelated to this, commit? =2D-=20 Philip Falkner --Boundary-00=_zjmvFKzXZP+yCCz Content-Type: text/x-diff; charset="iso-8859-1"; name="configs.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="configs.patch" Index: scene_opengl.h =================================================================== --- scene_opengl.h (revision 628242) +++ scene_opengl.h (working copy) @@ -44,16 +44,26 @@ class SceneOpenGL void cleanupShm(); void initBuffer(); void initRenderingContext(); - bool findConfig( const int* attrs, GLXFBConfig* config, VisualID visual = None ); + bool initBufferConfigs(); + bool initDrawableConfigs(); void waitSync(); void flushBuffer( int mask, QRegion damage ); typedef GLuint Texture; typedef GLenum Target; GC gcroot; + class FBConfigInfo + { + public: + GLXFBConfig fbconfig; + int bind_texture_format; + int y_inverted; + }; Drawable buffer; GLXFBConfig fbcbuffer; static bool db; - static GLXFBConfig fbcdrawable; + static GLXFBConfig fbcbuffer_db; + static GLXFBConfig fbcbuffer_nondb; + static FBConfigInfo fbcdrawableinfo[ 32 + 1 ]; static GLXDrawable glxbuffer; static GLXContext ctxbuffer; static GLXContext ctxdrawable; Index: scene_opengl.cpp =================================================================== --- scene_opengl.cpp (revision 628242) +++ scene_opengl.cpp (working copy) @@ -74,8 +74,11 @@ namespace KWinInternal // SceneOpenGL //**************************************** -// the config used for windows -GLXFBConfig SceneOpenGL::fbcdrawable; +// the configs used for the destination +GLXFBConfig SceneOpenGL::fbcbuffer_db; +GLXFBConfig SceneOpenGL::fbcbuffer_nondb; +// the configs used for windows +SceneOpenGL::FBConfigInfo SceneOpenGL::fbcdrawableinfo[ 32 + 1 ]; // GLX content GLXContext SceneOpenGL::ctxbuffer; GLXContext SceneOpenGL::ctxdrawable; @@ -100,59 +103,6 @@ static void checkGLError( const char* tx kWarning() << "GL error (" << txt << "): 0x" << QString::number( err, 16 ) << endl; } -// attributes for finding a double-buffered destination window config -static const int buffer_db_attrs[] = - { - GLX_CONFIG_CAVEAT, GLX_NONE, - GLX_DOUBLEBUFFER, True, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - None - }; - -// attributes for finding a non-double-buffered destination pixmap config -static const int buffer_nondb_attrs[] = - { - GLX_CONFIG_CAVEAT, GLX_NONE, - GLX_DOUBLEBUFFER, False, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - None - }; - -// attributes for finding config for windows -const int drawable_attrs[] = - { - GLX_CONFIG_CAVEAT, GLX_NONE, - GLX_DOUBLEBUFFER, False, - GLX_DEPTH_SIZE, 0, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_ALPHA_SIZE, 1, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - None - }; - -// attributes for finding config for windows when using tfp -const int drawable_tfp_attrs[] = - { - GLX_CONFIG_CAVEAT, GLX_NONE, - GLX_DOUBLEBUFFER, False, - GLX_DEPTH_SIZE, 0, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_ALPHA_SIZE, 1, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_BIND_TO_TEXTURE_RGBA_EXT, True, // additional for tfp - None - }; - SceneOpenGL::SceneOpenGL( Workspace* ws ) : Scene( ws ) { @@ -169,9 +119,14 @@ SceneOpenGL::SceneOpenGL( Workspace* ws initBuffer(); // create destination buffer int vis_buffer, vis_drawable; glXGetFBConfigAttrib( display(), fbcbuffer, GLX_VISUAL_ID, &vis_buffer ); - glXGetFBConfigAttrib( display(), fbcdrawable, GLX_VISUAL_ID, &vis_drawable ); - kDebug( 1212 ) << "Buffer visual: 0x" << QString::number( vis_buffer, 16 ) << ", drawable visual: 0x" - << QString::number( vis_drawable, 16 ) << endl; + kDebug( 1212 ) << "Buffer visual (depth " << QX11Info::appDepth() << "): 0x" << QString::number( vis_buffer, 16 ) << endl; + for( int i = 0; i <= 32; i++ ) + { + if( fbcdrawableinfo[ i ].fbconfig == NULL ) + continue; + glXGetFBConfigAttrib( display(), fbcdrawableinfo[ i ].fbconfig, GLX_VISUAL_ID, &vis_drawable ); + kDebug( 1212 ) << "Drawable visual (depth " << i << "): 0x" << QString::number( vis_drawable, 16 ) << endl; + } initRenderingContext(); // Initialize OpenGL @@ -250,7 +205,7 @@ void SceneOpenGL::selectMode() else if( initTfp()) tfp_mode = true; } - if( !tfp_mode && !findConfig( drawable_attrs, &fbcdrawable )) + if( !initDrawableConfigs()) assert( false ); // 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 @@ -261,7 +216,7 @@ bool SceneOpenGL::initTfp() { if( glXBindTexImageEXT == NULL || glXReleaseTexImageEXT == NULL ) return false; - if( !findConfig( drawable_tfp_attrs, &fbcdrawable )) + if( !initDrawableConfigs()) return false; return true; } @@ -333,7 +288,7 @@ void SceneOpenGL::initRenderingContext() } if( !tfp_mode && !shm_mode ) { - ctxdrawable = glXCreateNewContext( display(), fbcdrawable, GLX_RGBA_TYPE, ctxbuffer, + ctxdrawable = glXCreateNewContext( display(), fbcdrawableinfo[ QX11Info::appDepth() ].fbconfig, GLX_RGBA_TYPE, ctxbuffer, direct_rendering ? GL_TRUE : GL_FALSE ); } } @@ -341,8 +296,10 @@ void SceneOpenGL::initRenderingContext() // create destination buffer void SceneOpenGL::initBuffer() { - if( findConfig( buffer_db_attrs, &fbcbuffer ) && wspace->createOverlay()) + initBufferConfigs(); + if( fbcbuffer_db != NULL && wspace->createOverlay()) { // we have overlay, try to create double-buffered window in it + fbcbuffer = fbcbuffer_db; XVisualInfo* visual = glXGetVisualFromFBConfig( display(), fbcbuffer ); XSetWindowAttributes attrs; attrs.colormap = XCreateColormap( display(), rootWindow(), visual->visual, AllocNone ); @@ -356,8 +313,9 @@ void SceneOpenGL::initBuffer() db = true; XFree( visual ); } - else if( findConfig( buffer_nondb_attrs, &fbcbuffer )) + else if( fbcbuffer_nondb != NULL ) { // cannot get any double-buffered drawable, will double-buffer using a pixmap + fbcbuffer = fbcbuffer_nondb; db = false; XGCValues gcattr; gcattr.subwindow_mode = IncludeInferiors; @@ -370,72 +328,180 @@ void SceneOpenGL::initBuffer() assert( false ); } -// print info about found configs -static void debugFBConfig( GLXFBConfig* fbconfigs, int i, const int* attrs ) +// choose the best configs for the destination buffer +bool SceneOpenGL::initBufferConfigs() { - int pos = 0; - while( attrs[ pos ] != (int)None ) - { - int value; - if( glXGetFBConfigAttrib( display(), fbconfigs[ i ], attrs[ pos ], &value ) - == Success ) - kDebug( 1212 ) << "ATTR: 0x" << QString::number( attrs[ pos ], 16 ) - << ": 0x" << QString::number( attrs[ pos + 1 ], 16 ) - << ": 0x" << QString::number( value, 16 ) << endl; + int cnt; + GLXFBConfig *fbconfigs = glXGetFBConfigs( display(), DefaultScreen( display() ), &cnt ); + fbcbuffer_db = NULL; + fbcbuffer_nondb = NULL; + + for( int i = 0; i < 2; i++ ) + { + int back, stencil, depth, caveat, alpha; + if( i > 0 ) + back = INT_MAX; else - kDebug( 1212 ) << "ATTR FAIL: 0x" << QString::number( attrs[ pos ], 16 ) << endl; - pos += 2; + back = 1; + stencil = 0; + depth = 0; + caveat = INT_MAX; + alpha = 0; + for( int j = 0; j < cnt; j++ ) + { + XVisualInfo *vi; + int visual_depth; + vi = glXGetVisualFromFBConfig( display(), fbconfigs[ j ] ); + if( vi == NULL ) + continue; + visual_depth = vi->depth; + XFree( vi ); + if( visual_depth != QX11Info::appDepth() ) + continue; + int value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_ALPHA_SIZE, &alpha ); + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_BUFFER_SIZE, &value ); + if( value != QX11Info::appDepth() && ( value - alpha ) != QX11Info::appDepth() ) + continue; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_DOUBLEBUFFER, &value ); + if( i > 0 ) + { + if( value > back ) + continue; + } + else + { + if( value < back ) + continue; + } + back = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_STENCIL_SIZE, &value ); + if( value < stencil ) + continue; + stencil = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_DEPTH_SIZE, &value ); + if( value < depth ) + continue; + depth = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_CONFIG_CAVEAT, &value ); + if( value > caveat ) + continue; + caveat = value; + if( i > 0 ) + fbcbuffer_nondb = fbconfigs[ j ]; + else + fbcbuffer_db = fbconfigs[ j ]; + } + } + if( cnt ) + XFree( fbconfigs ); + if( fbcbuffer_db == NULL && fbcbuffer_nondb == NULL ) + { + kDebug( 1212 ) << "Couldn't find framebuffer configuration for buffer!" << endl; + return false; } + return true; } -// find config matching the given attributes and possibly the given X visual -bool SceneOpenGL::findConfig( const int* attrs, GLXFBConfig* config, VisualID visual ) +// make a list of the best configs for windows by depth +bool SceneOpenGL::initDrawableConfigs() { int cnt; - GLXFBConfig* fbconfigs = glXChooseFBConfig( display(), DefaultScreen( display()), - attrs, &cnt ); - if( fbconfigs != NULL ) + GLXFBConfig *fbconfigs = glXGetFBConfigs( display(), DefaultScreen( display() ), &cnt ); + + for( int i = 0; i <= 32; i++ ) { - if( visual == None ) - { - *config = fbconfigs[ 0 ]; - kDebug( 1212 ) << "Found FBConfig" << endl; - debugFBConfig( fbconfigs, 0, attrs ); - XFree( fbconfigs ); - return true; - } - else + int back, stencil, depth, caveat, alpha, rgba; + back = INT_MAX; + stencil = INT_MAX; + depth = INT_MAX; + caveat = INT_MAX; + rgba = 0; + fbcdrawableinfo[ i ].fbconfig = NULL; + fbcdrawableinfo[ i ].bind_texture_format = 0; + fbcdrawableinfo[ i ].y_inverted = 0; + for( int j = 0; j < cnt; j++ ) { - for( int i = 0; - i < cnt; - ++i ) + XVisualInfo *vi; + int visual_depth; + vi = glXGetVisualFromFBConfig( display(), fbconfigs[ j ] ); + if( vi == NULL ) + continue; + visual_depth = vi->depth; + XFree( vi ); + if( visual_depth != i ) + continue; + int value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_ALPHA_SIZE, &alpha ); + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_BUFFER_SIZE, &value ); + if( value != i && ( value - alpha ) != i ) + continue; + if( tfp_mode ) { - int value; - glXGetFBConfigAttrib( display(), fbconfigs[ i ], GLX_VISUAL_ID, &value ); - if( value == (int)visual ) + value = 0; + if( i == 32 ) { - kDebug( 1212 ) << "Found FBConfig" << endl; - *config = fbconfigs[ i ]; - debugFBConfig( fbconfigs, i, attrs ); - XFree( fbconfigs ); - return true; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_BIND_TO_TEXTURE_RGBA_EXT, &value ); + if( value ) + { + rgba = 1; + fbcdrawableinfo[ i ].bind_texture_format = GLX_TEXTURE_FORMAT_RGBA_EXT; + } + } + if( !value ) + { + if( rgba ) + continue; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_BIND_TO_TEXTURE_RGB_EXT, &value ); + if( !value ) + continue; + fbcdrawableinfo[ i ].bind_texture_format = GLX_TEXTURE_FORMAT_RGB_EXT; } } + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_DOUBLEBUFFER, &value ); + if( value > back ) + continue; + back = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_STENCIL_SIZE, &value ); + if( value > stencil ) + continue; + stencil = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_DEPTH_SIZE, &value ); + if( value > depth ) + continue; + depth = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_CONFIG_CAVEAT, &value ); + if( value > caveat ) + continue; + caveat = value; + glXGetFBConfigAttrib( display(), fbconfigs[ j ], + GLX_Y_INVERTED_EXT, &value ); + fbcdrawableinfo[ i ].y_inverted = value; + fbcdrawableinfo[ i ].fbconfig = fbconfigs[ j ]; } } -#if 0 // for debug - fbconfigs = glXGetFBConfigs( display(), DefaultScreen( display()), &cnt ); - for( int i = 0; - i < cnt; - ++i ) + if( cnt ) + XFree( fbconfigs ); + if( fbcdrawableinfo[ QX11Info::appDepth() ].fbconfig == NULL ) { - kDebug( 1212 ) << "Listing FBConfig:" << i << endl; - debugFBConfig( fbconfigs, i, attrs ); + kDebug( 1212 ) << "Couldn't find framebuffer configuration for default depth!" << endl; + return false; } - if( fbconfigs != NULL ) - XFree( fbconfigs ); -#endif - return false; + return true; } // the entry function for painting @@ -764,6 +830,15 @@ void SceneOpenGL::Window::bindTexture() glBindTexture( texture_target, texture ); return; } + if( tfp_mode ) + { + if( fbcdrawableinfo[ toplevel->depth() ].fbconfig == NULL ) + { + kDebug( 1212 ) << "No framebuffer configuration for depth " << toplevel->depth() + << "; not binding window" << endl; + return; + } + } // Get the pixmap with the window contents Pixmap pix = toplevel->windowPixmap(); // HACK @@ -855,16 +930,14 @@ void SceneOpenGL::Window::bindTexture() } static const int attrs[] = { - GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, + GLX_TEXTURE_FORMAT_EXT, fbcdrawableinfo[ toplevel->depth() ].bind_texture_format, None }; // the GLXPixmap will reference the X pixmap, so it will be freed automatically // when no longer needed - bound_glxpixmap = glXCreatePixmap( display(), fbcdrawable, pix, attrs ); + bound_glxpixmap = glXCreatePixmap( display(), fbcdrawableinfo[ toplevel->depth() ].fbconfig, pix, attrs ); findTextureTarget(); - int value; - glXGetFBConfigAttrib( display(), fbcdrawable, GLX_Y_INVERTED_EXT, &value ); - texture_y_inverted = value ? true : false; + texture_y_inverted = fbcdrawableinfo[ toplevel->depth() ].y_inverted ? true : false; glBindTexture( texture_target, texture ); if( !strict_binding ) glXBindTexImageEXT( display(), bound_glxpixmap, GLX_FRONT_LEFT_EXT, NULL ); @@ -872,8 +945,10 @@ void SceneOpenGL::Window::bindTexture() } else { // non-tfp case, copy pixmap contents to a texture + // note that if toplevel->depth() is not QX11Info::appDepth(), this may + // not work (however, it does seem to work with nvidia) findTextureTarget(); - GLXDrawable pixmap = glXCreatePixmap( display(), fbcdrawable, pix, NULL ); + GLXDrawable pixmap = glXCreatePixmap( display(), fbcdrawableinfo[ QX11Info::appDepth() ].fbconfig, pix, NULL ); glXMakeContextCurrent( display(), pixmap, pixmap, ctxdrawable ); if( last_pixmap != None ) glXDestroyPixmap( display(), last_pixmap ); --Boundary-00=_zjmvFKzXZP+yCCz Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Kwin mailing list Kwin@kde.org https://mail.kde.org/mailman/listinfo/kwin --Boundary-00=_zjmvFKzXZP+yCCz--