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. |