зеркало из https://github.com/mozilla/gecko-dev.git
Bug 721070 - Checkerboarding at bottom after pinch zooming out. r=kats,pcwalton
Certain conditions would cause MultiTileLayer to incorrectly invalidate tiles, or to reuse tiles incorrectly, which would cause checkerboarding (sometimes permanent until a redraw occurs). This addresses said issues: - Removes manual invalidation on Document:Shown and Tab:Selected. This is unnecessary, as the entire buffer will be invalidated when this happens anyway. Sometimes Document:Shown happens *after* drawing has occurred, which caused the entire screen to checkerboard incorrectly. - Fix re-using off-screen tiles with the incorrect resolution. Tiles are stored in a hash-map based on their unscaled position. As only tiles that intersect with the update region in tile-space are invalidated, sometimes tiles that were off-screen, but whose unscaled tile origin appears on-screen would be incorrectly re-used. Fix this by checking that a tile's resolution matches the current resolution before reusing it.
This commit is contained in:
Родитель
ccf4980df5
Коммит
773061c1f7
|
@ -162,8 +162,6 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateAndDraw", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateLater", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Document:Shown", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Tab:Selected:Done", this);
|
||||
|
||||
sendResizeEventIfNecessary();
|
||||
}
|
||||
|
@ -252,7 +250,6 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
Point tileOrigin = new Point((origin.x / TILE_SIZE.width) * TILE_SIZE.width,
|
||||
(origin.y / TILE_SIZE.height) * TILE_SIZE.height);
|
||||
mRenderOffset.set(origin.x - tileOrigin.x, origin.y - tileOrigin.y);
|
||||
((MultiTileLayer)mTileLayer).invalidateBuffer();
|
||||
}
|
||||
|
||||
// If the window size has changed, reallocate the buffer to match.
|
||||
|
@ -519,16 +516,6 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.DRAW, rect));
|
||||
} else if ("Viewport:UpdateLater".equals(event)) {
|
||||
mUpdateViewportOnEndDraw = true;
|
||||
} else if (("Document:Shown".equals(event) ||
|
||||
"Tab:Selected:Done".equals(event)) &&
|
||||
(mTileLayer instanceof MultiTileLayer)) {
|
||||
beginTransaction(mTileLayer);
|
||||
try {
|
||||
((MultiTileLayer)mTileLayer).invalidateTiles();
|
||||
((MultiTileLayer)mTileLayer).invalidateBuffer();
|
||||
} finally {
|
||||
endTransaction(mTileLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -333,7 +333,7 @@ public class MultiTileLayer extends Layer {
|
|||
}
|
||||
|
||||
// Dirty tile, find out if we already have this tile to reuse.
|
||||
boolean reusedTile = true;
|
||||
boolean reusedTile;
|
||||
Point tileOrigin = new Point(x, y);
|
||||
SubTile tile = mPositionHash.get(longFromPoint(tileOrigin));
|
||||
|
||||
|
@ -343,6 +343,10 @@ public class MultiTileLayer extends Layer {
|
|||
reusedTile = false;
|
||||
} else {
|
||||
mTiles.remove(tile);
|
||||
|
||||
// Reuse the tile (i.e. keep the texture data and metrics)
|
||||
// only if the resolution matches
|
||||
reusedTile = FloatUtils.fuzzyEquals(tile.getResolution(), getResolution());
|
||||
}
|
||||
|
||||
// Place tile at the end of the tile-list so it isn't re-used.
|
||||
|
@ -396,10 +400,36 @@ public class MultiTileLayer extends Layer {
|
|||
@Override
|
||||
public void draw(RenderContext context) {
|
||||
for (SubTile layer : mTiles) {
|
||||
// Skip invalid tiles
|
||||
if (layer.key == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Avoid work, only draw tiles that intersect with the viewport
|
||||
RectF layerBounds = layer.getBounds(context, new FloatSize(layer.getSize()));
|
||||
if (RectF.intersects(layerBounds, context.viewport))
|
||||
if (RectF.intersects(layerBounds, context.viewport)) {
|
||||
layer.draw(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOrigin(Point origin) {
|
||||
Point oldOrigin = getOrigin();
|
||||
|
||||
if (!origin.equals(oldOrigin)) {
|
||||
super.setOrigin(origin);
|
||||
invalidateBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResolution(float resolution) {
|
||||
float oldResolution = getResolution();
|
||||
|
||||
if (!FloatUtils.fuzzyEquals(resolution, oldResolution)) {
|
||||
super.setResolution(resolution);
|
||||
invalidateBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче