aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-02-07 17:28:15 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-07 17:28:21 +0000
commitdd8b72ae7319598cfc1024901e860c52f06e6ae1 (patch)
treeb6e94e11c082c691512f8989ae55794fa2e6b756 /src/core
parent1f2fff2544a9dc6a0f169a017d374eca9f04c6b5 (diff)
Revert "Use SkArenaAlloc instead of SkSmallAllocator in the SkAutoBlitterChoose code."
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>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapDevice.cpp1
-rw-r--r--src/core/SkBitmapProcShader.cpp26
-rw-r--r--src/core/SkBitmapProcShader.h2
-rw-r--r--src/core/SkBlitter.cpp70
-rw-r--r--src/core/SkBlitter.h2
-rw-r--r--src/core/SkBlitter_PM4f.cpp18
-rw-r--r--src/core/SkBlitter_RGB16.cpp17
-rw-r--r--src/core/SkColorFilterShader.cpp17
-rw-r--r--src/core/SkColorFilterShader.h6
-rw-r--r--src/core/SkColorShader.cpp8
-rw-r--r--src/core/SkColorShader.h8
-rw-r--r--src/core/SkComposeShader.cpp25
-rw-r--r--src/core/SkComposeShader.h5
-rw-r--r--src/core/SkCoreBlitters.h8
-rw-r--r--src/core/SkDraw.cpp20
-rw-r--r--src/core/SkEmptyShader.h8
-rw-r--r--src/core/SkLightingShader.cpp50
-rw-r--r--src/core/SkLocalMatrixShader.cpp7
-rw-r--r--src/core/SkLocalMatrixShader.h6
-rw-r--r--src/core/SkNormalBevelSource.cpp9
-rw-r--r--src/core/SkNormalBevelSource.h3
-rw-r--r--src/core/SkNormalFlatSource.cpp9
-rw-r--r--src/core/SkNormalFlatSource.h3
-rw-r--r--src/core/SkNormalMapSource.cpp30
-rw-r--r--src/core/SkNormalMapSource.h10
-rw-r--r--src/core/SkNormalSource.h6
-rw-r--r--src/core/SkPictureShader.cpp43
-rw-r--r--src/core/SkPictureShader.h14
-rw-r--r--src/core/SkRasterPipelineBlitter.cpp18
-rw-r--r--src/core/SkShader.cpp27
30 files changed, 314 insertions, 162 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index fe43ba24b6..a409517090 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -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).
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp
index 8c648b6051..11deac4aed 100644
--- a/src/core/SkBitmapProcShader.cpp
+++ b/src/core/SkBitmapProcShader.cpp
@@ -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);
}
}
diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h
index 204b27dd4c..4b7447e52e 100644
--- a/src/core/SkBitmapProcShader.h
+++ b/src/core/SkBitmapProcShader.h
@@ -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;
};
diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp
index a386904dcd..d8e3dfd664 100644
--- a/src/core/SkBlitter.cpp
+++ b/src/core/SkBlitter.cpp
@@ -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;
}
diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h
index 4d34ce3e91..cab2afc974 100644
--- a/src/core/SkBlitter.h
+++ b/src/core/SkBlitter.h
@@ -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,
diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp
index 61105ce2db..ce66580659 100644
--- a/src/core/SkBlitter_PM4f.cpp
+++ b/src/core/SkBlitter_PM4f.cpp
@@ -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);
}
diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp
index e91e23fd69..afa8cac184 100644
--- a/src/core/SkBlitter_RGB16.cpp
+++ b/src/core/SkBlitter_RGB16.cpp
@@ -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);
}
}
diff --git a/src/core/SkColorFilterShader.cpp b/src/core/SkColorFilterShader.cpp
index 5e96b24b41..4090a18b45 100644
--- a/src/core/SkColorFilterShader.cpp
+++ b/src/core/SkColorFilterShader.cpp
@@ -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);
diff --git a/src/core/SkColorFilterShader.h b/src/core/SkColorFilterShader.h
index e697736ae8..035acd8397 100644
--- a/src/core/SkColorFilterShader.h
+++ b/src/core/SkColorFilterShader.h
@@ -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;
diff --git a/src/core/SkColorShader.cpp b/src/core/SkColorShader.cpp
index 32d9b430c7..ed2a26b931 100644
--- a/src/core/SkColorShader.cpp
+++ b/src/core/SkColorShader.cpp
@@ -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,
diff --git a/src/core/SkColorShader.h b/src/core/SkColorShader.h
index b9db657b2b..813fd3e892 100644
--- a/src/core/SkColorShader.h
+++ b/src/core/SkColorShader.h
@@ -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;
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp
index 07bbd9a092..5cbd23eb08 100644
--- a/src/core/SkComposeShader.cpp
+++ b/src/core/SkComposeShader.cpp
@@ -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();
diff --git a/src/core/SkComposeShader.h b/src/core/SkComposeShader.h
index be788af2af..7f9ff69ca8 100644
--- a/src/core/SkComposeShader.h
+++ b/src/core/SkComposeShader.h
@@ -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;
diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h
index 63ddda9b13..62bf73e6a2 100644
--- a/src/core/SkCoreBlitters.h
+++ b/src/core/SkCoreBlitters.h
@@ -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
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 2891c95fdd..dd39d9eb97 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -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();
diff --git a/src/core/SkEmptyShader.h b/src/core/SkEmptyShader.h
index b2c9b76792..528ceeabee 100644
--- a/src/core/SkEmptyShader.h
+++ b/src/core/SkEmptyShader.h
@@ -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;
}
diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp
index 5bdaee5594..4ed0057682 100644
--- a/src/core/SkLightingShader.cpp
+++ b/src/core/SkLightingShader.cpp
@@ -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);
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkLocalMatrixShader.cpp b/src/core/SkLocalMatrixShader.cpp
index 9d9e109fcb..7a0a3697bd 100644
--- a/src/core/SkLocalMatrixShader.cpp
+++ b/src/core/SkLocalMatrixShader.cpp
@@ -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,
diff --git a/src/core/SkLocalMatrixShader.h b/src/core/SkLocalMatrixShader.h
index 5c0424053b..0641abe461 100644
--- a/src/core/SkLocalMatrixShader.h
+++ b/src/core/SkLocalMatrixShader.h
@@ -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);
diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp
index 5ff7d8231f..5d49253b01 100644
--- a/src/core/SkNormalBevelSource.cpp
+++ b/src/core/SkNormalBevelSource.cpp
@@ -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
diff --git a/src/core/SkNormalBevelSource.h b/src/core/SkNormalBevelSource.h
index 1d1983c66a..d133738bce 100644
--- a/src/core/SkNormalBevelSource.h
+++ b/src/core/SkNormalBevelSource.h
@@ -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)
diff --git a/src/core/SkNormalFlatSource.cpp b/src/core/SkNormalFlatSource.cpp
index 73ef549747..b4ed977285 100644
--- a/src/core/SkNormalFlatSource.cpp
+++ b/src/core/SkNormalFlatSource.cpp
@@ -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[],
diff --git a/src/core/SkNormalFlatSource.h b/src/core/SkNormalFlatSource.h
index 4a8f74304b..e1295596b9 100644
--- a/src/core/SkNormalFlatSource.h
+++ b/src/core/SkNormalFlatSource.h
@@ -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)
diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp
index 2d3d24181d..3a9f9cf76f 100644
--- a/src/core/SkNormalMapSource.cpp
+++ b/src/core/SkNormalMapSource.cpp
@@ -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,
diff --git a/src/core/SkNormalMapSource.h b/src/core/SkNormalMapSource.h
index f2b07f21e9..5908369fc7 100644
--- a/src/core/SkNormalMapSource.h
+++ b/src/core/SkNormalMapSource.h
@@ -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;
};
diff --git a/src/core/SkNormalSource.h b/src/core/SkNormalSource.h
index 221c09db99..32ef08ce52 100644
--- a/src/core/SkNormalSource.h
+++ b/src/core/SkNormalSource.h
@@ -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.
diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp
index 71026824cd..bdb6d060a7 100644
--- a/src/core/SkPictureShader.cpp
+++ b/src/core/SkPictureShader.cpp
@@ -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();
diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h
index 9807cd9482..ff83fa3bb8 100644
--- a/src/core/SkPictureShader.h
+++ b/src/core/SkPictureShader.h
@@ -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;
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 1a00009734..bb89f76b8f 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -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);
}
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index 9da760f843..9f97a7a74a 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -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