Bug 1021085 - Refactor code to ensure we use the same scrolling ancestor layer everywhere. r=Cwiiis, a=2.0+
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 23 Jun 2014 08:41:09 -0400
changeset 208354 e93838ffb061a154de2ee537916b29796089ba94
parent 208353 6e08edd34e5b7a284c0f80b3422036c571d1acbe
child 208355 1d45ce23b1bbd76e1c2c38e011ed7f2cd275d979
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersCwiiis, 2
bugs1021085
milestone32.0a2
Bug 1021085 - Refactor code to ensure we use the same scrolling ancestor layer everywhere. r=Cwiiis, a=2.0+
gfx/layers/client/ClientTiledThebesLayer.cpp
gfx/layers/client/ClientTiledThebesLayer.h
gfx/layers/client/TiledContentClient.cpp
--- a/gfx/layers/client/ClientTiledThebesLayer.cpp
+++ b/gfx/layers/client/ClientTiledThebesLayer.cpp
@@ -81,16 +81,42 @@ GetTransformToAncestorsParentLayer(Layer
     transform = transform * iter->GetTransform();
   }
   gfx3DMatrix ret;
   gfx::To3DMatrix(transform, ret);
   return ret;
 }
 
 void
+ClientTiledThebesLayer::GetAncestorLayers(ContainerLayer** aOutScrollAncestor,
+                                          ContainerLayer** aOutDisplayPortAncestor)
+{
+  ContainerLayer* scrollAncestor = nullptr;
+  ContainerLayer* displayPortAncestor = nullptr;
+  for (ContainerLayer* ancestor = GetParent(); ancestor; ancestor = ancestor->GetParent()) {
+    const FrameMetrics& metrics = ancestor->GetFrameMetrics();
+    if (!scrollAncestor && metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) {
+      scrollAncestor = ancestor;
+    }
+    if (!metrics.mDisplayPort.IsEmpty()) {
+      displayPortAncestor = ancestor;
+      // Any layer that has a displayport must be scrollable, so we can break
+      // here.
+      break;
+    }
+  }
+  if (aOutScrollAncestor) {
+    *aOutScrollAncestor = scrollAncestor;
+  }
+  if (aOutDisplayPortAncestor) {
+    *aOutDisplayPortAncestor = displayPortAncestor;
+  }
+}
+
+void
 ClientTiledThebesLayer::BeginPaint()
 {
   mPaintData.mLowPrecisionPaintCount = 0;
   mPaintData.mPaintFinished = false;
   mPaintData.mCompositionBounds.SetEmpty();
   mPaintData.mCriticalDisplayPort.SetEmpty();
 
   if (!GetBaseTransform().Is2D()) {
@@ -99,28 +125,17 @@ ClientTiledThebesLayer::BeginPaint()
     // given that it's a pretty rare scenario.
     return;
   }
 
   // Get the metrics of the nearest scrollable layer and the nearest layer
   // with a displayport.
   ContainerLayer* scrollAncestor = nullptr;
   ContainerLayer* displayPortAncestor = nullptr;
-  for (ContainerLayer* ancestor = GetParent(); ancestor; ancestor = ancestor->GetParent()) {
-    const FrameMetrics& metrics = ancestor->GetFrameMetrics();
-    if (!scrollAncestor && metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) {
-      scrollAncestor = ancestor;
-    }
-    if (!metrics.mDisplayPort.IsEmpty()) {
-      displayPortAncestor = ancestor;
-      // Any layer that has a displayport must be scrollable, so we can break
-      // here.
-      break;
-    }
-  }
+  GetAncestorLayers(&scrollAncestor, &displayPortAncestor);
 
   if (!displayPortAncestor || !scrollAncestor) {
     // No displayport or scroll ancestor, so we can't do progressive rendering.
 #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_B2G)
     // Both Android and b2g are guaranteed to have a displayport set, so this
     // should never happen.
     NS_WARNING("Tiled Thebes layer with no scrollable container ancestor");
 #endif
--- a/gfx/layers/client/ClientTiledThebesLayer.h
+++ b/gfx/layers/client/ClientTiledThebesLayer.h
@@ -64,16 +64,24 @@ public:
   {
     ClientLayer::Disconnect();
   }
 
   virtual void RenderLayer();
 
   virtual void ClearCachedResources() MOZ_OVERRIDE;
 
+  /**
+   * Helper method to find the nearest ancestor layers which
+   * scroll and have a displayport. The parameters are out-params
+   * which hold the return values; the values passed in may be null.
+   */
+  void GetAncestorLayers(ContainerLayer** aOutScrollAncestor,
+                         ContainerLayer** aOutDisplayPortAncestor);
+
 private:
   ClientLayerManager* ClientManager()
   {
     return static_cast<ClientLayerManager*>(mManager);
   }
 
   /**
    * For the initial PaintThebes of a transaction, calculates all the data
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -958,21 +958,22 @@ ClientTiledLayerBuffer::ComputeProgressi
   CSSToParentLayerScale zoom;
 #if defined(MOZ_WIDGET_ANDROID)
   bool abortPaint = mManager->ProgressiveUpdateCallback(!staleRegion.Contains(aInvalidRegion),
                                                         compositionBounds, zoom,
                                                         !drawingLowPrecision);
 #else
   MOZ_ASSERT(mSharedFrameMetricsHelper);
 
-  ContainerLayer* parent = mThebesLayer->AsLayer()->GetParent();
+  ContainerLayer* scrollAncestor = nullptr;
+  mThebesLayer->GetAncestorLayers(&scrollAncestor, nullptr);
 
   bool abortPaint =
     mSharedFrameMetricsHelper->UpdateFromCompositorFrameMetrics(
-      parent,
+      scrollAncestor,
       !staleRegion.Contains(aInvalidRegion),
       drawingLowPrecision,
       compositionBounds,
       zoom);
 #endif
 
   TILING_PRLOG_OBJ(("TILING 0x%p: Progressive update compositor bounds %s zoom %f abort %d\n", mThebesLayer, tmpstr.get(), zoom.scale, abortPaint), compositionBounds);