diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2009-09-30 14:37:55 (GMT) |
---|---|---|
committer | Tom Cooksey <thomas.cooksey@nokia.com> | 2009-10-01 16:13:01 (GMT) |
commit | ed6a2701320db60dd256df61a8030a867b917302 (patch) | |
tree | f03b904ff45c1348df548da0fb2e6e8905bc26da /src/opengl | |
parent | 30d9101ecabeb0778c829c3578f1fcf5ec276a8c (diff) | |
download | Qt-ed6a2701320db60dd256df61a8030a867b917302.zip Qt-ed6a2701320db60dd256df61a8030a867b917302.tar.gz Qt-ed6a2701320db60dd256df61a8030a867b917302.tar.bz2 |
Refactor retrieving the X11 visual for EGL
We need this in qwindowsurface_gl.cpp.
This patch was modified slightly by Tom, who stole it from another
branch. :-)
Reviewed-by: Gunnar
Diffstat (limited to 'src/opengl')
-rw-r--r-- | src/opengl/qgl_x11egl.cpp | 158 |
1 files changed, 84 insertions, 74 deletions
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index d4bf4da..d802bdd 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -140,85 +140,36 @@ void QGLWidget::updateOverlayGL() //handle overlay } -void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) +bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual) { - Q_D(QGLWidget); - if (context == 0) { - qWarning("QGLWidget::setContext: Cannot set null context"); - return; - } - if (!context->deviceIsPixmap() && context->device() != this) { - qWarning("QGLWidget::setContext: Context must refer to this widget"); - return; - } - - if (d->glcx) - d->glcx->doneCurrent(); - QGLContext* oldcx = d->glcx; - d->glcx = context; - - if (parentWidget()) { - // force creation of delay-created widgets - parentWidget()->winId(); - if (parentWidget()->x11Info().screen() != x11Info().screen()) - d_func()->xinfo = parentWidget()->d_func()->xinfo; - } - - // If the application has set WA_TranslucentBackground and not explicitly set - // the alpha buffer size to zero, modify the format so it have an alpha channel - QGLFormat& fmt = d->glcx->d_func()->glFormat; - const bool useArgbVisual = testAttribute(Qt::WA_TranslucentBackground); - if (useArgbVisual && fmt.alphaBufferSize() == -1) - fmt.setAlphaBufferSize(1); - - bool createFailed = false; - if (!d->glcx->isValid()) { - if (!d->glcx->create(shareContext ? shareContext : oldcx)) - createFailed = true; - } - if (createFailed) { - if (deleteOldContext) - delete oldcx; - return; - } - - if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { - if (deleteOldContext) - delete oldcx; - return; - } + bool foundVisualIsArgb = useArgbVisual; - bool visible = isVisible(); - if (visible) - hide(); - - XVisualInfo vi; memset(&vi, 0, sizeof(XVisualInfo)); // Check to see if EGL is suggesting an appropriate visual id: EGLint nativeVisualId; - QEglContext* qeglCtx = d->glcx->d_func()->eglContext; - qeglCtx->configAttrib(EGL_NATIVE_VISUAL_ID, &nativeVisualId); + eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &nativeVisualId); vi.visualid = nativeVisualId; if (vi.visualid) { // EGL has suggested a visual id, so get the rest of the visual info for that id: XVisualInfo *chosenVisualInfo; int matchingCount = 0; - chosenVisualInfo = XGetVisualInfo(x11Info().display(), VisualIDMask, &vi, &matchingCount); + chosenVisualInfo = XGetVisualInfo(x11Info.display(), VisualIDMask, &vi, &matchingCount); if (chosenVisualInfo) { #if !defined(QT_NO_XRENDER) if (useArgbVisual) { // Check to make sure the visual provided by EGL is ARGB XRenderPictFormat *format; - format = XRenderFindVisualFormat(x11Info().display(), chosenVisualInfo->visual); + format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual); if (format->type == PictTypeDirect && format->direct.alphaMask) { -// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid); +// qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid); + foundVisualIsArgb = true; vi = *chosenVisualInfo; } else { qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this is not ARGB", - nativeVisualId, (int)qeglCtx->config()); + nativeVisualId, (int)config); vi.visualid = 0; } } else @@ -231,32 +182,32 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, } else { qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this seems to be invalid!", - nativeVisualId, (int)qeglCtx->config()); + nativeVisualId, (int)config); vi.visualid = 0; } } // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo - - bool useArgb = context->format().alpha() && !context->deviceIsPixmap(); + #if !defined(QT_NO_XRENDER) - if (vi.visualid == 0 && useArgb) { + if (vi.visualid == 0 && useArgbVisual) { // Try to use XRender to find an ARGB visual we can use - vi.screen = x11Info().screen(); - vi.depth = 32; + vi.screen = x11Info.screen(); + vi.depth = 32; //### We might at some point (soon) get ARGB4444 vi.c_class = TrueColor; XVisualInfo *matchingVisuals; int matchingCount = 0; - matchingVisuals = XGetVisualInfo(x11Info().display(), + matchingVisuals = XGetVisualInfo(x11Info.display(), VisualScreenMask|VisualDepthMask|VisualClassMask, &vi, &matchingCount); for (int i = 0; i < matchingCount; ++i) { XRenderPictFormat *format; - format = XRenderFindVisualFormat(x11Info().display(), matchingVisuals[i].visual); + format = XRenderFindVisualFormat(x11Info.display(), matchingVisuals[i].visual); if (format->type == PictTypeDirect && format->direct.alphaMask) { vi = matchingVisuals[i]; + foundVisualIsArgb = true; // qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid); break; } @@ -267,17 +218,17 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, if (vi.visualid == 0) { EGLint depth; - qeglCtx->configAttrib(EGL_BUFFER_SIZE, &depth); + eglGetConfigAttrib(display, config, EGL_BUFFER_SIZE, &depth); int err; - err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi); + err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi); if (err == 0) { qWarning("Warning: Can't find an X visual which matches the EGL config(%d)'s depth (%d)!", - (int)qeglCtx->config(), depth); - depth = x11Info().depth(); - err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), depth, TrueColor, &vi); + (int)config, depth); + depth = x11Info.depth(); + err = XMatchVisualInfo(x11Info.display(), x11Info.screen(), depth, TrueColor, &vi); if (err == 0) { qWarning("Error: Couldn't get any matching X visual!"); - return; + return false; } else qWarning(" - Falling back to X11 suggested depth (%d)", depth); } @@ -285,8 +236,8 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, // qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth); // Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-( - if (useArgb) - useArgb = vi.depth == 32; + if (useArgbVisual) + foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444 } // qDebug("Visual Info:"); @@ -299,6 +250,65 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, // qDebug(" depth=%d", vi.depth); // qDebug(" screen=%d", vi.screen); // qDebug(" visualid=%d", vi.visualid); + return foundVisualIsArgb; +} + +void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, bool deleteOldContext) +{ + Q_D(QGLWidget); + if (context == 0) { + qWarning("QGLWidget::setContext: Cannot set null context"); + return; + } + if (!context->deviceIsPixmap() && context->device() != this) { + qWarning("QGLWidget::setContext: Context must refer to this widget"); + return; + } + + if (d->glcx) + d->glcx->doneCurrent(); + QGLContext* oldcx = d->glcx; + d->glcx = context; + + if (parentWidget()) { + // force creation of delay-created widgets + parentWidget()->winId(); + if (parentWidget()->x11Info().screen() != x11Info().screen()) + d_func()->xinfo = parentWidget()->d_func()->xinfo; + } + + // If the application has set WA_TranslucentBackground and not explicitly set + // the alpha buffer size to zero, modify the format so it have an alpha channel + QGLFormat& fmt = d->glcx->d_func()->glFormat; + const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground); + if (tryArgbVisual && fmt.alphaBufferSize() == -1) + fmt.setAlphaBufferSize(1); + + bool createFailed = false; + if (!d->glcx->isValid()) { + if (!d->glcx->create(shareContext ? shareContext : oldcx)) + createFailed = true; + } + if (createFailed) { + if (deleteOldContext) + delete oldcx; + return; + } + + if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { + if (deleteOldContext) + delete oldcx; + return; + } + + bool visible = isVisible(); + if (visible) + hide(); + + XVisualInfo vi; + QEglContext *eglContext = d->glcx->d_func()->eglContext; + bool usingArgbVisual = qt_egl_setup_x11_visual(vi, eglContext->display(), eglContext->config(), + x11Info(), tryArgbVisual); XSetWindowAttributes a; @@ -311,7 +321,7 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, a.border_pixel = colmap.pixel(Qt::black); unsigned int valueMask = CWBackPixel|CWBorderPixel; - if(useArgb) { + if (usingArgbVisual) { a.colormap = XCreateColormap(x11Info().display(), p, vi.visual, AllocNone); valueMask |= CWColormap; } |