Bug 752539 - Pass in the AutoLocalJNIFrame to some methods that implicitly require it. r=blassey
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 08 May 2012 09:35:59 -0400
changeset 95756 3bc06857dcd2b2d18774cf662323e6c1f8cb3cbf
parent 95755 4eda2c7b640cc191f95148f79244af8a3936accb
child 95757 75d817e6bf4d504d12e4ee4f626c762114dff69c
child 95761 9f87dbd4d39ce0874c90e8c124e101d65cc93e36
push id1439
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 20:19:22 +0000
treeherdermozilla-aurora@ea74834dccd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey
bugs752539
milestone15.0a1
Bug 752539 - Pass in the AutoLocalJNIFrame to some methods that implicitly require it. r=blassey
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJavaWrappers.cpp
widget/android/AndroidJavaWrappers.h
widget/android/nsWindow.cpp
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -1149,17 +1149,17 @@ AndroidBridge::CallEglCreateWindowSurfac
      *    s = EGLContext.getEGL().eglCreateWindowSurface(new EGLDisplayImpl(dpy),
      *                                                   new EGLConfigImpl(config),
      *                                                   view.getHolder(), null);
      *    return s.mEGLSurface;
      *
      * We can't do it from java, because the EGLConfigImpl constructor is private.
      */
 
-    jobject surfaceHolder = sview.GetSurfaceHolder(env, &jniFrame);
+    jobject surfaceHolder = sview.GetSurfaceHolder(&jniFrame);
     if (!surfaceHolder)
         return nsnull;
 
     // grab some fields and methods we'll need
     jmethodID constructConfig = env->GetMethodID(jEGLConfigImplClass, "<init>", "(I)V");
     jmethodID constructDisplay = env->GetMethodID(jEGLDisplayImplClass, "<init>", "(I)V");
 
     jmethodID getEgl = env->GetStaticMethodID(jEGLContextClass, "getEGL", "()Ljavax/microedition/khronos/egl/EGL;");
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -569,16 +569,20 @@ public:
     // any local refs that you need to keep around in global refs!
     void Purge() {
         if (mJNIEnv) {
             mJNIEnv->PopLocalFrame(NULL);
             Push();
         }
     }
 
