src/gui/egl/qegl.cpp
changeset 29 b72c6db6890b
parent 23 89e065397ea6
child 30 5dc02b23752f
equal deleted inserted replaced
25:e24348a560a6 29:b72c6db6890b
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include <QtGui/qpaintdevice.h>
    42 #include <QtGui/qpaintdevice.h>
    43 #include <QtGui/qpixmap.h>
    43 #include <QtGui/qpixmap.h>
    44 #include <QtGui/qwidget.h>
    44 #include <QtGui/qwidget.h>
       
    45 #include <QtCore/qatomic.h>
    45 #include <QtCore/qdebug.h>
    46 #include <QtCore/qdebug.h>
    46 #include "qegl_p.h"
    47 #include "qegl_p.h"
    47 
    48 
    48 QT_BEGIN_NAMESPACE
    49 QT_BEGIN_NAMESPACE
       
    50 
       
    51 
       
    52 /*
       
    53     QEglContextTracker is used to track the EGL contexts that we
       
    54     create internally in Qt, so that we can call eglTerminate() to
       
    55     free additional EGL resources when the last context is destroyed.
       
    56 */
       
    57 
       
    58 class QEglContextTracker
       
    59 {
       
    60 public:
       
    61     static void ref() { contexts.ref(); }
       
    62     static void deref() {
       
    63         if (!contexts.deref()) {
       
    64             eglTerminate(QEglContext::display());
       
    65             displayOpen = 0;
       
    66         }
       
    67     }
       
    68     static void setDisplayOpened() { displayOpen = 1; }
       
    69     static bool displayOpened() { return displayOpen; }
       
    70 
       
    71 private:
       
    72     static QBasicAtomicInt contexts;
       
    73     static QBasicAtomicInt displayOpen;
       
    74 };
       
    75 
       
    76 QBasicAtomicInt QEglContextTracker::contexts = Q_BASIC_ATOMIC_INITIALIZER(0);
       
    77 QBasicAtomicInt QEglContextTracker::displayOpen = Q_BASIC_ATOMIC_INITIALIZER(0);
    49 
    78 
    50 // Current GL and VG contexts.  These are used to determine if
    79 // Current GL and VG contexts.  These are used to determine if
    51 // we can avoid an eglMakeCurrent() after a call to lazyDoneCurrent().
    80 // we can avoid an eglMakeCurrent() after a call to lazyDoneCurrent().
    52 // If a background thread modifies the value, the worst that will
    81 // If a background thread modifies the value, the worst that will
    53 // happen is a redundant eglMakeCurrent() in the foreground thread.
    82 // happen is a redundant eglMakeCurrent() in the foreground thread.
    63     , currentSurface(EGL_NO_SURFACE)
    92     , currentSurface(EGL_NO_SURFACE)
    64     , current(false)
    93     , current(false)
    65     , ownsContext(true)
    94     , ownsContext(true)
    66     , sharing(false)
    95     , sharing(false)
    67 {
    96 {
       
    97     QEglContextTracker::ref();
    68 }
    98 }
    69 
    99 
    70 QEglContext::~QEglContext()
   100 QEglContext::~QEglContext()
    71 {
   101 {
    72     destroyContext();
   102     destroyContext();
    73 
   103 
    74     if (currentGLContext == this)
   104     if (currentGLContext == this)
    75         currentGLContext = 0;
   105         currentGLContext = 0;
    76     if (currentVGContext == this)
   106     if (currentVGContext == this)
    77         currentVGContext = 0;
   107         currentVGContext = 0;
       
   108     QEglContextTracker::deref();
    78 }
   109 }
    79 
   110 
    80 bool QEglContext::isValid() const
   111 bool QEglContext::isValid() const
    81 {
   112 {
    82     return (ctx != EGL_NO_CONTEXT);
   113     return (ctx != EGL_NO_CONTEXT);
   359     return props;
   390     return props;
   360 }
   391 }
   361 
   392 
   362 EGLDisplay QEglContext::display()
   393 EGLDisplay QEglContext::display()
   363 {
   394 {
   364     static bool openedDisplay = false;
   395     if (!QEglContextTracker::displayOpened()) {
   365 
       
   366     if (!openedDisplay) {
       
   367         dpy = eglGetDisplay(nativeDisplay());
   396         dpy = eglGetDisplay(nativeDisplay());
   368         openedDisplay = true;
   397         QEglContextTracker::setDisplayOpened();
   369         if (dpy == EGL_NO_DISPLAY) {
   398         if (dpy == EGL_NO_DISPLAY) {
   370             qWarning("QEglContext::display(): Falling back to EGL_DEFAULT_DISPLAY");
   399             qWarning("QEglContext::display(): Falling back to EGL_DEFAULT_DISPLAY");
   371             dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY));
   400             dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY));
   372         }
   401         }
   373         if (dpy == EGL_NO_DISPLAY) {
   402         if (dpy == EGL_NO_DISPLAY) {