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.
--- 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;
}
}