src/opengl/qgl_x11egl.cpp
changeset 18 2f34d5167611
parent 3 41300fa6a67c
child 30 5dc02b23752f
--- a/src/opengl/qgl_x11egl.cpp	Tue Feb 02 00:43:10 2010 +0200
+++ b/src/opengl/qgl_x11egl.cpp	Fri Apr 16 15:50:13 2010 +0300
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 ** All rights reserved.
 ** Contact: Nokia Corporation (qt-info@nokia.com)
 **
@@ -52,6 +52,119 @@
 
 QT_BEGIN_NAMESPACE
 
+
+bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config,
+                             const QX11Info &x11Info, bool useArgbVisual);
+
+/*
+    QGLTemporaryContext implementation
+*/
+
+class QGLTemporaryContextPrivate
+{
+public:
+    bool initialized;
+    Window window;
+    EGLContext context;
+    EGLSurface surface;
+    EGLDisplay display;
+};
+
+QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *)
+    : d(new QGLTemporaryContextPrivate)
+{
+    d->initialized = false;
+    d->window = 0;
+    d->context = 0;
+    d->surface = 0;
+    int screen = 0;
+
+    d->display = eglGetDisplay(EGLNativeDisplayType(X11->display));
+
+    if (!eglInitialize(d->display, NULL, NULL)) {
+        qWarning("QGLTemporaryContext: 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(d->display, attribs, &config, 1, &numConfigs);
+    if (!numConfigs) {
+        qWarning("QGLTemporaryContext: No EGL configurations available.");
+        return;
+    }
+
+    XVisualInfo visualInfo;
+    XVisualInfo *vi;
+    int numVisuals;
+    EGLint id = 0;
+
+    eglGetConfigAttrib(d->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, d->display, config, xinfo, false);
+    } else {
+        visualInfo.visualid = id;
+    }
+    vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals);
+    if (!vi || numVisuals < 1) {
+        qWarning("QGLTemporaryContext: Unable to get X11 visual info id.");
+        return;
+    }
+
+    d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen),
+                              0, 0, 1, 1, 0,
+                              vi->depth, InputOutput, vi->visual,
+                              0, 0);
+
+    d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL);
+
+    if (d->surface == EGL_NO_SURFACE) {
+        qWarning("QGLTemporaryContext: Error creating EGL surface.");
+        XFree(vi);
+        XDestroyWindow(X11->display, d->window);
+        return;
+    }
+
+    EGLint contextAttribs[] = {
+#ifdef QT_OPENGL_ES_2
+        EGL_CONTEXT_CLIENT_VERSION, 2,
+#endif
+        EGL_NONE
+    };
+    d->context = eglCreateContext(d->display, config, 0, contextAttribs);
+    if (d->context != EGL_NO_CONTEXT
+        && eglMakeCurrent(d->display, d->surface, d->surface, d->context))
+    {
+        d->initialized = true;
+    } else {
+        qWarning("QGLTemporaryContext: Error creating EGL context.");
+        eglDestroySurface(d->display, d->surface);
+        XDestroyWindow(X11->display, d->window);
+    }
+    XFree(vi);
+}
+
+QGLTemporaryContext::~QGLTemporaryContext()
+{
+    if (d->initialized) {
+        eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+        eglDestroyContext(d->display, d->context);
+        eglDestroySurface(d->display, d->surface);
+        XDestroyWindow(X11->display, d->window);
+    }
+}
+
 bool QGLFormat::hasOpenGLOverlays()
 {
     return false;
@@ -77,11 +190,6 @@
     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;
@@ -239,7 +347,7 @@
 
     // 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
-          
+
 #if !defined(QT_NO_XRENDER)
     if (vi.visualid == 0 && useArgbVisual) {
         // Try to use XRender to find an ARGB visual we can use
@@ -437,23 +545,6 @@
 {
 }
 
-void QGLExtensions::init()
-{
-    static bool init_done = false;
-
-    if (init_done)
-        return;
-    init_done = true;
-
-    // We need a context current to initialize the extensions.
-    QGLWidget tmpWidget;
-    tmpWidget.makeCurrent();
-
-    init_extensions();
-
-    tmpWidget.doneCurrent();
-}
-
 // Re-creates the EGL surface if the window ID has changed or if force is true
 void QGLWidgetPrivate::recreateEglSurface(bool force)
 {
@@ -518,7 +609,7 @@
 
         EGLint configCount = 0;
         do {
-            eglChooseConfig(QEglContext::defaultDisplay(0), configAttribs.properties(), targetConfig, 1, &configCount);
+            eglChooseConfig(QEglContext::display(), configAttribs.properties(), targetConfig, 1, &configCount);
             if (configCount > 0) {
                 // Got one
                 qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" )
@@ -557,7 +648,7 @@
         pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB);
 
     EGLSurface pixmapSurface;
-    pixmapSurface = eglCreatePixmapSurface(QEglContext::defaultDisplay(0),
+    pixmapSurface = eglCreatePixmapSurface(QEglContext::display(),
                                            pixmapConfig,
                                            (EGLNativePixmapType) pixmapData->handle(),
                                            pixmapAttribs.properties());
@@ -666,7 +757,7 @@
     QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
     if (pixmapData->gl_surface) {
         EGLBoolean success;
-        success = eglDestroySurface(QEglContext::defaultDisplay(0), (EGLSurface)pixmapData->gl_surface);
+        success = eglDestroySurface(QEglContext::display(), (EGLSurface)pixmapData->gl_surface);
         if (success == EGL_FALSE) {
             qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: "
                        << QEglContext::errorString(eglGetError());
@@ -681,7 +772,7 @@
     QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
     if (pixmapData->gl_surface) {
         EGLBoolean success;
-        success = eglReleaseTexImage(QEglContext::defaultDisplay(0),
+        success = eglReleaseTexImage(QEglContext::display(),
                                      (EGLSurface)pixmapData->gl_surface,
                                      EGL_BACK_BUFFER);
         if (success == EGL_FALSE) {