Bug 1415994 - 5. Use LayerSession from GeckoSession; r=snorp
authorJim Chen <nchen@mozilla.com>
Tue, 14 Nov 2017 18:18:35 -0500
changeset 443557 bb53058de7e93eb4faf3bc1623ba5306e463be71
parent 443556 3b24c9b8f391e34796510196c7c8051997e56c5b
child 443558 44d0e1e39f89f44767b07f480f620cd1daf207f1
push id8527
push userCallek@gmail.com
push dateThu, 11 Jan 2018 21:05:50 +0000
treeherdermozilla-beta@95342d212a7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1415994
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1415994 - 5. Use LayerSession from GeckoSession; r=snorp Make GeckoSession inherit from LayerSession, and connect its Compositor to native code as part of the GeckoSession routine. MozReview-Commit-ID: wQaH1A0a7z
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
widget/android/nsWindow.cpp
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
@@ -6,16 +6,17 @@
 
 package org.mozilla.gecko;
 
 import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Arrays;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
+import org.mozilla.gecko.gfx.LayerSession;
 import org.mozilla.gecko.mozglue.JNIObject;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
@@ -26,17 +27,18 @@ import android.os.IBinder;
 import android.os.IInterface;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-public class GeckoSession implements Parcelable {
+public class GeckoSession extends LayerSession
+                          implements Parcelable {
     private static final String LOGTAG = "GeckoSession";
     private static final boolean DEBUG = false;
 
     /* package */ enum State implements NativeQueue.State {
         INITIAL(0),
         READY(1);
 
         private final int mRank;
@@ -294,40 +296,42 @@ public class GeckoSession implements Par
             if (mBinder == null) {
                 mBinder = new Binder();
                 mBinder.attachInterface(this, Window.class.getName());
             }
             return mBinder;
         }
 
         @WrapForJNI(dispatchTo = "proxy")
-        static native void open(Window instance, EventDispatcher dispatcher,
-                                GeckoBundle settings, String chromeUri,
-                                int screenId, boolean privateMode);
+        public static native void open(Window instance, Compositor compositor,
+                                       EventDispatcher dispatcher,
+                                       GeckoBundle settings, String chromeUri,
+                                       int screenId, boolean privateMode);
 
         @WrapForJNI(dispatchTo = "proxy")
         @Override protected native void disposeNative();
 
         @WrapForJNI(dispatchTo = "proxy")
-        native void close();
+        public native void close();
 
         @WrapForJNI(dispatchTo = "proxy")
-        native void transfer(EventDispatcher dispatcher, GeckoBundle settings);
+        public native void transfer(Compositor compositor, EventDispatcher dispatcher,
+                                    GeckoBundle settings);
 
         @WrapForJNI(calledFrom = "gecko")
         private synchronized void onTransfer(final EventDispatcher dispatcher) {
             final NativeQueue nativeQueue = dispatcher.getNativeQueue();
             if (mNativeQueue != nativeQueue) {
                 nativeQueue.setState(mNativeQueue.getState());
                 mNativeQueue = nativeQueue;
             }
         }
 
         @WrapForJNI(dispatchTo = "proxy")
-        native void attach(GeckoView view, Object compositor);
+        public native void attach(GeckoView view);
 
         @WrapForJNI(calledFrom = "gecko")
         private synchronized void onReady() {
             if (mNativeQueue.checkAndSetState(State.INITIAL, State.READY)) {
                 Log.i(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() +
                       " - chrome startup finished");
             }
         }
@@ -375,20 +379,21 @@ public class GeckoSession implements Par
             throw new IllegalStateException("Session is open");
         }
 
         mWindow = window;
         mSettings = new GeckoSessionSettings(settings, this);
 
         if (mWindow != null) {
             if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-                mWindow.transfer(mEventDispatcher, mSettings.asBundle());
+                mWindow.transfer(mCompositor, mEventDispatcher, mSettings.asBundle());
             } else {
                 GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                         mWindow, "transfer",
+                        Compositor.class, mCompositor,
                         EventDispatcher.class, mEventDispatcher,
                         GeckoBundle.class, mSettings.asBundle());
             }
         }
     }
 
     /* package */ void transferFrom(final GeckoSession session) {
         transferFrom(session.mWindow, session.mSettings);
@@ -478,42 +483,42 @@ public class GeckoSession implements Par
 
         final String chromeUri = mSettings.getString(GeckoSessionSettings.CHROME_URI);
         final int screenId = mSettings.getInt(GeckoSessionSettings.SCREEN_ID);
         final boolean isPrivate = mSettings.getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE);
 
         mWindow = new Window(mNativeQueue);
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-            Window.open(mWindow, mEventDispatcher, mSettings.asBundle(),
-                        chromeUri, screenId, isPrivate);
+            Window.open(mWindow, mCompositor, mEventDispatcher,
+                        mSettings.asBundle(), chromeUri, screenId, isPrivate);
         } else {
             GeckoThread.queueNativeCallUntil(
                 GeckoThread.State.PROFILE_READY,
                 Window.class, "open",
                 Window.class, mWindow,
+                Compositor.class, mCompositor,
                 EventDispatcher.class, mEventDispatcher,
                 GeckoBundle.class, mSettings.asBundle(),
                 String.class, chromeUri,
                 screenId, isPrivate);
         }
     }
 
     public void attachView(final GeckoView view) {
         if (view == null) {
             return;
         }
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-            mWindow.attach(view, view.getCompositor());
+            mWindow.attach(view);
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                     mWindow, "attach",
-                    GeckoView.class, view,
-                    Object.class, view.getCompositor());
+                    GeckoView.class, view);
         }
     }
 
     public void closeWindow() {
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             mWindow.close();
             mWindow.disposeNative();
         } else {
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -274,33 +274,35 @@ public:
      */
 private:
     nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
 
 public:
     // Create and attach a window.
     static void Open(const jni::Class::LocalRef& aCls,
                      GeckoSession::Window::Param aWindow,
+                     jni::Object::Param aCompositor,
                      jni::Object::Param aDispatcher,
                      jni::Object::Param aSettings,
                      jni::String::Param aChromeURI,
                      int32_t aScreenId,
                      bool aPrivateMode);
 
     // Close and destroy the nsWindow.
     void Close();
 
     // Transfer this nsWindow to new GeckoSession objects.
     void Transfer(const GeckoSession::Window::LocalRef& inst,
+                  jni::Object::Param aCompositor,
                   jni::Object::Param aDispatcher,
                   jni::Object::Param aSettings);
 
     // Reattach this nsWindow to a new GeckoView.
     void Attach(const GeckoSession::Window::LocalRef& inst,
-                jni::Object::Param aView, jni::Object::Param aCompositor);
+                jni::Object::Param aView);
 
     void EnableEventDispatcher();
 };
 
 /**
  * NativePanZoomController handles its native calls on the UI thread, so make
  * it separate from GeckoViewSupport.
  */
@@ -1259,16 +1261,17 @@ nsWindow::GeckoViewSupport::~GeckoViewSu
     if (window.mLayerViewSupport) {
         window.mLayerViewSupport.Detach();
     }
 }
 
 /* static */ void
 nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
                                  GeckoSession::Window::Param aWindow,
+                                 jni::Object::Param aCompositor,
                                  jni::Object::Param aDispatcher,
                                  jni::Object::Param aSettings,
                                  jni::String::Param aChromeURI,
                                  int32_t aScreenId,
                                  bool aPrivateMode)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
@@ -1282,22 +1285,21 @@ nsWindow::GeckoViewSupport::Open(const j
         url = aChromeURI->ToCString();
     } else {
         nsresult rv = Preferences::GetCString("toolkit.defaultChromeURI", url);
         if (NS_FAILED(rv)) {
             url = NS_LITERAL_CSTRING("chrome://geckoview/content/geckoview.xul");
         }
     }
 
+    // Prepare an nsIAndroidView to pass as argument to the window.
     RefPtr<AndroidView> androidView = new AndroidView();
     androidView->mEventDispatcher->Attach(
             java::EventDispatcher::Ref::From(aDispatcher), nullptr);
-    if (aSettings) {
-        androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
-    }
+    androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
 
     nsAutoCString chromeFlags("chrome,dialog=0,resizable,scrollbars");
     if (aPrivateMode) {
         chromeFlags += ",private";
     }
     nsCOMPtr<mozIDOMWindowProxy> domWindow;
     ww->OpenWindow(nullptr, url.get(), nullptr, chromeFlags.get(),
                    androidView, getter_AddRefs(domWindow));
