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 180151 bd59c5ef0677817e38d833f065316b527d79f914
parent 180150 5ff928574d65e91b8322d0aa709d6f98397ac7e9
child 180152 efdfbde5f291a9b3cb1889e7c96ba5ea070ef2e8
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
reviewersBenWa, botond
bugs993554
milestone31.0a1
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;