+    JNIEnv* GetEnv() {
+        return mJNIEnv;
+    }
+
     bool CheckForException() {
         if (mJNIEnv->ExceptionCheck()) {
             mJNIEnv->ExceptionDescribe();
             mJNIEnv->ExceptionClear();
             return true;
         }
 
         return false;
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -731,115 +731,158 @@ AndroidGeckoLayerClient::SyncViewportInf
     AndroidViewTransform viewTransform;
     viewTransform.Init(viewTransformJObj);
 
     aScrollOffset = nsIntPoint(viewTransform.GetX(env), viewTransform.GetY(env));
     aScaleX = aScaleY = viewTransform.GetScale(env);
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSoftwareDrawBitmap(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSoftwareDrawBitmap(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSoftwareDrawBuffer(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSoftwareDrawBuffer(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSurface(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSurface(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetSurfaceMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetSurfaceMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 jobject
-AndroidGeckoSurfaceView::GetSurfaceHolder(JNIEnv *env, AutoLocalJNIFrame *jniFrame)
+AndroidGeckoSurfaceView::GetSurfaceHolder(AutoLocalJNIFrame *jniFrame)
 {
-    if (!env || !jniFrame)
+    if (!jniFrame || !jniFrame->GetEnv())
         return nsnull;
 
-    jobject ret = env->CallObjectMethod(wrapped_obj, jGetHolderMethod);
+    jobject ret = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jGetHolderMethod);
     if (jniFrame->CheckForException())
         return nsnull;
 
     return ret;
 }
 
 bool
-AndroidGeckoLayerClient::CreateFrame(JNIEnv *env, AndroidLayerRendererFrame& aFrame)
+AndroidGeckoLayerClient::CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame)
 {
-    AutoLocalJNIFrame jniFrame(env, 1);
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
 
-    jobject frameJObj = env->CallObjectMethod(wrapped_obj, jCreateFrameMethod);
-    if (jniFrame.CheckForException())
+    jobject frameJObj = jniFrame->GetEnv()->CallObjectMethod(wrapped_obj, jCreateFrameMethod);
+    if (jniFrame->CheckForException())
         return false;
     NS_ABORT_IF_FALSE(frameJObj, "No frame object!");
 
-    aFrame.Init(env, frameJObj);
+    aFrame.Init(jniFrame->GetEnv(), frameJObj);
+    return true;
+}
+
+bool
+AndroidGeckoLayerClient::ActivateProgram(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jActivateProgramMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
+}
+
+bool
+AndroidGeckoLayerClient::DeactivateProgram(AutoLocalJNIFrame *jniFrame)
+{
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
     return true;
 }
 
-void
-AndroidGeckoLayerClient::ActivateProgram(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::BeginDrawing(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jActivateProgramMethod);
-}
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
 
-void
-AndroidGeckoLayerClient::DeactivateProgram(JNIEnv *env)
-{
-    env->CallVoidMethod(wrapped_obj, jDeactivateProgramMethod);
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jBeginDrawingMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
-void
-AndroidLayerRendererFrame::BeginDrawing(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::DrawBackground(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jBeginDrawingMethod);
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
-void
-AndroidLayerRendererFrame::DrawBackground(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::DrawForeground(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jDrawBackgroundMethod);
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
+
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jDrawForegroundMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
-void
-AndroidLayerRendererFrame::DrawForeground(JNIEnv *env)
+bool
+AndroidLayerRendererFrame::EndDrawing(AutoLocalJNIFrame *jniFrame)
 {
-    env->CallVoidMethod(wrapped_obj, jDrawForegroundMethod);
-}
+    if (!jniFrame || !jniFrame->GetEnv())
+        return false;
 
-void
-AndroidLayerRendererFrame::EndDrawing(JNIEnv *env)
-{
-    env->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
+    jniFrame->GetEnv()->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
+    if (jniFrame->CheckForException())
+        return false;
+
+    return true;
 }
 
 float
 AndroidViewTransform::GetX(JNIEnv *env)
 {
     if (!env)
         return 0.0f;
     return env->GetFloatField(wrapped_obj, jXField);
--- a/widget/android/AndroidJavaWrappers.h
+++ b/widget/android/AndroidJavaWrappers.h
@@ -176,20 +176,20 @@ private:
 
 class AndroidLayerRendererFrame : public WrappedJavaObject {
 public:
     static void InitLayerRendererFrameClass(JNIEnv *jEnv);
 
     void Init(JNIEnv *env, jobject jobj);
     void Dispose(JNIEnv *env);
 
-    void BeginDrawing(JNIEnv *env);
-    void DrawBackground(JNIEnv *env);
-    void DrawForeground(JNIEnv *env);
-    void EndDrawing(JNIEnv *env);
+    bool BeginDrawing(AutoLocalJNIFrame *jniFrame);
+    bool DrawBackground(AutoLocalJNIFrame *jniFrame);
+    bool DrawForeground(AutoLocalJNIFrame *jniFrame);
+    bool EndDrawing(AutoLocalJNIFrame *jniFrame);
 
 private:
     static jclass jLayerRendererFrameClass;
     static jmethodID jBeginDrawingMethod;
     static jmethodID jDrawBackgroundMethod;
     static jmethodID jDrawForegroundMethod;
     static jmethodID jEndDrawingMethod;
 };
@@ -203,19 +203,19 @@ public:
     AndroidGeckoLayerClient() {}
     AndroidGeckoLayerClient(jobject jobj) { Init(jobj); }
 
     void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight,
                                float aCssPageWidth, float aCssPageHeight);
     void SetPageSize(float aZoom, float aPageWidth, float aPageHeight, float aCssPageWidth, float aCssPageHeight);
     void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
                           nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
-    bool CreateFrame(JNIEnv *env, AndroidLayerRendererFrame& aFrame);
-    void ActivateProgram(JNIEnv *env);
-    void DeactivateProgram(JNIEnv *env);
+    bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
+    bool ActivateProgram(AutoLocalJNIFrame *jniFrame);
+    bool DeactivateProgram(AutoLocalJNIFrame *jniFrame);
 
 protected:
     static jclass jGeckoLayerClientClass;
     static jmethodID jSetFirstPaintViewport;
     static jmethodID jSetPageSize;
     static jmethodID jSyncViewportInfoMethod;
     static jmethodID jCreateFrameMethod;
     static jmethodID jActivateProgramMethod;
@@ -237,24 +237,24 @@ public:
     enum {
         DRAW_ERROR = 0,
         DRAW_GLES_2 = 1,
         DRAW_2D = 2,
         DRAW_DISABLED = 3
     };
 
     int BeginDrawing();
-    jobject GetSoftwareDrawBitmap(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
-    jobject GetSoftwareDrawBuffer(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
+    jobject GetSoftwareDrawBitmap(AutoLocalJNIFrame *jniFrame);
+    jobject GetSoftwareDrawBuffer(AutoLocalJNIFrame *jniFrame);
     void EndDrawing();
     void Draw2D(jobject bitmap, int width, int height);
     void Draw2D(jobject buffer, int stride);
 
-    jobject GetSurface(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
-    jobject GetSurfaceHolder(JNIEnv *env, AutoLocalJNIFrame *jniFrame);
+    jobject GetSurface(AutoLocalJNIFrame *jniFrame);
+    jobject GetSurfaceHolder(AutoLocalJNIFrame *jniFrame);
 
 protected:
     static jclass jGeckoSurfaceViewClass;
     static jmethodID jBeginDrawingMethod;
     static jmethodID jEndDrawingMethod;
     static jmethodID jDraw2DBitmapMethod;
     static jmethodID jDraw2DBufferMethod;
     static jmethodID jGetSoftwareDrawBitmapMethod;
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -912,17 +912,17 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe
         case AndroidGeckoEvent::SURFACE_CREATED:
             sSurfaceExists = true;
 
             if (AndroidBridge::Bridge()->HasNativeWindowAccess()) {
                 AndroidGeckoSurfaceView& sview(AndroidBridge::Bridge()->SurfaceView());
                 JNIEnv *env = AndroidBridge::GetJNIEnv();
                 if (env) {
                     AutoLocalJNIFrame jniFrame(env);
-                    jobject surface = sview.GetSurface(env, &jniFrame);
+                    jobject surface = sview.GetSurface(&jniFrame);
                     if (surface) {
                         sNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindow(env, surface);
                         if (sNativeWindow) {
                             AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, 0, 0, AndroidBridge::WINDOW_FORMAT_RGB_565);
                         }
                     }
                 }
             }
@@ -1176,17 +1176,17 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
             if (targetSurface->CairoStatus()) {
                 ALOG("### Failed to create a valid surface from the bitmap");
             } else {
                 DrawTo(targetSurface);
             }
 
             AndroidBridge::Bridge()->UnlockWindow(sNativeWindow);
         } else if (AndroidBridge::Bridge()->HasNativeBitmapAccess()) {
-            jobject bitmap = sview.GetSoftwareDrawBitmap(env, &jniFrame);
+            jobject bitmap = sview.GetSoftwareDrawBitmap(&jniFrame);
             if (!bitmap) {
                 ALOG("no bitmap to draw into - skipping draw");
                 return;
             }
 
             if (!AndroidBridge::Bridge()->ValidateBitmap(bitmap, mBounds.width, mBounds.height))
                 return;
 
@@ -1205,17 +1205,17 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
                 ALOG("### Failed to create a valid surface from the bitmap");
             } else {
                 DrawTo(targetSurface);
             }
 
             AndroidBridge::Bridge()->UnlockBitmap(bitmap);
             sview.Draw2D(bitmap, mBounds.width, mBounds.height);
         } else {
-            jobject bytebuf = sview.GetSoftwareDrawBuffer(env, &jniFrame);
+            jobject bytebuf = sview.GetSoftwareDrawBuffer(&jniFrame);
             if (!bytebuf) {
                 ALOG("no buffer to draw into - skipping draw");
                 return;
             }
 
             void *buf = env->GetDirectBufferAddress(bytebuf);
             int cap = env->GetDirectBufferCapacity(bytebuf);
             if (!buf || cap != (mBounds.width * mBounds.height * 2)) {
@@ -2228,25 +2228,21 @@ nsWindow::DrawWindowUnderlay(LayerManage
     JNIEnv *env = GetJNIForThread();
     NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowUnderlay()!");
     if (!env)
         return;
 
     AutoLocalJNIFrame jniFrame(env);
 
     AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient();
-    if (!client.CreateFrame(env, mLayerRendererFrame))
-        return;
-    client.ActivateProgram(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.BeginDrawing(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.DrawBackground(env);
-    if (jniFrame.CheckForException()) return;
-    client.DeactivateProgram(env);
+    if (!client.CreateFrame(&jniFrame, mLayerRendererFrame)) return;
+    if (!client.ActivateProgram(&jniFrame)) return;
+    if (!mLayerRendererFrame.BeginDrawing(&jniFrame)) return;
+    if (!mLayerRendererFrame.DrawBackground(&jniFrame)) return;
+    if (!client.DeactivateProgram(&jniFrame)) return; // redundant, but in case somebody adds code after this...
 }
 
 void
 nsWindow::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
 {
     JNIEnv *env = GetJNIForThread();
     NS_ABORT_IF_FALSE(env, "No JNI environment at DrawWindowOverlay()!");
     if (!env)
@@ -2254,25 +2250,20 @@ nsWindow::DrawWindowOverlay(LayerManager
 
     AutoLocalJNIFrame jniFrame(env);
 
     NS_ABORT_IF_FALSE(!mLayerRendererFrame.isNull(),
                       "Frame should have been created in DrawWindowUnderlay()!");
 
     AndroidGeckoLayerClient& client = AndroidBridge::Bridge()->GetLayerClient();
 
-    client.ActivateProgram(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.DrawForeground(env);
-    if (jniFrame.CheckForException()) return;
-    mLayerRendererFrame.EndDrawing(env);
-    if (jniFrame.CheckForException()) return;
-    client.DeactivateProgram(env);
-    if (jniFrame.CheckForException()) return;
-
+    if (!client.ActivateProgram(&jniFrame)) return;
+    if (!mLayerRendererFrame.DrawForeground(&jniFrame)) return;
+    if (!mLayerRendererFrame.EndDrawing(&jniFrame)) return;
+    if (!client.DeactivateProgram(&jniFrame)) return;
     mLayerRendererFrame.Dispose(env);
 }
 
 // off-main-thread compositor fields and functions
 
 nsRefPtr<mozilla::layers::CompositorParent> nsWindow::sCompositorParent = 0;
 nsRefPtr<mozilla::layers::CompositorChild> nsWindow::sCompositorChild = 0;
 base::Thread * nsWindow::sCompositorThread = 0;