Revert "Use SkArenaAlloc instead of SkSmallAllocator in the SkAutoBlitterChoose code."
authorRobert Phillips <robertphillips@google.com>
Tue, 7 Feb 2017 17:28:15 +0000 (17:28 +0000)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 7 Feb 2017 17:28:21 +0000 (17:28 +0000)
This reverts commit 2b57b7f7a7fc97db57f190b5a8ebcf68e177ee2d.

Reason for revert: Android compile failing

Original change's description:
> Use SkArenaAlloc instead of SkSmallAllocator in the SkAutoBlitterChoose code.
>
>
> TBR=reed@google.com
> Change-Id: Iefb044bf7657fbf982f23aa91a3f4d013ce2c626
> Reviewed-on: https://skia-review.googlesource.com/7786
> Reviewed-by: Mike Klein <mtklein@chromium.org>
> Reviewed-by: Herb Derby <herb@google.com>
> Commit-Queue: Herb Derby <herb@google.com>
>

TBR=mtklein@chromium.org,mtklein@google.com,herb@google.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true

Change-Id: Id09c35377dddae0811d998b7d0c34c422325a5bc
Reviewed-on: https://skia-review.googlesource.com/8129
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
49 files changed:
bench/SkLinearBitmapPipelineBench.cpp
experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.cpp
experimental/SkPerlinNoiseShader2/SkPerlinNoiseShader2.h
gm/SkLinearBitmapPipelineGM.cpp
include/core/SkShader.h
include/effects/SkPerlinNoiseShader.h
src/core/SkBitmapDevice.cpp
src/core/SkBitmapProcShader.cpp
src/core/SkBitmapProcShader.h
src/core/SkBlitter.cpp
src/core/SkBlitter.h
src/core/SkBlitter_PM4f.cpp
src/core/SkBlitter_RGB16.cpp
src/core/SkColorFilterShader.cpp
src/core/SkColorFilterShader.h
src/core/SkColorShader.cpp
src/core/SkColorShader.h
src/core/SkComposeShader.cpp
src/core/SkComposeShader.h
src/core/SkCoreBlitters.h
src/core/SkDraw.cpp
src/core/SkEmptyShader.h
src/core/SkLightingShader.cpp
src/core/SkLocalMatrixShader.cpp
src/core/SkLocalMatrixShader.h
src/core/SkNormalBevelSource.cpp
src/core/SkNormalBevelSource.h
src/core/SkNormalFlatSource.cpp
src/core/SkNormalFlatSource.h
src/core/SkNormalMapSource.cpp
src/core/SkNormalMapSource.h
src/core/SkNormalSource.h
src/core/SkPictureShader.cpp
src/core/SkPictureShader.h
src/core/SkRasterPipelineBlitter.cpp
src/core/SkShader.cpp
src/effects/SkGaussianEdgeShader.cpp
src/effects/SkPerlinNoiseShader.cpp
src/effects/gradients/SkGradientShaderPriv.h
src/effects/gradients/SkLinearGradient.cpp
src/effects/gradients/SkLinearGradient.h
src/effects/gradients/SkRadialGradient.cpp
src/effects/gradients/SkRadialGradient.h
src/effects/gradients/SkSweepGradient.cpp
src/effects/gradients/SkSweepGradient.h
src/effects/gradients/SkTwoPointConicalGradient.cpp
src/effects/gradients/SkTwoPointConicalGradient.h
src/image/SkImageShader.cpp
src/image/SkImageShader.h

index 0391798..4e892b6 100644 (file)
@@ -7,8 +7,6 @@
 
 #include <memory>
 #include "Benchmark.h"
-
-#include "SkArenaAlloc.h"
 #include "SkBitmapProcShader.h"
 #include "SkColor.h"
 #include "SkArenaAlloc.h"
