Bug 1445662 - Update RemoteContentController to allow the GPU process controller thread to be different from the compositor thread. r?rhunt draft
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 15 Mar 2018 15:10:39 -0400
changeset 768174 a61776dfd7a00dc34d92e5a58bfe3bcd120ac4ff
parent 768173 2ed455f5acc857a0dd05b554ab8b569ed6c2ecd7
push id102813
push userkgupta@mozilla.com
push dateThu, 15 Mar 2018 19:11:06 +0000
reviewersrhunt
bugs1445662
milestone61.0a1
Bug 1445662 - Update RemoteContentController to allow the GPU process controller thread to be different from the compositor thread. r?rhunt A couple of RemoteContentController methods get called on the controller thread in the GPU process. This is the same as the compositor thread so we could just do compositor-thread stuff here, but we will want to support the controller thread being the main thread instead of the compositor thread. So we detect those cases and bounce the message accordingly. MozReview-Commit-ID: IOHrBcVswnt
gfx/layers/ipc/RemoteContentController.cpp
gfx/layers/ipc/RemoteContentController.h
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -55,35 +55,62 @@ RemoteContentController::HandleTapOnMain
 
   dom::TabParent* tab = dom::TabParent::GetTabParentFromLayersId(aGuid.mLayersId);
   if (tab) {
     tab->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
   }
 }
 
 void
