Bug 1445662 - Ensure ZoomToRect runs on the controller thread. r?rhunt draft
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 14 Mar 2018 16:57:52 -0400
changeset 767608 ebcc25a043f6386347e0fe30165673884183411d
parent 767607 5e63a1d7e9e5da8410243ecb8d75ec298547e633
child 767609 e09524afb6c133c5944d1bba21f7c6ccf35bb235
push id102649
push userkgupta@mozilla.com
push dateWed, 14 Mar 2018 20:58:42 +0000
reviewersrhunt
bugs1445662
milestone61.0a1
Bug 1445662 - Ensure ZoomToRect runs on the controller thread. r?rhunt Currently the ZoomToRect function is only ever called on Android, on the UI process main thread, which is neither the controller nor the sampler thread. Instead of allowing "random" threads to run inside APZ, we ensure that callers run it on the controller thread. MozReview-Commit-ID: 64LkHaFLIOl
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/util/ChromeProcessController.cpp
gfx/layers/ipc/APZCTreeManagerParent.cpp
widget/nsBaseWidget.cpp
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1886,16 +1886,21 @@ APZCTreeManager::SetKeyboardMap(const Ke
   mKeyboardMap = aKeyboardMap;
 }
 
 void
 APZCTreeManager::ZoomToRect(const ScrollableLayerGuid& aGuid,
                             const CSSRect& aRect,
                             const uint32_t aFlags)
 {
+  // We could probably move this to run on the sampler thread if needed, but
+  // either way we should restrict it to a single thread. For now let's use the
+  // controller thread.
+  APZThreadUtils::AssertOnControllerThread();
+
   RefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(aGuid);
   if (apzc) {
     apzc->ZoomToRect(aRect, aFlags);
   }
 }
 
 void
 APZCTreeManager::ContentReceivedInputBlock(uint64_t aInputBlockId, bool aPreventDefault)
--- a/gfx/layers/apz/util/ChromeProcessController.cpp
+++ b/gfx/layers/apz/util/ChromeProcessController.cpp
@@ -153,18 +153,24 @@ ChromeProcessController::HandleDoubleTap
   const float resolution = presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f;
   CSSPoint point(aPoint.x / resolution, aPoint.y / resolution);
   CSSRect zoomToRect = CalculateRectToZoomTo(document, point);
 
   uint32_t presShellId;
   FrameMetrics::ViewID viewId;
   if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
       document->GetDocumentElement(), &presShellId, &viewId)) {
-    mAPZCTreeManager->ZoomToRect(
-      ScrollableLayerGuid(aGuid.mLayersId, presShellId, viewId), zoomToRect);
+    APZThreadUtils::RunOnControllerThread(
+      NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
+        "IAPZCTreeManager::ZoomToRect",
+        mAPZCTreeManager,
+        &IAPZCTreeManager::ZoomToRect,
+        ScrollableLayerGuid(aGuid.mLayersId, presShellId, viewId),
+        zoomToRect,
+        ZoomToRectBehavior::DEFAULT_BEHAVIOR));
   }
 }
 
 void
 ChromeProcessController::HandleTap(TapType aType,
                                    const mozilla::LayoutDevicePoint& aPoint,
                                    Modifiers aModifiers,
                                    const ScrollableLayerGuid& aGuid,
--- a/gfx/layers/ipc/APZCTreeManagerParent.cpp
+++ b/gfx/layers/ipc/APZCTreeManagerParent.cpp
@@ -182,17 +182,22 @@ APZCTreeManagerParent::RecvZoomToRect(
     const uint32_t& aFlags)
 {
   if (aGuid.mLayersId != mLayersId) {
     // Guard against bad data from hijacked child processes
     NS_ERROR("Unexpected layers id in RecvZoomToRect; dropping message...");
     return IPC_FAIL_NO_REASON(this);
   }
 
-  mTreeManager->ZoomToRect(aGuid, aRect, aFlags);
+  APZThreadUtils::RunOnControllerThread(
+    NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
+      "layers::IAPZCTreeManager::ZoomToRect",
+      mTreeManager,
+      &IAPZCTreeManager::ZoomToRect,
+      aGuid, aRect, aFlags));
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 APZCTreeManagerParent::RecvContentReceivedInputBlock(
     const uint64_t& aInputBlockId,
     const bool& aPreventDefault)
 {
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1928,17 +1928,24 @@ nsBaseWidget::ZoomToRect(const uint32_t&
                          const FrameMetrics::ViewID& aViewId,
                          const CSSRect& aRect,
                          const uint32_t& aFlags)
 {
   if (!mCompositorSession || !mAPZC) {
     return;
   }
   uint64_t layerId = mCompositorSession->RootLayerTreeId();
-  mAPZC->ZoomToRect(ScrollableLayerGuid(layerId, aPresShellId, aViewId), aRect, aFlags);
+  APZThreadUtils::RunOnControllerThread(
+    NewRunnableMethod<ScrollableLayerGuid, CSSRect, uint32_t>(
+      "layers::IAPZCTreeManager::ZoomToRect",
+      mAPZC,
+      &IAPZCTreeManager::ZoomToRect,
+      ScrollableLayerGuid(layerId, aPresShellId, aViewId),
+      aRect,
+      aFlags));
 }
 
 #ifdef ACCESSIBILITY
 
 a11y::Accessible*
 nsBaseWidget::GetRootAccessible()
 {
   NS_ENSURE_TRUE(mWidgetListener, nullptr);