@@ -201,11 +199,12 @@ struct SkBitmapFPOrigShader : public CommonBitmapFPBenchmark {
 
         SkAutoTMalloc<SkPMColor> buffer4b(width*height);
 
-        SkArenaAlloc alloc{kSkBlitterContextSize * sizeof(uint32_t)};
+        uint32_t storage[kSkBlitterContextSize];
         const SkShader::ContextRec rec(fPaint, fM, nullptr,
                                        SkShader::ContextRec::kPMColor_DstType,
                                        nullptr);
-        SkShader::Context* ctx = fPaint.getShader()->makeContext(rec, &alloc);
+        SkASSERT(fPaint.getShader()->contextSize(rec) <= sizeof(storage));
+        SkShader::Context* ctx = fPaint.getShader()->createContext(rec, storage);
 
         int count = 100;
 
index 06589f2..401d3c3 100644 (file)
@@ -5,10 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "SkPerlinNoiseShader2.h"
-
-#include "SkArenaAlloc.h"
 #include "SkDither.h"
+#include "SkPerlinNoiseShader2.h"
 #include "SkColorFilter.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
@@ -571,9 +569,13 @@ SkPMColor SkPerlinNoiseShader2::PerlinNoiseShaderContext::shade(
     return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
 }
 
-SkShader::Context* SkPerlinNoiseShader2::onMakeContext(const ContextRec& rec,
-                                                       SkArenaAlloc* alloc) const {
-    return alloc->make<PerlinNoiseShaderContext>(*this, rec);
+SkShader::Context* SkPerlinNoiseShader2::onCreateContext(const ContextRec& rec,
+                                                        void* storage) const {
+    return new (storage) PerlinNoiseShaderContext(*this, rec);
+}
+
+size_t SkPerlinNoiseShader2::onContextSize(const ContextRec&) const {
+    return sizeof(PerlinNoiseShaderContext);
 }
 
 SkPerlinNoiseShader2::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
index 1f4839c..f1b94e1 100644 (file)
@@ -114,7 +114,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 
 private:
     SkPerlinNoiseShader2(SkPerlinNoiseShader2::Type type, SkScalar baseFrequencyX,
index 1bf4301..e881645 100644 (file)
@@ -6,8 +6,6 @@
  */
 
 #include "gm.h"
-
-#include "SkArenaAlloc.h"
 #include "SkBlitter.h"
 #include "SkCanvas.h"
 #include "SkColor.h"
@@ -61,7 +59,7 @@ static void draw_rect_orig(SkCanvas* canvas, const SkRect& r, SkColor c, const S
 
     sk_sp<SkImage> image(SkImage::MakeRasterCopy(SkPixmap(info, pmsrc.addr32(), pmsrc.rowBytes())));
     SkPaint paint;
-    SkArenaAlloc alloc{kSkBlitterContextSize * sizeof(uint32_t)};
+    int32_t storage[kSkBlitterContextSize];
 
     sk_sp<SkShader> shader = image->makeShader(SkShader::kRepeat_TileMode,
                                                SkShader::kRepeat_TileMode);
@@ -75,8 +73,9 @@ static void draw_rect_orig(SkCanvas* canvas, const SkRect& r, SkColor c, const S
     const SkShader::ContextRec rec(paint, *mat, nullptr,
                                    SkBlitter::PreferredShaderDest(pmsrc.info()),
                                    canvas->imageInfo().colorSpace());
+    SkASSERT(paint.getShader()->contextSize(rec) <= sizeof(storage));
 
-    SkShader::Context* ctx = paint.getShader()->makeContext(rec, &alloc);
+    SkShader::Context* ctx = paint.getShader()->createContext(rec, storage);
 
     for (int y = 0; y < ir.height(); y++) {
         ctx->shadeSpan(0, y, pmdst.writable_addr32(0, y), ir.width());
index 97cad6e..30a10dc 100644 (file)
@@ -17,9 +17,9 @@
 #include "SkPaint.h"
 #include "../gpu/GrColor.h"
 
-class SkArenaAlloc;
 class SkColorFilter;
 class SkColorSpace;
+class SkArenaAlloc;
 class SkImage;
 class SkPath;
 class SkPicture;
@@ -229,11 +229,15 @@ public:
     };
 
     /**
-     * Make a context using the memory provided by the arena.
-     *
-     * @return pointer to context or nullptr if can't be created
+     *  Create the actual object that does the shading.
+     *  Size of storage must be >= contextSize.
      */
-    Context* makeContext(const ContextRec&, SkArenaAlloc*) const;
+    Context* createContext(const ContextRec&, void* storage) const;
+
+    /**
+     *  Return the size of a Context returned by createContext.
+     */
+    size_t contextSize(const ContextRec&) const;
 
 #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
     /**
@@ -472,10 +476,16 @@ protected:
     bool computeTotalInverse(const ContextRec&, SkMatrix* totalInverse) const;
 
     /**
-     * Specialize creating a SkShader context using the supplied allocator.
-     * @return pointer to context owned by the arena allocator.
+     *  Your subclass must also override contextSize() if it overrides onCreateContext().
+     *  Base class impl returns NULL.
+     */
+    virtual Context* onCreateContext(const ContextRec&, void* storage) const;
+
+    /**
+     *  Override this if your subclass overrides createContext, to return the correct size of
+     *  your subclass' context.
      */
-    virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const = 0;
+    virtual size_t onContextSize(const ContextRec&) const;
 
     virtual bool onAsLuminanceColor(SkColor*) const {
         return false;
index 4e648f3..45d4367 100644 (file)
@@ -92,7 +92,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
+    size_t onContextSize(const ContextRec&) const override;
 
 private:
     SkPerlinNoiseShader(SkPerlinNoiseShader::Type type, SkScalar baseFrequencyX,
index fe43ba2..a409517 100644 (file)
@@ -326,7 +326,6 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
 
     USE_SHADER:
 
-    // TODO(herb): Move this over to SkArenaAlloc when arena alloc has a facility to return sk_sps.
     // Since the shader need only live for our stack-frame, pass in a custom allocator. This
     // can save malloc calls, and signals to SkMakeBitmapShader to not try to copy the bitmap
     // if its mutable, since that precaution is not needed (give the short lifetime of the shader).
index 8c648b6..11deac4 100644 (file)
@@ -6,8 +6,6 @@
  */
 
 #include "SkBitmapProcShader.h"
-
-#include "SkArenaAlloc.h"
 #include "SkBitmapProcState.h"
 #include "SkBitmapProvider.h"
 #include "SkXfermodePriv.h"
@@ -35,6 +33,10 @@ public:
         }
     }
 
+    ~BitmapProcInfoContext() override {
+        fInfo->~SkBitmapProcInfo();
+    }
+
     uint32_t getFlags() const override { return fFlags; }
 
 private:
@@ -199,10 +201,10 @@ size_t SkBitmapProcLegacyShader::ContextSize(const ContextRec& rec, const SkImag
     return s;
 }
 
-SkShader::Context* SkBitmapProcLegacyShader::MakeContext(
-    const SkShader& shader, TileMode tmx, TileMode tmy,
-    const SkBitmapProvider& provider, const ContextRec& rec, SkArenaAlloc* alloc)
-{
+SkShader::Context* SkBitmapProcLegacyShader::MakeContext(const SkShader& shader,
+                                                   TileMode tmx, TileMode tmy,
+                                                   const SkBitmapProvider& provider,
+                                                   const ContextRec& rec, void* storage) {
     SkMatrix totalInverse;
     // Do this first, so we know the matrix can be inverted.
     if (!shader.computeTotalInverse(rec, &totalInverse)) {
@@ -213,17 +215,21 @@ SkShader::Context* SkBitmapProcLegacyShader::MakeContext(
     bool useLinearPipeline = choose_linear_pipeline(rec, provider.info());
 
     if (useLinearPipeline) {
-        SkBitmapProcInfo* info = alloc->make<SkBitmapProcInfo>(provider, tmx, tmy);
+        void* infoStorage = (char*)storage + sizeof(LinearPipelineContext);
+        SkBitmapProcInfo* info = new (infoStorage) SkBitmapProcInfo(provider, tmx, tmy);
         if (!info->init(totalInverse, *rec.fPaint)) {
+            info->~SkBitmapProcInfo();
             return nullptr;
         }
 
-        return alloc->make<LinearPipelineContext>(shader, rec, info);
+        return new (storage) LinearPipelineContext(shader, rec, info);
     } else {
-        SkBitmapProcState* state = alloc->make<SkBitmapProcState>(provider, tmx, tmy);
+        void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext);
+        SkBitmapProcState* state = new (stateStorage) SkBitmapProcState(provider, tmx, tmy);
         if (!state->setup(totalInverse, *rec.fPaint)) {
+            state->~SkBitmapProcState();
             return nullptr;
         }
-        return alloc->make<BitmapProcShaderContext>(shader, rec, state);
+        return new (storage) BitmapProcShaderContext(shader, rec, state);
     }
 }
index 204b27d..4b7447e 100644 (file)
@@ -18,7 +18,7 @@ private:
 
     static size_t ContextSize(const ContextRec&, const SkImageInfo& srcInfo);
     static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy,
-                                const SkBitmapProvider&, const ContextRec&, SkArenaAlloc* alloc);
+                                const SkBitmapProvider&, const ContextRec&, void* storage);
 
     typedef SkShader INHERITED;
 };
index a386904..d8e3dfd 100644 (file)
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkArenaAlloc.h"
 #include "SkBlitter.h"
 #include "SkAntiRun.h"
 #include "SkColor.h"
@@ -586,15 +585,24 @@ class Sk3DShader : public SkShader {
 public:
     Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {}
 
-    Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override {
+    size_t onContextSize(const ContextRec& rec) const override {
+        size_t size = sizeof(Sk3DShaderContext);
+        if (fProxy) {
+            size += fProxy->contextSize(rec);
+        }
+        return size;
+    }
+
+    Context* onCreateContext(const ContextRec& rec, void* storage) const override {
         SkShader::Context* proxyContext = nullptr;
         if (fProxy) {
-            proxyContext = fProxy->makeContext(rec, alloc);
+            char* proxyContextStorage = (char*) storage + sizeof(Sk3DShaderContext);
+            proxyContext = fProxy->createContext(rec, proxyContextStorage);
             if (!proxyContext) {
                 return nullptr;
             }
         }
-        return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext);
+        return new (storage) Sk3DShaderContext(*this, rec, proxyContext);
     }
 
     class Sk3DShaderContext : public SkShader::Context {
@@ -785,15 +793,15 @@ SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo&
 SkBlitter* SkBlitter::Choose(const SkPixmap& device,
                              const SkMatrix& matrix,
                              const SkPaint& origPaint,
-                             SkArenaAlloc* alloc,
+                             SkTBlitterAllocator* allocator,
                              bool drawCoverage) {
-    SkASSERT(alloc != nullptr);
+    SkASSERT(allocator != nullptr);
 
     // which check, in case we're being called by a client with a dummy device
     // (e.g. they have a bounder that always aborts the draw)
     if (kUnknown_SkColorType == device.colorType() ||
             (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) {
-        return alloc->make<SkNullBlitter>();
+        return allocator->createT<SkNullBlitter>();
     }
 
     SkShader* shader = origPaint.getShader();
@@ -819,7 +827,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
                 paint.writable()->setBlendMode(mode);
                 break;
             case kSkipDrawing_SkXfermodeInterpretation:{
-                return alloc->make<SkNullBlitter>();
+                return allocator->createT<SkNullBlitter>();
             }
             default:
                 break;
@@ -844,10 +852,10 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
     if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) {
         SkASSERT(nullptr == shader);
         SkASSERT(paint->isSrcOver());
-        return alloc->make<SkA8_Coverage_Blitter>(device, *paint);
+        return allocator->createT<SkA8_Coverage_Blitter>(device, *paint);
     }
 
-    if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc)) {
+    if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, allocator)) {
         return blitter;
     }
 
@@ -883,12 +891,21 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
         const SkShader::ContextRec rec(*paint, matrix, nullptr,
                                        PreferredShaderDest(device.info()),
                                        device.colorSpace());
-        // Try to create the ShaderContext
-        shaderContext = shader->makeContext(rec, alloc);
-        if (!shaderContext) {
-            return alloc->make<SkNullBlitter>();
+        size_t contextSize = shader->contextSize(rec);
+        if (contextSize) {
+            // Try to create the ShaderContext
+            shaderContext = allocator->createWithIniter(
+                contextSize,
+                [&rec, shader](void* storage) {
+                    return shader->createContext(rec, storage);
+                });
+            if (!shaderContext) {
+                return allocator->createT<SkNullBlitter>();
+            }
+            SkASSERT(shaderContext);
+        } else {
+            return allocator->createT<SkNullBlitter>();
         }
-        SkASSERT(shaderContext);
     }
 
     SkBlitter*  blitter = nullptr;
@@ -896,14 +913,14 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
         case kAlpha_8_SkColorType:
             SkASSERT(!drawCoverage);  // Handled above.
             if (shader) {
-                blitter = alloc->make<SkA8_Shader_Blitter>(device, *paint, shaderContext);
+                blitter = allocator->createT<SkA8_Shader_Blitter>(device, *paint, shaderContext);
             } else {
-                blitter = alloc->make<SkA8_Blitter>(device, *paint);
+                blitter = allocator->createT<SkA8_Blitter>(device, *paint);
             }
             break;
 
         case kRGB_565_SkColorType:
-            blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloc);
+            blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, allocator);
             break;
 
         case kN32_SkColorType:
@@ -913,23 +930,23 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
             if (device.info().gammaCloseToSRGB())
 #endif
             {
-                blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, alloc);
+                blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, allocator);
             } else {
                 if (shader) {
-                        blitter = alloc->make<SkARGB32_Shader_Blitter>(
+                        blitter = allocator->createT<SkARGB32_Shader_Blitter>(
                                 device, *paint, shaderContext);
                 } else if (paint->getColor() == SK_ColorBLACK) {
-                    blitter = alloc->make<SkARGB32_Black_Blitter>(device, *paint);
+                    blitter = allocator->createT<SkARGB32_Black_Blitter>(device, *paint);
                 } else if (paint->getAlpha() == 0xFF) {
-                    blitter = alloc->make<SkARGB32_Opaque_Blitter>(device, *paint);
+                    blitter = allocator->createT<SkARGB32_Opaque_Blitter>(device, *paint);
                 } else {
-                    blitter = alloc->make<SkARGB32_Blitter>(device, *paint);
+                    blitter = allocator->createT<SkARGB32_Blitter>(device, *paint);
                 }
             }
             break;
 
         case kRGBA_F16_SkColorType:
-            blitter = SkBlitter_F16_Create(device, *paint, shaderContext, alloc);
+            blitter = SkBlitter_F16_Create(device, *paint, shaderContext, allocator);
             break;
 
         default:
@@ -937,16 +954,15 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device,
     }
 
     if (!blitter) {
-        blitter = alloc->make<SkNullBlitter>();
+        blitter = allocator->createT<SkNullBlitter>();
     }
 
     if (shader3D) {
         SkBlitter* innerBlitter = blitter;
-        // FIXME - comment about allocator
         // innerBlitter was allocated by allocator, which will delete it.
         // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
         // wrapper the blitter to notify it when we see an emboss mask.
-        blitter = alloc->make<Sk3DBlitter>(innerBlitter, shaderContext);
+        blitter = allocator->createT<Sk3DBlitter>(innerBlitter, shaderContext);
     }
     return blitter;
 }
