Bug 796117 - Keep tiles cached when changing resolution. r=Cwiiis

--HG--
extra : rebase_source : fdc4bb831c367d2d33dadb75c6d1f9784b97d44d
This commit is contained in:
Benoit Girard 2012-10-15 15:08:45 -04:00
Родитель 929cb0551e
Коммит dba6881f18
2 изменённых файлов: 34 добавлений и 26 удалений

Просмотреть файл

@ -263,6 +263,12 @@ BasicTiledThebesLayer::PaintThebes(gfxContext* aContext,
resolution.height *= metrics.mResolution.height;
}
// If the resolution has changed, discard all the old tiles.
// They will end up being retained on the shadow side by ReusableTileStoreOGL
if (mTiledBuffer.GetResolution() != resolution) {
mValidRegion = nsIntRegion();
}
// Calculate the scroll offset since the last transaction. Progressive tile
// painting is only used when scrolling.
gfx::Point scrollOffset(0, 0);

Просмотреть файл

@ -59,33 +59,19 @@ ReusableTileStoreOGL::InvalidateTiles(TiledThebesLayerOGL* aLayer,
mContext->MakeCurrent();
for (uint32_t i = 0; i < mTiles.Length();) {
ReusableTiledTextureOGL* tile = mTiles[i];
// Check if the tile region is contained within the new valid region.
nsIntRect tileRect;
bool release = false;
if (tile->mResolution == aResolution) {
if (aValidRegion.Contains(tile->mTileRegion)) {
release = true;
} else {
tileRect = tile->mTileRegion.GetBounds();
}
} else {
nsIntRect tileRect = tile->mTileRegion.GetBounds();
if (tile->mResolution != aResolution) {
nsIntRegion transformedTileRegion(tile->mTileRegion);
transformedTileRegion.ScaleRoundOut(tile->mResolution.width / aResolution.width,
tile->mResolution.height / aResolution.height);
if (aValidRegion.Contains(transformedTileRegion))
release = true;
else
tileRect = transformedTileRegion.GetBounds();
tileRect = transformedTileRegion.GetBounds();
}
// If the tile region wasn't contained within the valid region, check if
// it intersects with the currently rendered region.
if (!release) {
// Transform the tile region to see if it falls inside the rendered bounds
gfxRect tileBounds = aLayer->GetEffectiveTransform().TransformBounds(gfxRect(tileRect));
if (renderBounds.Contains(tileBounds))
release = true;
// Check if the tile region is contained within the new valid region.
if (aValidRegion.Contains(tileRect)) {
release = true;
}
if (release) {
@ -134,16 +120,20 @@ ReusableTileStoreOGL::HarvestTiles(TiledThebesLayerOGL* aLayer,
// A tile will consume 256^2 of memory, don't retain small tile trims.
// This works around the display port sometimes creating a small 1 pixel wide
// tile because of rounding error.
if (w < 16)
if (w < 16) {
x += w;
continue;
}
for (int y = validBounds.y; y < validBounds.YMost();) {
int h = tileSize - aVideoMemoryTiledBuffer->GetTileStart(y);
if (y + h > validBounds.y + validBounds.height)
h = validBounds.y + validBounds.height - y;
if (h < 16)
if (h < 16) {
y += h;
continue;
}
// If the new valid region doesn't contain this tile region,
// harvest the tile.
@ -166,9 +156,6 @@ ReusableTileStoreOGL::HarvestTiles(TiledThebesLayerOGL* aLayer,
}
if (retainTile) {
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Retaining tile at %d,%d, x%f for reuse\n", x, y, aOldResolution.width);
#endif
TiledTexture removedTile;
if (aVideoMemoryTiledBuffer->RemoveTile(nsIntPoint(x, y), removedTile)) {
ReusableTiledTextureOGL* reusedTile =
@ -176,6 +163,9 @@ ReusableTileStoreOGL::HarvestTiles(TiledThebesLayerOGL* aLayer,
tileSize, aOldResolution);
mTiles.AppendElement(reusedTile);
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
bool replacedATile = false;
#endif
// Remove any tile that is superseded by this new tile.
// (same resolution, same area)
for (int i = 0; i < mTiles.Length() - 1; i++) {
@ -186,10 +176,20 @@ ReusableTileStoreOGL::HarvestTiles(TiledThebesLayerOGL* aLayer,
mTiles[i]->mResolution == aOldResolution) {
mContext->fDeleteTextures(1, &mTiles[i]->mTexture.mTextureHandle);
mTiles.RemoveElementAt(i);
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
replacedATile = true;
#endif
// There should only be one similar tile
break;
}
}
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
if (replacedATile) {
printf_stderr("Replaced tile at %d,%d, x%f for reuse\n", x, y, aOldResolution.width);
} else {
printf_stderr("New tile at %d,%d, x%f for reuse\n", x, y, aOldResolution.width);
}
#endif
}
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
else
@ -218,6 +218,7 @@ ReusableTileStoreOGL::HarvestTiles(TiledThebesLayerOGL* aLayer,
}
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr("Retained tile limit: %f\n", aVideoMemoryTiledBuffer->GetTileCount() * mSizeLimit);
printf_stderr("Retained %d tiles\n", mTiles.Length());
#endif
}
@ -274,6 +275,7 @@ ReusableTileStoreOGL::DrawTiles(TiledThebesLayerOGL* aLayer,
transform.Scale(scaleFactor.width, scaleFactor.height, 1);
// Subtract the layer's valid region from the tile region.
// This region will be drawn by the layer itself.
nsIntRegion transformedValidRegion(aValidRegion);
if (aResolution != tile->mResolution)
transformedValidRegion.ScaleRoundOut(1.0f/scaleFactor.width,