Poke the compositor to composite on a pan or zoom; stub AndroidBridge::GetViewTransform()
authorPatrick Walton <pwalton@mozilla.com>
Fri, 03 Feb 2012 18:35:58 -0800
changeset 89080 72ee03c1e571ed3e4fb5795a2aa16c7e800dc9f3
parent 89079 afa846fcbd500b20dcb6e6ef6cf366e65e6f482f
child 89081 e1f70b352cad41eaf7377f6566ab6723e7c59a47
push id610
push usergsharp@mozilla.com
push dateFri, 16 Mar 2012 04:42:47 +0000
treeherderfx-team@e5f6caa40409 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
Poke the compositor to composite on a pan or zoom; stub AndroidBridge::GetViewTransform()
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/CompositorParent.h
mobile/android/base/GeckoAppShell.java
mobile/android/base/gfx/FlexibleGLSurfaceView.java
mozglue/android/APKOpen.cpp
widget/android/AndroidBridge.cpp
widget/android/AndroidBridge.h
widget/android/AndroidJNI.cpp
widget/android/nsWindow.cpp
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -78,16 +78,23 @@ CompositorParent::RecvStop()
 {
   mStopped = true;
   Destroy();
   return true;
 }
 
 
 void
+CompositorParent::ScheduleCompositionOnCompositorThread(::base::Thread &aCompositorThread)
+{
+  CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
+  aCompositorThread.message_loop()->PostTask(FROM_HERE, composeTask);
+}
+
+void
 CompositorParent::ScheduleComposition()
 {
   printf_stderr("Schedule composition\n");
   CancelableTask *composeTask = NewRunnableMethod(this, &CompositorParent::Composite);
   MessageLoop::current()->PostTask(FROM_HERE, composeTask);
 
 // Test code for async scrolling.
 #ifdef OMTC_TEST_ASYNC_SCROLLING
--- a/gfx/layers/ipc/CompositorParent.h
+++ b/gfx/layers/ipc/CompositorParent.h
@@ -38,16 +38,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_layers_CompositorParent_h
 #define mozilla_layers_CompositorParent_h
 
 #include "mozilla/layers/PCompositorParent.h"
 #include "mozilla/layers/PLayersParent.h"
+#include "base/thread.h"
 #include "ShadowLayersManager.h"
 
 class nsIWidget;
 
 namespace mozilla {
 namespace layers {
 
 class LayerManager;
@@ -84,16 +85,17 @@ public:
 
   virtual void ShadowLayersUpdated() MOZ_OVERRIDE;
   void Destroy();
 
   LayerManager* GetLayerManager() { return mLayerManager; }
 
   void SetTransformation(float aScale, nsIntPoint aScrollOffset);
   void AsyncRender();
+  void ScheduleCompositionOnCompositorThread(::base::Thread &aCompositorThread);
 
 protected:
   virtual PLayersParent* AllocPLayers(const LayersBackend &backendType);
   virtual bool DeallocPLayers(PLayersParent* aLayers);
 
 private:
   void ScheduleComposition();
   void Composite();
--- a/mobile/android/base/GeckoAppShell.java
+++ b/mobile/android/base/GeckoAppShell.java
@@ -165,16 +165,17 @@ public class GeckoAppShell
     public static native void notifyNoMessageInList(int aRequestId, long aProcessId);
     public static native void notifyListCreated(int aListId, int aMessageId, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId, long aProcessId);
     public static native void notifyGotNextMessage(int aMessageId, String aReceiver, String aSender, String aBody, long aTimestamp, int aRequestId, long aProcessId);
     public static native void notifyReadingMessageListFailed(int aError, int aRequestId, long aProcessId);
 
     public static native ByteBuffer allocateDirectBuffer(long size);
     public static native void freeDirectBuffer(ByteBuffer buf);
     public static native void bindWidgetTexture();
+    public static native void scheduleComposite();
 
     // A looper thread, accessed by GeckoAppShell.getHandler
     private static class LooperThread extends Thread {
         public SynchronousQueue<Handler> mHandlerQueue =
             new SynchronousQueue<Handler>();
         
         public void run() {
             setName("GeckoLooper Thread");
--- a/mobile/android/base/gfx/FlexibleGLSurfaceView.java
+++ b/mobile/android/base/gfx/FlexibleGLSurfaceView.java
@@ -47,16 +47,17 @@ import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
 public class FlexibleGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
     private static final String LOGTAG = "GeckoFlexibleGLSurfaceView";
 
     private GLSurfaceView.Renderer mRenderer;
     private GLThread mGLThread; // Protected by this class's monitor.
     private GLController mController;
+    private Listener mListener;
 
     public FlexibleGLSurfaceView(Context context) {
         super(context);
         init();
     }
 
     public FlexibleGLSurfaceView(Context context, AttributeSet attributeSet) {
         super(context, attributeSet);
@@ -74,20 +75,27 @@ public class FlexibleGLSurfaceView exten
     public void setRenderer(GLSurfaceView.Renderer renderer) {
         mRenderer = renderer;
     }
 
     public GLSurfaceView.Renderer getRenderer() {
         return mRenderer;
     }
 
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
     public synchronized void requestRender() {
         if (mGLThread != null) {
             mGLThread.renderFrame();
         }
+        if (mListener != null) {
+            mListener.renderRequested();
+        }
     }
 
     /**
      * Creates a Java GL thread. After this is called, the FlexibleGLSurfaceView may be used just
      * like a GLSurfaceView. It is illegal to access the controller after this has been called.
      */
     public synchronized void createGLThread() {
         if (mGLThread != null) {
@@ -177,16 +185,20 @@ public class FlexibleGLSurfaceView exten
             Log.e(LOGTAG, "### registerCxxCompositor point D: " + flexView.getGLController());
             return flexView.getGLController();
         } catch (Exception e) {
             Log.e(LOGTAG, "### Exception! " + e);
             return null;
         }
     }
 
+    public interface Listener {
+        void renderRequested();
+    }
+
     public static class FlexibleGLSurfaceViewException extends RuntimeException {
         public static final long serialVersionUID = 1L;
 
         FlexibleGLSurfaceViewException(String e) {
             super(e);
         }
     }
 }
--- a/mozglue/android/APKOpen.cpp
+++ b/mozglue/android/APKOpen.cpp
@@ -291,16 +291,17 @@ SHELL_WRAPPER3(callObserver, jstring, js
 SHELL_WRAPPER1(removeObserver, jstring)
 SHELL_WRAPPER1(onChangeNetworkLinkStatus, jstring)
 SHELL_WRAPPER1(reportJavaCrash, jstring)
 SHELL_WRAPPER0(executeNextRunnable)
 SHELL_WRAPPER1(cameraCallbackBridge, jbyteArray)
 SHELL_WRAPPER3(notifyBatteryChange, jdouble, jboolean, jdouble)
 SHELL_WRAPPER3(notifySmsReceived, jstring, jstring, jlong)
 SHELL_WRAPPER0(bindWidgetTexture)
+SHELL_WRAPPER0(scheduleComposite)
 SHELL_WRAPPER3_WITH_RETURN(saveMessageInSentbox, jint, jstring, jstring, jlong)
 SHELL_WRAPPER6(notifySmsSent, jint, jstring, jstring, jlong, jint, jlong)
 SHELL_WRAPPER4(notifySmsDelivered, jint, jstring, jstring, jlong)
 SHELL_WRAPPER3(notifySmsSendFailed, jint, jint, jlong)
 SHELL_WRAPPER7(notifyGetSms, jint, jstring, jstring, jstring, jlong, jint, jlong)
 SHELL_WRAPPER3(notifyGetSmsFailed, jint, jint, jlong)
 SHELL_WRAPPER3(notifySmsDeleted, jboolean, jint, jlong)
 SHELL_WRAPPER3(notifySmsDeleteFailed, jint, jint, jlong)
@@ -705,16 +706,17 @@ loadGeckoLibs(const char *apkName)
   GETFUNC(removeObserver);
   GETFUNC(onChangeNetworkLinkStatus);
   GETFUNC(reportJavaCrash);
   GETFUNC(executeNextRunnable);
   GETFUNC(cameraCallbackBridge);
   GETFUNC(notifyBatteryChange);
   GETFUNC(notifySmsReceived);
   GETFUNC(bindWidgetTexture);
+  GETFUNC(scheduleComposite);
   GETFUNC(saveMessageInSentbox);
   GETFUNC(notifySmsSent);
   GETFUNC(notifySmsDelivered);
   GETFUNC(notifySmsSendFailed);
   GETFUNC(notifyGetSms);
   GETFUNC(notifyGetSmsFailed);
   GETFUNC(notifySmsDeleted);
   GETFUNC(notifySmsDeleteFailed);
--- a/widget/android/AndroidBridge.cpp
+++ b/widget/android/AndroidBridge.cpp
@@ -30,16 +30,20 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "mozilla/Util.h"
+#include "mozilla/layers/CompositorChild.h"
+#include "mozilla/layers/CompositorParent.h"
+
 #include <android/log.h>
 #include <dlfcn.h>
 
 #include "mozilla/Hal.h"
 #include "nsXULAppAPI.h"
 #include <prthread.h>
 #include "nsXPCOMStrings.h"
 
@@ -1844,16 +1848,48 @@ AndroidBridge::IsTablet()
 {
     JNIEnv *env = GetJNIEnv();
     if (!env)
         return false;
 
     return env->CallStaticBooleanMethod(mGeckoAppShellClass, jIsTablet);
 }
 
+void
+AndroidBridge::SetCompositorParent(mozilla::layers::CompositorParent* aCompositorParent,
+                                   ::base::Thread* aCompositorThread)
+{
+    mCompositorParent = aCompositorParent;
+    mCompositorThread = aCompositorThread;
+}
+
+void
+AndroidBridge::ScheduleComposite()
+{
+    if (mCompositorParent) {
+        mCompositorParent->ScheduleCompositionOnCompositorThread(*mCompositorThread);
+    }
+}
+
+void
+AndroidBridge::GetViewTransform(nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY)
+{
+    __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### GetViewTransform() TODO");
+}
+
+AndroidBridge::AndroidBridge()
+: mLayerClient(NULL)
+, mLayerClientType(0)
+{
+}
+
+AndroidBridge::~AndroidBridge()
+{
+}
+
 /* Implementation file */
 NS_IMPL_ISUPPORTS1(nsAndroidBridge, nsIAndroidBridge)
 
 nsAndroidBridge::nsAndroidBridge()
 {
 }
 
 nsAndroidBridge::~nsAndroidBridge()
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -50,45 +50,54 @@
 #include "nsThreadUtils.h"
 
 #include "AndroidFlexViewWrapper.h"
 #include "AndroidJavaWrappers.h"
 
 #include "nsIMutableArray.h"
 #include "nsIMIMEInfo.h"
 #include "nsColor.h"
+#include "BasicLayers.h"
 
 #include "nsIAndroidBridge.h"
 
 // Some debug #defines
 // #define DEBUG_ANDROID_EVENTS
 // #define DEBUG_ANDROID_WIDGET
 
 class nsWindow;
 class nsIDOMMozSmsMessage;
 
 /* See the comment in AndroidBridge about this function before using it */
 extern "C" JNIEnv * GetJNIForThread();
 
 extern bool mozilla_AndroidBridge_SetMainThread(void *);
 extern jclass GetGeckoAppShellClass();
 
+namespace base {
+class Thread;
+} // end namespace base
+
 namespace mozilla {
 
 namespace hal {
 class BatteryInformation;
 class NetworkInformation;
 } // namespace hal
 
 namespace dom {
 namespace sms {
 struct SmsFilterData;
 } // namespace sms
 } // namespace dom
 
+namespace layers {
+class CompositorParent;
+} // namespace layers
+
 // The order and number of the members in this structure must correspond
 // to the attrsAppearance array in GeckoAppShell.getSystemColors()
 typedef struct AndroidSystemColors {
     nscolor textColorPrimary;
     nscolor textColorPrimaryInverse;
     nscolor textColorSecondary;
     nscolor textColorSecondaryInverse;
     nscolor textColorTertiary;
@@ -386,36 +395,46 @@ public:
     void ClearMessageList(PRInt32 aListId);
 
     bool IsTablet();
 
     void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo);
     void EnableNetworkNotifications();
     void DisableNetworkNotifications();
 
+    void SetCompositorParent(mozilla::layers::CompositorParent* aCompositorParent,
+                             base::Thread* aCompositorThread);
+    void ScheduleComposite();
+    void GetViewTransform(nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY);
+
 protected:
     static AndroidBridge *sBridge;
 
     // the global JavaVM
     JavaVM *mJavaVM;
 
     // the JNIEnv for the main thread
     JNIEnv *mJNIEnv;
     void *mThread;
 
     // the GeckoSurfaceView
     AndroidGeckoSurfaceView mSurfaceView;
 
     AndroidGeckoLayerClient *mLayerClient;
     int mLayerClientType;
 
+    nsRefPtr<mozilla::layers::CompositorParent> mCompositorParent;
+    base::Thread *mCompositorThread;
+
     // the GeckoAppShell java class
     jclass mGeckoAppShellClass;
 
-    AndroidBridge() : mLayerClient(NULL), mLayerClientType(0) { }
+    AndroidBridge();
+    ~AndroidBridge();
+
     bool Init(JNIEnv *jEnv, jclass jGeckoApp);
 
     bool mOpenedGraphicsLibraries;
     void OpenGraphicsLibraries();
 
     bool mHasNativeBitmapAccess;
     bool mHasNativeWindowAccess;
 
--- a/widget/android/AndroidJNI.cpp
+++ b/widget/android/AndroidJNI.cpp
@@ -101,16 +101,17 @@ extern "C" {
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifySmsDeleteFailed(JNIEnv* jenv, jclass, jint, jint, jlong);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyNoMessageInList(JNIEnv* jenv, jclass, jint, jlong);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyListCreated(JNIEnv* jenv, jclass, jint, jint, jstring, jstring, jstring, jlong, jint, jlong);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyGotNextMessage(JNIEnv* jenv, jclass, jint, jstring, jstring, jstring, jlong, jint, jlong);
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_notifyReadingMessageListFailed(JNIEnv* jenv, jclass, jint, jint, jlong);
 
 #ifdef MOZ_JAVA_COMPOSITOR
     NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_bindWidgetTexture(JNIEnv* jenv, jclass);
+    NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_scheduleComposite(JNIEnv* jenv, jclass);
 #endif
 
 }
 
 
 /*
  * Incoming JNI methods
  */
@@ -848,9 +849,16 @@ Java_org_mozilla_gecko_GeckoAppShell_not
 #ifdef MOZ_JAVA_COMPOSITOR
 
 NS_EXPORT void JNICALL
 Java_org_mozilla_gecko_GeckoAppShell_bindWidgetTexture(JNIEnv* jenv, jclass)
 {
     nsWindow::BindToTexture();
 }
 
+NS_EXPORT void JNICALL
+Java_org_mozilla_gecko_GeckoAppShell_scheduleComposite(JNIEnv*, jclass)
+{
+    __android_log_print(ANDROID_LOG_ERROR, "Gecko", "### scheduleComposite()");
+    AndroidBridge::Bridge()->ScheduleComposite();
+}
+
 #endif
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -771,18 +771,22 @@ nsWindow::GetLayerManager(PLayersChild*,
         return mLayerManager;
     }
 
     bool useCompositor =
         Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
 
     if (useCompositor) {
         CreateCompositor();
-        if (mLayerManager)
+        if (mLayerManager) {
+            AndroidBridge::Bridge()->SetCompositorParent(mCompositorParent, mCompositorThread);
             return mLayerManager;
+        }
+
+        // If we get here, then off main thread compositing failed to initialize.
         sFailedToCreateGLContext = true;
     }
 
     mUseAcceleratedRendering = GetShouldAccelerate();
 
     if (!mUseAcceleratedRendering ||
         sFailedToCreateGLContext)
     {