Bug 796117 - New Mobile tilestore tiles will now replace equivalent tiles. r=Cwiiis
☠☠ backed out by 2d10007609f1 ☠ ☠
authorBenoit Girard <b56girard@gmail.com>
Fri, 12 Oct 2012 17:50:08 -0400
changeset 110417 b7f31a7368000ae093dca8ae21152af9a867fbe5
parent 110416 2d29c74b9c9cb3014d7b53eb7cbffef99236da5e
child 110418 938c4afc92b938ced3bcf5ae332dddf047057360
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersCwiiis
bugs796117
milestone19.0a1
Bug 796117 - New Mobile tilestore tiles will now replace equivalent tiles. r=Cwiiis
gfx/layers/opengl/ReusableTileStoreOGL.cpp
--- a/gfx/layers/opengl/ReusableTileStoreOGL.cpp
+++ b/gfx/layers/opengl/ReusableTileStoreOGL.cpp
@@ -126,21 +126,30 @@ ReusableTileStoreOGL::HarvestTiles(Tiled
   //     to make it simpler.
   uint16_t tileSize = aVideoMemoryTiledBuffer->GetTileLength();
   nsIntRect validBounds = aOldValidRegion.GetBounds();
   for (int x = validBounds.x; x < validBounds.XMost();) {
     int w = tileSize - aVideoMemoryTiledBuffer->GetTileStart(x);
     if (x + w > validBounds.x + validBounds.width)
       w = validBounds.x + validBounds.width - x;
 
+    // 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)
+      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)
+        continue;
+
       // If the new valid region doesn't contain this tile region,
       // harvest the tile.
       nsIntRegion tileRegion;
       tileRegion.And(aOldValidRegion, nsIntRect(x, y, w, h));
 
       nsIntRegion intersectingRegion;
       bool retainTile = false;
       if (aNewResolution != aOldResolution) {
@@ -161,16 +170,31 @@ ReusableTileStoreOGL::HarvestTiles(Tiled
         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 =
             new ReusableTiledTextureOGL(removedTile, nsIntPoint(x, y), tileRegion,
                                         tileSize, aOldResolution);
           mTiles.AppendElement(reusedTile);
+
+          // Remove any tile that is superseded by this new tile.
+          // (same resolution, same area)
+          for (int i = 0; i < mTiles.Length() - 1; i++) {
+            // XXX Perhaps we should check the region instead of the origin
+            //     so a partial tile doesn't replace a full older tile?
+            if (aVideoMemoryTiledBuffer->RoundDownToTileEdge(mTiles[i]->mTileOrigin.x) == aVideoMemoryTiledBuffer->RoundDownToTileEdge(x) &&
+                aVideoMemoryTiledBuffer->RoundDownToTileEdge(mTiles[i]->mTileOrigin.y) == aVideoMemoryTiledBuffer->RoundDownToTileEdge(y) &&
+                mTiles[i]->mResolution == aOldResolution) {
+              mContext->fDeleteTextures(1, &mTiles[i]->mTexture.mTextureHandle);
+              mTiles.RemoveElementAt(i);
+              // There should only be one similar tile
+              break;
+            }
+          }
         }
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
         else
           printf_stderr("Failed to retain tile for reuse\n");
 #endif
       }
 
       y += h;