Chromium Code Reviews| Index: src/core/SkDraw.cpp |
| diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp |
| index d8d6fcf57fe123b7926eae12b668114c600e94dc..88a55cacce253b47837f29d6af6ab7f70d1058ec 100644 |
| --- a/src/core/SkDraw.cpp |
| +++ b/src/core/SkDraw.cpp |
| @@ -1890,7 +1890,7 @@ static bool texture_to_matrix(const VertState& state, const SkPoint verts[], |
| class SkTriColorShader : public SkShader { |
| public: |
| - SkTriColorShader() {} |
| + SkTriColorShader(); |
| size_t contextSize() const override; |
| @@ -1898,29 +1898,47 @@ public: |
| public: |
| TriColorShaderContext(const SkTriColorShader& shader, const ContextRec&); |
| virtual ~TriColorShaderContext(); |
| - |
| - bool setup(const SkPoint pts[], const SkColor colors[], int, int, int); |
| - |
| void shadeSpan(int x, int y, SkPMColor dstC[], int count) override; |
| private: |
| + bool setup(const SkPoint pts[], const SkColor colors[], int, int, int); |
| + |
| SkMatrix fDstToUnit; |
| SkPMColor fColors[3]; |
| + bool fSetup; |
| typedef SkShader::Context INHERITED; |
| }; |
| + struct TriColorShaderData { |
| + const SkPoint* pts; |
| + const SkColor* colors; |
| + const VertState *state; |
| + }; |
| + |
| SK_TO_STRING_OVERRIDE() |
| // For serialization. This will never be called. |
| Factory getFactory() const override { sk_throw(); return nullptr; } |
| + // Supply setup data to context from drawing setup |
| + void bindSetupData(TriColorShaderData* setupData) { fSetupData = setupData; } |
| + |
| + // Take the setup data from context when needed. |
| + TriColorShaderData* takeSetupData() { |
| + TriColorShaderData *data = fSetupData; |
| + fSetupData = NULL; |
| + return data; |
| + } |
| + |
| protected: |
| Context* onCreateContext(const ContextRec& rec, void* storage) const override { |
| return new (storage) TriColorShaderContext(*this, rec); |
| } |
| private: |
| + TriColorShaderData *fSetupData; |
| + |
| typedef SkShader INHERITED; |
| }; |
| @@ -1948,6 +1966,7 @@ bool SkTriColorShader::TriColorShaderContext::setup(const SkPoint pts[], const S |
| if (!this->getCTM().invert(&ctmInv)) { |
| return false; |
| } |
| + // TODO replace INV(m) * INV(ctm) with INV(ctm * m) |
| fDstToUnit.setConcat(im, ctmInv); |
| return true; |
| } |
| @@ -1966,10 +1985,14 @@ static int ScalarTo256(SkScalar v) { |
| return SkAlpha255To256(scale); |
| } |
| +SkTriColorShader::SkTriColorShader() |
| + : INHERITED(NULL) |
| + , fSetupData(NULL) {} |
| SkTriColorShader::TriColorShaderContext::TriColorShaderContext(const SkTriColorShader& shader, |
| const ContextRec& rec) |
| - : INHERITED(shader, rec) {} |
| + : INHERITED(shader, rec) |
| + , fSetup(false) {} |
| SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {} |
| @@ -1977,6 +2000,17 @@ size_t SkTriColorShader::contextSize() const { |
| return sizeof(TriColorShaderContext); |
| } |
| void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) { |
| + SkTriColorShader* parent = static_cast<SkTriColorShader*>(const_cast<SkShader*>(&fShader)); |
| + TriColorShaderData* set = parent->takeSetupData(); |
| + if (set) { |
| + fSetup = setup(set->pts, set->colors, set->state->f0, set->state->f1, set->state->f2); |
|
aleksandar_stojiljkovic
2015/11/10 08:58:51
Reed, what do you think about this approach?
Ther
|
| + } |
| + |
| + if (!fSetup) { |
| + // Invalid matrices. Not checked before so no need to assert. |
| + return; |
| + } |
| + |
| const int alphaScale = Sk255To256(this->getPaintAlpha()); |
| SkPoint src; |
| @@ -2093,6 +2127,8 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count, |
| VertState::Proc vertProc = state.chooseProc(vmode); |
| if (textures || colors) { |
| + SkTriColorShader::TriColorShaderData verticesSetup = { vertices, colors, &state }; |
| + |
| while (vertProc(&state)) { |
| if (textures) { |
| SkMatrix tempM; |
| @@ -2104,35 +2140,14 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count, |
| } |
| } |
| if (colors) { |
| - // Find the context for triShader. |
| - SkTriColorShader::TriColorShaderContext* triColorShaderContext; |
| - |
| - SkShader::Context* shaderContext = blitter->getShaderContext(); |
| - SkASSERT(shaderContext); |
| - if (p.getShader() == &triShader) { |
| - triColorShaderContext = |
| - static_cast<SkTriColorShader::TriColorShaderContext*>(shaderContext); |
| - } else { |
| - // The shader is a compose shader and triShader is its first shader. |
| - SkASSERT(p.getShader() == composeShader); |
| - SkASSERT(composeShader->getShaderA() == &triShader); |
| - SkComposeShader::ComposeShaderContext* composeShaderContext = |
| - static_cast<SkComposeShader::ComposeShaderContext*>(shaderContext); |
| - SkShader::Context* shaderContextA = composeShaderContext->getShaderContextA(); |
| - triColorShaderContext = |
| - static_cast<SkTriColorShader::TriColorShaderContext*>(shaderContextA); |
| - } |
| - |
| - if (!triColorShaderContext->setup(vertices, colors, |
| - state.f0, state.f1, state.f2)) { |
| - continue; |
| - } |
| + triShader.bindSetupData(&verticesSetup); |
| } |
| SkPoint tmp[] = { |
| devVerts[state.f0], devVerts[state.f1], devVerts[state.f2] |
| }; |
| SkScan::FillTriangle(tmp, *fRC, blitter.get()); |
| + triShader.bindSetupData(NULL); |
| } |
| } else { |
| // no colors[] and no texture, stroke hairlines with paint's color. |