Bug 677920 - Part 1: Add a ReleaseSurface method to GLContextEGL. r=matt.woodrow
authorAli Juma <ajuma@mozilla.com>
Tue, 23 Aug 2011 16:48:27 -0400
changeset 75775 6e7449c449ba336e49e2167d8edf3c28169c9962
parent 75774 dff3ecc0451a911ea5f96c2cd8b8a9cdcc28584b
child 75776 6f12501fde073115b7babd7d78be9636a3401f06
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersmatt
bugs677920
milestone9.0a1
Bug 677920 - Part 1: Add a ReleaseSurface method to GLContextEGL. r=matt.woodrow
gfx/thebes/GLContext.h
gfx/thebes/GLContextProviderEGL.cpp
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -564,16 +564,18 @@ public:
 #endif
         return MakeCurrentImpl(aForce);
     }
 
     virtual PRBool SetupLookupFunction() = 0;
 
     virtual void WindowDestroyed() {}
 
+    virtual void ReleaseSurface() {}
+
     void *GetUserData(void *aKey) {
         void *result = nsnull;
         mUserData.Get(aKey, &result);
         return result;
     }
 
     void SetUserData(void *aKey, void *aValue) {
         mUserData.Put(aKey, aValue);
--- a/gfx/thebes/GLContextProviderEGL.cpp
+++ b/gfx/thebes/GLContextProviderEGL.cpp
@@ -690,17 +690,19 @@ public:
         if (mGLWidget)
             return;
 
 #ifdef DEBUG
         printf_stderr("Destroying context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
 #endif
 
         sEGLLibrary.fDestroyContext(EGL_DISPLAY(), mContext);
-        sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+        if (mSurface) {
+            sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+        }
     }
 
     GLContextType GetContextType() {
         return ContextTypeEGL;
     }
 
     PRBool Init()
     {
@@ -778,24 +780,30 @@ public:
     }
 
     PRBool MakeCurrentImpl(PRBool aForce = PR_FALSE) {
         PRBool succeeded = PR_TRUE;
 
         // Assume that EGL has the same problem as WGL does,
         // where MakeCurrent with an already-current context is
         // still expensive.
-        if (aForce || sEGLLibrary.fGetCurrentContext() != mContext) {
+        if (!mSurface || aForce || sEGLLibrary.fGetCurrentContext() != mContext) {
             if (mGLWidget) {
 #ifdef MOZ_WIDGET_QT
                 static_cast<QGLWidget*>(mGLWidget)->makeCurrent();
 #else
                 succeeded = PR_FALSE;
 #endif
             } else {
+#ifndef MOZ_WIDGET_QT
+                if (!mSurface) {
+                    EGLConfig config = CreateConfig();
+                    mSurface = CreateSurfaceForWindow(NULL, config);
+                }
+#endif
                 succeeded = sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
                                                      mSurface, mSurface,
                                                      mContext);
             }
             NS_ASSERTION(succeeded, "Failed to make GL context current!");
         }
 
         return succeeded;
@@ -805,27 +813,38 @@ public:
     virtual PRBool
     RenewSurface() {
         /* We don't support renewing on QT because we don't create the surface ourselves */
         return PR_FALSE;
     }
 #else
     virtual PRBool
     RenewSurface() {
-        sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
-
+        ReleaseSurface();
         EGLConfig config = CreateConfig();
         mSurface = CreateSurfaceForWindow(NULL, config);
 
         return sEGLLibrary.fMakeCurrent(EGL_DISPLAY(),
                                         mSurface, mSurface,
                                         mContext);
     }
 #endif
 
+#ifndef MOZ_WIDGET_QT
+    virtual void
+    ReleaseSurface() {
+        if (mSurface) {
+            sEGLLibrary.fMakeCurrent(EGL_DISPLAY(), EGL_NO_SURFACE, EGL_NO_SURFACE,
+                                     EGL_NO_CONTEXT);
+            sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+            mSurface = NULL;
+        }
+    }
+#endif
+
     PRBool SetupLookupFunction()
     {
         mLookupFunc = (PlatformLookupFunction)sEGLLibrary.fGetProcAddress;
         return PR_TRUE;
     }
 
     void *GetNativeData(NativeDataType aType)
     {
@@ -835,17 +854,21 @@ public:
 
         default:
             return nsnull;
         }
     }
 
     PRBool SwapBuffers()
     {
-        return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
+        if (mSurface) {
+            return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
+        } else {
+            return PR_FALSE;
+        }
     }
     // GLContext interface - returns Tiled Texture Image in our case
     virtual already_AddRefed<TextureImage>
     CreateTextureImage(const nsIntSize& aSize,
                        TextureImage::ContentType aContentType,
                        GLenum aWrapMode,
                        PRBool aUseNearestFilter=PR_FALSE);
 
@@ -1038,17 +1061,19 @@ GLContextEGL::ResizeOffscreen(const gfxI
                                                  pbsize);
         if (!surface) {
             NS_WARNING("Failed to resize pbuffer");
             return nsnull;
         }
 
         SetOffscreenSize(aNewSize, pbsize);
 
-        sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+        if (mSurface) {
+            sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
+        }
 
         mSurface = surface;
 
         MakeCurrent(PR_TRUE);
         ClearSafely();
 
         return PR_TRUE;
     }