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>
Wed, 14 Mar 2018 16:57:52 -0400
changeset 767610 b215d3db6fcfbe43575624e70bcf8cc56bfa11bd
parent 767609 e09524afb6c133c5944d1bba21f7c6ccf35bb235
push id102649
push userkgupta@mozilla.com
push dateWed, 14 Mar 2018 20:58:42 +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: 6kLqdl6jgO0
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