Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(118)

Unified Diff: src/core/SkDraw.cpp

Issue 1431713003: drawVertices crashes when shader+colorfilter in the paint (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Skip rendering when matrices are not valid - as original code did it that way Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698