diff options
Diffstat (limited to 'src/core')
37 files changed, 637 insertions, 290 deletions
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index b7bd39c197..e52982354d 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -17,21 +17,21 @@ static bool only_scale_and_translate(const SkMatrix& matrix) { return (matrix.getType() & ~mask) == 0; } -class BitmapProcInfoContext : public SkShader::Context { +class BitmapProcInfoContext : public SkShaderBase::Context { public: // The info has been allocated elsewhere, but we are responsible for calling its destructor. - BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec, + BitmapProcInfoContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec, SkBitmapProcInfo* info) : INHERITED(shader, rec) , fInfo(info) { fFlags = 0; if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) { - fFlags |= SkShader::kOpaqueAlpha_Flag; + fFlags |= SkShaderBase::kOpaqueAlpha_Flag; } if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) { - fFlags |= SkShader::kConstInY32_Flag; + fFlags |= SkShaderBase::kConstInY32_Flag; } } @@ -41,14 +41,14 @@ private: SkBitmapProcInfo* fInfo; uint32_t fFlags; - typedef SkShader::Context INHERITED; + typedef SkShaderBase::Context INHERITED; }; /////////////////////////////////////////////////////////////////////////////////////////////////// class BitmapProcShaderContext : public BitmapProcInfoContext { public: - BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec, + BitmapProcShaderContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec, SkBitmapProcState* state) : INHERITED(shader, rec, state) , fState(state) @@ -104,7 +104,7 @@ private: class LinearPipelineContext : public BitmapProcInfoContext { public: - LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& rec, + LinearPipelineContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec, SkBitmapProcInfo* info, SkArenaAlloc* alloc) : INHERITED(shader, rec, info), fAllocator{alloc} { @@ -183,12 +183,12 @@ private: /////////////////////////////////////////////////////////////////////////////////////////////////// -static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) { +static bool choose_linear_pipeline(const SkShaderBase::ContextRec& rec, const SkImageInfo& srcInfo) { // If we get here, we can reasonably use either context, respect the caller's preference // bool needsPremul = srcInfo.alphaType() == kUnpremul_SkAlphaType; bool needsSwizzle = srcInfo.bytesPerPixel() == 4 && srcInfo.colorType() != kN32_SkColorType; - return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType + return SkShaderBase::ContextRec::kPM4f_DstType == rec.fPreferredDstType || needsPremul || needsSwizzle; } @@ -199,8 +199,8 @@ size_t SkBitmapProcLegacyShader::ContextSize(const ContextRec& rec, const SkImag return s; } -SkShader::Context* SkBitmapProcLegacyShader::MakeContext( - const SkShader& shader, TileMode tmx, TileMode tmy, +SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext( + const SkShaderBase& shader, TileMode tmx, TileMode tmy, const SkBitmapProvider& provider, const ContextRec& rec, SkArenaAlloc* alloc) { SkMatrix totalInverse; diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index 204b27dd4c..2a2599cb1d 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -8,19 +8,19 @@ #define SkBitmapProcShader_DEFINED #include "SkImagePriv.h" -#include "SkShader.h" +#include "SkShaderBase.h" class SkBitmapProvider; -class SkBitmapProcLegacyShader : public SkShader { +class SkBitmapProcLegacyShader : public SkShaderBase { private: friend class SkImageShader; static size_t ContextSize(const ContextRec&, const SkImageInfo& srcInfo); - static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy, + static Context* MakeContext(const SkShaderBase&, TileMode tmx, TileMode tmy, const SkBitmapProvider&, const ContextRec&, SkArenaAlloc* alloc); - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif diff --git a/src/core/SkBlitter.cpp b/src/core/SkBlitter.cpp index 30f845ac06..ba79abd3f0 100644 --- a/src/core/SkBlitter.cpp +++ b/src/core/SkBlitter.cpp @@ -14,6 +14,7 @@ #include "SkWriteBuffer.h" #include "SkMask.h" #include "SkMaskFilter.h" +#include "SkShaderBase.h" #include "SkString.h" #include "SkTLazy.h" #include "SkUtils.h" @@ -582,14 +583,14 @@ SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, #include "SkColorShader.h" #include "SkColorPriv.h" -class Sk3DShader : public SkShader { +class Sk3DShader : public SkShaderBase { public: Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {} Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override { - SkShader::Context* proxyContext = nullptr; + SkShaderBase::Context* proxyContext = nullptr; if (fProxy) { - proxyContext = fProxy->makeContext(rec, alloc); + proxyContext = as_SB(fProxy)->makeContext(rec, alloc); if (!proxyContext) { return nullptr; } @@ -597,11 +598,11 @@ public: return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext); } - class Sk3DShaderContext : public SkShader::Context { + class Sk3DShaderContext : public Context { public: // Calls proxyContext's destructor but will NOT free its memory. Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec, - SkShader::Context* proxyContext) + Context* proxyContext) : INHERITED(shader, rec) , fMask(nullptr) , fProxyContext(proxyContext) @@ -685,12 +686,12 @@ public: private: // Unowned. - const SkMask* fMask; + const SkMask* fMask; // Memory is unowned, but we need to call the destructor. - SkShader::Context* fProxyContext; - SkPMColor fPMColor; + Context* fProxyContext; + SkPMColor fPMColor; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; #ifndef SK_IGNORE_TO_STRING @@ -699,7 +700,7 @@ public: if (fProxy) { str->append("Proxy: "); - fProxy->toString(str); + as_SB(fProxy)->toString(str); } this->INHERITED::toString(str); @@ -718,7 +719,7 @@ protected: private: sk_sp<SkShader> fProxy; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) { @@ -727,7 +728,7 @@ sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) { class Sk3DBlitter : public SkBlitter { public: - Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext) + Sk3DBlitter(SkBlitter* proxy, SkShaderBase::Context* shaderContext) : fProxy(proxy) , fShaderContext(shaderContext) {} @@ -764,21 +765,21 @@ public: private: // Both pointers are unowned. They will be deleted by SkSmallAllocator. - SkBlitter* fProxy; - SkShader::Context* fShaderContext; + SkBlitter* fProxy; + SkShaderBase::Context* fShaderContext; }; /////////////////////////////////////////////////////////////////////////////// #include "SkCoreBlitters.h" -SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { +SkShaderBase::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) { #ifdef SK_FORCE_PM4f_FOR_L32_BLITS return SkShader::ContextRec::kPM4f_DstType; #else return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType) - ? SkShader::ContextRec::kPM4f_DstType - : SkShader::ContextRec::kPMColor_DstType; + ? SkShaderBase::ContextRec::kPM4f_DstType + : SkShaderBase::ContextRec::kPMColor_DstType; #endif } @@ -792,7 +793,7 @@ bool SkBlitter::UseRasterPipelineBlitter(const SkPixmap& device, const SkPaint& } // ... unless the shader is raster pipeline-only. - if (paint.getShader() && paint.getShader()->isRasterPipelineOnly()) { + if (paint.getShader() && as_SB(paint.getShader())->isRasterPipelineOnly()) { return true; } @@ -814,7 +815,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, return alloc->make<SkNullBlitter>(); } - SkShader* shader = origPaint.getShader(); + auto* shader = as_SB(origPaint.getShader()); SkColorFilter* cf = origPaint.getColorFilter(); SkBlendMode mode = origPaint.getBlendMode(); sk_sp<Sk3DShader> shader3D; @@ -826,7 +827,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader)); // we know we haven't initialized lazyPaint yet, so just do it paint.writable()->setShader(shader3D); - shader = shader3D.get(); + shader = as_SB(shader3D.get()); } if (mode != SkBlendMode::kSrcOver) { @@ -876,7 +877,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, // xfermodes (and filters) require shaders for our current blitters paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor())); paint.writable()->setAlpha(0xFF); - shader = paint->getShader(); + shader = as_SB(paint->getShader()); } else if (cf) { // if no shader && no xfermode, we just apply the colorfilter to // our color and move on. @@ -890,7 +891,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, if (cf) { SkASSERT(shader); paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf))); - shader = paint->getShader(); + shader = as_SB(paint->getShader()); // blitters should ignore the presence/absence of a filter, since // if there is one, the shader will take care of it. } @@ -898,9 +899,9 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, /* * We create a SkShader::Context object, and store it on the blitter. */ - SkShader::Context* shaderContext = nullptr; + SkShaderBase::Context* shaderContext = nullptr; if (shader) { - const SkShader::ContextRec rec(*paint, matrix, nullptr, + const SkShaderBase::ContextRec rec(*paint, matrix, nullptr, PreferredShaderDest(device.info()), device.colorSpace()); // Try to create the ShaderContext @@ -974,7 +975,7 @@ SkBlitter* SkBlitter::Choose(const SkPixmap& device, /////////////////////////////////////////////////////////////////////////////// SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext) + SkShaderBase::Context* shaderContext) : INHERITED(device) , fShader(paint.getShader()) , fShaderContext(shaderContext) { @@ -983,7 +984,7 @@ SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, fShader->ref(); fShaderFlags = fShaderContext->getFlags(); - fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag); + fConstInY = SkToBool(fShaderFlags & SkShaderBase::kConstInY32_Flag); } SkShaderBlitter::~SkShaderBlitter() { diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h index 27552b918f..6558045f4f 100644 --- a/src/core/SkBlitter.h +++ b/src/core/SkBlitter.h @@ -13,7 +13,7 @@ #include "SkColor.h" #include "SkRect.h" #include "SkRegion.h" -#include "SkShader.h" +#include "SkShaderBase.h" class SkArenaAlloc; class SkMatrix; @@ -148,7 +148,7 @@ public: SkArenaAlloc*); ///@} - static SkShader::ContextRec::DstType PreferredShaderDest(const SkImageInfo&); + static SkShaderBase::ContextRec::DstType PreferredShaderDest(const SkImageInfo&); static bool UseRasterPipelineBlitter(const SkPixmap&, const SkPaint&); diff --git a/src/core/SkBlitter_A8.cpp b/src/core/SkBlitter_A8.cpp index 1fd4d5f0d9..6f0df2ef26 100644 --- a/src/core/SkBlitter_A8.cpp +++ b/src/core/SkBlitter_A8.cpp @@ -227,7 +227,7 @@ void SkA8_Blitter::blitRect(int x, int y, int width, int height) { /////////////////////////////////////////////////////////////////////// SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext) + SkShaderBase::Context* shaderContext) : INHERITED(device, paint, shaderContext) { fXfermode = SkXfermode::Peek(paint.getBlendMode()); @@ -247,9 +247,9 @@ void SkA8_Shader_Blitter::blitH(int x, int y, int width) { (unsigned)(x + width) <= (unsigned)fDevice.width()); uint8_t* device = fDevice.writable_addr8(x, y); - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; - if ((shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) { + if ((shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) && !fXfermode) { memset(device, 0xFF, width); } else { SkPMColor* span = fBuffer; @@ -280,12 +280,12 @@ static inline uint8_t aa_blend8(SkPMColor src, U8CPU da, int aa) { void SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) { - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; SkXfermode* mode = fXfermode; uint8_t* aaExpand = fAAExpand; SkPMColor* span = fBuffer; uint8_t* device = fDevice.writable_addr8(x, y); - int opaque = shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag; + int opaque = shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag; for (;;) { int count = *runs; @@ -327,7 +327,7 @@ void SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) { int height = clip.height(); uint8_t* device = fDevice.writable_addr8(x, y); const uint8_t* alpha = mask.getAddr8(x, y); - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; SkPMColor* span = fBuffer; diff --git a/src/core/SkBlitter_ARGB32.cpp b/src/core/SkBlitter_ARGB32.cpp index 4478b2bd64..aef1044a94 100644 --- a/src/core/SkBlitter_ARGB32.cpp +++ b/src/core/SkBlitter_ARGB32.cpp @@ -330,7 +330,7 @@ static void blend_srcmode(SkPMColor* SK_RESTRICT device, } SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, - const SkPaint& paint, SkShader::Context* shaderContext) + const SkPaint& paint, SkShaderBase::Context* shaderContext) : INHERITED(device, paint, shaderContext) { fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor))); @@ -338,7 +338,7 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, fXfermode = SkXfermode::Peek(paint.getBlendMode()); int flags = 0; - if (!(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) { + if (!(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { flags |= SkBlitRow::kSrcPixelAlpha_Flag32; } // we call this on the output from the shader @@ -348,7 +348,7 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, fShadeDirectlyIntoDevice = false; if (fXfermode == nullptr) { - if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) { + if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) { fShadeDirectlyIntoDevice = true; } } else { @@ -361,7 +361,7 @@ SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device, } } - fConstInY = SkToBool(shaderContext->getFlags() & SkShader::kConstInY32_Flag); + fConstInY = SkToBool(shaderContext->getFlags() & SkShaderBase::kConstInY32_Flag); } SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() { @@ -390,10 +390,10 @@ void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height()); - uint32_t* device = fDevice.writable_addr32(x, y); - size_t deviceRB = fDevice.rowBytes(); - SkShader::Context* shaderContext = fShaderContext; - SkPMColor* span = fBuffer; + uint32_t* device = fDevice.writable_addr32(x, y); + size_t deviceRB = fDevice.rowBytes(); + auto* shaderContext = fShaderContext; + SkPMColor* span = fBuffer; if (fConstInY) { if (fShadeDirectlyIntoDevice) { @@ -427,7 +427,7 @@ void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { if (fShadeDirectlyIntoDevice) { void* ctx; - SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx); + auto shadeProc = shaderContext->asAShadeProc(&ctx); if (shadeProc) { do { shadeProc(ctx, x, y, device, width); @@ -464,9 +464,9 @@ void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) { - SkPMColor* span = fBuffer; - uint32_t* device = fDevice.writable_addr32(x, y); - SkShader::Context* shaderContext = fShaderContext; + SkPMColor* span = fBuffer; + uint32_t* device = fDevice.writable_addr32(x, y); + auto* shaderContext = fShaderContext; if (fXfermode && !fShadeDirectlyIntoDevice) { for (;;) { @@ -493,7 +493,7 @@ void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[], x += count; } } else if (fShadeDirectlyIntoDevice || - (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) { + (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) { for (;;) { int count = *runs; if (count <= 0) { @@ -546,11 +546,11 @@ void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) SkASSERT(mask.fBounds.contains(clip)); - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; SkBlitMask::RowProc proc = nullptr; if (!fXfermode) { unsigned flags = 0; - if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) { + if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) { flags |= SkBlitMask::kSrcIsOpaque_RowFlag; } proc = SkBlitMask::RowFactory(kN32_SkColorType, mask.fFormat, @@ -597,9 +597,9 @@ void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); - uint32_t* device = fDevice.writable_addr32(x, y); - size_t deviceRB = fDevice.rowBytes(); - SkShader::Context* shaderContext = fShaderContext; + uint32_t* device = fDevice.writable_addr32(x, y); + size_t deviceRB = fDevice.rowBytes(); + auto* shaderContext = fShaderContext; if (fConstInY) { SkPMColor c; @@ -637,7 +637,7 @@ void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) { if (fShadeDirectlyIntoDevice) { void* ctx; - SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx); + auto shadeProc = shaderContext->asAShadeProc(&ctx); if (255 == alpha) { if (shadeProc) { do { diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp index 61105ce2db..f83e0c214e 100644 --- a/src/core/SkBlitter_PM4f.cpp +++ b/src/core/SkBlitter_PM4f.cpp @@ -139,7 +139,7 @@ public: template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter { public: SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - const SkShader::Context::BlitState& bstate) + const SkShaderBase::Context::BlitState& bstate) : INHERITED(device, paint, bstate.fCtx) , fState(device.info(), paint, bstate.fCtx) , fBState(bstate) @@ -309,10 +309,10 @@ public: } protected: - State fState; - SkShader::Context::BlitState fBState; - SkShader::Context::BlitBW fBlitBW; - SkShader::Context::BlitAA fBlitAA; + State fState; + SkShaderBase::Context::BlitState fBState; + SkShaderBase::Context::BlitBW fBlitBW; + SkShaderBase::Context::BlitAA fBlitAA; typedef SkShaderBlitter INHERITED; }; @@ -320,13 +320,14 @@ protected: /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// -static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderContext) { - return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) +static bool is_opaque(const SkPaint& paint, const SkShaderBase::Context* shaderContext) { + return shaderContext ? SkToBool(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) : 0xFF == paint.getAlpha(); } struct State4f { - State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) { + State4f(const SkImageInfo& info, const SkPaint& paint, + const SkShaderBase::Context* shaderContext) { fMode = paint.getBlendMode(); if (shaderContext) { fBuffer.reset(info.width()); @@ -336,12 +337,11 @@ struct State4f { fFlags = 0; } - SkPM4f fPM4f; - SkAutoTMalloc<SkPM4f> fBuffer; - uint32_t fFlags; - SkBlendMode fMode; - - SkShader::Context::BlitState fBState; + SkPM4f fPM4f; + SkAutoTMalloc<SkPM4f> fBuffer; + uint32_t fFlags; + SkBlendMode fMode; + SkShaderBase::Context::BlitState fBState; }; struct State32 : State4f { @@ -350,7 +350,8 @@ struct State32 : State4f { SkXfermode::D32Proc fProc1; SkXfermode::D32Proc fProcN; - State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) + State32(const SkImageInfo& info, const SkPaint& paint, + const SkShaderBase::Context* shaderContext) : State4f(info, paint, shaderContext) { if (is_opaque(paint, shaderContext)) { @@ -382,7 +383,8 @@ struct StateF16 : State4f { SkXfermode::F16Proc fProc1; SkXfermode::F16Proc fProcN; - StateF16(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) + StateF16(const SkImageInfo& info, const SkPaint& paint, + const SkShaderBase::Context* shaderContext) : State4f(info, paint, shaderContext) { if (is_opaque(paint, shaderContext)) { @@ -404,12 +406,12 @@ struct StateF16 : State4f { }; template <typename State> SkBlitter* create(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, + SkShaderBase::Context* shaderContext, SkArenaAlloc* alloc) { SkASSERT(alloc != nullptr); if (shaderContext) { - SkShader::Context::BlitState bstate; + SkShaderBase::Context::BlitState bstate; sk_bzero(&bstate, sizeof(bstate)); bstate.fCtx = shaderContext; bstate.fMode = paint.getBlendMode(); @@ -426,13 +428,13 @@ template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain } SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, + SkShaderBase::Context* shaderContext, SkArenaAlloc* alloc) { return create<State32>(device, paint, shaderContext, alloc); } SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, + SkShaderBase::Context* shaderContext, SkArenaAlloc* alloc) { return create<StateF16>(device, paint, shaderContext, alloc); } diff --git a/src/core/SkBlitter_RGB16.cpp b/src/core/SkBlitter_RGB16.cpp index 6330a39357..2c7fbf76da 100644 --- a/src/core/SkBlitter_RGB16.cpp +++ b/src/core/SkBlitter_RGB16.cpp @@ -110,7 +110,7 @@ private: class SkRGB16_Shader_Blitter : public SkShaderBlitter { public: SkRGB16_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext); + SkShaderBase::Context* shaderContext); ~SkRGB16_Shader_Blitter() override; void blitH(int x, int y, int width) override; virtual void blitAntiH(int x, int y, const SkAlpha* antialias, @@ -132,7 +132,7 @@ private: class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter { public: SkRGB16_Shader_Xfermode_Blitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext); + SkShaderBase::Context* shaderContext); ~SkRGB16_Shader_Xfermode_Blitter() override; void blitH(int x, int y, int width) override; virtual void blitAntiH(int x, int y, const SkAlpha* antialias, @@ -671,7 +671,7 @@ void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) { SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext) + SkShaderBase::Context* shaderContext) : INHERITED(device, paint, shaderContext) { SkASSERT(paint.isSrcOver()); @@ -683,7 +683,7 @@ SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device, uint32_t shaderFlags = fShaderFlags; // shaders take care of global alpha, so we never set it in SkBlitRow - if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) { + if (!(shaderFlags & SkShaderBase::kOpaqueAlpha_Flag)) { flags |= SkBlitRow::kSrcPixelAlpha_Flag; } if (paint.isDither()) { @@ -708,13 +708,13 @@ void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) { } void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) { - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; SkBlitRow::Proc16 proc = fOpaqueProc; SkPMColor* buffer = fBuffer; uint16_t* dst = fDevice.writable_addr16(x, y); size_t dstRB = fDevice.rowBytes(); - if (fShaderFlags & SkShader::kConstInY32_Flag) { + if (fShaderFlags & SkShaderBase::kConstInY32_Flag) { shaderContext->shadeSpan(x, y, buffer, width); do { proc(dst, buffer, width, 0xFF, x, y); @@ -748,7 +748,7 @@ static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) { void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha* SK_RESTRICT antialias, const int16_t* SK_RESTRICT runs) { - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; SkPMColor* SK_RESTRICT span = fBuffer; uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y); @@ -797,7 +797,7 @@ void SkRGB16_Shader_Blitter::blitAntiH(int x, int y, SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter( const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext) + SkShaderBase::Context* shaderContext) : INHERITED(device, paint, shaderContext) { fXfermode = SkXfermode::Peek(paint.getBlendMode()); @@ -825,7 +825,7 @@ void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) { void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, const SkAlpha* SK_RESTRICT antialias, const int16_t* SK_RESTRICT runs) { - SkShader::Context* shaderContext = fShaderContext; + auto* shaderContext = fShaderContext; SkXfermode* mode = fXfermode; SkPMColor* SK_RESTRICT span = fBuffer; uint8_t* SK_RESTRICT aaExpand = fAAExpand; @@ -880,7 +880,7 @@ void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y, /////////////////////////////////////////////////////////////////////////////// SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, + SkShaderBase::Context* shaderContext, SkArenaAlloc* alloc) { SkASSERT(alloc != nullptr); diff --git a/src/core/SkColorFilterShader.cpp b/src/core/SkColorFilterShader.cpp index 6569e1379a..4798422dfa 100644 --- a/src/core/SkColorFilterShader.cpp +++ b/src/core/SkColorFilterShader.cpp @@ -49,14 +49,14 @@ uint32_t SkColorFilterShader::FilterShaderContext::getFlags() const { // in the shader flags. // if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) { - shaderF &= ~SkShader::kOpaqueAlpha_Flag; + shaderF &= ~kOpaqueAlpha_Flag; } return shaderF; } -SkShader::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec, - SkArenaAlloc* alloc) const { - SkShader::Context* shaderContext = fShader->makeContext(rec, alloc); +SkShaderBase::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec, + SkArenaAlloc* alloc) const { + auto* shaderContext = as_SB(fShader)->makeContext(rec, alloc); if (nullptr == shaderContext) { return nullptr; } @@ -69,7 +69,7 @@ sk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xform SkColorFilterShader::FilterShaderContext::FilterShaderContext( const SkColorFilterShader& filterShader, - SkShader::Context* shaderContext, + SkShaderBase::Context* shaderContext, const ContextRec& rec) : INHERITED(filterShader, rec) , fShaderContext(shaderContext) @@ -96,7 +96,7 @@ void SkColorFilterShader::FilterShaderContext::shadeSpan4f(int x, int y, SkPM4f sk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(const AsFPArgs& args) const { - sk_sp<GrFragmentProcessor> fp1(fShader->asFragmentProcessor(args)); + sk_sp<GrFragmentProcessor> fp1(as_SB(fShader)->asFragmentProcessor(args)); if (!fp1) { return nullptr; } @@ -117,7 +117,7 @@ void SkColorFilterShader::toString(SkString* str) const { str->append("SkColorFilterShader: ("); str->append("Shader: "); - fShader->toString(str); + as_SB(fShader)->toString(str); str->append(" Filter: "); // TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added diff --git a/src/core/SkColorFilterShader.h b/src/core/SkColorFilterShader.h index 18f65ba67f..7f4202158a 100644 --- a/src/core/SkColorFilterShader.h +++ b/src/core/SkColorFilterShader.h @@ -9,11 +9,11 @@ #define SkColorFilterShader_DEFINED #include "SkColorFilter.h" -#include "SkShader.h" +#include "SkShaderBase.h" class SkArenaAlloc; -class SkColorFilterShader : public SkShader { +class SkColorFilterShader : public SkShaderBase { public: SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter); @@ -21,10 +21,10 @@ public: sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; #endif - class FilterShaderContext : public SkShader::Context { + class FilterShaderContext : public Context { public: // Takes ownership of shaderContext and calls its destructor. - FilterShaderContext(const SkColorFilterShader&, SkShader::Context*, const ContextRec&); + FilterShaderContext(const SkColorFilterShader&, SkShaderBase::Context*, const ContextRec&); uint32_t getFlags() const override; @@ -37,9 +37,9 @@ public: } private: - SkShader::Context* fShaderContext; + SkShaderBase::Context* fShaderContext; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; SK_TO_STRING_OVERRIDE() @@ -54,7 +54,7 @@ private: sk_sp<SkShader> fShader; sk_sp<SkColorFilter> fFilter; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif diff --git a/src/core/SkColorShader.cpp b/src/core/SkColorShader.cpp index 94d1abc6f0..32b2c54d71 100644 --- a/src/core/SkColorShader.cpp +++ b/src/core/SkColorShader.cpp @@ -31,7 +31,8 @@ uint32_t SkColorShader::ColorShaderContext::getFlags() const { return fFlags; } -SkShader::Context* SkColorShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { +SkShaderBase::Context* SkColorShader::onMakeContext(const ContextRec& rec, + SkArenaAlloc* alloc) const { return alloc->make<ColorShaderContext>(*this, rec); } @@ -149,7 +150,8 @@ uint32_t SkColor4Shader::Color4Context::getFlags() const { return fFlags; } -SkShader::Context* SkColor4Shader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { +SkShaderBase::Context* SkColor4Shader::onMakeContext(const ContextRec& rec, + SkArenaAlloc* alloc) const { return alloc->make<Color4Context>(*this, rec); } @@ -250,28 +252,28 @@ sk_sp<SkShader> SkShader::MakeColorShader(const SkColor4f& color, sk_sp<SkColorS /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// -static void D32_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, +static void D32_BlitBW(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst, int count) { SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; proc(state->fMode, dst.writable_addr32(x, y), src, count, nullptr); } -static void D32_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, +static void D32_BlitAA(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst, int count, const SkAlpha aa[]) { SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; proc(state->fMode, dst.writable_addr32(x, y), src, count, aa); } -static void F16_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, +static void F16_BlitBW(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst, int count) { SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; proc(state->fMode, dst.writable_addr64(x, y), src, count, nullptr); } -static void F16_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, +static void F16_BlitAA(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst, int count, const SkAlpha aa[]) { SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; @@ -279,7 +281,7 @@ static void F16_BlitAA(SkShader::Context::BlitState* state, int x, int y, const } static bool choose_blitprocs(const SkPM4f* pm4, const SkImageInfo& info, - SkShader::Context::BlitState* state) { + SkShaderBase::Context::BlitState* state) { uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag; if (pm4->a() == 1) { flags |= SkXfermode::kSrcIsOpaque_D32Flag; diff --git a/src/core/SkColorShader.h b/src/core/SkColorShader.h index 0a6a935afd..9af83c1163 100644 --- a/src/core/SkColorShader.h +++ b/src/core/SkColorShader.h @@ -9,7 +9,7 @@ #define SkColorShader_DEFINED #include "SkColorSpaceXformer.h" -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkPM4f.h" /** \class SkColorShader @@ -17,7 +17,7 @@ accomplished by just using the color field on the paint, but if an actual shader object is needed, this provides that feature. */ -class SK_API SkColorShader : public SkShader { +class SK_API SkColorShader : public SkShaderBase { public: /** Create a ColorShader that ignores the color in the paint, and uses the specified color. Note: like all shaders, at draw time the paint's alpha @@ -28,7 +28,7 @@ public: bool isOpaque() const override; bool isConstant() const override { return true; } - class ColorShaderContext : public SkShader::Context { + class ColorShaderContext : public Context { public: ColorShaderContext(const SkColorShader& shader, const ContextRec&); @@ -45,7 +45,7 @@ public: SkPMColor fPMColor; uint32_t fFlags; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; GradientType asAGradient(GradientInfo* info) const override; @@ -77,10 +77,10 @@ protected: private: SkColor fColor; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; -class SkColor4Shader : public SkShader { +class SkColor4Shader : public SkShaderBase { public: SkColor4Shader(const SkColor4f&, sk_sp<SkColorSpace>); @@ -89,7 +89,7 @@ public: } bool isConstant() const override { return true; } - class Color4Context : public SkShader::Context { + class Color4Context : public Context { public: Color4Context(const SkColor4Shader& shader, const ContextRec&); @@ -106,7 +106,7 @@ public: SkPMColor fPMColor; uint32_t fFlags; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; GradientType asAGradient(GradientInfo* info) const override; @@ -136,7 +136,7 @@ private: const SkColor4f fColor4; const SkColor fCachedByteColor; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif diff --git a/src/core/SkColorSpaceXformer.cpp b/src/core/SkColorSpaceXformer.cpp index f5f22a18b1..74daf661eb 100644 --- a/src/core/SkColorSpaceXformer.cpp +++ b/src/core/SkColorSpaceXformer.cpp @@ -14,6 +14,7 @@ #include "SkImageFilter.h" #include "SkImagePriv.h" #include "SkMakeUnique.h" +#include "SkShaderBase.h" std::unique_ptr<SkColorSpaceXformer> SkColorSpaceXformer::Make(sk_sp<SkColorSpace> dst) { std::unique_ptr<SkColorSpaceXform> fromSRGB = SkColorSpaceXform_Base::New( @@ -53,7 +54,7 @@ sk_sp<SkImageFilter> SkColorSpaceXformer::apply(const SkImageFilter* imageFilter } sk_sp<SkShader> SkColorSpaceXformer::apply(const SkShader* shader) { - return shader->makeColorSpace(this); + return as_SB(shader)->makeColorSpace(this); } void SkColorSpaceXformer::apply(SkColor* xformed, const SkColor* srgb, int n) { diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp index 942c2931d2..7735494291 100644 --- a/src/core/SkComposeShader.cpp +++ b/src/core/SkComposeShader.cpp @@ -72,7 +72,7 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const { buffer.write32((int)fMode); } -SkShader::Context* SkComposeShader::onMakeContext( +SkShaderBase::Context* SkComposeShader::onMakeContext( const ContextRec& rec, SkArenaAlloc* alloc) const { // we preconcat our localMatrix (if any) with the device matrix @@ -90,8 +90,8 @@ SkShader::Context* SkComposeShader::onMakeContext( newRec.fMatrix = &tmpM; newRec.fPaint = &opaquePaint; - SkShader::Context* contextA = fShaderA->makeContext(newRec, alloc); - SkShader::Context* contextB = fShaderB->makeContext(newRec, alloc); + SkShaderBase::Context* contextA = as_SB(fShaderA)->makeContext(newRec, alloc); + SkShaderBase::Context* contextB = as_SB(fShaderB)->makeContext(newRec, alloc); if (!contextA || !contextB) { return nullptr; } @@ -106,7 +106,7 @@ sk_sp<SkShader> SkComposeShader::onMakeColorSpace(SkColorSpaceXformer* xformer) SkComposeShader::ComposeShaderContext::ComposeShaderContext( const SkComposeShader& shader, const ContextRec& rec, - SkShader::Context* contextA, SkShader::Context* contextB) + SkShaderBase::Context* contextA, SkShaderBase::Context* contextB) : INHERITED(shader, rec) , fShaderContextA(contextA) , fShaderContextB(contextB) {} @@ -121,7 +121,7 @@ bool SkComposeShader::asACompose(ComposeRec* rec) const { } bool SkComposeShader::isRasterPipelineOnly() const { - return fShaderA->isRasterPipelineOnly() || fShaderB->isRasterPipelineOnly(); + return as_SB(fShaderA)->isRasterPipelineOnly() || as_SB(fShaderB)->isRasterPipelineOnly(); } bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS, @@ -138,7 +138,7 @@ bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* d // will be smashed, and I'll need them again for fShaderB. store_rgba saves off 4 registers // even though we only need to save r,g. pipeline->append(SkRasterPipeline::store_rgba, storage->fXY); - if (!fShaderB->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // SRC + if (!as_SB(fShaderB)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // SRC return false; } // This outputs r,g,b,a, which we'll need later when we apply the mode, but we save it off now @@ -146,7 +146,7 @@ bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* d pipeline->append(SkRasterPipeline::store_rgba, storage->fRGBA); // Now we restore the device x,y for the next shader pipeline->append(SkRasterPipeline::load_rgba, storage->fXY); - if (!fShaderA->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // DST + if (!as_SB(fShaderA)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // DST return false; } // We now have our logical 'dst' in r,g,b,a, but we need it in dr,dg,db,da for the mode @@ -169,8 +169,8 @@ bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* d #define TMP_COLOR_COUNT 64 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) { - SkShader::Context* shaderContextA = fShaderContextA; - SkShader::Context* shaderContextB = fShaderContextB; + auto* shaderContextA = fShaderContextA; + auto* shaderContextB = fShaderContextB; SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode; unsigned scale = SkAlpha255To256(this->getPaintAlpha()); @@ -229,8 +229,8 @@ void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re } void SkComposeShader::ComposeShaderContext::shadeSpan4f(int x, int y, SkPM4f result[], int count) { - SkShader::Context* shaderContextA = fShaderContextA; - SkShader::Context* shaderContextB = fShaderContextB; + auto* shaderContextA = fShaderContextA; + auto* shaderContextB = fShaderContextB; SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode; unsigned alpha = this->getPaintAlpha(); Sk4f scale(alpha * (1.0f / 255)); @@ -272,17 +272,17 @@ sk_sp<GrFragmentProcessor> SkComposeShader::asFragmentProcessor(const AsFPArgs& GrConstColorProcessor::kIgnore_InputMode); break; case SkBlendMode::kSrc: - return fShaderB->asFragmentProcessor(args); + return as_SB(fShaderB)->asFragmentProcessor(args); break; case SkBlendMode::kDst: - return fShaderA->asFragmentProcessor(args); + return as_SB(fShaderA)->asFragmentProcessor(args); break; default: - sk_sp<GrFragmentProcessor> fpA(fShaderA->asFragmentProcessor(args)); + sk_sp<GrFragmentProcessor> fpA(as_SB(fShaderA)->asFragmentProcessor(args)); if (!fpA) { return nullptr; } - sk_sp<GrFragmentProcessor> fpB(fShaderB->asFragmentProcessor(args)); + sk_sp<GrFragmentProcessor> fpB(as_SB(fShaderB)->asFragmentProcessor(args)); if (!fpB) { return nullptr; } @@ -297,9 +297,9 @@ void SkComposeShader::toString(SkString* str) const { str->append("SkComposeShader: ("); str->append("ShaderA: "); - fShaderA->toString(str); + as_SB(fShaderA)->toString(str); str->append(" ShaderB: "); - fShaderB->toString(str); + as_SB(fShaderB)->toString(str); if (SkBlendMode::kSrcOver != fMode) { str->appendf(" Xfermode: %s", SkXfermode::ModeName(fMode)); } diff --git a/src/core/SkComposeShader.h b/src/core/SkComposeShader.h index d3f8c9dc27..8592f3a8ae 100644 --- a/src/core/SkComposeShader.h +++ b/src/core/SkComposeShader.h @@ -8,7 +8,7 @@ #ifndef SkComposeShader_DEFINED #define SkComposeShader_DEFINED -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkBlendMode.h" class SkColorSpacXformer; @@ -19,7 +19,7 @@ class SkColorSpacXformer; This subclass of shader returns the composition of two other shaders, combined by a xfermode. */ -class SK_API SkComposeShader : public SkShader { +class SK_API SkComposeShader : public SkShaderBase { public: /** Create a new compose shader, given shaders A, B, and a combining xfermode mode. When the xfermode is called, it will be given the result from shader A as its @@ -40,21 +40,21 @@ public: sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; #endif - class ComposeShaderContext : public SkShader::Context { + class ComposeShaderContext : public Context { public: // When this object gets destroyed, it will call contextA and contextB's destructor // but it will NOT free the memory. ComposeShaderContext(const SkComposeShader&, const ContextRec&, - SkShader::Context* contextA, SkShader::Context* contextB); + SkShaderBase::Context* contextA, SkShaderBase::Context* contextB); void shadeSpan(int x, int y, SkPMColor[], int count) override; void shadeSpan4f(int x, int y, SkPM4f[], int count) override; private: - SkShader::Context* fShaderContextA; - SkShader::Context* fShaderContextB; + SkShaderBase::Context* fShaderContextA; + SkShaderBase::Context* fShaderContextB; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; #ifdef SK_DEBUG @@ -82,7 +82,7 @@ private: sk_sp<SkShader> fShaderB; SkBlendMode fMode; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif diff --git a/src/core/SkCoreBlitters.h b/src/core/SkCoreBlitters.h index 8dfeb7486a..7f3de32ab1 100644 --- a/src/core/SkCoreBlitters.h +++ b/src/core/SkCoreBlitters.h @@ -11,7 +11,7 @@ #include "SkBitmapProcShader.h" #include "SkBlitter.h" #include "SkBlitRow.h" -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkXfermodePriv.h" class SkRasterBlitter : public SkBlitter { @@ -33,14 +33,14 @@ public: * exchange that object. */ SkShaderBlitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext); + SkShaderBase::Context* shaderContext); virtual ~SkShaderBlitter(); protected: - uint32_t fShaderFlags; - const SkShader* fShader; - SkShader::Context* fShaderContext; - bool fConstInY; + uint32_t fShaderFlags; + const SkShader* fShader; + SkShaderBase::Context* fShaderContext; + bool fConstInY; private: // illegal @@ -84,7 +84,7 @@ private: class SkA8_Shader_Blitter : public SkShaderBlitter { public: SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext); + SkShaderBase::Context* shaderContext); ~SkA8_Shader_Blitter() override; void blitH(int x, int y, int width) override; void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override; @@ -155,7 +155,7 @@ private: class SkARGB32_Shader_Blitter : public SkShaderBlitter { public: SkARGB32_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext); + SkShaderBase::Context* shaderContext); ~SkARGB32_Shader_Blitter() override; void blitH(int x, int y, int width) override; void blitV(int x, int y, int height, SkAlpha alpha) override; @@ -176,10 +176,10 @@ private: typedef SkShaderBlitter INHERITED; }; -SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*, +SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint&, SkShaderBase::Context*, SkArenaAlloc*); -SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*, +SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShaderBase::Context*, SkArenaAlloc*); /////////////////////////////////////////////////////////////////////////////// @@ -198,7 +198,7 @@ SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShader */ SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint, - SkShader::Context* shaderContext, + SkShaderBase::Context* shaderContext, SkArenaAlloc* allocator); diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp index 125ab7a9ce..7720acc088 100644 --- a/src/core/SkDraw_vertices.cpp +++ b/src/core/SkDraw_vertices.cpp @@ -13,7 +13,7 @@ #include "SkPM4fPriv.h" #include "SkRasterClip.h" #include "SkScan.h" -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkString.h" #include "SkVertState.h" @@ -69,7 +69,7 @@ static bool texture_to_matrix(const VertState& state, const SkPoint verts[], return matrix->setPolyToPoly(src, dst, 3); } -class SkTriColorShader : public SkShader { +class SkTriColorShader : public SkShaderBase { public: SkTriColorShader(bool isOpaque) : fIsOpaque(isOpaque) {} @@ -102,7 +102,7 @@ private: Matrix43 fM43; const bool fIsOpaque; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #ifndef SK_IGNORE_TO_STRING diff --git a/src/core/SkEmptyShader.h b/src/core/SkEmptyShader.h index b2c9b76792..c1bcfe0957 100644 --- a/src/core/SkEmptyShader.h +++ b/src/core/SkEmptyShader.h @@ -8,7 +8,7 @@ #ifndef SkEmptyShader_DEFINED #define SkEmptyShader_DEFINED -#include "SkShader.h" +#include "SkShaderBase.h" // TODO: move this to private, as there is a public factory on SkShader @@ -16,7 +16,7 @@ * \class SkEmptyShader * A Shader that always draws nothing. Its createContext always returns nullptr. */ -class SK_API SkEmptyShader : public SkShader { +class SK_API SkEmptyShader : public SkShaderBase { public: SkEmptyShader() {} @@ -24,7 +24,7 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader) protected: - SkShader::Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override { + Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override { return nullptr; } @@ -35,7 +35,7 @@ protected: } private: - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif diff --git a/src/core/SkGlobalInitialization_core.cpp b/src/core/SkGlobalInitialization_core.cpp index 298357eb78..9fa128f987 100644 --- a/src/core/SkGlobalInitialization_core.cpp +++ b/src/core/SkGlobalInitialization_core.cpp @@ -19,6 +19,7 @@ #include "SkPathEffect.h" #include "SkPictureShader.h" #include "SkRecordedDrawable.h" +#include "SkShaderBase.h" /* * Registers all of the required effects subclasses for picture deserialization. @@ -42,7 +43,7 @@ void SkFlattenable::PrivateInitializer::InitCore() { SkColorFilter::InitializeFlattenables(); SkPathEffect::InitializeFlattenables(); - SkShader::InitializeFlattenables(); + SkShaderBase::InitializeFlattenables(); SkXfermode::InitializeFlattenables(); // Drawable diff --git a/src/core/SkLightingShader.cpp b/src/core/SkLightingShader.cpp index ca370b0a3a..cdfa528e1e 100644 --- a/src/core/SkLightingShader.cpp +++ b/src/core/SkLightingShader.cpp @@ -16,6 +16,7 @@ #include "SkNormalSource.h" #include "SkPoint3.h" #include "SkReadBuffer.h" +#include "SkShaderBase.h" #include "SkWriteBuffer.h" //////////////////////////////////////////////////////////////////////////// @@ -36,7 +37,7 @@ /** \class SkLightingShaderImpl This subclass of shader applies lighting. */ -class SkLightingShaderImpl : public SkShader { +class SkLightingShaderImpl : public SkShaderBase { public: /** Create a new lighting shader that uses the provided normal map and lights to light the diffuse bitmap. @@ -57,12 +58,12 @@ public: sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override; #endif - class LightingShaderContext : public SkShader::Context { + class LightingShaderContext : public Context { public: // The context takes ownership of the context and provider. It will call their destructors // and then indirectly free their memory by calling free() on heapAllocated LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&, - SkShader::Context* diffuseContext, SkNormalSource::Provider*, + SkShaderBase::Context* diffuseContext, SkNormalSource::Provider*, void* heapAllocated); void shadeSpan(int x, int y, SkPMColor[], int count) override; @@ -70,12 +71,12 @@ public: uint32_t getFlags() const override { return fFlags; } private: - SkShader::Context* fDiffuseContext; + SkShaderBase::Context* fDiffuseContext; SkNormalSource::Provider* fNormalProvider; SkColor fPaintColor; uint32_t fFlags; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; SK_TO_STRING_OVERRIDE() @@ -93,7 +94,7 @@ private: friend class SkLightingShader; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; //////////////////////////////////////////////////////////////////////////// @@ -270,7 +271,7 @@ sk_sp<GrFragmentProcessor> SkLightingShaderImpl::asFragmentProcessor(const AsFPA if (fDiffuseShader) { sk_sp<GrFragmentProcessor> fpPipeline[] = { - fDiffuseShader->asFragmentProcessor(args), + as_SB(fDiffuseShader)->asFragmentProcessor(args), sk_make_sp<LightingFP>(std::move(normalFP), fLights) }; if(!fpPipeline[0]) { @@ -298,7 +299,7 @@ bool SkLightingShaderImpl::isOpaque() const { SkLightingShaderImpl::LightingShaderContext::LightingShaderContext( const SkLightingShaderImpl& shader, const ContextRec& rec, - SkShader::Context* diffuseContext, SkNormalSource::Provider* normalProvider, + SkShaderBase::Context* diffuseContext, SkNormalSource::Provider* normalProvider, void* heapAllocated) : INHERITED(shader, rec) , fDiffuseContext(diffuseContext) @@ -419,7 +420,7 @@ sk_sp<SkFlattenable> SkLightingShaderImpl::CreateProc(SkReadBuffer& buf) { bool hasDiffuse = buf.readBool(); sk_sp<SkShader> diffuseShader = nullptr; if (hasDiffuse) { - diffuseShader = buf.readFlattenable<SkShader>(); + diffuseShader = buf.readFlattenable<SkShaderBase>(); } return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move(normalSource), @@ -438,12 +439,12 @@ void SkLightingShaderImpl::flatten(SkWriteBuffer& buf) const { } } -SkShader::Context* SkLightingShaderImpl::onMakeContext( +SkShaderBase::Context* SkLightingShaderImpl::onMakeContext( const ContextRec& rec, SkArenaAlloc* alloc) const { - SkShader::Context *diffuseContext = nullptr; + SkShaderBase::Context *diffuseContext = nullptr; if (fDiffuseShader) { - diffuseContext = fDiffuseShader->makeContext(rec, alloc); + diffuseContext = as_SB(fDiffuseShader)->makeContext(rec, alloc); if (!diffuseContext) { return nullptr; } diff --git a/src/core/SkLocalMatrixShader.cpp b/src/core/SkLocalMatrixShader.cpp index 8a9a1656d9..e21e4a84b7 100644 --- a/src/core/SkLocalMatrixShader.cpp +++ b/src/core/SkLocalMatrixShader.cpp @@ -17,7 +17,7 @@ sk_sp<GrFragmentProcessor> SkLocalMatrixShader::asFragmentProcessor(const AsFPAr if (args.fLocalMatrix) { tmp.preConcat(*args.fLocalMatrix); } - return fProxyShader->asFragmentProcessor(AsFPArgs( + return as_SB(fProxyShader)->asFragmentProcessor(AsFPArgs( args.fContext, args.fViewMatrix, &tmp, args.fFilterQuality, args.fDstColorSpace)); } #endif @@ -37,7 +37,7 @@ void SkLocalMatrixShader::flatten(SkWriteBuffer& buffer) const { buffer.writeFlattenable(fProxyShader.get()); } -SkShader::Context* SkLocalMatrixShader::onMakeContext( +SkShaderBase::Context* SkLocalMatrixShader::onMakeContext( const ContextRec& rec, SkArenaAlloc* alloc) const { ContextRec newRec(rec); @@ -48,7 +48,7 @@ SkShader::Context* SkLocalMatrixShader::onMakeContext( } else { newRec.fLocalMatrix = &this->getLocalMatrix(); } - return fProxyShader->makeContext(newRec, alloc); + return as_SB(fProxyShader)->makeContext(newRec, alloc); } SkImage* SkLocalMatrixShader::onIsAImage(SkMatrix* outMatrix, enum TileMode* mode) const { @@ -72,15 +72,15 @@ bool SkLocalMatrixShader::onAppendStages(SkRasterPipeline* p, if (localM) { tmp.setConcat(*localM, this->getLocalMatrix()); } - return fProxyShader->appendStages(p, dst, scratch, ctm, paint, - localM ? &tmp : &this->getLocalMatrix()); + return as_SB(fProxyShader)->appendStages(p, dst, scratch, ctm, paint, + localM ? &tmp : &this->getLocalMatrix()); } #ifndef SK_IGNORE_TO_STRING void SkLocalMatrixShader::toString(SkString* str) const { str->append("SkLocalMatrixShader: ("); - fProxyShader->toString(str); + as_SB(fProxyShader)->toString(str); this->INHERITED::toString(str); @@ -97,7 +97,7 @@ sk_sp<SkShader> SkShader::makeWithLocalMatrix(const SkMatrix& localMatrix) const sk_sp<SkShader> baseShader; SkMatrix otherLocalMatrix; - sk_sp<SkShader> proxy(this->makeAsALocalMatrixShader(&otherLocalMatrix)); + sk_sp<SkShader> proxy(as_SB(this)->makeAsALocalMatrixShader(&otherLocalMatrix)); if (proxy) { otherLocalMatrix.preConcat(localMatrix); lm = &otherLocalMatrix; diff --git a/src/core/SkLocalMatrixShader.h b/src/core/SkLocalMatrixShader.h index b00ee89d56..4572e9fe2e 100644 --- a/src/core/SkLocalMatrixShader.h +++ b/src/core/SkLocalMatrixShader.h @@ -8,7 +8,7 @@ #ifndef SkLocalMatrixShader_DEFINED #define SkLocalMatrixShader_DEFINED -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkReadBuffer.h" #include "SkWriteBuffer.h" @@ -16,7 +16,7 @@ class GrFragmentProcessor; class SkArenaAlloc; class SkColorSpaceXformer; -class SkLocalMatrixShader : public SkShader { +class SkLocalMatrixShader : public SkShaderBase { public: SkLocalMatrixShader(sk_sp<SkShader> proxy, const SkMatrix& localMatrix) : INHERITED(&localMatrix) @@ -52,7 +52,8 @@ protected: const SkMatrix&, const SkPaint&, const SkMatrix*) const override; sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override { - return fProxyShader->makeColorSpace(xformer)->makeWithLocalMatrix(this->getLocalMatrix()); + return as_SB(fProxyShader)->makeColorSpace(xformer)->makeWithLocalMatrix( + this->getLocalMatrix()); } #ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP @@ -62,13 +63,13 @@ protected: #endif bool isRasterPipelineOnly() const final { - return fProxyShader->isRasterPipelineOnly(); + return as_SB(fProxyShader)->isRasterPipelineOnly(); } private: sk_sp<SkShader> fProxyShader; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif diff --git a/src/core/SkMipMap.h b/src/core/SkMipMap.h index f3425cbeaa..4ca9cbd63e 100644 --- a/src/core/SkMipMap.h +++ b/src/core/SkMipMap.h @@ -12,7 +12,7 @@ #include "SkPixmap.h" #include "SkScalar.h" #include "SkSize.h" -#include "SkShader.h" +#include "SkShaderBase.h" class SkBitmap; class SkDiscardableMemory; @@ -33,8 +33,8 @@ public: static SkMipMap* Build(const SkBitmap& src, SkDestinationSurfaceColorMode, SkDiscardableFactoryProc); - static SkDestinationSurfaceColorMode DeduceColorMode(const SkShader::ContextRec& rec) { - return (SkShader::ContextRec::kPMColor_DstType == rec.fPreferredDstType) + static SkDestinationSurfaceColorMode DeduceColorMode(const SkShaderBase::ContextRec& rec) { + return (SkShaderBase::ContextRec::kPMColor_DstType == rec.fPreferredDstType) ? SkDestinationSurfaceColorMode::kLegacy : SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware; } diff --git a/src/core/SkNormalBevelSource.cpp b/src/core/SkNormalBevelSource.cpp index 05bb5f6163..0f1305cd15 100644 --- a/src/core/SkNormalBevelSource.cpp +++ b/src/core/SkNormalBevelSource.cpp @@ -241,7 +241,7 @@ private: }; sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor( - const SkShader::AsFPArgs& args) const { + const SkShaderBase::AsFPArgs& args) const { // This assumes a uniform scale. Anisotropic scaling might not be handled gracefully. SkScalar maxScale = args.fViewMatrix->getMaxScale(); @@ -258,7 +258,7 @@ SkNormalBevelSourceImpl::Provider::Provider() {} SkNormalBevelSourceImpl::Provider::~Provider() {} -SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShader::ContextRec &rec, +SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShaderBase::ContextRec &rec, SkArenaAlloc* alloc) const { return alloc->make<Provider>(); } diff --git a/src/core/SkNormalBevelSource.h b/src/core/SkNormalBevelSource.h index 2fefacda8e..1e06303879 100644 --- a/src/core/SkNormalBevelSource.h +++ b/src/core/SkNormalBevelSource.h @@ -18,10 +18,10 @@ public: , fHeight(height) {} #if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const override; + sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override; #endif - SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec, + SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec, SkArenaAlloc*) const override; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalBevelSourceImpl) diff --git a/src/core/SkNormalFlatSource.cpp b/src/core/SkNormalFlatSource.cpp index 2547f4bda4..922ad15e92 100644 --- a/src/core/SkNormalFlatSource.cpp +++ b/src/core/SkNormalFlatSource.cpp @@ -60,7 +60,7 @@ private: }; sk_sp<GrFragmentProcessor> SkNormalFlatSourceImpl::asFragmentProcessor( - const SkShader::AsFPArgs&) const { + const SkShaderBase::AsFPArgs&) const { return sk_make_sp<NormalFlatFP>(); } @@ -73,7 +73,7 @@ SkNormalFlatSourceImpl::Provider::Provider() {} SkNormalFlatSourceImpl::Provider::~Provider() {} -SkNormalSource::Provider* SkNormalFlatSourceImpl::asProvider(const SkShader::ContextRec &rec, +SkNormalSource::Provider* SkNormalFlatSourceImpl::asProvider(const SkShaderBase::ContextRec &rec, SkArenaAlloc *alloc) const { return alloc->make<Provider>(); } diff --git a/src/core/SkNormalFlatSource.h b/src/core/SkNormalFlatSource.h index 82b56f1a8b..938e28f3c5 100644 --- a/src/core/SkNormalFlatSource.h +++ b/src/core/SkNormalFlatSource.h @@ -15,10 +15,10 @@ public: SkNormalFlatSourceImpl(){} #if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const override; + sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override; #endif - SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec, + SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec, SkArenaAlloc* alloc) const override; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalFlatSourceImpl) diff --git a/src/core/SkNormalMapSource.cpp b/src/core/SkNormalMapSource.cpp index fb133da1b7..f655b687d6 100644 --- a/src/core/SkNormalMapSource.cpp +++ b/src/core/SkNormalMapSource.cpp @@ -118,8 +118,8 @@ private: }; sk_sp<GrFragmentProcessor> SkNormalMapSourceImpl::asFragmentProcessor( - const SkShader::AsFPArgs& args) const { - sk_sp<GrFragmentProcessor> mapFP = fMapShader->asFragmentProcessor(args); + const SkShaderBase::AsFPArgs& args) const { + sk_sp<GrFragmentProcessor> mapFP = as_SB(fMapShader)->asFragmentProcessor(args); if (!mapFP) { return nullptr; } @@ -132,11 +132,11 @@ sk_sp<GrFragmentProcessor> SkNormalMapSourceImpl::asFragmentProcessor( //////////////////////////////////////////////////////////////////////////// SkNormalMapSourceImpl::Provider::Provider(const SkNormalMapSourceImpl& source, - SkShader::Context* mapContext) + SkShaderBase::Context* mapContext) : fSource(source) , fMapContext(mapContext) {} -SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShader::ContextRec &rec, +SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShaderBase::ContextRec &rec, SkArenaAlloc* alloc) const { SkMatrix normTotalInv; if (!this->computeNormTotalInverse(rec, &normTotalInv)) { @@ -146,10 +146,10 @@ SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShader::Cont // 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, - rec.fPreferredDstType, rec.fDstColorSpace); + SkShaderBase::ContextRec overrideRec(overridePaint, *(rec.fMatrix), rec.fLocalMatrix, + rec.fPreferredDstType, rec.fDstColorSpace); - SkShader::Context* context = fMapShader->makeContext(overrideRec, alloc); + auto* context = as_SB(fMapShader)->makeContext(overrideRec, alloc); if (!context) { return nullptr; } @@ -157,7 +157,7 @@ SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShader::Cont return alloc->make<Provider>(*this, context); } -bool SkNormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& rec, +bool SkNormalMapSourceImpl::computeNormTotalInverse(const SkShaderBase::ContextRec& rec, SkMatrix* normTotalInverse) const { SkMatrix total = SkMatrix::Concat(*rec.fMatrix, fMapShader->getLocalMatrix()); if (rec.fLocalMatrix) { @@ -221,7 +221,7 @@ void SkNormalMapSourceImpl::Provider::fillScanLine(int x, int y, SkPoint3 output sk_sp<SkFlattenable> SkNormalMapSourceImpl::CreateProc(SkReadBuffer& buf) { - sk_sp<SkShader> mapShader = buf.readFlattenable<SkShader>(); + sk_sp<SkShader> mapShader = buf.readFlattenable<SkShaderBase>(); SkMatrix invCTM; buf.readMatrix(&invCTM); diff --git a/src/core/SkNormalMapSource.h b/src/core/SkNormalMapSource.h index f2b07f21e9..a02e6abd09 100644 --- a/src/core/SkNormalMapSource.h +++ b/src/core/SkNormalMapSource.h @@ -17,10 +17,10 @@ public: , fInvCTM(invCTM) {} #if SK_SUPPORT_GPU - sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const override; + sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override; #endif - SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec, + SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec, SkArenaAlloc* alloc) const override; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalMapSourceImpl) @@ -28,18 +28,19 @@ public: protected: void flatten(SkWriteBuffer& buf) const override; - bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* normTotalInverse) const; + bool computeNormTotalInverse(const SkShaderBase::ContextRec& rec, + SkMatrix* normTotalInverse) const; private: class Provider : public SkNormalSource::Provider { public: - Provider(const SkNormalMapSourceImpl& source, SkShader::Context* mapContext); + Provider(const SkNormalMapSourceImpl& source, SkShaderBase::Context* mapContext); void fillScanLine(int x, int y, SkPoint3 output[], int count) const override; private: const SkNormalMapSourceImpl& fSource; - SkShader::Context* fMapContext; + SkShaderBase::Context* fMapContext; typedef SkNormalSource::Provider INHERITED; }; diff --git a/src/core/SkNormalSource.h b/src/core/SkNormalSource.h index 221c09db99..54d44d410a 100644 --- a/src/core/SkNormalSource.h +++ b/src/core/SkNormalSource.h @@ -9,7 +9,7 @@ #define SkNormalSource_DEFINED #include "SkFlattenable.h" -#include "SkShader.h" +#include "SkShaderBase.h" class SkMatrix; struct SkPoint3; @@ -28,7 +28,7 @@ public: /** Returns a fragment processor that takes no input and outputs a normal (already rotated) as its output color. To be used as a child fragment processor. */ - virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const = 0; + virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const = 0; #endif class Provider { @@ -44,7 +44,7 @@ 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 SkShaderBase::ContextRec&, SkArenaAlloc*) const = 0; /** Returns a normal source that provides normals sourced from the the normal map argument. diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 568ba6a021..2d3eb1822b 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -26,6 +26,7 @@ #include "SkScalar.h" #include "SkScalerContext.h" #include "SkShader.h" +#include "SkShaderBase.h" #include "SkStringUtils.h" #include "SkStroke.h" #include "SkStrokeRec.h" @@ -1250,7 +1251,7 @@ static SkPaint::Hinting computeHinting(const SkPaint& paint) { static bool justAColor(const SkPaint& paint, SkColor* color) { SkColor c = paint.getColor(); - SkShader* shader = paint.getShader(); + const auto* shader = as_SB(paint.getShader()); if (shader && !shader->asLuminanceColor(&c)) { return false; } @@ -2071,8 +2072,7 @@ void SkPaint::toString(SkString* str) const { str->append("</dd>"); } - SkShader* shader = this->getShader(); - if (shader) { + if (const auto* shader = as_SB(this->getShader())) { str->append("<dt>Shader:</dt><dd>"); shader->toString(str); str->append("</dd>"); diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index a92cf04d28..d6ee941251 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -277,11 +277,11 @@ bool SkPictureShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* cs, SkAr // Keep bitmapShader alive by using alloc instead of stack memory auto& bitmapShader = *alloc->make<sk_sp<SkShader>>(); bitmapShader = this->refBitmapShader(ctm, localMatrix, cs); - return bitmapShader && bitmapShader->appendStages(p, cs, alloc, ctm, paint); + return bitmapShader && as_SB(bitmapShader)->appendStages(p, cs, alloc, ctm, paint); } ///////////////////////////////////////////////////////////////////////////////////////// -SkShader::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) +SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix, rec.fDstColorSpace)); @@ -310,7 +310,7 @@ SkPictureShader::PictureShaderContext::PictureShaderContext( : INHERITED(shader, rec) , fBitmapShader(std::move(bitmapShader)) { - fBitmapShaderContext = fBitmapShader->makeContext(rec, alloc); + fBitmapShaderContext = as_SB(fBitmapShader)->makeContext(rec, alloc); //if fBitmapShaderContext is null, we are invalid } @@ -319,7 +319,7 @@ uint32_t SkPictureShader::PictureShaderContext::getFlags() const { return fBitmapShaderContext->getFlags(); } -SkShader::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) { +SkShaderBase::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) { SkASSERT(fBitmapShaderContext); return fBitmapShaderContext->asAShadeProc(ctx); } @@ -358,7 +358,7 @@ sk_sp<GrFragmentProcessor> SkPictureShader::asFragmentProcessor(const AsFPArgs& if (!bitmapShader) { return nullptr; } - return bitmapShader->asFragmentProcessor(SkShader::AsFPArgs( + return as_SB(bitmapShader)->asFragmentProcessor(SkShaderBase::AsFPArgs( args.fContext, args.fViewMatrix, nullptr, args.fFilterQuality, args.fDstColorSpace)); } #endif diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h index 10b1f932d7..f7a509f181 100644 --- a/src/core/SkPictureShader.h +++ b/src/core/SkPictureShader.h @@ -8,7 +8,7 @@ #ifndef SkPictureShader_DEFINED #define SkPictureShader_DEFINED -#include "SkShader.h" +#include "SkShaderBase.h" class SkArenaAlloc; class SkBitmap; @@ -20,7 +20,7 @@ class SkPicture; * The SkPicture is first rendered into a tile, which is then used to shade the area according * to specified tiling rules. */ -class SkPictureShader : public SkShader { +class SkPictureShader : public SkShaderBase { public: static sk_sp<SkShader> Make(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*, const SkRect*); @@ -52,7 +52,7 @@ private: SkRect fTile; TileMode fTmx, fTmy; - class PictureShaderContext : public SkShader::Context { + class PictureShaderContext : public Context { public: PictureShaderContext( const SkPictureShader&, const ContextRec&, sk_sp<SkShader> bitmapShader, SkArenaAlloc*); @@ -62,18 +62,18 @@ private: ShadeProc asAShadeProc(void** ctx) override; void shadeSpan(int x, int y, SkPMColor dstC[], int count) override; - sk_sp<SkShader> fBitmapShader; - SkShader::Context* fBitmapShaderContext; - void* fBitmapShaderContextStorage; + sk_sp<SkShader> fBitmapShader; + SkShaderBase::Context* fBitmapShaderContext; + void* fBitmapShaderContextStorage; - typedef SkShader::Context INHERITED; + typedef Context INHERITED; }; // Should never be set by a public constructor. This is only used when onMakeColorSpace() // forces a deferred color space xform. sk_sp<SkColorSpace> fColorSpace; - typedef SkShader INHERITED; + typedef SkShaderBase INHERITED; }; #endif // SkPictureShader_DEFINED diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp index 023ff1e234..cc48df03db 100644 --- a/src/core/SkRasterPipelineBlitter.cpp +++ b/src/core/SkRasterPipelineBlitter.cpp @@ -16,6 +16,7 @@ #include "SkPM4fPriv.h" #include "SkRasterPipeline.h" #include "SkShader.h" +#include "SkShaderBase.h" #include "SkUtils.h" #include "../jumper/SkJumper.h" @@ -23,13 +24,14 @@ class SkRasterPipelineBlitter final : public SkBlitter { public: // This is our common entrypoint for creating the blitter once we've sorted out shaders. static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkArenaAlloc*, - const SkRasterPipeline& shaderPipeline, SkShader::Context* shaderCtx, + const SkRasterPipeline& shaderPipeline, + SkShaderBase::Context* shaderCtx, bool is_opaque, bool is_constant, bool wants_dither); SkRasterPipelineBlitter(SkPixmap dst, SkBlendMode blend, SkArenaAlloc* alloc, - SkShader::Context* shaderCtx) + SkShaderBase::Context* shaderCtx) : fDst(dst) , fBlend(blend) , fAlloc(alloc) @@ -54,11 +56,11 @@ private: // If we have an SkShader::Context, use it to fill our shader buffer. void maybe_shade(int x, int y, int w); - SkPixmap fDst; - SkBlendMode fBlend; - SkArenaAlloc* fAlloc; - SkShader::Context* fShaderCtx; - SkRasterPipeline fColorPipeline; + SkPixmap fDst; + SkBlendMode fBlend; + SkArenaAlloc* fAlloc; + SkShaderBase::Context* fShaderCtx; + SkRasterPipeline fColorPipeline; // We may be able to specialize blitH() into a memset. bool fCanMemsetInBlitH = false; @@ -90,7 +92,7 @@ SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, SkArenaAlloc* alloc) { SkColorSpace* dstCS = dst.colorSpace(); auto paintColor = alloc->make<SkPM4f>(SkPM4f_from_SkColor(paint.getColor(), dstCS)); - auto shader = paint.getShader(); + auto shader = as_SB(paint.getShader()); SkRasterPipeline_<256> shaderPipeline; if (!shader) { @@ -124,11 +126,12 @@ SkBlitter* SkCreateRasterPipelineBlitter(const SkPixmap& dst, if (dstCS) { // We need to transform the shader into the dst color space, and extend its lifetime. sk_sp<SkShader> in_dstCS = SkColorSpaceXformer::Make(sk_ref_sp(dstCS))->apply(shader); - shader = in_dstCS.get(); + shader = as_SB(in_dstCS.get()); alloc->make<sk_sp<SkShader>>(std::move(in_dstCS)); } - SkShader::ContextRec rec(paint, ctm, nullptr, SkShader::ContextRec::kPM4f_DstType, dstCS); - SkShader::Context* shaderCtx = shader->makeContext(rec, alloc); + SkShaderBase::ContextRec rec(paint, ctm, nullptr, SkShaderBase::ContextRec::kPM4f_DstType, + dstCS); + SkShaderBase::Context* shaderCtx = shader->makeContext(rec, alloc); if (!shaderCtx) { // When a shader fails to create a context, it has vetoed drawing entirely. return alloc->make<SkNullBlitter>(); @@ -154,7 +157,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst, const SkPaint& paint, SkArenaAlloc* alloc, const SkRasterPipeline& shaderPipeline, - SkShader::Context* shaderCtx, + SkShaderBase::Context* shaderCtx, bool is_opaque, bool is_constant, bool wants_dither) { diff --git a/src/core/SkReadBuffer.h b/src/core/SkReadBuffer.h index adc529ea77..453d22fe91 100644 --- a/src/core/SkReadBuffer.h +++ b/src/core/SkReadBuffer.h @@ -20,7 +20,7 @@ #include "SkReadBuffer.h" #include "SkReader32.h" #include "SkRefCnt.h" -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkTHash.h" #include "SkWriteBuffer.h" #include "SkXfermodePriv.h" @@ -150,7 +150,7 @@ public: sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilter>(); } sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); } sk_sp<SkRasterizer> readRasterizer() { return this->readFlattenable<SkRasterizer>(); } - sk_sp<SkShader> readShader() { return this->readFlattenable<SkShader>(); } + sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); } sk_sp<SkXfermode> readXfermode() { return this->readFlattenable<SkXfermode>(); } // binary data and arrays diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index ff5b400a25..4f39f704b8 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -18,7 +18,7 @@ #include "SkRasterPipeline.h" #include "SkReadBuffer.h" #include "SkScalar.h" -#include "SkShader.h" +#include "SkShaderBase.h" #include "SkTLazy.h" #include "SkWriteBuffer.h" #include "../jumper/SkJumper.h" @@ -46,22 +46,18 @@ static inline void dec_shader_counter() { #endif } -SkShader::SkShader(const SkMatrix* localMatrix) { +SkShaderBase::SkShaderBase(const SkMatrix* localMatrix) + : fLocalMatrix(localMatrix ? *localMatrix : SkMatrix::I()) { inc_shader_counter(); - if (localMatrix) { - fLocalMatrix = *localMatrix; - } else { - fLocalMatrix.reset(); - } // Pre-cache so future calls to fLocalMatrix.getType() are threadsafe. (void)fLocalMatrix.getType(); } -SkShader::~SkShader() { +SkShaderBase::~SkShaderBase() { dec_shader_counter(); } -void SkShader::flatten(SkWriteBuffer& buffer) const { +void SkShaderBase::flatten(SkWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); bool hasLocalM = !fLocalMatrix.isIdentity(); buffer.writeBool(hasLocalM); @@ -70,9 +66,9 @@ void SkShader::flatten(SkWriteBuffer& buffer) const { } } -bool SkShader::computeTotalInverse(const SkMatrix& ctm, - const SkMatrix* outerLocalMatrix, - SkMatrix* totalInverse) const { +bool SkShaderBase::computeTotalInverse(const SkMatrix& ctm, + const SkMatrix* outerLocalMatrix, + SkMatrix* totalInverse) const { SkMatrix total = SkMatrix::Concat(ctm, fLocalMatrix); if (outerLocalMatrix) { total.preConcat(*outerLocalMatrix); @@ -81,7 +77,7 @@ bool SkShader::computeTotalInverse(const SkMatrix& ctm, return total.invert(totalInverse); } -bool SkShader::asLuminanceColor(SkColor* colorPtr) const { +bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const { SkColor storage; if (nullptr == colorPtr) { colorPtr = &storage; @@ -93,14 +89,14 @@ bool SkShader::asLuminanceColor(SkColor* colorPtr) const { return false; } -SkShader::Context* SkShader::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { +SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const { if (!this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr)) { return nullptr; } return this->onMakeContext(rec, alloc); } -SkShader::Context::Context(const SkShader& shader, const ContextRec& rec) +SkShaderBase::Context::Context(const SkShaderBase& shader, const ContextRec& rec) : fShader(shader), fCTM(*rec.fMatrix) { // We should never use a context for RP-only shaders. @@ -114,13 +110,13 @@ SkShader::Context::Context(const SkShader& shader, const ContextRec& rec) fPaintAlpha = rec.fPaint->getAlpha(); } -SkShader::Context::~Context() {} +SkShaderBase::Context::~Context() {} -SkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) { +SkShaderBase::Context::ShadeProc SkShaderBase::Context::asAShadeProc(void** ctx) { return nullptr; } -void SkShader::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { +void SkShaderBase::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { const int N = 128; SkPMColor tmp[N]; while (count > 0) { @@ -146,7 +142,7 @@ void SkShader::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) { #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) #endif -void SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { +void SkShaderBase::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { SkASSERT(count > 0); SkPMColor colors[kTempColorCount]; @@ -200,7 +196,7 @@ void SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) #endif } -SkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) { +SkShaderBase::Context::MatrixClass SkShaderBase::Context::ComputeMatrixClass(const SkMatrix& mat) { MatrixClass mc = kLinear_MatrixClass; if (mat.hasPerspective()) { @@ -215,17 +211,31 @@ SkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMat ////////////////////////////////////////////////////////////////////////////// +const SkMatrix& SkShader::getLocalMatrix() const { + return as_SB(this)->getLocalMatrix(); +} + +#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP +bool SkShader::isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const { + return as_SB(this)->onIsABitmap(outTexture, outMatrix, xy); +} +#endif + +SkImage* SkShader::isAImage(SkMatrix* localMatrix, TileMode xy[2]) const { + return as_SB(this)->onIsAImage(localMatrix, xy); +} + SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { return kNone_GradientType; } #if SK_SUPPORT_GPU -sk_sp<GrFragmentProcessor> SkShader::asFragmentProcessor(const AsFPArgs&) const { +sk_sp<GrFragmentProcessor> SkShaderBase::asFragmentProcessor(const AsFPArgs&) const { return nullptr; } #endif -sk_sp<SkShader> SkShader::makeAsALocalMatrixShader(SkMatrix*) const { +sk_sp<SkShader> SkShaderBase::makeAsALocalMatrixShader(SkMatrix*) const { return nullptr; } @@ -250,7 +260,7 @@ sk_sp<SkShader> SkShader::MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, } #ifndef SK_IGNORE_TO_STRING -void SkShader::toString(SkString* str) const { +void SkShaderBase::toString(SkString* str) const { if (!fLocalMatrix.isIdentity()) { str->append(" "); fLocalMatrix.toString(str); @@ -258,21 +268,21 @@ void SkShader::toString(SkString* str) const { } #endif -bool SkShader::appendStages(SkRasterPipeline* p, - SkColorSpace* dstCS, - SkArenaAlloc* alloc, - const SkMatrix& ctm, - const SkPaint& paint, - const SkMatrix* localM) const { +bool SkShaderBase::appendStages(SkRasterPipeline* p, + SkColorSpace* dstCS, + SkArenaAlloc* alloc, + const SkMatrix& ctm, + const SkPaint& paint, + const SkMatrix* localM) const { return this->onAppendStages(p, dstCS, alloc, ctm, paint, localM); } -bool SkShader::onAppendStages(SkRasterPipeline* p, - SkColorSpace* dstCS, - SkArenaAlloc* alloc, - const SkMatrix& ctm, - const SkPaint& paint, - const SkMatrix* localM) const { +bool SkShaderBase::onAppendStages(SkRasterPipeline* p, + SkColorSpace* dstCS, + SkArenaAlloc* alloc, + const SkMatrix& ctm, + const SkPaint& paint, + const SkMatrix* localM) const { return false; } diff --git a/src/core/SkShaderBase.h b/src/core/SkShaderBase.h new file mode 100644 index 0000000000..e03fb76bab --- /dev/null +++ b/src/core/SkShaderBase.h @@ -0,0 +1,324 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkShaderBase_DEFINED +#define SkShaderBase_DEFINED + +#include "SkFilterQuality.h" +#include "SkMatrix.h" +#include "SkShader.h" + +class GrContext; +class GrFragmentProcessor; +class SkArenaAlloc; +class SkColorSpace; +class SkColorSpaceXformer; +class SkImage; +struct SkImageInfo; +class SkPaint; +class SkRasterPipeline; + +class SkShaderBase : public SkShader { +public: + SkShaderBase(const SkMatrix* localMatrix = nullptr); + + ~SkShaderBase() override; + + /** + * Returns true if the shader is guaranteed to produce only a single color. + * Subclasses can override this to allow loop-hoisting optimization. + */ + virtual bool isConstant() const { return false; } + + const SkMatrix& getLocalMatrix() const { return fLocalMatrix; } + + enum Flags { + //!< set if all of the colors will be opaque + kOpaqueAlpha_Flag = 1 << 0, + + /** set if the spans only vary in X (const in Y). + e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient + that varies from left-to-right. This flag specifies this for + shadeSpan(). + */ + kConstInY32_Flag = 1 << 1, + + /** hint for the blitter that 4f is the preferred shading mode. + */ + kPrefers4f_Flag = 1 << 2, + }; + + /** + * ContextRec acts as a parameter bundle for creating Contexts. + */ + struct ContextRec { + enum DstType { + kPMColor_DstType, // clients prefer shading into PMColor dest + kPM4f_DstType, // clients prefer shading into PM4f dest + }; + + ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM, + DstType dstType, SkColorSpace* dstColorSpace) + : fPaint(&paint) + , fMatrix(&matrix) + , fLocalMatrix(localM) + , fPreferredDstType(dstType) + , fDstColorSpace(dstColorSpace) {} + + const SkPaint* fPaint; // the current paint associated with the draw + const SkMatrix* fMatrix; // the current matrix in the canvas + const SkMatrix* fLocalMatrix; // optional local matrix + const DstType fPreferredDstType; // the "natural" client dest type + SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any) + }; + + class Context : public ::SkNoncopyable { + public: + Context(const SkShaderBase& shader, const ContextRec&); + + virtual ~Context(); + + /** + * Called sometimes before drawing with this shader. Return the type of + * alpha your shader will return. The default implementation returns 0. + * Your subclass should override if it can (even sometimes) report a + * non-zero value, since that will enable various blitters to perform + * faster. + */ + virtual uint32_t getFlags() const { return 0; } + + /** + * Called for each span of the object being drawn. Your subclass should + * set the appropriate colors (with premultiplied alpha) that correspond + * to the specified device coordinates. + */ + virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0; + + virtual void shadeSpan4f(int x, int y, SkPM4f[], int count); + + struct BlitState; + typedef void (*BlitBW)(BlitState*, + int x, int y, const SkPixmap&, int count); + typedef void (*BlitAA)(BlitState*, + int x, int y, const SkPixmap&, int count, const SkAlpha[]); + + struct BlitState { + // inputs + Context* fCtx; + SkBlendMode fMode; + + // outputs + enum { N = 2 }; + void* fStorage[N]; + BlitBW fBlitBW; + BlitAA fBlitAA; + }; + + // Returns true if one or more of the blitprocs are set in the BlitState + bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) { + state->fBlitBW = nullptr; + state->fBlitAA = nullptr; + if (this->onChooseBlitProcs(info, state)) { + SkASSERT(state->fBlitBW || state->fBlitAA); + return true; + } + return false; + } + + /** + * The const void* ctx is only const because all the implementations are const. + * This can be changed to non-const if a new shade proc needs to change the ctx. + */ + typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count); + virtual ShadeProc asAShadeProc(void** ctx); + + /** + * Similar to shadeSpan, but only returns the alpha-channel for a span. + * The default implementation calls shadeSpan() and then extracts the alpha + * values from the returned colors. + */ + virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); + + // Notification from blitter::blitMask in case we need to see the non-alpha channels + virtual void set3DMask(const SkMask*) {} + + protected: + // Reference to shader, so we don't have to dupe information. + const SkShaderBase& fShader; + + enum MatrixClass { + kLinear_MatrixClass, // no perspective + kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each + // scanline + kPerspective_MatrixClass // slow perspective, need to mappoints each pixel + }; + static MatrixClass ComputeMatrixClass(const SkMatrix&); + + uint8_t getPaintAlpha() const { return fPaintAlpha; } + const SkMatrix& getTotalInverse() const { return fTotalInverse; } + MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } + const SkMatrix& getCTM() const { return fCTM; } + + virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; } + + private: + SkMatrix fCTM; + SkMatrix fTotalInverse; + uint8_t fPaintAlpha; + uint8_t fTotalInverseClass; + + typedef SkNoncopyable INHERITED; + }; + + /** + * Make a context using the memory provided by the arena. + * + * @return pointer to context or nullptr if can't be created + */ + Context* makeContext(const ContextRec&, SkArenaAlloc*) const; + + /** + * If the shader subclass is composed of two shaders, return true, and if rec is not NULL, + * fill it out with info about the shader. + * + * These are bare pointers; the ownership and reference count are unchanged. + */ + + struct ComposeRec { + const SkShader* fShaderA; + const SkShader* fShaderB; + SkBlendMode fBlendMode; + }; + + virtual bool asACompose(ComposeRec*) const { return false; } + +#if SK_SUPPORT_GPU + struct AsFPArgs { + AsFPArgs() {} + AsFPArgs(GrContext* context, + const SkMatrix* viewMatrix, + const SkMatrix* localMatrix, + SkFilterQuality filterQuality, + SkColorSpace* dstColorSpace) + : fContext(context) + , fViewMatrix(viewMatrix) + , fLocalMatrix(localMatrix) + , fFilterQuality(filterQuality) + , fDstColorSpace(dstColorSpace) {} + + GrContext* fContext; + const SkMatrix* fViewMatrix; + const SkMatrix* fLocalMatrix; + SkFilterQuality fFilterQuality; + SkColorSpace* fDstColorSpace; + }; + + /** + * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is + * returned if there is no GPU implementation. + * + * The GPU device does not call SkShader::createContext(), instead we pass the view matrix, + * local matrix, and filter quality directly. + * + * The GrContext may be used by the to create textures that are required by the returned + * processor. + * + * The returned GrFragmentProcessor should expect an unpremultiplied input color and + * produce a premultiplied output. + */ + virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const; +#endif + + /** + * If the shader can represent its "average" luminance in a single color, return true and + * if color is not NULL, return that color. If it cannot, return false and ignore the color + * parameter. + * + * Note: if this returns true, the returned color will always be opaque, as only the RGB + * components are used to compute luminance. + */ + bool asLuminanceColor(SkColor*) const; + + /** + * Returns a shader transformed into a new color space via the |xformer|. + */ + sk_sp<SkShader> makeColorSpace(SkColorSpaceXformer* xformer) const { + return this->onMakeColorSpace(xformer); + } + + /** + * If this shader can be represented by another shader + a localMatrix, return that shader and + * the localMatrix. If not, return nullptr and ignore the localMatrix parameter. + */ + virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const; + + virtual bool isRasterPipelineOnly() const { return false; } + + bool appendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*, + const SkMatrix& ctm, const SkPaint&, const SkMatrix* localM=nullptr) const; + + bool computeTotalInverse(const SkMatrix& ctm, + const SkMatrix* outerLocalMatrix, + SkMatrix* totalInverse) const; + +#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP + virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const { + return false; + } +#endif + + virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const { + return nullptr; + } + + SK_TO_STRING_VIRT() + + SK_DEFINE_FLATTENABLE_TYPE(SkShaderBase) + SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP() + +protected: + void flatten(SkWriteBuffer&) const override; + + /** + * Specialize creating a SkShader context using the supplied allocator. + * @return pointer to context owned by the arena allocator. + */ + virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const { + return nullptr; + } + + virtual bool onAsLuminanceColor(SkColor*) const { + return false; + } + + virtual sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer*) const { + return sk_ref_sp(const_cast<SkShaderBase*>(this)); + } + + virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*, + const SkMatrix&, const SkPaint&, const SkMatrix* localM) const; + +private: + // This is essentially const, but not officially so it can be modified in constructors. + SkMatrix fLocalMatrix; + + typedef SkShader INHERITED; +}; + +inline SkShaderBase* as_SB(SkShader* shader) { + return static_cast<SkShaderBase*>(shader); +} + +inline const SkShaderBase* as_SB(const SkShader* shader) { + return static_cast<const SkShaderBase*>(shader); +} + +inline const SkShaderBase* as_SB(const sk_sp<SkShader>& shader) { + return static_cast<SkShaderBase*>(shader.get()); +} + +#endif // SkShaderBase_DEFINED |