Move surface ownership to GLContextProviderEGL.
authorAli Juma <ajuma@mozilla.com>
Mon, 06 Feb 2012 16:53:09 -0500
changeset 90893 43e6ffa6c2caf4accebc035598fc183ed8303b29
parent 90892 1cdaddcade2cf195a2ddd2701f8a45839d2471ee
child 90894 959073324dda2ec7f83e62e88ca5d9be0f454177
push idunknown
push userunknown
push dateunknown
milestone12.0a1
Move surface ownership to GLContextProviderEGL.
gfx/gl/GLContextProviderEGL.cpp
gfx/layers/ipc/CompositorParent.cpp
mobile/android/base/gfx/FlexibleGLSurfaceView.java
mobile/android/base/gfx/GLController.java
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidFlexViewWrapper.cpp
widget/android/AndroidFlexViewWrapper.h
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -1929,20 +1929,20 @@ static EGLSurface
 CreateSurfaceForWindow(nsIWidget *aWidget, EGLConfig config)
 {
     EGLSurface surface;
 
 #ifdef DEBUG
     sEGLLibrary.DumpEGLConfig(config);
 #endif
 
-    if (true) {
-        printf_stderr("... registering OGL compositor with bridge\n");
-        return mozilla::AndroidBridge::Bridge()->RegisterCompositor();
-    }
+    printf_stderr("... requesting window surface from bridge\n");
+    surface = mozilla::AndroidBridge::Bridge()->ProvideEGLSurface();
+    printf_stderr("got surface %p\n", surface);
+    return surface;
 #ifdef MOZ_JAVA_COMPOSITOR
 #elif defined(MOZ_WIDGET_ANDROID)
     printf_stderr("... requesting window surface from bridge\n");
 
     // On Android, we have to ask Java to make the eglCreateWindowSurface
     // call for us.  See GLHelpers.java for a description of why.
     //
     // We also only have one true "window", so we just use it directly and ignore
@@ -1990,17 +1990,22 @@ GLContextProviderEGL::CreateForWindow(ns
         return nsnull;
     }
 
     if (!CreateConfig(&config)) {
         printf_stderr("Failed to create EGL config!\n");
         return nsnull;
     }
 
-    EGLSurface surface = CreateSurfaceForWindow(aWidget, config);
+#ifdef MOZ_WIDGET_ANDROID
+    printf_stderr("... registering OGL compositor with bridge\n");
+    mozilla::AndroidBridge::Bridge()->RegisterCompositor();
+#endif
+
+   EGLSurface surface = CreateSurfaceForWindow(aWidget, config);
 
     if (!surface) {
         return nsnull;
     }
 
     if (!sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API)) {
         sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
         return nsnull;
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -103,17 +103,17 @@ CompositorParent::PauseComposition()
 
 void
 CompositorParent::ResumeComposition()
 {
   if (mPaused) {
     mPaused = false;
 
 #ifdef MOZ_WIDGET_ANDROID
-    //static_cast<LayerManagerOGL*>(mLayerManager.get())->gl()->RenewSurface();
+    static_cast<LayerManagerOGL*>(mLayerManager.get())->gl()->RenewSurface();
 #endif
   }
 }
 
 void
 CompositorParent::SchedulePauseOnCompositorThread(::base::Thread &aCompositorThread)
 {
   CancelableTask *pauseTask = NewRunnableMethod(this,
--- a/mobile/android/base/gfx/FlexibleGLSurfaceView.java
+++ b/mobile/android/base/gfx/FlexibleGLSurfaceView.java
@@ -153,16 +153,17 @@ public class FlexibleGLSurfaceView exten
                                             int height) {
         mController.sizeChanged(width, height);
         if (mGLThread != null) {
             mGLThread.surfaceChanged(width, height);
         }
         
         if (mListener != null) {
             mListener.compositionResumeRequested();
+            mListener.renderRequested();
         }
     }
 
     public synchronized void surfaceCreated(SurfaceHolder holder) {
         mController.surfaceCreated();
         if (mGLThread != null) {
             mGLThread.surfaceCreated();
         }
--- a/mobile/android/base/gfx/GLController.java
+++ b/mobile/android/base/gfx/GLController.java
@@ -243,16 +243,42 @@ public class GLController {
 
         mGL = mEGLContext.getGL();
 
         if (mView.getRenderer() != null) {
             mView.getRenderer().onSurfaceCreated((GL10)mGL, mEGLConfig);
             mView.getRenderer().onSurfaceChanged((GL10)mGL, mView.getWidth(), mView.getHeight());
         }
     }
+        
+    private EGLSurface provideEGLSurface() {
+        if (mEGL == null) {
+            mEGL = (EGL10)EGLContext.getEGL();
+
+            mEGLDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+            if (mEGLDisplay == EGL10.EGL_NO_DISPLAY) {
+                throw new GLControllerException("eglGetDisplay() failed");
+            }
+
+            int[] version = new int[2];
+            if (!mEGL.eglInitialize(mEGLDisplay, version)) {
+                throw new GLControllerException("eglInitialize() failed");
+            }
+
+            mEGLConfig = chooseConfig();
+        }
+
+        SurfaceHolder surfaceHolder = mView.getHolder();
+        mEGLSurface = mEGL.eglCreateWindowSurface(mEGLDisplay, mEGLConfig, surfaceHolder, null);
+        if (mEGLSurface == null || mEGLSurface == EGL10.EGL_NO_SURFACE) {
+            throw new GLControllerException("EGL window surface could not be created!");
+        }
+
+        return mEGLSurface;
+    }
 
     public static class GLControllerException extends RuntimeException {
         public static final long serialVersionUID = 1L;
 
         GLControllerException(String e) {
             super(e);
         }
     }
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -1040,35 +1040,39 @@ AndroidBridge::CallEglCreateWindowSurfac
 
     jint realSurface = env->GetIntField(surf, sfield);
 
     return (void*) realSurface;
 }
 
 static AndroidGLController sController;
 
-EGLSurface
+void
 AndroidBridge::RegisterCompositor()
 {
     ALOG_BRIDGE("AndroidBridge::RegisterCompositor");
     JNIEnv *env = GetJNIForThread();
     if (!env)
-        return NULL;
+        return;
 
     AutoLocalJNIFrame jniFrame(env, 3);
 
     jmethodID registerCompositor = env->GetStaticMethodID(jFlexSurfaceView, "registerCxxCompositor", "()Lorg/mozilla/gecko/gfx/GLController;");
 
     jobject glController = env->CallStaticObjectMethod(jFlexSurfaceView, registerCompositor);
 
     sController.Acquire(env, glController);
     sController.SetGLVersion(2);
-    sController.InitGLContext();
+}
+
+EGLSurface
+AndroidBridge::ProvideEGLSurface()
+{
     sController.WaitForValidSurface();
-    return sController.GetEGLSurface();
+    return sController.ProvideEGLSurface();
 }
 
 void
 AndroidBridge::PerformPreRenderHook()
 {
     JNIEnv *env = GetJNIForThread();
     if (!env) {
         return;
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -320,17 +320,18 @@ public:
         int mEntries;
         JNIEnv* mJNIEnv;
     };
 
     /* See GLHelpers.java as to why this is needed */
     void *CallEglCreateWindowSurface(void *dpy, void *config, AndroidGeckoSurfaceView& surfaceView);
 
     // Switch Java to composite with the Gecko Compositor thread
-    EGLSurface RegisterCompositor();
+    void RegisterCompositor();
+    EGLSurface ProvideEGLSurface();
     void PerformPreRenderHook();
     void PerformPostRenderHook();
 
     bool GetStaticStringField(const char *classID, const char *field, nsAString &result);
 
     bool GetStaticIntField(const char *className, const char *fieldName, PRInt32* aInt);
 
     void SetKeepScreenOn(bool on);
--- a/widget/android/AndroidFlexViewWrapper.cpp
+++ b/widget/android/AndroidFlexViewWrapper.cpp
@@ -80,16 +80,17 @@ jmethodID AndroidGLController::jGetEGLCo
 jmethodID AndroidGLController::jGetEGLContextMethod = 0;
 jmethodID AndroidGLController::jGetEGLSurfaceMethod = 0;
 jmethodID AndroidGLController::jHasSurfaceMethod = 0;
 jmethodID AndroidGLController::jSwapBuffersMethod = 0;
 jmethodID AndroidGLController::jCheckForLostContextMethod = 0;
 jmethodID AndroidGLController::jWaitForValidSurfaceMethod = 0;
 jmethodID AndroidGLController::jGetWidthMethod = 0;
 jmethodID AndroidGLController::jGetHeightMethod = 0;
+jmethodID AndroidGLController::jProvideEGLSurfaceMethod = 0;
 
 void
 AndroidGLController::Init(JNIEnv *aJEnv)
 {
     const char *className = "org/mozilla/gecko/gfx/GLController";
     jclass jClass = reinterpret_cast<jclass>(aJEnv->NewGlobalRef(aJEnv->FindClass(className)));
 
     jSetGLVersionMethod = aJEnv->GetMethodID(jClass, "setGLVersion", "(I)V");
@@ -98,16 +99,18 @@ AndroidGLController::Init(JNIEnv *aJEnv)
     jGetEGLDisplayMethod = aJEnv->GetMethodID(jClass, "getEGLDisplay",
                                               "()Ljavax/microedition/khronos/egl/EGLDisplay;");
     jGetEGLConfigMethod = aJEnv->GetMethodID(jClass, "getEGLConfig",
                                              "()Ljavax/microedition/khronos/egl/EGLConfig;");
     jGetEGLContextMethod = aJEnv->GetMethodID(jClass, "getEGLContext",
                                               "()Ljavax/microedition/khronos/egl/EGLContext;");
     jGetEGLSurfaceMethod = aJEnv->GetMethodID(jClass, "getEGLSurface",
                                               "()Ljavax/microedition/khronos/egl/EGLSurface;");
+    jProvideEGLSurfaceMethod = aJEnv->GetMethodID(jClass, "provideEGLSurface",
+                                                  "()Ljavax/microedition/khronos/egl/EGLSurface;");
     jHasSurfaceMethod = aJEnv->GetMethodID(jClass, "hasSurface", "()Z");
     jSwapBuffersMethod = aJEnv->GetMethodID(jClass, "swapBuffers", "()Z");
     jCheckForLostContextMethod = aJEnv->GetMethodID(jClass, "checkForLostContext", "()Z");
     jWaitForValidSurfaceMethod = aJEnv->GetMethodID(jClass, "waitForValidSurface", "()V");
     jGetWidthMethod = aJEnv->GetMethodID(jClass, "getWidth", "()I");
     jGetHeightMethod = aJEnv->GetMethodID(jClass, "getHeight", "()I");
 }
 
@@ -176,16 +179,23 @@ AndroidGLController::GetEGLContext()
 
 EGLSurface
 AndroidGLController::GetEGLSurface()
 {
     jobject jObj = mJEnv->CallObjectMethod(mJObj, jGetEGLSurfaceMethod);
     return reinterpret_cast<EGLSurface>(mJEnv->GetIntField(jObj, jEGLSurfacePointerField));
 }
 
+EGLSurface
+AndroidGLController::ProvideEGLSurface()
+{
+    jobject jObj = mJEnv->CallObjectMethod(mJObj, jProvideEGLSurfaceMethod);
+    return reinterpret_cast<EGLSurface>(mJEnv->GetIntField(jObj, jEGLSurfacePointerField));
+}
+
 bool
 AndroidGLController::HasSurface()
 {
     return mJEnv->CallBooleanMethod(mJObj, jHasSurfaceMethod);
 }
 
 bool
 AndroidGLController::SwapBuffers()
--- a/widget/android/AndroidFlexViewWrapper.h
+++ b/widget/android/AndroidFlexViewWrapper.h
@@ -82,16 +82,17 @@ public:
 
     void SetGLVersion(int aVersion);
     void InitGLContext();
     void DisposeGLContext();
     EGLDisplay GetEGLDisplay();
     EGLConfig GetEGLConfig();
     EGLContext GetEGLContext();
     EGLSurface GetEGLSurface();
+    EGLSurface ProvideEGLSurface();
     bool HasSurface();
     bool SwapBuffers();
     bool CheckForLostContext();
     void WaitForValidSurface();
     int GetWidth();
     int GetHeight();
 
 private:
@@ -103,15 +104,16 @@ private:
     static jmethodID jGetEGLContextMethod;
     static jmethodID jGetEGLSurfaceMethod;
     static jmethodID jHasSurfaceMethod;
     static jmethodID jSwapBuffersMethod;
     static jmethodID jCheckForLostContextMethod;
     static jmethodID jWaitForValidSurfaceMethod;
     static jmethodID jGetWidthMethod;
     static jmethodID jGetHeightMethod;
+    static jmethodID jProvideEGLSurfaceMethod;
 
     JNIEnv *mJEnv;
     jobject mJObj;
 };
 
 #endif