index 4d34ce3..cab2afc 100644 (file)
@@ -137,7 +137,7 @@ public:
     static SkBlitter* Choose(const SkPixmap& dst,
                              const SkMatrix& matrix,
                              const SkPaint& paint,
-                             SkArenaAlloc*,
+                             SkTBlitterAllocator*,
                              bool drawCoverage = false);
 
     static SkBlitter* ChooseSprite(const SkPixmap& dst,
index 61105ce..ce66580 100644 (file)
@@ -6,8 +6,6 @@
  */
 
 #include "SkCoreBlitters.h"
-
-#include "SkArenaAlloc.h"
 #include "SkColorPriv.h"
 #include "SkShader.h"
 #include "SkUtils.h"
@@ -405,8 +403,8 @@ struct StateF16 : State4f {
 
 template <typename State> SkBlitter* create(const SkPixmap& device, const SkPaint& paint,
                                             SkShader::Context* shaderContext,
-                                            SkArenaAlloc* alloc) {
-    SkASSERT(alloc != nullptr);
+                                            SkTBlitterAllocator* allocator) {
+    SkASSERT(allocator != nullptr);
 
     if (shaderContext) {
         SkShader::Context::BlitState bstate;
@@ -415,24 +413,24 @@ template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain
         bstate.fMode = paint.getBlendMode();
 
         (void)shaderContext->chooseBlitProcs(device.info(), &bstate);
-        return alloc->make<SkState_Shader_Blitter<State>>(device, paint, bstate);
+        return allocator->createT<SkState_Shader_Blitter<State>>(device, paint, bstate);
     } else {
         SkColor color = paint.getColor();
         if (0 == SkColorGetA(color)) {
             return nullptr;
         }
-        return alloc->make<SkState_Blitter<State>>(device, paint);
+        return allocator->createT<SkState_Blitter<State>>(device, paint);
     }
 }
 
 SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint,
                                    SkShader::Context* shaderContext,
-                                   SkArenaAlloc* alloc) {
-    return create<State32>(device, paint, shaderContext, alloc);
+                                   SkTBlitterAllocator* allocator) {
+    return create<State32>(device, paint, shaderContext, allocator);
 }
 
 SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint& paint,
                                 SkShader::Context* shaderContext,
-                                SkArenaAlloc* alloc) {
-    return create<StateF16>(device, paint, shaderContext, alloc);
+                                SkTBlitterAllocator* allocator) {
+    return create<StateF16>(device, paint, shaderContext, allocator);
 }
index e91e23f..afa8cac 100644 (file)
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkArenaAlloc.h"
 #include "SkBlitRow.h"
 #include "SkCoreBlitters.h"
 #include "SkColorPriv.h"
@@ -881,8 +880,8 @@ void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y,
 
 SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
         SkShader::Context* shaderContext,
-        SkArenaAlloc* alloc) {
-    SkASSERT(alloc != nullptr);
+        SkTBlitterAllocator* allocator) {
+    SkASSERT(allocator != nullptr);
 
     SkBlitter* blitter;
     SkShader* shader = paint.getShader();
@@ -894,24 +893,24 @@ SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
     if (shader) {
         SkASSERT(shaderContext != nullptr);
         if (!is_srcover) {
-            blitter = alloc->make<SkRGB16_Shader_Xfermode_Blitter>(device, paint,
+            blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device, paint,
                                                                           shaderContext);
         } else {
-            blitter = alloc->make<SkRGB16_Shader_Blitter>(device, paint, shaderContext);
+            blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint, shaderContext);
         }
     } else {
         // no shader, no xfermode, (and we always ignore colorfilter)
         SkColor color = paint.getColor();
         if (0 == SkColorGetA(color)) {
-            blitter = alloc->make<SkNullBlitter>();
+            blitter = allocator->createT<SkNullBlitter>();
 #ifdef USE_BLACK_BLITTER
         } else if (SK_ColorBLACK == color) {
-            blitter = alloc->make<SkRGB16_Black_Blitter>(device, paint);
+            blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint);
 #endif
         } else if (0xFF == SkColorGetA(color)) {
-            blitter = alloc->make<SkRGB16_Opaque_Blitter>(device, paint);
+            blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint);
         } else {
-            blitter = alloc->make<SkRGB16_Blitter>(device, paint);
+            blitter = allocator->createT<SkRGB16_Blitter>(device, paint);
         }
     }
 
index 5e96b24..4090a18 100644 (file)
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkArenaAlloc.h"
 #include "SkColorFilterShader.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
