diff options
Diffstat (limited to 'src/core/SkBlitter.cpp')
-rw-r--r-- | src/core/SkBlitter.cpp | 70 |
1 files changed, 43 insertions, 27 deletions
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; } |