SkSTArenaAlloc

Syntactic sugar, gets rid of some boilerplate.

Change-Id: Ibdb28b7a8f1d5e4a4e18c12d423b987d7194e340
Reviewed-on: https://skia-review.googlesource.com/17837
Commit-Queue: Florin Malita <fmalita@chromium.org>
Reviewed-by: Herb Derby <herb@google.com>
diff --git a/bench/SkLinearBitmapPipelineBench.cpp b/bench/SkLinearBitmapPipelineBench.cpp
index bc1b5df..0a86778 100644
--- a/bench/SkLinearBitmapPipelineBench.cpp
+++ b/bench/SkLinearBitmapPipelineBench.cpp
@@ -150,8 +150,7 @@
         SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};
 
 
-        char storage[600];
-        SkArenaAlloc allocator{storage, sizeof(storage), 512};
+        SkSTArenaAlloc<600> allocator(512);
         SkLinearBitmapPipeline pipeline{
             fInvert, filterQuality, fXTile, fYTile, SK_ColorBLACK, srcPixmap, &allocator};
 
diff --git a/gm/SkLinearBitmapPipelineGM.cpp b/gm/SkLinearBitmapPipelineGM.cpp
index cab20d3..f07d2f7 100644
--- a/gm/SkLinearBitmapPipelineGM.cpp
+++ b/gm/SkLinearBitmapPipelineGM.cpp
@@ -115,8 +115,7 @@
     uint32_t flags = 0;
     auto procN = SkXfermode::GetD32Proc(SkBlendMode::kSrcOver, flags);
 
-    char storage[512];
-    SkArenaAlloc allocator{storage, sizeof(storage)};
+    SkSTArenaAlloc<512> allocator;
     SkLinearBitmapPipeline pipeline{
             inv, filterQuality,
             SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode,
diff --git a/src/core/SkArenaAlloc.h b/src/core/SkArenaAlloc.h
index c43fcf8a..f102cf6 100644
--- a/src/core/SkArenaAlloc.h
+++ b/src/core/SkArenaAlloc.h
@@ -70,11 +70,6 @@
     enum Tracking {kDontTrack, kTrack};
     SkArenaAlloc(char* block, size_t size, size_t, Tracking tracking = kDontTrack);
 
-    template <size_t kSize>
-    SkArenaAlloc(char (&block)[kSize], size_t extraSize = kSize, Tracking tracking = kDontTrack)
-        : SkArenaAlloc(block, kSize, extraSize, tracking)
-    {}
-
     SkArenaAlloc(size_t extraSize, Tracking tracking = kDontTrack)
         : SkArenaAlloc(nullptr, 0, extraSize, tracking)
     {}
@@ -224,4 +219,18 @@
     uint32_t       fFib0 {1}, fFib1 {1};
 };
 
+// Helper for defining allocators with inline/reserved storage.
+// For argument declarations, stick to the base type (SkArenaAlloc).
+template <size_t InlineStorageSize>
+class SkSTArenaAlloc : public SkArenaAlloc {
+public:
+    explicit SkSTArenaAlloc(size_t extraSize = InlineStorageSize, Tracking tracking = kDontTrack)
+        : INHERITED(fInlineStorage, InlineStorageSize, extraSize, tracking) {}
+
+private:
+    char fInlineStorage[InlineStorageSize];
+
+    using INHERITED = SkArenaAlloc;
+};
+
 #endif//SkFixedAlloc_DEFINED
diff --git a/src/core/SkAutoBlitterChoose.h b/src/core/SkAutoBlitterChoose.h
index 460e30d..3698598 100644
--- a/src/core/SkAutoBlitterChoose.h
+++ b/src/core/SkAutoBlitterChoose.h
@@ -38,8 +38,7 @@
     // Owned by fAlloc, which will handle the delete.
     SkBlitter*          fBlitter;
 
-    char fStorage[kSkBlitterContextSize];
-    SkArenaAlloc fAlloc{fStorage};
+    SkSTArenaAlloc<kSkBlitterContextSize> fAlloc;
 };
 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose)
 
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 3c7e647..6fded02 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -526,8 +526,7 @@
     bool            fDone;
     bool            fIsSimple;
     SkDrawLooper::Context* fLooperContext;
