summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Cooksey <thomas.cooksey@nokia.com>2009-05-22 14:48:51 (GMT)
committerTom Cooksey <thomas.cooksey@nokia.com>2009-05-22 17:40:52 (GMT)
commitc8e908a3ee259576ffe96e382ab677d7e3df1a4f (patch)
tree41c4f8dced9a2de7e79d321752473e0b5086ad7c
parent73a9e0fac1e1b417878286791877bcefeedb16a1 (diff)
downloadQt-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.cpp104
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);
}