+RemoteContentController::HandleTapOnCompositorThread(TapType aTapType,
+                                                     LayoutDevicePoint aPoint,
+                                                     Modifiers aModifiers,
+                                                     ScrollableLayerGuid aGuid,
+                                                     uint64_t aInputBlockId)
+{
+  MOZ_ASSERT(XRE_IsGPUProcess());
+  MOZ_ASSERT(MessageLoop::current() == mCompositorThread);
+
+  // The raw pointer to APZCTreeManagerParent is ok here because we are on the
+  // compositor thread.
+  APZCTreeManagerParent* apzctmp =
+      CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId);
+  if (apzctmp) {
+    Unused << apzctmp->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
+  }
+}
+
+void
 RemoteContentController::HandleTap(TapType aTapType,
                                    const LayoutDevicePoint& aPoint,
                                    Modifiers aModifiers,
                                    const ScrollableLayerGuid& aGuid,
                                    uint64_t aInputBlockId)
 {
   APZThreadUtils::AssertOnControllerThread();
 
   if (XRE_GetProcessType() == GeckoProcessType_GPU) {
-    MOZ_ASSERT(MessageLoop::current() == mCompositorThread);
-
-    // The raw pointer to APZCTreeManagerParent is ok here because we are on the
-    // compositor thread.
-    APZCTreeManagerParent* apzctmp =
-        CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId);
-    if (apzctmp) {
-      Unused << apzctmp->SendHandleTap(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
+    if (MessageLoop::current() == mCompositorThread) {
+      HandleTapOnCompositorThread(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
+    } else {
+      // We have to send messages from the compositor thread
+      mCompositorThread->PostTask(NewRunnableMethod<TapType,
+                                                    LayoutDevicePoint,
+                                                    Modifiers,
+                                                    ScrollableLayerGuid,
+                                                    uint64_t>(
+        "layers::RemoteContentController::HandleTapOnCompositorThread",
+        this,
+        &RemoteContentController::HandleTapOnCompositorThread,
+        aTapType,
+        aPoint,
+        aModifiers,
+        aGuid,
+        aInputBlockId));
     }
-
     return;
   }
 
   MOZ_ASSERT(XRE_IsParentProcess());
 
   if (NS_IsMainThread()) {
     HandleTapOnMainThread(aTapType, aPoint, aModifiers, aGuid, aInputBlockId);
   } else {
@@ -101,39 +128,63 @@ RemoteContentController::HandleTap(TapTy
       aPoint,
       aModifiers,
       aGuid,
       aInputBlockId));
   }
 }
 
 void
+RemoteContentController::NotifyPinchGestureOnCompositorThread(
+    PinchGestureInput::PinchGestureType aType,
+    const ScrollableLayerGuid& aGuid,
+    LayoutDeviceCoord aSpanChange,
+    Modifiers aModifiers)
+{
+  MOZ_ASSERT(MessageLoop::current() == mCompositorThread);
+
+  // The raw pointer to APZCTreeManagerParent is ok here because we are on the
+  // compositor thread.
+  APZCTreeManagerParent* apzctmp =
+      CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId);
+  if (apzctmp) {
+    Unused << apzctmp->SendNotifyPinchGesture(aType, aGuid, aSpanChange, aModifiers);
+  }
+}
+
+void
 RemoteContentController::NotifyPinchGesture(PinchGestureInput::PinchGestureType aType,
                                             const ScrollableLayerGuid& aGuid,
                                             LayoutDeviceCoord aSpanChange,
                                             Modifiers aModifiers)
 {
   APZThreadUtils::AssertOnControllerThread();
 
   // For now we only ever want to handle this NotifyPinchGesture message in
   // the parent process, even if the APZ is sending it to a content process.
 
   // If we're in the GPU process, try to find a handle to the parent process
   // and send it there.
   if (XRE_IsGPUProcess()) {
-    MOZ_ASSERT(MessageLoop::current() == mCompositorThread);
-
-    // The raw pointer to APZCTreeManagerParent is ok here because we are on the
-    // compositor thread.
-    APZCTreeManagerParent* apzctmp =
-        CompositorBridgeParent::GetApzcTreeManagerParentForRoot(aGuid.mLayersId);
-    if (apzctmp) {
-      Unused << apzctmp->SendNotifyPinchGesture(aType, aGuid, aSpanChange, aModifiers);
-      return;
+    if (MessageLoop::current() == mCompositorThread) {
+      NotifyPinchGestureOnCompositorThread(aType, aGuid, aSpanChange, aModifiers);
+    } else {
+      mCompositorThread->PostTask(NewRunnableMethod<PinchGestureInput::PinchGestureType,
+                                                    ScrollableLayerGuid,
+                                                    LayoutDeviceCoord,
+                                                    Modifiers>(
+        "layers::RemoteContentController::NotifyPinchGestureOnCompositorThread",
+        this,
+        &RemoteContentController::NotifyPinchGestureOnCompositorThread,
+        aType,
+        aGuid,
+        aSpanChange,
+        aModifiers));
     }
+    return;
   }
 
   // If we're in the parent process, handle it directly. We don't have a handle
   // to the widget though, so we fish out the ChromeProcessController and
   // delegate to that instead.
   if (XRE_IsParentProcess()) {
     MOZ_ASSERT(NS_IsMainThread());
     RefPtr<GeckoContentController> rootController =
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -85,16 +85,25 @@ private:
   MessageLoop* mCompositorThread;
   bool mCanSend;
 
   void HandleTapOnMainThread(TapType aType,
                              LayoutDevicePoint aPoint,
                              Modifiers aModifiers,
                              ScrollableLayerGuid aGuid,
                              uint64_t aInputBlockId);
+  void HandleTapOnCompositorThread(TapType aType,
+                                   LayoutDevicePoint aPoint,
+                                   Modifiers aModifiers,
+                                   ScrollableLayerGuid aGuid,
+                                   uint64_t aInputBlockId);
+  void NotifyPinchGestureOnCompositorThread(PinchGestureInput::PinchGestureType aType,
+                                            const ScrollableLayerGuid& aGuid,
+                                            LayoutDeviceCoord aSpanChange,
+                                            Modifiers aModifiers);
 
   void CancelAutoscrollInProcess(const ScrollableLayerGuid& aScrollId);
   void CancelAutoscrollCrossProcess(const ScrollableLayerGuid& aScrollId);
 };
 
 } // namespace layers
 
 } // namespace mozilla