diff options
author | Tom Cooksey <thomas.cooksey@nokia.com> | 2009-05-22 14:48:51 (GMT) |
---|---|---|
committer | Tom Cooksey <thomas.cooksey@nokia.com> | 2009-05-22 17:40:52 (GMT) |
commit | c8e908a3ee259576ffe96e382ab677d7e3df1a4f (patch) | |
tree | 41c4f8dced9a2de7e79d321752473e0b5086ad7c | |
parent | 73a9e0fac1e1b417878286791877bcefeedb16a1 (diff) | |
download | Qt-c8e908a3ee259576ffe96e382ab677d7e3df1a4f.zip Qt-c8e908a3ee259576ffe96e382ab677d7e3df1a4f.tar.gz Qt-c8e908a3ee259576ffe96e382ab677d7e3df1a4f.tar.bz2 |
Try to use the X11 visual ID provided by EGL
EGL has an EGL_NATIVE_VISUAL_ID which can by used as the window's visual
ID. We now try to use this ID to avoid an XVisual <-> EGLConfig
mis-match. Of course this is usually broken in the EGL library, so we
fall back to trying to match outselves.
-rw-r--r-- | src/opengl/qgl_x11egl.cpp | 104 |
1 files changed, 74 insertions, 30 deletions
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 480a2dc..74b9038 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -114,13 +114,6 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) eglSwapInterval(d->eglContext->display(), d->glFormat.swapInterval()); #endif - // Create the EGL surface to draw into. - if (!d->eglContext->createSurface(device())) { - delete d->eglContext; - d->eglContext = 0; - return false; - } - return true; } @@ -250,13 +243,34 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, return; } + + // Create the EGL Context (which will also choose the config for us) if (d->glcx) d->glcx->doneCurrent(); QGLContext* oldcx = d->glcx; d->glcx = context; + 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; + } + + + + // Make sure native winIds are avaliable if (parentWidget()) { - // force creation of delay-created widgets parentWidget()->winId(); if (parentWidget()->x11Info().screen() != x11Info().screen()) d_func()->xinfo = parentWidget()->d_func()->xinfo; @@ -267,16 +281,55 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, 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); + 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); + if (chosenVisualInfo) { + memcpy(&vi, chosenVisualInfo, sizeof(XVisualInfo)); + XFree(chosenVisualInfo); + } + else { + qWarning("Warning: EGL suggested using X visual ID %d for config %d, but this seems to be invalid!", + nativeVisualId, (int)qeglCtx->config()); + vi.visualid = 0; + } + } + + if (vi.visualid == 0) { + // EGL does not know the visual ID, so try to select an appropriate one ourselves: + EGLint depth; + qeglCtx->configAttrib(EGL_BUFFER_SIZE, &depth); + + int err; + 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); + if (err == 0) { + qWarning("Error: Couldn't get any matching X visual!"); + return; + } + else + qWarning(" - Falling back to X11 suggested depth (%d)", depth); + } - int err = XMatchVisualInfo(x11Info().display(), x11Info().screen(), x11Info().depth(), TrueColor, &vi); - if (err == 0) { - qWarning("Error: Couldn't get a matching X visual for format"); - return; } XSetWindowAttributes a; - Window p = RootWindow(X11->display, vi.screen); + Window p = RootWindow(x11Info().display(), x11Info().screen()); if (parentWidget()) p = parentWidget()->winId(); @@ -294,27 +347,18 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext, create(w); // Create with the ID of the window we've just created - d->eglSurfaceWindowId = w; // Remember the window id we created the surface for - - if (visible) - show(); - bool createFailed = false; - if (!d->glcx->isValid()) { - if (!d->glcx->create(shareContext ? shareContext : oldcx)) - createFailed = true; - } - if (createFailed) { - if (deleteOldContext) - delete oldcx; + // Create the EGL surface to draw into. + if (!d->glcx->d_func()->eglContext->createSurface(this)) { + delete d->glcx->d_func()->eglContext; + d->glcx->d_func()->eglContext = 0; return; } - if (d->glcx->windowCreated() || d->glcx->deviceIsPixmap()) { - if (deleteOldContext) - delete oldcx; - return; - } + d->eglSurfaceWindowId = w; // Remember the window id we created the surface for + + if (visible) + show(); d->glcx->setWindowCreated(true); } |