@@ -53,15 +52,19 @@ uint32_t SkColorFilterShader::FilterShaderContext::getFlags() const {
     return shaderF;
 }
 
-SkShader::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
-                                                      SkArenaAlloc* alloc) const {
-    SkShader::Context* shaderContext = fShader->makeContext(rec, alloc);
+SkShader::Context* SkColorFilterShader::onCreateContext(const ContextRec& rec,
+                                                        void* storage) const {
+    char* shaderContextStorage = (char*)storage + sizeof(FilterShaderContext);
+    SkShader::Context* shaderContext = fShader->createContext(rec, shaderContextStorage);
     if (nullptr == shaderContext) {
         return nullptr;
     }
-    return alloc->make<FilterShaderContext>(*this, shaderContext, rec);
+    return new (storage) FilterShaderContext(*this, shaderContext, rec);
 }
 
+size_t SkColorFilterShader::onContextSize(const ContextRec& rec) const {
+    return sizeof(FilterShaderContext) + fShader->contextSize(rec);
+}
 
 SkColorFilterShader::FilterShaderContext::FilterShaderContext(
                                                          const SkColorFilterShader& filterShader,
@@ -71,6 +74,10 @@ SkColorFilterShader::FilterShaderContext::FilterShaderContext(
     , fShaderContext(shaderContext)
 {}
 
+SkColorFilterShader::FilterShaderContext::~FilterShaderContext() {
+    fShaderContext->~Context();
+}
+
 void SkColorFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[],
                                                          int count) {
     const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
index e697736..035acd8 100644 (file)
@@ -11,8 +11,6 @@
 #include "SkColorFilter.h"
 #include "SkShader.h"
 
-class SkArenaAlloc;
-
 class SkColorFilterShader : public SkShader {
 public:
     SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter);
@@ -25,6 +23,7 @@ public:
     public:
         // Takes ownership of shaderContext and calls its destructor.
         FilterShaderContext(const SkColorFilterShader&, SkShader::Context*, const ContextRec&);
+        virtual ~FilterShaderContext();
 
         uint32_t getFlags() const override;
 
@@ -47,7 +46,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc* alloc) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 
 private:
     sk_sp<SkShader>      fShader;
index 32d9b43..ed2a26b 100644 (file)
@@ -31,8 +31,8 @@ uint32_t SkColorShader::ColorShaderContext::getFlags() const {
     return fFlags;
 }
 
-SkShader::Context* SkColorShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
-    return alloc->make<ColorShaderContext>(*this, rec);
+SkShader::Context* SkColorShader::onCreateContext(const ContextRec& rec, void* storage) const {
+    return new (storage) ColorShaderContext(*this, rec);
 }
 
 SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shader,
@@ -149,8 +149,8 @@ uint32_t SkColor4Shader::Color4Context::getFlags() const {
     return fFlags;
 }
 
-SkShader::Context* SkColor4Shader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
-    return alloc->make<Color4Context>(*this, rec);
+SkShader::Context* SkColor4Shader::onCreateContext(const ContextRec& rec, void* storage) const {
+    return new (storage) Color4Context(*this, rec);
 }
 
 SkColor4Shader::Color4Context::Color4Context(const SkColor4Shader& shader,
index b9db657..813fd3e 100644 (file)
@@ -59,13 +59,12 @@ public:
 protected:
     SkColorShader(SkReadBuffer&);
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
-
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
+    size_t onContextSize(const ContextRec&) const override { return sizeof(ColorShaderContext); }
     bool onAsLuminanceColor(SkColor* lum) const override {
         *lum = fColor;
         return true;
     }
-
     bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
                         const SkMatrix& ctm, const SkPaint&, const SkMatrix*) const override;
 
@@ -116,7 +115,8 @@ public:
 protected:
     SkColor4Shader(SkReadBuffer&);
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
+    size_t onContextSize(const ContextRec&) const override { return sizeof(Color4Context); }
     bool onAsLuminanceColor(SkColor* lum) const override {
         *lum = fCachedByteColor;
         return true;
index 07bbd9a..5cbd23e 100644 (file)
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkArenaAlloc.h"
 #include "SkComposeShader.h"
 #include "SkColorFilter.h"
 #include "SkColorPriv.h"
@@ -30,6 +29,12 @@ sk_sp<SkShader> SkShader::MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader>
 
 ///////////////////////////////////////////////////////////////////////////////
 
+size_t SkComposeShader::onContextSize(const ContextRec& rec) const {
+    return sizeof(ComposeShaderContext)
+        + fShaderA->contextSize(rec)
+        + fShaderB->contextSize(rec);
+}
+
 class SkAutoAlphaRestore {
 public:
     SkAutoAlphaRestore(SkPaint* paint, uint8_t newAlpha) {
@@ -75,9 +80,10 @@ template <typename T> void safe_call_destructor(T* obj) {
     }
 }
 
-SkShader::Context* SkComposeShader::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const
-{
+SkShader::Context* SkComposeShader::onCreateContext(const ContextRec& rec, void* storage) const {
+    char* aStorage = (char*) storage + sizeof(ComposeShaderContext);
+    char* bStorage = aStorage + fShaderA->contextSize(rec);
+
     // we preconcat our localMatrix (if any) with the device matrix
     // before calling our sub-shaders
     SkMatrix tmpM;
@@ -93,15 +99,15 @@ SkShader::Context* SkComposeShader::onMakeContext(
     newRec.fMatrix = &tmpM;
     newRec.fPaint = &opaquePaint;
 
-    SkShader::Context* contextA = fShaderA->makeContext(newRec, alloc);
-    SkShader::Context* contextB = fShaderB->makeContext(newRec, alloc);
+    SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage);
+    SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage);
     if (!contextA || !contextB) {
         safe_call_destructor(contextA);
         safe_call_destructor(contextB);
         return nullptr;
     }
 
-    return alloc->make<ComposeShaderContext>(*this, rec, contextA, contextB);
+    return new (storage) ComposeShaderContext(*this, rec, contextA, contextB);
 }
 
 SkComposeShader::ComposeShaderContext::ComposeShaderContext(
@@ -111,6 +117,11 @@ SkComposeShader::ComposeShaderContext::ComposeShaderContext(
     , fShaderContextA(contextA)
     , fShaderContextB(contextB) {}
 
+SkComposeShader::ComposeShaderContext::~ComposeShaderContext() {
+    fShaderContextA->~Context();
+    fShaderContextB->~Context();
+}
+
 bool SkComposeShader::asACompose(ComposeRec* rec) const {
     if (rec) {
         rec->fShaderA   = fShaderA.get();
index be788af..7f9ff69 100644 (file)
@@ -45,6 +45,8 @@ public:
         ComposeShaderContext(const SkComposeShader&, const ContextRec&,
                              SkShader::Context* contextA, SkShader::Context* contextB);
 
+        virtual ~ComposeShaderContext();
+
         void shadeSpan(int x, int y, SkPMColor[], int count) override;
 
     private:
@@ -67,7 +69,8 @@ public:
 protected:
     SkComposeShader(SkReadBuffer&);
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void*) const override;
 
 private:
     sk_sp<SkShader>     fShaderA;
index 63ddda9..62bf73e 100644 (file)
@@ -178,10 +178,10 @@ private:
 };
 
 SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*,
-                                   SkArenaAlloc*);
+                                   SkTBlitterAllocator*);
 
 SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*,
-                                SkArenaAlloc*);
+                                SkTBlitterAllocator*);
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -200,11 +200,11 @@ SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShader
 
 SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
                                 SkShader::Context* shaderContext,
-                                SkArenaAlloc* allocator);
+                                SkTBlitterAllocator* allocator);
 
 
 // Returns nullptr if no SkRasterPipeline blitter can be constructed for this paint.
 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
-                                         SkArenaAlloc*);
+                                         SkTBlitterAllocator*);
 
 #endif
index 2891c95..dd39d9e 100644 (file)
@@ -7,8 +7,6 @@
 #define __STDC_LIMIT_MACROS
 
 #include "SkDraw.h"
