Bug 794465 - Only use progressive tile drawing when scrolling. r=bgirard
authorChris Lord <chrislord.net@gmail.com>
Wed, 26 Sep 2012 21:42:09 +0100
changeset 111777 2786b171b97fb91ed5bb66c70469f0b520f5dee5
parent 111776 49a7067b35fe4ce11e2994e18867f2383b58a20d
child 111778 ac9fdc7330d7fba845400ec9be7e269443189b29
push idunknown
push userunknown
push dateunknown
reviewersbgirard
bugs794465
milestone18.0a1
Bug 794465 - Only use progressive tile drawing when scrolling. r=bgirard To prevent seams appearing in updated content, only use progressive tile drawing when scrolling. This is the most critical time to keep interactivity consistent.
gfx/layers/basic/BasicTiledThebesLayer.cpp
--- a/gfx/layers/basic/BasicTiledThebesLayer.cpp
+++ b/gfx/layers/basic/BasicTiledThebesLayer.cpp
@@ -242,48 +242,51 @@ BasicTiledThebesLayer::PaintThebes(gfxCo
 
   gfxSize resolution(1, 1);
   for (ContainerLayer* parent = GetParent(); parent; parent = parent->GetParent()) {
     const FrameMetrics& metrics = parent->GetFrameMetrics();
     resolution.width *= metrics.mResolution.width;
     resolution.height *= metrics.mResolution.height;
   }
 
-  // Force immediate tile painting when the layer has changed resolution.
+  // Calculate the scroll offset since the last transaction. Progressive tile
+  // painting is only used when scrolling.
+  gfx::Point scrollOffset(0, 0);
+  Layer* primaryScrollable = BasicManager()->GetPrimaryScrollableLayer();
+  if (primaryScrollable) {
+    const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
+    scrollOffset = metrics.mViewportScrollOffset;
+  }
+  int32_t scrollDiffX = scrollOffset.x - mLastScrollOffset.x;
+  int32_t scrollDiffY = scrollOffset.y - mLastScrollOffset.y;
+
+  // Only draw progressively when we're panning and the resolution is unchanged.
   if (gfxPlatform::UseProgressiveTilePainting() &&
-      mTiledBuffer.GetResolution() == resolution) {
+      mTiledBuffer.GetResolution() == resolution &&
+      (scrollDiffX != 0 || scrollDiffY != 0)) {
     // Paint tiles that have no content before tiles that only have stale content.
     nsIntRegion staleRegion = mTiledBuffer.GetValidRegion();
     staleRegion.And(staleRegion, regionToPaint);
     if (!staleRegion.IsEmpty() && !staleRegion.Contains(regionToPaint)) {
       regionToPaint.Sub(regionToPaint, staleRegion);
     }
 
     // The following code decides what order to draw tiles in, based on the
     // current scroll direction of the primary scrollable layer.
     // XXX While this code is of a reasonable size currently, it is likely
     //     we'll want to add more comprehensive methods of deciding what
     //     tiles to draw. This is a good candidate for splitting out into a
     //     separate function.
 
-    gfx::Point scrollOffset(0, 0);
-    Layer* primaryScrollable = BasicManager()->GetPrimaryScrollableLayer();
-    if (primaryScrollable) {
-      const FrameMetrics& metrics = primaryScrollable->AsContainerLayer()->GetFrameMetrics();
-      scrollOffset = metrics.mViewportScrollOffset;
-    }
-
     // First, decide whether to iterate on the region from the beginning or end
     // of the rect list. This relies on the specific behaviour of nsRegion when
     // subtracting rects. If we're moving more in the X direction, we draw
     // tiles by column, otherwise by row.
     nsIntRegionRectIterator it(regionToPaint);
     const nsIntRect* rect;
-    int32_t scrollDiffX = scrollOffset.x - mLastScrollOffset.x;
-    int32_t scrollDiffY = scrollOffset.y - mLastScrollOffset.y;
     if ((NS_ABS(scrollDiffY) > NS_ABS(scrollDiffX) && scrollDiffY >= 0)) {
       rect = it.Next();
     } else {
       const nsIntRect* lastRect;
       while (lastRect = it.Next()) {
         rect = lastRect;
       }
     }