Bug 1371979 - Reduce memory allocation / deallocation in DrawTargetTiled::PushClip(Rect) / PopClip. r?Bas draft
authorMarkus Stange <mstange@themasta.com>
Sun, 11 Jun 2017 01:05:16 -0400
changeset 592203 7deaf0ba00e375c281a7241c5b09fbf96a547240
parent 592202 fb369ac57e9a5307f3a7b95749ff5b1e40d82464
child 632747 735357c6018be9032ada5da2016eecff397288f7
push id63307
push userbmo:mstange@themasta.com
push dateSun, 11 Jun 2017 05:05:40 +0000
reviewersBas
bugs1371979
milestone55.0a1
Bug 1371979 - Reduce memory allocation / deallocation in DrawTargetTiled::PushClip(Rect) / PopClip. r?Bas MozReview-Commit-ID: 8ejQOevZR8t
gfx/2d/DrawTargetTiled.cpp
gfx/2d/DrawTargetTiled.h
--- a/gfx/2d/DrawTargetTiled.cpp
+++ b/gfx/2d/DrawTargetTiled.cpp
@@ -111,74 +111,77 @@ TILED_COMMAND4(DrawFilter, FilterNode*, 
 TILED_COMMAND1(ClearRect, const Rect&)
 TILED_COMMAND4(MaskSurface, const Pattern&, SourceSurface*, Point, const DrawOptions&)
 TILED_COMMAND5(FillGlyphs, ScaledFont*, const GlyphBuffer&, const Pattern&, const DrawOptions&, const GlyphRenderingOptions*)
 TILED_COMMAND3(Mask, const Pattern&, const Pattern&, const DrawOptions&)
 
 void
 DrawTargetTiled::PushClip(const Path* aPath)
 {
-  mClippedOutTilesStack.push_back(std::vector<uint32_t>());
-  std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
+  if (!mClippedOutTilesStack.append(std::vector<bool>(mTiles.size()))) {
+    MOZ_CRASH("out of memory");
+  }
+  std::vector<bool>& clippedTiles = mClippedOutTilesStack.back();
 
   Rect deviceRect = aPath->GetBounds(mTransform);
 
   for (size_t i = 0; i < mTiles.size(); i++) {
     if (!mTiles[i].mClippedOut) {
       if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
                                    mTiles[i].mTileOrigin.y,
                                    mTiles[i].mDrawTarget->GetSize().width,
                                    mTiles[i].mDrawTarget->GetSize().height))) {
         mTiles[i].mDrawTarget->PushClip(aPath);
       } else {
         mTiles[i].mClippedOut = true;
-        clippedTiles.push_back(i);
+        clippedTiles[i] = true;
       }
     }
   }
 }
 
 void
 DrawTargetTiled::PushClipRect(const Rect& aRect)
 {
-  mClippedOutTilesStack.push_back(std::vector<uint32_t>());
-  std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
+  if (!mClippedOutTilesStack.append(std::vector<bool>(mTiles.size()))) {
+    MOZ_CRASH("out of memory");
+  }
+  std::vector<bool>& clippedTiles = mClippedOutTilesStack.back();
 
   Rect deviceRect = mTransform.TransformBounds(aRect);
 
   for (size_t i = 0; i < mTiles.size(); i++) {
     if (!mTiles[i].mClippedOut) {
       if (deviceRect.Intersects(Rect(mTiles[i].mTileOrigin.x,
                                    mTiles[i].mTileOrigin.y,
                                    mTiles[i].mDrawTarget->GetSize().width,
                                    mTiles[i].mDrawTarget->GetSize().height))) {
         mTiles[i].mDrawTarget->PushClipRect(aRect);
       } else {
         mTiles[i].mClippedOut = true;
-        clippedTiles.push_back(i);
+        clippedTiles[i] = true;
       }
     }
   }
 }
 
 void
 DrawTargetTiled::PopClip()
 {
+  std::vector<bool>& clippedTiles = mClippedOutTilesStack.back();
+  MOZ_ASSERT(clippedTiles.size() == mTiles.size());
   for (size_t i = 0; i < mTiles.size(); i++) {
     if (!mTiles[i].mClippedOut) {
       mTiles[i].mDrawTarget->PopClip();
+    } else if (clippedTiles[i]) {
+      mTiles[i].mClippedOut = false;
     }
   }
 
-  std::vector<uint32_t>& clippedTiles = mClippedOutTilesStack.back();
-  for (size_t i = 0; i < clippedTiles.size(); i++) {
-    mTiles[clippedTiles[i]].mClippedOut = false;
-  }
-
-  mClippedOutTilesStack.pop_back();
+  mClippedOutTilesStack.popBack();
 }
 
 void
 DrawTargetTiled::CopySurface(SourceSurface *aSurface,
                              const IntRect &aSourceRect,
                              const IntPoint &aDestination)
 {
   for (size_t i = 0; i < mTiles.size(); i++) {
--- a/gfx/2d/DrawTargetTiled.h
+++ b/gfx/2d/DrawTargetTiled.h
@@ -2,16 +2,19 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_DRAWTARGETTILED_H_
 #define MOZILLA_GFX_DRAWTARGETTILED_H_
 
 #include "2D.h"
+
+#include "mozilla/Vector.h"
+
 #include "Filters.h"
 #include "Logging.h"
 
 #include <vector>
 
 namespace mozilla {
 namespace gfx {
 
@@ -154,17 +157,22 @@ public:
   }
   virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override
   {
     return mTiles[0].mDrawTarget->CreateFilter(aType);
   }
 
 private:
   std::vector<TileInternal> mTiles;
-  std::vector<std::vector<uint32_t> > mClippedOutTilesStack;
+
+  // mClippedOutTilesStack[clipIndex][tileIndex] is true if the tile at
+  // tileIndex has become completely clipped out at the clip stack depth
+  // clipIndex.
+  Vector<std::vector<bool>,8> mClippedOutTilesStack;
+
   IntRect mRect;
 
   struct PushedLayer
   {
     explicit PushedLayer(bool aOldPermitSubpixelAA)
       : mOldPermitSubpixelAA(aOldPermitSubpixelAA)
     {}
     bool mOldPermitSubpixelAA;