-    char            fStorage[48];
-    SkArenaAlloc    fAlloc {fStorage};
+    SkSTArenaAlloc<48>     fAlloc;
 
     bool doNext(SkDrawFilter::Type drawType);
 };
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 8245d46..47f6e8b 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1258,8 +1258,7 @@
         int ix = SkScalarRoundToInt(matrix.getTranslateX());
         int iy = SkScalarRoundToInt(matrix.getTranslateY());
         if (clipHandlesSprite(*fRC, ix, iy, pmap)) {
-            char storage[kSkBlitterContextSize];
-            SkArenaAlloc allocator{storage};
+            SkSTArenaAlloc<kSkBlitterContextSize> allocator;
             // blitter will be owned by the allocator.
             SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, *paint, pmap, ix, iy, &allocator);
             if (blitter) {
@@ -1315,8 +1314,7 @@
 
     if (nullptr == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) {
         // blitter will be owned by the allocator.
-        char storage[kSkBlitterContextSize];
-        SkArenaAlloc allocator{storage};
+        SkSTArenaAlloc<kSkBlitterContextSize> allocator;
         SkBlitter* blitter = SkBlitter::ChooseSprite(fDst, paint, pmap, x, y, &allocator);
         if (blitter) {
             SkScan::FillIRect(bounds, *fRC, blitter);
diff --git a/src/core/SkDrawLooper.cpp b/src/core/SkDrawLooper.cpp
index 54c9af1..db6bd54 100644
--- a/src/core/SkDrawLooper.cpp
+++ b/src/core/SkDrawLooper.cpp
@@ -14,8 +14,7 @@
 
 bool SkDrawLooper::canComputeFastBounds(const SkPaint& paint) const {
     SkCanvas canvas;
-    char storage[48];
-    SkArenaAlloc alloc {storage};
+    SkSTArenaAlloc<48> alloc;
 
     SkDrawLooper::Context* context = this->makeContext(&canvas, &alloc);
     for (;;) {
@@ -38,8 +37,7 @@
     const SkRect src = s;
 
     SkCanvas canvas;
-    char storage[48];
-    SkArenaAlloc alloc {storage};
+    SkSTArenaAlloc<48> alloc;
 
     *dst = src;   // catch case where there are no loops
     SkDrawLooper::Context* context = this->makeContext(&canvas, &alloc);
diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp
index 442ba08..125ab7a 100644
--- a/src/core/SkDraw_vertices.cpp
+++ b/src/core/SkDraw_vertices.cpp
@@ -206,8 +206,7 @@
     constexpr size_t outerSize = sizeof(SkTriColorShader) +
                                  sizeof(SkComposeShader) +
                                  (sizeof(SkPoint) + sizeof(SkPM4f)) * defCount;
-    char            outerStorage[outerSize];
-    SkArenaAlloc    outerAlloc(outerStorage, sizeof(outerStorage));
+    SkSTArenaAlloc<outerSize> outerAlloc;
 
     SkPoint* devVerts = outerAlloc.makeArray<SkPoint>(count);
     fMatrix->mapPoints(devVerts, vertices, count);
@@ -237,8 +236,7 @@
         p.setShader(sk_ref_sp(shader));
 
         while (vertProc(&state)) {
-            char            innerStorage[2048];
-            SkArenaAlloc    innerAlloc(innerStorage, sizeof(innerStorage));
+            SkSTArenaAlloc<2048> innerAlloc;
 
             const SkMatrix* ctm = fMatrix;
             SkMatrix tmpCtm;
diff --git a/src/core/SkEdgeBuilder.h b/src/core/SkEdgeBuilder.h
index d238351..8d38f10 100644
--- a/src/core/SkEdgeBuilder.h
+++ b/src/core/SkEdgeBuilder.h
@@ -42,8 +42,7 @@
     bool vertical_line(const SkEdge* edge);
     bool vertical_line(const SkAnalyticEdge* edge);
 
-    char                fStorage[512];
-    SkArenaAlloc        fAlloc{fStorage};
+    SkSTArenaAlloc<512> fAlloc;
     SkTDArray<void*>    fList;
 
     /*
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index da38102..9d3e1dc 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -167,12 +167,10 @@
 class SkRasterPipeline_ : public SkRasterPipeline {
 public:
     SkRasterPipeline_()
-        : SkRasterPipeline(&fBuiltinAlloc)
-        , fBuiltinAlloc(fBuffer) {}
+        : SkRasterPipeline(&fBuiltinAlloc) {}
 
 private:
-    char         fBuffer[bytes];
-    SkArenaAlloc fBuiltinAlloc;
+    SkSTArenaAlloc<bytes> fBuiltinAlloc;
 };
 
 
diff --git a/src/pathops/SkOpBuilder.cpp b/src/pathops/SkOpBuilder.cpp
index c4eb0a9..a7aa92f 100644
--- a/src/pathops/SkOpBuilder.cpp
+++ b/src/pathops/SkOpBuilder.cpp
@@ -13,8 +13,7 @@
 #include "SkPathOpsCommon.h"
 
 static bool one_contour(const SkPath& path) {
-    char storage[256];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<256> allocator;
     int verbCount = path.countVerbs();
     uint8_t* verbs = (uint8_t*) allocator.makeArrayDefault<uint8_t>(verbCount);
     (void) path.getVerbs(verbs, verbCount);
@@ -51,8 +50,7 @@
         path->setFillType(fillType);
         return true;
     }
-    char storage[4096];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<4096> allocator;
     SkOpContourHead contourHead;
     SkOpGlobalState globalState(&contourHead, &allocator  SkDEBUGPARAMS(false)
             SkDEBUGPARAMS(nullptr));
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index fd08aaa..5449510 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -217,8 +217,7 @@
 
 bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result
         SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) {
-    char storage[4096];
-    SkArenaAlloc allocator(storage);  // FIXME: add a constant expression here, tune
+    SkSTArenaAlloc<4096> allocator;  // FIXME: add a constant expression here, tune
     SkOpContour contour;
     SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
     SkOpGlobalState globalState(contourList, &allocator
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index e671ab8..d9d0879 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -146,8 +146,7 @@
         return true;
     }
     // turn path into list of segments
-    char storage[4096];
-    SkArenaAlloc allocator(storage);  // FIXME: constant-ize, tune
+    SkSTArenaAlloc<4096> allocator;  // FIXME: constant-ize, tune
     SkOpContour contour;
     SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
     SkOpGlobalState globalState(contourList, &allocator
diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp
index 4236d2d..8b62a6a 100644
--- a/src/pathops/SkPathOpsTightBounds.cpp
+++ b/src/pathops/SkPathOpsTightBounds.cpp
@@ -47,8 +47,7 @@
         *result = path.getBounds();
         return true;
     }
-    char storage[4096];
-    SkArenaAlloc allocator(storage);  // FIXME: constant-ize, tune
+    SkSTArenaAlloc<4096> allocator;  // FIXME: constant-ize, tune
     SkOpContour contour;
     SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
     SkOpGlobalState globalState(contourList, &allocator  SkDEBUGPARAMS(false)
diff --git a/src/pathops/SkPathOpsWinding.cpp b/src/pathops/SkPathOpsWinding.cpp
index 5692ae3..4c0f043 100644
--- a/src/pathops/SkPathOpsWinding.cpp
+++ b/src/pathops/SkPathOpsWinding.cpp
@@ -233,8 +233,7 @@
 }
 
 bool SkOpSpan::sortableTop(SkOpContour* contourHead) {
-    char storage[1024];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<1024> allocator;
     int dirOffset;
     double t = get_t_guess(fTopTTry++, &dirOffset);
     SkOpRayHit hitBase;
diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp
index 3dc7ba9..5820d85 100644
--- a/src/utils/SkPatchUtils.cpp
+++ b/src/utils/SkPatchUtils.cpp
@@ -326,8 +326,7 @@
         flags |= SkVertices::kHasColors_BuilderFlag;
     }
 
-    char allocStorage[2048];
-    SkArenaAlloc alloc(allocStorage, sizeof(allocStorage));
+    SkSTArenaAlloc<2048> alloc;
     SkRGBAf* cornerColors = srcColors ? alloc.makeArray<SkRGBAf>(4) : nullptr;
     SkRGBAf* tmpColors = srcColors ? alloc.makeArray<SkRGBAf>(vertexCount) : nullptr;
     auto convertCS = interpColorsLinearly ? SkColorSpace::MakeSRGB() : nullptr;
diff --git a/tests/ArenaAllocTest.cpp b/tests/ArenaAllocTest.cpp
index cb2ae0e..137e60e 100644
--- a/tests/ArenaAllocTest.cpp
+++ b/tests/ArenaAllocTest.cpp
@@ -93,8 +93,7 @@
     {
         created = 0;
         destroyed = 0;
-        char block[64];
-        SkArenaAlloc arena{block};
+        SkSTArenaAlloc<64> arena;
 
         REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
         Foo* foo = arena.make<Foo>(3, 4.0f);
@@ -145,8 +144,7 @@
     REPORTER_ASSERT(r, destroyed == 11);
 
     {
-        char storage[64];
-        SkArenaAlloc arena{storage};
+        SkSTArenaAlloc<64> arena;
         arena.makeArrayDefault<char>(256);
         arena.reset();
         arena.reset();
@@ -155,8 +153,7 @@
     {
         created = 0;
         destroyed = 0;
-        char storage[64];
-        SkArenaAlloc arena{storage};
+        SkSTArenaAlloc<64> arena;
 
         Start start;
         Node* current = nullptr;
@@ -173,8 +170,7 @@
     {
         created = 0;
         destroyed = 0;
-        char storage[64];
-        SkArenaAlloc arena{storage};
+        SkSTArenaAlloc<64> arena;
 
         sk_sp<FooRefCnt> f = arena.makeSkSp<FooRefCnt>(4, 5.0f);
         REPORTER_ASSERT(r, f->x == 4);
diff --git a/tests/PathOpsAngleIdeas.cpp b/tests/PathOpsAngleIdeas.cpp
index 003242f..c50260f 100644
--- a/tests/PathOpsAngleIdeas.cpp
+++ b/tests/PathOpsAngleIdeas.cpp
@@ -558,8 +558,7 @@
 }
 
 DEF_TEST(PathOpsAngleOverlapHullsOne, reporter) {
-    char storage[4096];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<4096> allocator;
 //    gPathOpsAngleIdeasVerbose = true;
     const QuadPts quads[] = {
 {{{939.4808349609375, 914.355224609375}, {-357.7921142578125, 590.842529296875}, {736.8936767578125, -350.717529296875}}},
@@ -574,8 +573,7 @@
 }
 
 DEF_TEST(PathOpsAngleOverlapHulls, reporter) {
-    char storage[4096];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<4096> allocator;
     if (!gPathOpsAngleIdeasVerbose) {  // takes a while to run -- so exclude it by default
         return;
     }
diff --git a/tests/PathOpsAngleTest.cpp b/tests/PathOpsAngleTest.cpp
index cfa8fc0..7f4c04a 100644
--- a/tests/PathOpsAngleTest.cpp
+++ b/tests/PathOpsAngleTest.cpp
@@ -239,8 +239,7 @@
 static const int circleDataSetSize = (int) SK_ARRAY_COUNT(circleDataSet);
 
 DEF_TEST(PathOpsAngleCircle, reporter) {
-    char storage[4096];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<4096> allocator;
     SkOpContourHead contour;
     SkOpGlobalState state(&contour, &allocator  SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
     contour.init(&state, false, false);
@@ -432,8 +431,7 @@
 };
 
 DEF_TEST(PathOpsAngleAfter, reporter) {
-    char storage[4096];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<4096> allocator;
     SkOpContourHead contour;
     SkOpGlobalState state(&contour, &allocator  SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
     contour.init(&state, false, false);
@@ -505,8 +503,7 @@
 }
 
 DEF_TEST(PathOpsAngleAllOnOneSide, reporter) {
-    char storage[4096];
-    SkArenaAlloc allocator(storage);
+    SkSTArenaAlloc<4096> allocator;
     SkOpContourHead contour;
     SkOpGlobalState state(&contour, &allocator  SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr));
     contour.init(&state, false, false);