@@ -1307,33 +1309,33 @@ nsWindow::GeckoViewSupport::Open(const j
             nsPIDOMWindowOuter::From(domWindow);
     nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(pdomWindow);
     MOZ_ASSERT(widget);
 
     const auto window = static_cast<nsWindow*>(widget.get());
     window->SetScreenId(aScreenId);
 
     // Attach a new GeckoView support object to the new window.
-    window->mGeckoViewSupport = mozilla::MakeUnique<GeckoViewSupport>(
-        window, (GeckoSession::Window::LocalRef(aCls.Env(), aWindow)));
+    GeckoSession::Window::LocalRef sessionWindow(aCls.Env(), aWindow);
+    window->mGeckoViewSupport =
+            mozilla::MakeUnique<GeckoViewSupport>(window, sessionWindow);
+    window->mGeckoViewSupport->mDOMWindow = pdomWindow;
+    window->mAndroidView = androidView;
 
-    window->mGeckoViewSupport->mDOMWindow = pdomWindow;
+    // Attach other session support objects.
+    window->mGeckoViewSupport->Transfer(
+            sessionWindow, aCompositor, aDispatcher, aSettings);
 
     // Attach a new GeckoEditable support object to the new window.
     auto editable = GeckoEditable::New();
     auto editableChild = GeckoEditableChild::New(editable);
     editable->SetDefaultEditableChild(editableChild);
     window->mEditable = editable;
     window->mEditableSupport.Attach(editableChild, window, editableChild);
 
-    // Attach again using the new window.
-    androidView->mEventDispatcher->Attach(
-            java::EventDispatcher::Ref::From(aDispatcher), pdomWindow);
-    window->mAndroidView = androidView;
-
     if (window->mWidgetListener) {
         nsCOMPtr<nsIXULWindow> xulWindow(
                 window->mWidgetListener->GetXULWindow());
         if (xulWindow) {
             // Our window is not intrinsically sized, so tell nsXULWindow to
             // not set a size for us.
             xulWindow->SetIntrinsicallySized(false);
         }
@@ -1353,55 +1355,48 @@ nsWindow::GeckoViewSupport::Close()
 
     mDOMWindow->ForceClose();
     mDOMWindow = nullptr;
     mGeckoViewWindow = nullptr;
 }
 
 void
 nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
+                                     jni::Object::Param aCompositor,
                                      jni::Object::Param aDispatcher,
                                      jni::Object::Param aSettings)
 {
-    if (!window.mAndroidView) {
-        return;
-    }
-
-    window.mAndroidView->mEventDispatcher->Attach(
-            java::EventDispatcher::Ref::From(aDispatcher), mDOMWindow);
-    window.mAndroidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
-
-    inst->OnTransfer(aDispatcher);
-}
-
-void
-nsWindow::GeckoViewSupport::Attach(const GeckoSession::Window::LocalRef& inst,
-                                   jni::Object::Param aView,
-                                   jni::Object::Param aCompositor)
-{
-    // Associate our previous GeckoEditable with the new GeckoView.
-    MOZ_ASSERT(window.mEditable);
-    window.mEditable->OnViewChange(aView);
-
-    // mNPZCSupport might have already been detached through the Java side calling
-    // NativePanZoomController.destroy().
     if (window.mNPZCSupport) {
         window.mNPZCSupport.Detach();
     }
 
     if (window.mLayerViewSupport) {
         window.mLayerViewSupport.Detach();
     }
 
-    if (aCompositor) {
-        auto compositor = LayerView::Compositor::LocalRef(
-                inst.Env(), LayerView::Compositor::Ref::From(aCompositor));
-        window.mLayerViewSupport.Attach(compositor, &window, compositor);
-        compositor->Reattach();
+    auto compositor = LayerSession::Compositor::LocalRef(
+            inst.Env(), LayerSession::Compositor::Ref::From(aCompositor));
+    window.mLayerViewSupport.Attach(compositor, &window, compositor);
+
+    if (window.mAndroidView) {
+        window.mAndroidView->mEventDispatcher->Attach(
+                java::EventDispatcher::Ref::From(aDispatcher), mDOMWindow);
+        window.mAndroidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
     }
+
+    inst->OnTransfer(aDispatcher);
+}
+
+void
+nsWindow::GeckoViewSupport::Attach(const GeckoSession::Window::LocalRef& inst,
+                                   jni::Object::Param aView)
+{
+    // Associate our previous GeckoEditable with the new GeckoView.
+    MOZ_ASSERT(window.mEditable);
+    window.mEditable->OnViewChange(aView);
 }
 
 void
 nsWindow::InitNatives()
 {
     nsWindow::GeckoViewSupport::Base::Init();
     nsWindow::LayerViewSupport::Init();
     nsWindow::NPZCSupport::Init();