-
-#include "SkArenaAlloc.h"
 #include "SkBlendModePriv.h"
 #include "SkBlitter.h"
 #include "SkCanvas.h"
@@ -55,7 +53,7 @@ public:
     }
     SkAutoBlitterChoose(const SkPixmap& dst, const SkMatrix& matrix,
                         const SkPaint& paint, bool drawCoverage = false) {
-        fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAlloc, drawCoverage);
+        fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCoverage);
     }
 
     SkBlitter*  operator->() { return fBlitter; }
@@ -64,16 +62,13 @@ public:
     void choose(const SkPixmap& dst, const SkMatrix& matrix,
                 const SkPaint& paint, bool drawCoverage = false) {
         SkASSERT(!fBlitter);
-        fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAlloc, drawCoverage);
+        fBlitter = SkBlitter::Choose(dst, matrix, paint, &fAllocator, drawCoverage);
     }
 
 private:
     // Owned by fAllocator, which will handle the delete.
     SkBlitter*          fBlitter;
     SkTBlitterAllocator fAllocator;
-
-    // FIXME - pick a good inline and number.
-    SkArenaAlloc fAlloc{1024};
 };
 #define SkAutoBlitterChoose(...) SK_REQUIRE_LOCAL_VAR(SkAutoBlitterChoose)
 
@@ -87,8 +82,6 @@ public:
     SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint,
                               const SkMatrix* localMatrix = nullptr)
             : fPaint(paint) /* makes a copy of the paint */ {
-        // TODO(herb): Move this over to SkArenaAlloc when arena alloc has a
-        // facility to return sk_sps.
         fPaint.setShader(SkMakeBitmapShader(src, SkShader::kClamp_TileMode,
                                             SkShader::kClamp_TileMode, localMatrix,
                                             kNever_SkCopyPixelsMode,
@@ -1776,8 +1769,9 @@ public:
     }
 
 protected:
-    Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override {
-        return alloc->make<TriColorShaderContext>(*this, rec);
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec& rec, void* storage) const override {
+        return new (storage) TriColorShaderContext(*this, rec);
     }
 
 private:
@@ -1833,6 +1827,10 @@ SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorS
 
 SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
 
+size_t SkTriColorShader::onContextSize(const ContextRec&) const {
+    return sizeof(TriColorShaderContext);
+}
+
 void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
     SkTriColorShader* parent = static_cast<SkTriColorShader*>(const_cast<SkShader*>(&fShader));
     TriColorShaderData* set = parent->takeSetupData();
index b2c9b76..528ceea 100644 (file)
@@ -24,7 +24,13 @@ public:
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
 
 protected:
-    SkShader::Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override {
+    size_t onContextSize(const ContextRec&) const override {
+        // Even though createContext returns nullptr we have to return a value of at least
+        // sizeof(SkShader::Context) to satisfy SkSmallAllocator.
+        return sizeof(SkShader::Context);
+    }
+
+    SkShader::Context* onCreateContext(const ContextRec&, void*) const override {
         return nullptr;
     }
 
index 5bdaee5..4ed0057 100644 (file)
@@ -5,7 +5,6 @@
  * found in the LICENSE file.
  */
 
-#include "SkArenaAlloc.h"
 #include "SkBitmapProcShader.h"
 #include "SkBitmapProcState.h"
 #include "SkColor.h"
@@ -64,6 +63,8 @@ public:
                               SkShader::Context* diffuseContext, SkNormalSource::Provider*,
                               void* heapAllocated);
 
+        ~LightingShaderContext() override;
+
         void shadeSpan(int x, int y, SkPMColor[], int count) override;
 
         uint32_t getFlags() const override { return fFlags; }
@@ -74,6 +75,8 @@ public:
         SkColor                   fPaintColor;
         uint32_t                  fFlags;
 
+        void* fHeapAllocated;
+
         typedef SkShader::Context INHERITED;
     };
 
@@ -82,7 +85,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void*) const override;
 
 private:
     sk_sp<SkShader> fDiffuseShader;
@@ -305,7 +309,8 @@ SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
         void* heapAllocated)
     : INHERITED(shader, rec)
     , fDiffuseContext(diffuseContext)
-    , fNormalProvider(normalProvider) {
+    , fNormalProvider(normalProvider)
+    , fHeapAllocated(heapAllocated) {
     bool isOpaque = shader.isOpaque();
 
     // update fFlags
@@ -318,6 +323,17 @@ SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
     fFlags = flags;
 }
 
+SkLightingShaderImpl::LightingShaderContext::~LightingShaderContext() {
+    // The dependencies have been created outside of the context on memory that was allocated by
+    // the onCreateContext() method. Call the destructors and free the memory.
+    if (fDiffuseContext) {
+        fDiffuseContext->~Context();
+    }
+    fNormalProvider->~Provider();
+
+    sk_free(fHeapAllocated);
+}
+
 static inline SkPMColor convert(SkColor3f color, U8CPU a) {
     if (color.fX <= 0.0f) {
         color.fX = 0.0f;
@@ -441,23 +457,39 @@ void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const {
     }
 }
 
-SkShader::Context* SkLightingShaderImpl::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const
-{
+size_t SkLightingShaderImpl::onContextSize(const ContextRec& rec) const {
+    return sizeof(LightingShaderContext);
+}
+
+SkShader::Context* SkLightingShaderImpl::onCreateContext(const ContextRec& rec,
+                                                         void* storage) const {
+    size_t heapRequired = (fDiffuseShader ? fDiffuseShader->contextSize(rec) : 0) +
+                          fNormalSource->providerSize(rec);
+    void* heapAllocated = sk_malloc_throw(heapRequired);
+
+    void* diffuseContextStorage = heapAllocated;
+    void* normalProviderStorage = (char*) diffuseContextStorage +
+                                  (fDiffuseShader ? fDiffuseShader->contextSize(rec) : 0);
+
     SkShader::Context *diffuseContext = nullptr;
     if (fDiffuseShader) {
-        diffuseContext = fDiffuseShader->makeContext(rec, alloc);
+        diffuseContext = fDiffuseShader->createContext(rec, diffuseContextStorage);
         if (!diffuseContext) {
+            sk_free(heapAllocated);
             return nullptr;
         }
     }
 
-    SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec, alloc);
+    SkNormalSource::Provider* normalProvider = fNormalSource->asProvider(rec,
+                                                                         normalProviderStorage);
     if (!normalProvider) {
+        diffuseContext->~Context();
+        sk_free(heapAllocated);
         return nullptr;
     }
 
-    return alloc->make<LightingShaderContext>(*this, rec, diffuseContext, normalProvider, nullptr);
+    return new (storage) LightingShaderContext(*this, rec, diffuseContext, normalProvider,
+                                               heapAllocated);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index 9d9e109..7a0a369 100644 (file)
@@ -37,9 +37,8 @@ void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const {
     buffer.writeFlattenable(fProxyShader.get());
 }
 
-SkShader::Context* SkLocalMatrixShader::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const
-{
+SkShader::Context* SkLocalMatrixShader::onCreateContext(const ContextRec& rec,
+                                                        void* storage) const {
     ContextRec newRec(rec);
     SkMatrix tmp;
     if (rec.fLocalMatrix) {
@@ -48,7 +47,7 @@ SkShader::Context* SkLocalMatrixShader::onMakeContext(
     } else {
         newRec.fLocalMatrix = &this->getLocalMatrix();
     }
-    return fProxyShader->makeContext(newRec, alloc);
+    return fProxyShader->createContext(newRec, storage);
 }
 
 bool SkLocalMatrixShader::onAppendStages(SkRasterPipeline* p,
index 5c04240..0641abe 100644 (file)
@@ -13,7 +13,6 @@
 #include "SkWriteBuffer.h"
 
 class GrFragmentProcessor;
-class SkArenaAlloc;
 
 class SkLocalMatrixShader : public SkShader {
 public:
@@ -42,8 +41,11 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
+    Context* onCreateContext(const ContextRec&, void*) const override;
 
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec& rec) const override {
+        return fProxyShader->contextSize(rec);
+    }
 
     SkImage* onIsAImage(SkMatrix* matrix, TileMode* mode) const override {
         return fProxyShader->isAImage(matrix, mode);
index 5ff7d82..5d49253 100644 (file)
@@ -7,7 +7,6 @@
 
 #include "SkNormalBevelSource.h"
 
-#include "SkArenaAlloc.h"
 #include "SkNormalSource.h"
 #include "SkNormalSourcePriv.h"
 #include "SkPoint3.h"
@@ -264,8 +263,12 @@ SkNormalBevelSourceImpl::Provider::Provider() {}
 SkNormalBevelSourceImpl::Provider::~Provider() {}
 
 SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShader::ContextRec &rec,
-                                                              SkArenaAlloc* alloc) const {
-    return alloc->make<Provider>();
+                                                              void *storage) const {
+    return new (storage) Provider();
+}
+
+size_t SkNormalBevelSourceImpl::providerSize(const SkShader::ContextRec&) const {
+    return sizeof(Provider);
 }
 
 // TODO Implement feature for the CPU pipeline
index 1d1983c..d133738 100644 (file)
@@ -22,7 +22,8 @@ public:
 #endif
 
     SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
-                                         SkArenaAlloc*) const override;
+                                         void* storage) const override;
+    size_t providerSize(const SkShader::ContextRec& rec) const override;
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalBevelSourceImpl)
 
index 73ef549..b4ed977 100644 (file)
@@ -7,7 +7,6 @@
 
 #include "SkNormalFlatSource.h"
 
-#include "SkArenaAlloc.h"
 #include "SkNormalSource.h"
 #include "SkNormalSourcePriv.h"
 #include "SkPoint3.h"
@@ -78,8 +77,12 @@ SkNormalFlatSourceImpl::Provider::Provider() {}
 SkNormalFlatSourceImpl::Provider::~Provider() {}
 
 SkNormalSource::Provider* SkNormalFlatSourceImpl::asProvider(const SkShader::ContextRec &rec,
-                                                             SkArenaAlloc *alloc) const {
-    return alloc->make<Provider>();
+                                                             void *storage) const {
+    return new (storage) Provider();
+}
+
+size_t SkNormalFlatSourceImpl::providerSize(const SkShader::ContextRec&) const {
+    return sizeof(Provider);
 }
 
 void SkNormalFlatSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output[],
index 4a8f743..e129559 100644 (file)
@@ -19,7 +19,8 @@ public:
 #endif
 
     SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
-                                         SkArenaAlloc* alloc) const override;
+                                         void* storage) const override;
+    size_t providerSize(const SkShader::ContextRec& rec) const override;
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalFlatSourceImpl)
 
