Bug 1548687 - Optimization to reduce the number of IPC messages. r=botond
☠☠ backed out by c05a24ea5373 ☠ ☠
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 19 Jun 2019 19:23:41 +0000
changeset 479242 a6aa3a8b41b0e7fe8cc8f6e757e87a0109c7b3a4
parent 479241 0454826b604706e611221cb0e0dd79f339a4da25
child 479243 1ddcedc57f6ff5f8313cea655ea3f7425f8e7894
push id36177
push userrmaries@mozilla.com
push dateThu, 20 Jun 2019 09:46:31 +0000
treeherdermozilla-central@a440f0629814 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1548687
milestone69.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 1548687 - Optimization to reduce the number of IPC messages. r=botond The case being fixed by this bug is currently relatively rare, in that it requires the scrolling of a frame that contains OOP content. This patch adds a bit of optimization to ensure that we only send the affected transforms (i.e. for the scrolled OOP layers subtrees) in this scenario, so that we don't cause unnecessary IPC overhead. Differential Revision: https://phabricator.services.mozilla.com/D35202
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -593,17 +593,17 @@ APZCTreeManager::UpdateHitTestingTreeImp
 
 #if ENABLE_APZCTM_LOGGING
   // Make the hit-test tree line up with the layer dump
   printf_stderr("APZCTreeManager (%p)\n", this);
   if (mRootNode) {
     mRootNode->Dump("  ");
   }
 #endif
-  CollectTransformsForChromeMainThread();
+  CollectTransformsForChromeMainThread(nullptr);
 }
 
 void APZCTreeManager::UpdateFocusState(LayersId aRootLayerTreeId,
                                        LayersId aOriginatingLayersId,
                                        const FocusTarget& aFocusTarget) {
   AssertOnUpdaterThread();
 
   if (!StaticPrefs::APZKeyboardEnabled()) {
@@ -3252,36 +3252,50 @@ bool APZCTreeManager::GetAPZTestData(Lay
   auto it = mTestData.find(aLayersId);
   if (it == mTestData.end()) {
     return false;
   }
   *aOutData = *(it->second);
   return true;
 }
 
-void APZCTreeManager::CollectTransformsForChromeMainThread() {
+void APZCTreeManager::CollectTransformsForChromeMainThread(
+    const AsyncPanZoomController* aAncestor) {
   RefPtr<GeckoContentController> controller =
       GetContentController(mRootLayersId);
   if (!controller) {
     return;
   }
   nsTArray<MatrixMessage> messages;
+  bool underAncestor = (aAncestor == nullptr);
   {
     RecursiveMutexAutoLock lock(mTreeLock);
     // This formulation duplicates matrix multiplications closer
     // to the root of the tree. For now, aiming for separation
     // of concerns rather than minimum number of multiplications.
     ForEachNode<ReverseIterator>(
-        mRootNode.get(), [&messages](HitTestingTreeNode* aNode) {
+        mRootNode.get(), [&](HitTestingTreeNode* aNode) {
+          bool atAncestor = (aAncestor && aNode->GetApzc() == aAncestor);
+          MOZ_ASSERT(!(underAncestor && atAncestor));
+          underAncestor |= atAncestor;
+          if (!underAncestor) {
+            return;
+          }
           LayersId layersId = aNode->GetLayersId();
           HitTestingTreeNode* parent = aNode->GetParent();
           if (!parent || layersId != parent->GetLayersId()) {
             messages.AppendElement(
                 MatrixMessage(aNode->GetCSSTransformToRoot(), layersId));
           }
+        }, [&](HitTestingTreeNode* aNode) {
+          bool atAncestor = (aAncestor && aNode->GetApzc() == aAncestor);
+          if (atAncestor) {
+            MOZ_ASSERT(underAncestor);
+            underAncestor = false;
+          }
         });
   }
   controller->NotifyLayerTransforms(messages);
 }
 
 /*static*/
 LayerToParentLayerMatrix4x4 APZCTreeManager::ComputeTransformForScrollThumb(
     const LayerToParentLayerMatrix4x4& aCurrentTransform,
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -497,19 +497,23 @@ class APZCTreeManager : public IAPZCTree
   void UpdateWheelTransaction(LayoutDeviceIntPoint aRefPoint,
                               EventMessage aEventMessage) override;
 
   bool GetAPZTestData(LayersId aLayersId, APZTestData* aOutData);
 
   /**
    * Iterates over the hit testing tree, collects LayersIds and associated
    * transforms from layer coordinate space to root coordinate space, and
-   * sends these over to the main thread of the chrome process.
+   * sends these over to the main thread of the chrome process. If the provided
+   * |aAncestor| argument is non-null, then only the transforms for layer
+   * subtrees scrolled by the aAncestor (i.e. descendants of aAncestor) will be
+   * sent.
    */
-  void CollectTransformsForChromeMainThread();
+  void CollectTransformsForChromeMainThread(
+      const AsyncPanZoomController* aAncestor);
 
   /**
    * Compute the updated shadow transform for a scroll thumb layer that
    * reflects async scrolling of the associated scroll frame.
    *
    * @param aCurrentTransform The current shadow transform on the scroll thumb
    *    layer, as returned by Layer::GetLocalTransform() or similar.
    * @param aScrollableContentTransform The current content transform on the
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3915,20 +3915,21 @@ void AsyncPanZoomController::RequestCont
 
   controller->RequestContentRepaint(request);
   mExpectedGeckoMetrics = aFrameMetrics;
   mLastPaintRequestMetrics = request;
 
   // We're holding the APZC lock here, so redispatch this so we can get
   // the tree lock without the APZC lock.
   controller->DispatchToRepaintThread(
-      NewRunnableMethod(
+      NewRunnableMethod<AsyncPanZoomController*>(
           "layers::APZCTreeManager::CollectTransformsForChromeMainThread",
           GetApzcTreeManager(),
-          &APZCTreeManager::CollectTransformsForChromeMainThread));
+          &APZCTreeManager::CollectTransformsForChromeMainThread,
+          this));
 }
 
 bool AsyncPanZoomController::UpdateAnimation(
     const TimeStamp& aSampleTime,
     nsTArray<RefPtr<Runnable>>* aOutDeferredTasks) {
   AssertOnSamplerThread();
 
   // This function may get called multiple with the same sample time, for two