summaryrefslogtreecommitdiffstats
path: root/src/opengl/qgl_x11egl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/opengl/qgl_x11egl.cpp')
-rw-r--r--src/opengl/qgl_x11egl.cpp164
1 files changed, 143 insertions, 21 deletions
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index a868e83..271f4de 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -52,6 +52,116 @@
QT_BEGIN_NAMESPACE
+
+bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config,
+ const QX11Info &x11Info, bool useArgbVisual);
+//
+// QGLTempContext is a lass for creating a temporary GL context (which is
+// needed during QGLWidget initialization to retrieve GL extension info).
+// Faster to construct than a full QGLWidget.
+//
+class QGLTempContext
+{
+public:
+ QGLTempContext(int screen = 0) :
+ initialized(false),
+ window(0),
+ context(0),
+ surface(0)
+ {
+ display = eglGetDisplay(EGLNativeDisplayType(X11->display));
+
+ if (!eglInitialize(display, NULL, NULL)) {
+ qWarning("QGLTempContext: Unable to initialize EGL display.");
+ return;
+ }
+
+ EGLConfig config;
+ int numConfigs = 0;
+ EGLint attribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+#ifdef QT_OPENGL_ES_2
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+#endif
+ EGL_NONE
+ };
+
+ eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+ if (!numConfigs) {
+ qWarning("QGLTempContext: No EGL configurations available.");
+ return;
+ }
+
+ XVisualInfo visualInfo;
+ XVisualInfo *vi;
+ int numVisuals;
+ EGLint id = 0;
+
+ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &id);
+ if (id == 0) {
+ // EGL_NATIVE_VISUAL_ID is optional and might not be supported
+ // on some implementations - we'll have to do it the hard way
+ QX11Info xinfo;
+ qt_egl_setup_x11_visual(visualInfo, display, config, xinfo, false);
+ } else {
+ visualInfo.visualid = id;
+ }
+ vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals);
+ if (!vi || numVisuals < 1) {
+ qWarning("QGLTempContext: Unable to get X11 visual info id.");
+ return;
+ }
+
+ window = XCreateWindow(X11->display, RootWindow(X11->display, screen),
+ 0, 0, 1, 1, 0,
+ vi->depth, InputOutput, vi->visual,
+ 0, 0);
+
+ surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType) window, NULL);
+
+ if (surface == EGL_NO_SURFACE) {
+ qWarning("QGLTempContext: Error creating EGL surface.");
+ XFree(vi);
+ XDestroyWindow(X11->display, window);
+ return;
+ }
+
+ EGLint contextAttribs[] = {
+#ifdef QT_OPENGL_ES_2
+ EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+ EGL_NONE
+ };
+ context = eglCreateContext(display, config, 0, contextAttribs);
+ if (context != EGL_NO_CONTEXT
+ && eglMakeCurrent(display, surface, surface, context))
+ {
+ initialized = true;
+ } else {
+ qWarning("QGLTempContext: Error creating EGL context.");
+ eglDestroySurface(display, surface);
+ XDestroyWindow(X11->display, window);
+ }
+ XFree(vi);
+ }
+
+ ~QGLTempContext() {
+ if (initialized) {
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroyContext(display, context);
+ eglDestroySurface(display, surface);
+ XDestroyWindow(X11->display, window);
+ }
+ }
+
+private:
+ bool initialized;
+ Window window;
+ EGLContext context;
+ EGLSurface surface;
+ EGLDisplay display;
+};
+
bool QGLFormat::hasOpenGLOverlays()
{
return false;
@@ -173,10 +283,16 @@ void QGLWidget::updateOverlayGL()
//handle overlay
}
+//#define QT_DEBUG_X11_VISUAL_SELECTION 1
+
bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, const QX11Info &x11Info, bool useArgbVisual)
{
bool foundVisualIsArgb = useArgbVisual;
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("qt_egl_setup_x11_visual() - useArgbVisual=%d", useArgbVisual);
+#endif
+
memset(&vi, 0, sizeof(XVisualInfo));
EGLint eglConfigColorSize;
@@ -199,7 +315,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
XRenderPictFormat *format;
format = XRenderFindVisualFormat(x11Info.display(), chosenVisualInfo->visual);
if (format->type == PictTypeDirect && format->direct.alphaMask) {
-// qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using ARGB X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#endif
foundVisualIsArgb = true;
vi = *chosenVisualInfo;
}
@@ -212,7 +330,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
#endif
{
if (eglConfigColorSize == chosenVisualInfo->depth) {
-// qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using opaque X Visual ID (%d) provided by EGL", (int)vi.visualid);
+#endif
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!",
@@ -248,7 +368,9 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
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);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Using X Visual ID (%d) for ARGB visual as provided by XRender", (int)vi.visualid);
+#endif
break;
}
}
@@ -272,24 +394,28 @@ bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig conf
} else
qWarning(" - Falling back to X11 suggested depth (%d)", depth);
}
-// else
-// qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ else
+ qDebug("Using X Visual ID (%d) for EGL provided depth (%d)", (int)vi.visualid, depth);
+#endif
// Don't try to use ARGB now unless the visual is 32-bit - even then it might stil fail :-(
if (useArgbVisual)
foundVisualIsArgb = vi.depth == 32; //### We might at some point (soon) get ARGB4444
}
-// qDebug("Visual Info:");
-// qDebug(" bits_per_rgb=%d", vi.bits_per_rgb);
-// qDebug(" red_mask=0x%x", vi.red_mask);
-// qDebug(" green_mask=0x%x", vi.green_mask);
-// qDebug(" blue_mask=0x%x", vi.blue_mask);
-// qDebug(" colormap_size=%d", vi.colormap_size);
-// qDebug(" c_class=%d", vi.c_class);
-// qDebug(" depth=%d", vi.depth);
-// qDebug(" screen=%d", vi.screen);
-// qDebug(" visualid=%d", vi.visualid);
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qDebug("Visual Info:");
+ qDebug(" bits_per_rgb=%d", vi.bits_per_rgb);
+ qDebug(" red_mask=0x%x", vi.red_mask);
+ qDebug(" green_mask=0x%x", vi.green_mask);
+ qDebug(" blue_mask=0x%x", vi.blue_mask);
+ qDebug(" colormap_size=%d", vi.colormap_size);
+ qDebug(" c_class=%d", vi.c_class);
+ qDebug(" depth=%d", vi.depth);
+ qDebug(" screen=%d", vi.screen);
+ qDebug(" visualid=%d", vi.visualid);
+#endif
return foundVisualIsArgb;
}
@@ -320,7 +446,7 @@ void QGLWidget::setContext(QGLContext *context, const QGLContext* shareContext,
// 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);
+ const bool tryArgbVisual = testAttribute(Qt::WA_TranslucentBackground) || fmt.alpha();
if (tryArgbVisual && fmt.alphaBufferSize() == -1)
fmt.setAlphaBufferSize(1);
@@ -430,12 +556,8 @@ void QGLExtensions::init()
init_done = true;
// We need a context current to initialize the extensions.
- QGLWidget tmpWidget;
- tmpWidget.makeCurrent();
-
+ QGLTempContext context;
init_extensions();
-
- tmpWidget.doneCurrent();
}
// Re-creates the EGL surface if the window ID has changed or if force is true