diff options
author | reed <reed@google.com> | 2016-03-18 12:42:26 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-03-18 12:42:26 -0700 |
commit | 58fc94e55fb52704f86aa6fde97719131a3c9ed4 (patch) | |
tree | dc8074968cc98643982438862d46acb7032a738a | |
parent | d2497f35ce9e9e70ab6c7acd82b212c80cb86d3a (diff) |
allow more options for shader blitprocs
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1810383004
Review URL: https://codereview.chromium.org/1810383004
-rw-r--r-- | include/core/SkShader.h | 31 | ||||
-rw-r--r-- | src/core/SkBlitter_PM4f.cpp | 45 | ||||
-rw-r--r-- | src/core/SkColorShader.h | 4 | ||||
-rw-r--r-- | src/core/SkShader.cpp | 36 | ||||
-rw-r--r-- | src/effects/gradients/Sk4fLinearGradient.cpp | 24 | ||||
-rw-r--r-- | src/effects/gradients/Sk4fLinearGradient.h | 8 |
6 files changed, 88 insertions, 60 deletions
diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 39ffd86f3a..c9c760d06d 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -142,18 +142,35 @@ public: 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; SkXfermode* fXfer; + + // outputs enum { N = 2 }; void* fStorage[N]; + BlitBW fBlitBW; + BlitAA fBlitAA; }; - typedef void (*BlitProc)(BlitState*, - int x, int y, const SkPixmap&, int count, const SkAlpha[]); - BlitProc chooseBlitProc(const SkImageInfo& info, BlitState* state) { - return this->onChooseBlitProc(info, state); + + // 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. @@ -188,9 +205,7 @@ public: MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } const SkMatrix& getCTM() const { return fCTM; } - virtual BlitProc onChooseBlitProc(const SkImageInfo&, BlitState*) { - return nullptr; - } + virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; } private: SkMatrix fCTM; diff --git a/src/core/SkBlitter_PM4f.cpp b/src/core/SkBlitter_PM4f.cpp index da669a2df1..b7d8e7f8d3 100644 --- a/src/core/SkBlitter_PM4f.cpp +++ b/src/core/SkBlitter_PM4f.cpp @@ -134,22 +134,22 @@ public: /////////////////////////////////////////////////////////////////////////////////////////////////// -template <typename State, bool UseBProc> class SkState_Shader_Blitter : public SkShaderBlitter { +template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter { public: SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint, - const SkShader::Context::BlitState& bstate, - SkShader::Context::BlitProc bproc) + const SkShader::Context::BlitState& bstate) : INHERITED(device, paint, bstate.fCtx) , fState(device.info(), paint, bstate.fCtx) , fBState(bstate) - , fBProc(bproc) + , fBlitBW(bstate.fBlitBW) + , fBlitAA(bstate.fBlitAA) {} void blitH(int x, int y, int width) override { SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width()); - if (UseBProc) { - fBProc(&fBState, x, y, fDevice, width, nullptr); + if (fBlitBW) { + fBlitBW(&fBState, x, y, fDevice, width); return; } @@ -161,9 +161,9 @@ public: void blitV(int x, int y, int height, SkAlpha alpha) override { SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height()); - if (UseBProc) { + if (fBlitAA) { for (const int bottom = y + height; y < bottom; ++y) { - fBProc(&fBState, x, y, fDevice, 1, &alpha); + fBlitAA(&fBState, x, y, fDevice, 1, &alpha); } return; } @@ -187,9 +187,9 @@ public: SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height()); - if (UseBProc) { + if (fBlitBW) { for (const int bottom = y + height; y < bottom; ++y) { - fBProc(&fBState, x, y, fDevice, width, nullptr); + fBlitBW(&fBState, x, y, fDevice, width); } return; } @@ -219,8 +219,8 @@ public: } int aa = *antialias; if (aa) { - if (UseBProc && (aa == 255)) { - fBProc(&fBState, x, y, fDevice, count, nullptr); + if (fBlitBW && (aa == 255)) { + fBlitBW(&fBState, x, y, fDevice, count); } else { fShaderContext->shadeSpan4f(x, y, fState.fBuffer, count); if (aa == 255) { @@ -282,9 +282,9 @@ public: const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y); const size_t maskRB = mask.fRowBytes; - if (UseBProc) { + if (fBlitAA) { for (; y < clip.fBottom; ++y) { - fBProc(&fBState, x, y, fDevice, width, maskRow); + fBlitAA(&fBState, x, y, fDevice, width, maskRow); maskRow += maskRB; } return; @@ -309,7 +309,8 @@ public: protected: State fState; SkShader::Context::BlitState fBState; - SkShader::Context::BlitProc fBProc; + SkShader::Context::BlitBW fBlitBW; + SkShader::Context::BlitAA fBlitAA; typedef SkShaderBlitter INHERITED; }; @@ -338,8 +339,7 @@ struct State4f { SkAutoTMalloc<SkPM4f> fBuffer; uint32_t fFlags; - SkShader::Context::BlitState fBState; - SkShader::Context::BlitProc fBProc; + SkShader::Context::BlitState fBState; }; struct State32 : State4f { @@ -413,17 +413,12 @@ template <typename State> SkBlitter* create(const SkPixmap& device, const SkPain if (shaderContext) { SkShader::Context::BlitState bstate; + sk_bzero(&bstate, sizeof(bstate)); bstate.fCtx = shaderContext; bstate.fXfer = paint.getXfermode(); - auto bproc = shaderContext->chooseBlitProc(device.info(), &bstate); - if (bproc) { - return allocator->createT<SkState_Shader_Blitter<State, true>>(device, paint, bstate, - bproc); - } else { - return allocator->createT<SkState_Shader_Blitter<State, false>>(device, paint, bstate, - bproc); - } + (void)shaderContext->chooseBlitProcs(device.info(), &bstate); + return allocator->createT<SkState_Shader_Blitter<State>>(device, paint, bstate); } else { SkColor color = paint.getColor(); if (0 == SkColorGetA(color)) { diff --git a/src/core/SkColorShader.h b/src/core/SkColorShader.h index cc3ec45e08..db71b6ef9f 100644 --- a/src/core/SkColorShader.h +++ b/src/core/SkColorShader.h @@ -36,8 +36,8 @@ public: void shadeSpan4f(int x, int y, SkPM4f[], int count) override; protected: - BlitProc onChooseBlitProc(const SkImageInfo&, BlitState*) override; - + bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override; + private: SkPM4f fPM4f; SkPMColor fPMColor; diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index cb0517bf64..52d0064eb1 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -361,22 +361,36 @@ void SkColorShader::toString(SkString* str) const { /////////////////////////////////////////////////////////////////////////////// -static void D32_BlitProc(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, - int count, const SkAlpha aa[]) { +static void D32_BlitBW(SkShader::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->fXfer, dst.writable_addr32(x, y), src, count, nullptr); +} + +static void D32_BlitAA(SkShader::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->fXfer, dst.writable_addr32(x, y), src, count, aa); } -static void D64_BlitProc(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, - int count, const SkAlpha aa[]) { +static void D64_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, + int count) { + SkXfermode::D64Proc proc = (SkXfermode::D64Proc)state->fStorage[0]; + const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; + proc(state->fXfer, dst.writable_addr64(x, y), src, count, nullptr); +} + +static void D64_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst, + int count, const SkAlpha aa[]) { SkXfermode::D64Proc proc = (SkXfermode::D64Proc)state->fStorage[0]; const SkPM4f* src = (const SkPM4f*)state->fStorage[1]; proc(state->fXfer, dst.writable_addr64(x, y), src, count, aa); } -SkShader::Context::BlitProc -SkColorShader::ColorShaderContext::onChooseBlitProc(const SkImageInfo& info, BlitState* state) { +bool SkColorShader::ColorShaderContext::onChooseBlitProcs(const SkImageInfo& info, + BlitState* state) { uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag; if (fPM4f.a() == 1) { flags |= SkXfermode::kSrcIsOpaque_D32Flag; @@ -388,14 +402,18 @@ SkColorShader::ColorShaderContext::onChooseBlitProc(const SkImageInfo& info, Bli } state->fStorage[0] = (void*)SkXfermode::GetD32Proc(state->fXfer, flags); state->fStorage[1] = &fPM4f; - return D32_BlitProc; + state->fBlitBW = D32_BlitBW; + state->fBlitAA = D32_BlitAA; + return true; case kRGBA_F16_SkColorType: flags |= SkXfermode::kDstIsFloat16_D64Flag; state->fStorage[0] = (void*)SkXfermode::GetD64Proc(state->fXfer, flags); state->fStorage[1] = &fPM4f; - return D64_BlitProc; + state->fBlitBW = D64_BlitBW; + state->fBlitAA = D64_BlitAA; + return true; default: - return nullptr; + return false; } } diff --git a/src/effects/gradients/Sk4fLinearGradient.cpp b/src/effects/gradients/Sk4fLinearGradient.cpp index 82b2fcc69b..84b266accd 100644 --- a/src/effects/gradients/Sk4fLinearGradient.cpp +++ b/src/effects/gradients/Sk4fLinearGradient.cpp @@ -442,32 +442,34 @@ LinearGradient4fContext::mapTs(int x, int y, SkScalar ts[], int count) const { } } -SkShader::Context::BlitProc SkLinearGradient:: -LinearGradient4fContext::onChooseBlitProc(const SkImageInfo& info, BlitState* state) { +bool SkLinearGradient::LinearGradient4fContext::onChooseBlitProcs(const SkImageInfo& info, + BlitState* state) { SkXfermode::Mode mode; if (!SkXfermode::AsMode(state->fXfer, &mode)) { - return nullptr; + return false; } const SkGradientShaderBase& shader = static_cast<const SkGradientShaderBase&>(fShader); if (mode != SkXfermode::kSrc_Mode && !(mode == SkXfermode::kSrcOver_Mode && shader.colorsAreOpaque())) { - return nullptr; + return false; } switch (info.colorType()) { case kN32_SkColorType: - return D32_BlitProc; + state->fBlitBW = D32_BlitBW; + return true; case kRGBA_F16_SkColorType: - return D64_BlitProc; + state->fBlitBW = D64_BlitBW; + return true; default: - return nullptr; + return false; } } void SkLinearGradient:: -LinearGradient4fContext::D32_BlitProc(BlitState* state, int x, int y, const SkPixmap& dst, - int count, const SkAlpha aa[]) { +LinearGradient4fContext::D32_BlitBW(BlitState* state, int x, int y, const SkPixmap& dst, + int count) { // FIXME: ignoring coverage for now const LinearGradient4fContext* ctx = static_cast<const LinearGradient4fContext*>(state->fCtx); @@ -492,8 +494,8 @@ LinearGradient4fContext::D32_BlitProc(BlitState* state, int x, int y, const SkPi } void SkLinearGradient:: -LinearGradient4fContext::D64_BlitProc(BlitState* state, int x, int y, const SkPixmap& dst, - int count, const SkAlpha aa[]) { +LinearGradient4fContext::D64_BlitBW(BlitState* state, int x, int y, const SkPixmap& dst, + int count) { // FIXME: ignoring coverage for now const LinearGradient4fContext* ctx = static_cast<const LinearGradient4fContext*>(state->fCtx); diff --git a/src/effects/gradients/Sk4fLinearGradient.h b/src/effects/gradients/Sk4fLinearGradient.h index 9bce47c33d..30292c361f 100644 --- a/src/effects/gradients/Sk4fLinearGradient.h +++ b/src/effects/gradients/Sk4fLinearGradient.h @@ -22,7 +22,7 @@ public: protected: void mapTs(int x, int y, SkScalar ts[], int count) const override; - BlitProc onChooseBlitProc(const SkImageInfo&, BlitState*) override; + bool onChooseBlitProcs(const SkImageInfo&, BlitState*) override; private: using INHERITED = GradientShaderBase4fContext; @@ -40,10 +40,8 @@ private: bool isFast() const { return fDstToPosClass == kLinear_MatrixClass; } - static void D32_BlitProc(BlitState* state, int x, int y, const SkPixmap& dst, - int count, const SkAlpha aa[]); - static void D64_BlitProc(BlitState*, int x, int y, const SkPixmap& dst, - int count, const SkAlpha aa[]); + static void D32_BlitBW(BlitState*, int x, int y, const SkPixmap& dst, int count); + static void D64_BlitBW(BlitState*, int x, int y, const SkPixmap& dst, int count); mutable const Interval* fCachedInterval; }; |