index 2d3d241..3a9f9cf 100644 (file)
@@ -7,7 +7,6 @@
 
 #include "SkNormalMapSource.h"
 
-#include "SkArenaAlloc.h"
 #include "SkLightingShader.h"
 #include "SkMatrix.h"
 #include "SkNormalSource.h"
@@ -137,29 +136,42 @@ sk_sp<GrFragmentProcessor> SkNormalMapSourceImpl::asFragmentProcessor(
 ////////////////////////////////////////////////////////////////////////////
 
 SkNormalMapSourceImpl::Provider::Provider(const SkNormalMapSourceImpl& source,
-                                          SkShader::Context* mapContext)
+                                          SkShader::Context* mapContext,
+                                          SkPaint* overridePaint)
     : fSource(source)
-    , fMapContext(mapContext) {}
+    , fMapContext(mapContext)
+    , fOverridePaint(overridePaint) {}
+
+SkNormalMapSourceImpl::Provider::~Provider() {
+    fMapContext->~Context();
+    fOverridePaint->~SkPaint();
+}
 
 SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShader::ContextRec &rec,
-                                                            SkArenaAlloc* alloc) const {
+                                                            void *storage) const {
     SkMatrix normTotalInv;
     if (!this->computeNormTotalInverse(rec, &normTotalInv)) {
         return nullptr;
     }
 
     // Overriding paint's alpha because we need the normal map's RGB channels to be unpremul'd
-    SkPaint overridePaint {*(rec.fPaint)};
-    overridePaint.setAlpha(0xFF);
-    SkShader::ContextRec overrideRec(overridePaint, *(rec.fMatrix), rec.fLocalMatrix,
+    void* paintStorage = (char*)storage + sizeof(Provider);
+    SkPaint* overridePaint = new (paintStorage) SkPaint(*(rec.fPaint));
+    overridePaint->setAlpha(0xFF);
+    SkShader::ContextRec overrideRec(*overridePaint, *(rec.fMatrix), rec.fLocalMatrix,
                                      rec.fPreferredDstType, rec.fDstColorSpace);
 
-    SkShader::Context* context = fMapShader->makeContext(overrideRec, alloc);
+    void* mapContextStorage = (char*) paintStorage + sizeof(SkPaint);
+    SkShader::Context* context = fMapShader->createContext(overrideRec, mapContextStorage);
     if (!context) {
         return nullptr;
     }
 
-    return alloc->make<Provider>(*this, context);
+    return new (storage) Provider(*this, context, overridePaint);
+}
+
+size_t SkNormalMapSourceImpl::providerSize(const SkShader::ContextRec& rec) const {
+    return sizeof(Provider) + sizeof(SkPaint) + fMapShader->contextSize(rec);
 }
 
 bool SkNormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& rec,
index f2b07f2..5908369 100644 (file)
@@ -21,7 +21,8 @@ public:
 #endif
 
     SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
-                                         SkArenaAlloc* alloc) const override;
+                                         void* storage) const override;
+    size_t providerSize(const SkShader::ContextRec& rec) const override;
 
     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalMapSourceImpl)
 
@@ -33,7 +34,10 @@ protected:
 private:
     class Provider : public SkNormalSource::Provider {
     public:
-        Provider(const SkNormalMapSourceImpl& source, SkShader::Context* mapContext);
+        Provider(const SkNormalMapSourceImpl& source, SkShader::Context* mapContext,
+                 SkPaint* overridePaint);
+
+        virtual ~Provider() override;
 
         void fillScanLine(int x, int y, SkPoint3 output[], int count) const override;
 
@@ -41,6 +45,8 @@ private:
         const SkNormalMapSourceImpl& fSource;
         SkShader::Context* fMapContext;
 
+        SkPaint* fOverridePaint;
+
         typedef SkNormalSource::Provider INHERITED;
     };
 
index 221c09d..32ef08c 100644 (file)
@@ -44,7 +44,11 @@ public:
     /** Returns an instance of 'Provider' that provides normals for the CPU pipeline. The
         necessary data will be initialized in place at 'storage'.
     */
-    virtual Provider* asProvider(const SkShader::ContextRec&, SkArenaAlloc*) const = 0;
+    virtual Provider* asProvider(const SkShader::ContextRec&, void* storage) const = 0;
+
+    /** Amount of memory needed to store a provider object and its dependencies.
+     */
+    virtual size_t providerSize(const SkShader::ContextRec&) const = 0;
 
     /** Returns a normal source that provides normals sourced from the the normal map argument.
 
index 7102682..bdb6d06 100644 (file)
@@ -243,6 +243,19 @@ sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix, con
     return tileShader;
 }
 
+size_t SkPictureShader::onContextSize(const ContextRec&) const {
+    return sizeof(PictureShaderContext);
+}
+
+SkShader::Context* SkPictureShader::onCreateContext(const ContextRec& rec, void* storage) const {
+    sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix,
+                                                       rec.fDstColorSpace));
+    if (!bitmapShader) {
+        return nullptr;
+    }
+    return PictureShaderContext::Create(storage, *this, rec, bitmapShader);
+}
+
 bool SkPictureShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkArenaAlloc* alloc,
                                      const SkMatrix& ctm, const SkPaint& paint,
                                      const SkMatrix* localMatrix) const {
@@ -253,34 +266,36 @@ bool SkPictureShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkAr
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////
-SkShader::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc)
-const {
-    sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix,
-                                                       rec.fDstColorSpace));
-    if (!bitmapShader) {
-        return nullptr;
-    }
 
-    PictureShaderContext* ctx =
-        alloc->make<PictureShaderContext>(*this, rec, std::move(bitmapShader), alloc);
+SkShader::Context* SkPictureShader::PictureShaderContext::Create(void* storage,
+                   const SkPictureShader& shader, const ContextRec& rec,
+                                                                 sk_sp<SkShader> bitmapShader) {
+    PictureShaderContext* ctx = new (storage) PictureShaderContext(shader, rec,
+                                                                   std::move(bitmapShader));
     if (nullptr == ctx->fBitmapShaderContext) {
+        ctx->~PictureShaderContext();
         ctx = nullptr;
     }
     return ctx;
 }
 
-/////////////////////////////////////////////////////////////////////////////////////////
-
 SkPictureShader::PictureShaderContext::PictureShaderContext(
-        const SkPictureShader& shader, const ContextRec& rec, sk_sp<SkShader> bitmapShader,
-        SkArenaAlloc* alloc)
+        const SkPictureShader& shader, const ContextRec& rec, sk_sp<SkShader> bitmapShader)
     : INHERITED(shader, rec)
     , fBitmapShader(std::move(bitmapShader))
 {
-    fBitmapShaderContext = fBitmapShader->makeContext(rec, alloc);
+    fBitmapShaderContextStorage = sk_malloc_throw(fBitmapShader->contextSize(rec));
+    fBitmapShaderContext = fBitmapShader->createContext(rec, fBitmapShaderContextStorage);
     //if fBitmapShaderContext is null, we are invalid
 }
 
+SkPictureShader::PictureShaderContext::~PictureShaderContext() {
+    if (fBitmapShaderContext) {
+        fBitmapShaderContext->~Context();
+    }
+    sk_free(fBitmapShaderContextStorage);
+}
+
 uint32_t SkPictureShader::PictureShaderContext::getFlags() const {
     SkASSERT(fBitmapShaderContext);
     return fBitmapShaderContext->getFlags();
index 9807cd9..ff83fa3 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "SkShader.h"
 
-class SkArenaAlloc;
 class SkBitmap;
 class SkPicture;
 
@@ -35,9 +34,10 @@ public:
 protected:
     SkPictureShader(SkReadBuffer&);
     void flatten(SkWriteBuffer&) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
     bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
                         const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
 
 private:
     SkPictureShader(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*, const SkRect*);
@@ -52,14 +52,20 @@ private:
 
     class PictureShaderContext : public SkShader::Context {
     public:
-        PictureShaderContext(
-            const SkPictureShader&, const ContextRec&, sk_sp<SkShader> bitmapShader, SkArenaAlloc*);
+        static Context* Create(void* storage, const SkPictureShader&, const ContextRec&,
+                               sk_sp<SkShader> bitmapShader);
+
+        virtual ~PictureShaderContext();
 
         uint32_t getFlags() const override;
 
         ShadeProc asAShadeProc(void** ctx) override;
         void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
 
+    private:
+        PictureShaderContext(const SkPictureShader&, const ContextRec&,
+                             sk_sp<SkShader> bitmapShader);
+
         sk_sp<SkShader>     fBitmapShader;
         SkShader::Context*  fBitmapShaderContext;
         void*               fBitmapShaderContextStorage;
index 1a00009..bb89f76 100644 (file)
@@ -21,7 +21,7 @@
 class SkRasterPipelineBlitter : public SkBlitter {
 public:
     static SkBlitter* Create(const SkPixmap&, const SkPaint&, const SkMatrix& ctm,
-                             SkArenaAlloc*);
+                             SkTBlitterAllocator*);
 
     SkRasterPipelineBlitter(SkPixmap dst, SkBlendMode blend, SkPM4f paintColor)
         : fDst(dst)
@@ -71,7 +71,7 @@ private:
 SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst,
                                          const SkPaint& paint,
                                          const SkMatrix& ctm,
-                                         SkArenaAlloc* alloc) {
+                                         SkTBlitterAllocator* alloc) {
     return SkRasterPipelineBlitter::Create(dst, paint, ctm, alloc);
 }
 
@@ -88,12 +88,16 @@ static bool supported(const SkImageInfo& info) {
 SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
                                            const SkPaint& paint,
                                            const SkMatrix& ctm,
-                                           SkArenaAlloc* alloc) {
-    auto blitter = alloc->make<SkRasterPipelineBlitter>(
+                                           SkTBlitterAllocator* alloc) {
+    auto blitter = alloc->createT<SkRasterPipelineBlitter>(
             dst,
             paint.getBlendMode(),
             SkPM4f_from_SkColor(paint.getColor(), dst.colorSpace()));
 
+    auto earlyOut = [&] {
+        alloc->deleteLast();
+        return nullptr;
+    };
 
     SkBlendMode*      blend       = &blitter->fBlend;
     SkPM4f*           paintColor  = &blitter->fPaintColor;
@@ -104,7 +108,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
 
     // TODO: all temporary
     if (!supported(dst.info()) || !SkBlendMode_AppendStages(*blend)) {
-        return nullptr;
+        return earlyOut();
     }
 
     bool is_opaque   = paintColor->a() == 1.0f,
@@ -113,7 +117,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
         pipeline->append(SkRasterPipeline::seed_shader, &blitter->fCurrentY);
         if (!shader->appendStages(pipeline, dst.colorSpace(), &blitter->fArena,
                                   ctm, paint)) {
-            return nullptr;
+            return earlyOut();
         }
         if (!is_opaque) {
             pipeline->append(SkRasterPipeline::scale_1_float,
@@ -129,7 +133,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,
     if (colorFilter) {
         if (!colorFilter->appendStages(pipeline, dst.colorSpace(), &blitter->fArena,
                                        is_opaque)) {
-            return nullptr;
+            return earlyOut();
         }
         is_opaque = is_opaque && (colorFilter->getFlags() & SkColorFilter::kAlphaUnchanged_Flag);
     }
index 9da760f..9f97a7a 100644 (file)
@@ -90,11 +90,23 @@ bool SkShader::asLuminanceColor(SkColor* colorPtr) const {
     return false;
 }
 
-SkShader::Context* SkShader::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
+SkShader::Context* SkShader::createContext(const ContextRec& rec, void* storage) const {
     if (!this->computeTotalInverse(rec, nullptr)) {
         return nullptr;
     }
-    return this->onMakeContext(rec, alloc);
+    return this->onCreateContext(rec, storage);
+}
+
+SkShader::Context* SkShader::onCreateContext(const ContextRec& rec, void*) const {
+    return nullptr;
+}
+
+size_t SkShader::contextSize(const ContextRec& rec) const {
+    return this->onContextSize(rec);
+}
+
+size_t SkShader::onContextSize(const ContextRec&) const {
+    return 0;
 }
 
 SkShader::Context::Context(const SkShader& shader, const ContextRec& rec)
@@ -274,7 +286,16 @@ bool SkShader::onAppendStages(SkRasterPipeline* p,
     }
 
     ContextRec rec(*opaquePaint, ctm, localM, ContextRec::kPM4f_DstType, cs);
-    if (auto* ctx = this->makeContext(rec, alloc)) {
+    if (auto* ctx = this->createContext(rec,
+                                        alloc->makeArrayDefault<char>(this->contextSize(rec)))) {
+        struct ContextDestroyer {
+            ContextDestroyer(Context* ctx) : fContext(ctx) {}
+            ~ContextDestroyer() { fContext->~Context(); }
+
+            Context* fContext;
+        };
+
+        alloc->make<ContextDestroyer>(ctx);
         p->append(SkRasterPipeline::shader_adapter, ctx);
 
         // Legacy shaders aren't aware of color spaces. We can pretty
index 7bbbb79..be05e54 100644 (file)
@@ -9,8 +9,6 @@
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
 
-class SkArenaAlloc;
-
  /** \class SkGaussianEdgeShaderImpl
  This subclass of shader applies a Gaussian to shadow edge
 
@@ -36,9 +34,7 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* storage) const override {
-        return nullptr;
-    }
+
 private:
     friend class SkGaussianEdgeShader;
 
index 7582196..92f2946 100644 (file)
@@ -6,8 +6,6 @@
  */
 
 #include "SkPerlinNoiseShader.h"
-
-#include "SkArenaAlloc.h"
 #include "SkColorFilter.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
@@ -436,9 +434,13 @@ SkPMColor SkPerlinNoiseShader::PerlinNoiseShaderContext::shade(
     return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
 }
 
-SkShader::Context* SkPerlinNoiseShader::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const {
-    return alloc->make<PerlinNoiseShaderContext>(*this, rec);
+SkShader::Context* SkPerlinNoiseShader::onCreateContext(const ContextRec& rec,
+                                                        void* storage) const {
+    return new (storage) PerlinNoiseShaderContext(*this, rec);
+}
+
+size_t SkPerlinNoiseShader::onContextSize(const ContextRec&) const {
+    return sizeof(PerlinNoiseShaderContext);
 }
 
 SkPerlinNoiseShader::PerlinNoiseShaderContext::PerlinNoiseShaderContext(
index a9eef7d..75b6595 100644 (file)
@@ -11,7 +11,6 @@
 #include "SkGradientBitmapCache.h"
 #include "SkGradientShader.h"
 
-#include "SkArenaAlloc.h"
 #include "SkAutoMalloc.h"
 #include "SkClampRange.h"
 #include "SkColorPriv.h"
@@ -238,9 +237,10 @@ protected:
                                    int count);
 
     template <typename T, typename... Args>
-    static Context* CheckedMakeContext(SkArenaAlloc* alloc, Args&&... args) {
-        auto* ctx = alloc->make<T>(std::forward<Args>(args)...);
+    static Context* CheckedCreateContext(void* storage, Args&&... args) {
+        auto* ctx = new (storage) T(std::forward<Args>(args)...);
         if (!ctx->isValid()) {
+            ctx->~T();
             return nullptr;
         }
         return ctx;
index 73247cb..5a74bfd 100644 (file)
@@ -74,12 +74,16 @@ void SkLinearGradient::flatten(SkWriteBuffer& buffer) const {
     buffer.writePoint(fEnd);
 }
 
-SkShader::Context* SkLinearGradient::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const
-{
+size_t SkLinearGradient::onContextSize(const ContextRec& rec) const {
+    return use_4f_context(rec, fGradFlags)
+        ? sizeof(LinearGradient4fContext)
+        : sizeof(LinearGradientContext);
+}
+
+SkShader::Context* SkLinearGradient::onCreateContext(const ContextRec& rec, void* storage) const {
     return use_4f_context(rec, fGradFlags)
-           ? CheckedMakeContext<LinearGradient4fContext>(alloc, *this, rec)
-           : CheckedMakeContext<  LinearGradientContext>(alloc, *this, rec);
+        ? CheckedCreateContext<LinearGradient4fContext>(storage, *this, rec)
+        : CheckedCreateContext<  LinearGradientContext>(storage, *this, rec);
 }
 
 // For now, only a 2-stop raster pipeline specialization.
index 4118dee..f13599d 100644 (file)
@@ -66,7 +66,8 @@ public:
 protected:
     SkLinearGradient(SkReadBuffer& buffer);
     void flatten(SkWriteBuffer& buffer) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 
     bool onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*,
                         const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
index 7e56863..a7dca76 100644 (file)
@@ -39,10 +39,12 @@ SkRadialGradient::SkRadialGradient(const SkPoint& center, SkScalar radius, const
     , fRadius(radius) {
 }
 
-SkShader::Context* SkRadialGradient::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const
-{
-    return CheckedMakeContext<RadialGradientContext>(alloc, *this, rec);
+size_t SkRadialGradient::onContextSize(const ContextRec&) const {
+    return sizeof(RadialGradientContext);
+}
+
+SkShader::Context* SkRadialGradient::onCreateContext(const ContextRec& rec, void* storage) const {
+    return CheckedCreateContext<RadialGradientContext>(storage, *this, rec);
 }
 
 SkRadialGradient::RadialGradientContext::RadialGradientContext(
index f92fbb3..0b23903 100644 (file)
@@ -35,7 +35,8 @@ public:
 protected:
     SkRadialGradient(SkReadBuffer& buffer);
     void flatten(SkWriteBuffer& buffer) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 
 private:
     const SkPoint fCenter;
index 928de4c..27d5dbe 100644 (file)
@@ -45,10 +45,12 @@ void SkSweepGradient::flatten(SkWriteBuffer& buffer) const {
     buffer.writePoint(fCenter);
 }
 
-SkShader::Context* SkSweepGradient::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const
-{
-    return CheckedMakeContext<SweepGradientContext>(alloc, *this, rec);
+size_t SkSweepGradient::onContextSize(const ContextRec&) const {
+    return sizeof(SweepGradientContext);
+}
+
+SkShader::Context* SkSweepGradient::onCreateContext(const ContextRec& rec, void* storage) const {
+    return CheckedCreateContext<SweepGradientContext>(storage, *this, rec);
 }
 
 SkSweepGradient::SweepGradientContext::SweepGradientContext(
index 30ebb1a..f132118 100644 (file)
@@ -35,7 +35,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer& buffer) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 
 private:
     const SkPoint fCenter;
index a9740aa..599fd4c 100644 (file)
@@ -210,9 +210,13 @@ bool SkTwoPointConicalGradient::isOpaque() const {
     return false;
 }
 
-SkShader::Context* SkTwoPointConicalGradient::onMakeContext(
-    const ContextRec& rec, SkArenaAlloc* alloc) const {
-    return CheckedMakeContext<TwoPointConicalGradientContext>(alloc, *this, rec);
+size_t SkTwoPointConicalGradient::onContextSize(const ContextRec&) const {
+    return sizeof(TwoPointConicalGradientContext);
+}
+
+SkShader::Context* SkTwoPointConicalGradient::onCreateContext(const ContextRec& rec,
+                                                              void* storage) const {
+    return CheckedCreateContext<TwoPointConicalGradientContext>(storage, *this, rec);
 }
 
 SkTwoPointConicalGradient::TwoPointConicalGradientContext::TwoPointConicalGradientContext(
index e509f92..d16e4bc 100644 (file)
@@ -75,7 +75,8 @@ public:
 protected:
     SkTwoPointConicalGradient(SkReadBuffer& buffer);
     void flatten(SkWriteBuffer& buffer) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 
 private:
     SkPoint fCenter1;
index 64a09dd..90ae830 100644 (file)
@@ -48,10 +48,14 @@ bool SkImageShader::isOpaque() const {
     return fImage->isOpaque();
 }
 
-SkShader::Context* SkImageShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
+size_t SkImageShader::onContextSize(const ContextRec& rec) const {
+    return SkBitmapProcLegacyShader::ContextSize(rec, as_IB(fImage)->onImageInfo());
+}
+
+SkShader::Context* SkImageShader::onCreateContext(const ContextRec& rec, void* storage) const {
     return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY,
                                                  SkBitmapProvider(fImage.get(), rec.fDstColorSpace),
-                                                 rec, alloc);
+                                                 rec, storage);
 }
 
 SkImage* SkImageShader::onIsAImage(SkMatrix* texM, TileMode xy[]) const {
index ef5e87c..d065a1e 100644 (file)
@@ -30,7 +30,8 @@ public:
 
 protected:
     void flatten(SkWriteBuffer&) const override;
-    Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
+    size_t onContextSize(const ContextRec&) const override;
+    Context* onCreateContext(const ContextRec&, void* storage) const override;
 #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
     bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode*) const override;
 #endif