src/gui/egl/qegl.cpp
changeset 29 b72c6db6890b
parent 23 89e065397ea6
child 30 5dc02b23752f
--- a/src/gui/egl/qegl.cpp	Fri Jun 11 14:24:45 2010 +0300
+++ b/src/gui/egl/qegl.cpp	Wed Jun 23 19:07:03 2010 +0300
@@ -42,11 +42,40 @@
 #include <QtGui/qpaintdevice.h>
 #include <QtGui/qpixmap.h>
 #include <QtGui/qwidget.h>
+#include <QtCore/qatomic.h>
 #include <QtCore/qdebug.h>
 #include "qegl_p.h"
 
 QT_BEGIN_NAMESPACE
 
+
+/*
+    QEglContextTracker is used to track the EGL contexts that we
+    create internally in Qt, so that we can call eglTerminate() to
+    free additional EGL resources when the last context is destroyed.
+*/
+
+class QEglContextTracker
+{
+public:
+    static void ref() { contexts.ref(); }
+    static void deref() {
+        if (!contexts.deref()) {
+            eglTerminate(QEglContext::display());
+            displayOpen = 0;
+        }
+    }
+    static void setDisplayOpened() { displayOpen = 1; }
+    static bool displayOpened() { return displayOpen; }
+
+private:
+    static QBasicAtomicInt contexts;
+    static QBasicAtomicInt displayOpen;
+};
+
+QBasicAtomicInt QEglContextTracker::contexts = Q_BASIC_ATOMIC_INITIALIZER(0);
+QBasicAtomicInt QEglContextTracker::displayOpen = Q_BASIC_ATOMIC_INITIALIZER(0);
+
 // Current GL and VG contexts.  These are used to determine if
 // we can avoid an eglMakeCurrent() after a call to lazyDoneCurrent().
 // If a background thread modifies the value, the worst that will
@@ -65,6 +94,7 @@
     , ownsContext(true)
     , sharing(false)
 {
+    QEglContextTracker::ref();
 }
 
 QEglContext::~QEglContext()
@@ -75,6 +105,7 @@
         currentGLContext = 0;
     if (currentVGContext == this)
         currentVGContext = 0;
+    QEglContextTracker::deref();
 }
 
 bool QEglContext::isValid() const
@@ -361,11 +392,9 @@
 
 EGLDisplay QEglContext::display()
 {
-    static bool openedDisplay = false;
-
-    if (!openedDisplay) {
+    if (!QEglContextTracker::displayOpened()) {
         dpy = eglGetDisplay(nativeDisplay());
-        openedDisplay = true;
+        QEglContextTracker::setDisplayOpened();
         if (dpy == EGL_NO_DISPLAY) {
             qWarning("QEglContext::display(): Falling back to EGL_DEFAULT_DISPLAY");
             dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY));