From 76c415b586991d978d46a888fb40c631513407dc Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Fri, 4 Dec 2009 20:48:53 +0100 Subject: [PATCH 0946/1244] Fix WA_TranslucentBackground for QGLWidgets on X11/EGL Also check for existing QEglContext before creating a new one and leaking a context. Reviewed-by: TrustMe --- src/opengl/qgl_x11egl.cpp | 118 ++++++++++++++++++++++++++++----------------- 1 files changed, 73 insertions(+), 45 deletions(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index b51c239..a868e83 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -63,6 +63,7 @@ void qt_egl_add_platform_config(QEglProperties& props, QPaintDevice *device) props.setPixelFormat(static_cast(device)->format()); } +// Chooses the EGL config and creates the EGL context bool QGLContext::chooseContext(const QGLContext* shareContext) { Q_D(QGLContext); @@ -73,56 +74,74 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) int devType = device()->devType(); // Get the display and initialize it. - d->eglContext = new QEglContext(); - d->eglContext->setApi(QEgl::OpenGL); - if (!d->eglContext->openDisplay(device())) { - delete d->eglContext; - d->eglContext = 0; - return false; - } + if (d->eglContext == 0) { + d->eglContext = new QEglContext(); + d->eglContext->setApi(QEgl::OpenGL); + if (!d->eglContext->openDisplay(device())) { + delete d->eglContext; + d->eglContext = 0; + return false; + } - // Construct the configuration we need for this surface. - QEglProperties configProps; - qt_egl_set_format(configProps, devType, d->glFormat); - qt_egl_add_platform_config(configProps, device()); - configProps.setRenderableType(QEgl::OpenGL); - - QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; - if (device()->depth() == 16) { - configProps.setValue(EGL_RED_SIZE, 5); - configProps.setValue(EGL_GREEN_SIZE, 6); - configProps.setValue(EGL_BLUE_SIZE, 5); - configProps.setValue(EGL_ALPHA_SIZE, 0); - matchType = QEgl::ExactPixelFormat; - } - configProps.setRenderableType(QEgl::OpenGL); + // Construct the configuration we need for this surface. + QEglProperties configProps; + qt_egl_set_format(configProps, devType, d->glFormat); + qt_egl_add_platform_config(configProps, device()); + configProps.setRenderableType(QEgl::OpenGL); + +#if We_have_an_EGL_library_which_bothers_to_check_EGL_BUFFER_SIZE + if (device()->depth() == 16 && configProps.value(EGL_ALPHA_SIZE) <= 0) { + qDebug("Setting EGL_BUFFER_SIZE to 16"); + configProps.setValue(EGL_BUFFER_SIZE, 16); + configProps.setValue(EGL_ALPHA_SIZE, 0); + } - // Search for a matching configuration, reducing the complexity - // each time until we get something that matches. - if (!d->eglContext->chooseConfig(configProps, matchType)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } + if (!d->eglContext->chooseConfig(configProps, QEgl::BestPixelFormat)) { + delete d->eglContext; + d->eglContext = 0; + return false; + } +#else + QEgl::PixelFormatMatch matchType = QEgl::BestPixelFormat; + if ((device()->depth() == 16) && configProps.value(EGL_ALPHA_SIZE) == 0) { + configProps.setValue(EGL_RED_SIZE, 5); + configProps.setValue(EGL_GREEN_SIZE, 6); + configProps.setValue(EGL_BLUE_SIZE, 5); + configProps.setValue(EGL_ALPHA_SIZE, 0); + matchType = QEgl::ExactPixelFormat; + } - // Inform the higher layers about the actual format properties. - qt_egl_update_format(*(d->eglContext), d->glFormat); + // Search for a matching configuration, reducing the complexity + // each time until we get something that matches. + if (!d->eglContext->chooseConfig(configProps, matchType)) { + delete d->eglContext; + d->eglContext = 0; + return false; + } +#endif - // Create a new context for the configuration. - if (!d->eglContext->createContext - (shareContext ? shareContext->d_func()->eglContext : 0)) { - delete d->eglContext; - d->eglContext = 0; - return false; - } - d->sharing = d->eglContext->isSharing(); - if (d->sharing && shareContext) - const_cast(shareContext)->d_func()->sharing = true; +// qDebug("QGLContext::chooseContext() - using EGL config %d:", d->eglContext->config()); +// qDebug() << QEglProperties(d->eglContext->config()).toString(); + + // Create a new context for the configuration. + if (!d->eglContext->createContext + (shareContext ? shareContext->d_func()->eglContext : 0)) { + delete d->eglContext; + d->eglContext = 0; + return false; + } + d->sharing = d->eglContext->isSharing(); + if (d->sharing && shareContext) + const_cast(shareContext)->d_func()->sharing = true; #if defined(EGL_VERSION_1_1) - if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) - eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); + if (d->glFormat.swapInterval() != -1 && devType == QInternal::Widget) + eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); #endif + } + + // Inform the higher layers about the actual format properties. + qt_egl_update_format(*(d->eglContext), d->glFormat); return true; } @@ -160,6 +179,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf memset(&vi, 0, sizeof(XVisualInfo)); + EGLint eglConfigColorSize; + eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &eglConfigColorSize); + // Check to see if EGL is suggesting an appropriate visual id: EGLint nativeVisualId; eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId); @@ -189,8 +211,12 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf } else #endif { -// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); - vi = *chosenVisualInfo; + if (eglConfigColorSize == chosenVisualInfo->depth) { +// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); + vi = *chosenVisualInfo; + } else + qWarning("Warning: EGL suggested using X visual ID %d (%d bpp) for config %d (%d bpp), but the depths do not match!", + nativeVisualId, chosenVisualInfo->depth, (int)config, eglConfigColorSize); } XFree(chosenVisualInfo); } @@ -300,6 +326,8 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool createFailed = false; if (!d->glcx->isValid()) { + // Create the QGLContext here, which in turn chooses the EGL config + // and creates the EGL context: if (!d->glcx->create(shareContext ? shareContext : oldcx)) createFailed = true; } -- 1.6.5