Bug 993554 - Prevent clipping sync-scrollable subframes to the critical displayport on Fennec. r=BenWa,botond
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 23 Apr 2014 09:27:58 -0400
changeset 199325 bd59c5ef0677817e38d833f065316b527d79f914
parent 199324 5ff928574d65e91b8322d0aa709d6f98397ac7e9
child 199326 efdfbde5f291a9b3cb1889e7c96ba5ea070ef2e8
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBenWa, botond
bugs993554
milestone31.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 993554 - Prevent clipping sync-scrollable subframes to the critical displayport on Fennec. r=BenWa,botond
gfx/layers/client/ClientTiledThebesLayer.cpp
--- a/gfx/layers/client/ClientTiledThebesLayer.cpp
+++ b/gfx/layers/client/ClientTiledThebesLayer.cpp
@@ -81,16 +81,42 @@ ClientTiledThebesLayer::BeginPaint()
     //       CSS transforms.
     //
     //       Because of this, there may be unintended behaviour when setting
     //       2d CSS translations on the children of scrollable displayport
     //       layers.
     return;
   }
 
+#ifdef MOZ_WIDGET_ANDROID
+  // Subframes on Fennec are not async scrollable because they have no displayport.
+  // However, the code in RenderLayer() picks up a displayport from the nearest
+  // scrollable ancestor container layer anyway, which is incorrect for Fennec. This
+  // behaviour results in the subframe getting clipped improperly and perma-blank areas
+  // while scrolling the subframe. To work around this, we detect if this layer is
+  // the primary scrollable layer and disable the tiling behaviour if it is not.
+  bool isPrimaryScrollableThebesLayer = false;
+  if (Layer* scrollable = ClientManager()->GetPrimaryScrollableLayer()) {
+    if (GetParent() == scrollable) {
+      for (Layer* child = scrollable->GetFirstChild(); child; child = child->GetNextSibling()) {
+        if (child->GetType() == Layer::TYPE_THEBES) {
+          if (child == this) {
+            // |this| is the first thebes layer child of the GetPrimaryScrollableLayer()
+            isPrimaryScrollableThebesLayer = true;
+          }
+          break;
+        }
+      }
+    }
+  }
+  if (!isPrimaryScrollableThebesLayer) {
+    return;
+  }
+#endif
+
   // Get the metrics of the nearest scrollable layer and the nearest layer
   // with a displayport.
   ContainerLayer* displayPortParent = nullptr;
   ContainerLayer* scrollParent = nullptr;
   for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
     const FrameMetrics& metrics = parent->GetFrameMetrics();
     if (!scrollParent && metrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID) {
       scrollParent = parent;