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

Unified Diff: src/core/SkDraw.cpp

Issue 207683004: Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up Created 6 years, 9 months 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
Index: src/core/SkDraw.cpp
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 05b06453dbf200df8cebccfc3aee4c69825d5143..d74c1700d17fa4bea1389484fc6593c02aba2c82 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -2355,13 +2355,35 @@ static bool texture_to_matrix(const VertState& state, const SkPoint verts[],
return matrix->setPolyToPoly(src, dst, 3);
}
+/**
+ * This class is NOT immutable due to the setup() method being called repeatedly after
+ * the shader has been associated with a paint. This is okay because we only ever
+ * associate this shader with temporary paints.
+ */
class SkTriColorShader : public SkShader {
public:
SkTriColorShader() {}
- bool setup(const SkPoint pts[], const SkColor colors[], int, int, int);
+ // TODO(dominikg): Feels like this should be part of the context, but we don't have
+ // access to it where we need it.
+ bool setup(const SkPoint pts[], const SkColor colors[], int, int, int, const SkMatrix&);
+
+ virtual SkShader::Context* createContext(
+ const SkBitmap&, const SkPaint&, const SkMatrix&, void*) const SK_OVERRIDE;
+ virtual size_t contextSize() const SK_OVERRIDE;
+
+ class TriColorShaderContext : public SkShader::Context {
+ public:
+ TriColorShaderContext(const SkTriColorShader& shader, const SkBitmap& device,
+ const SkPaint& paint, const SkMatrix& matrix);
+ virtual ~TriColorShaderContext();
+
+ virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
+ private:
+ const SkTriColorShader& fTriColorShader;
scroggo 2014/03/24 21:24:46 Any reason SkTriColorShader does not simply static
Dominik Grewe 2014/03/26 17:22:22 Done.
- virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) SK_OVERRIDE;
+ typedef SkShader::Context INHERITED;
+ };
SK_DEVELOPER_TO_STRING()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTriColorShader)
@@ -2376,8 +2398,17 @@ private:
typedef SkShader INHERITED;
};
+SkShader::Context* SkTriColorShader::createContext(const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix, void* storage) const {
+ if (!this->validContext(device, paint, matrix)) {
+ return NULL;
+ }
+
+ return SkNEW_PLACEMENT_ARGS(storage, TriColorShaderContext, (*this, device, paint, matrix));
+}
+
bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[],
- int index0, int index1, int index2) {
+ int index0, int index1, int index2, const SkMatrix& matrix) {
scroggo 2014/03/24 21:24:46 Maybe rename this parameter to make it clear what
Dominik Grewe 2014/03/26 17:22:22 It's not the totalInverse though, is it? We use it
scroggo 2014/03/26 23:13:09 Oh, I misread the code below...
fColors[0] = SkPreMultiplyColor(colors[index0]);
fColors[1] = SkPreMultiplyColor(colors[index1]);
@@ -2394,7 +2425,9 @@ bool SkTriColorShader::setup(const SkPoint pts[], const SkColor colors[],
if (!m.invert(&im)) {
return false;
}
- return fDstToUnit.setConcat(im, this->getTotalInverse());
+ SkMatrix inverse;
+ SkASSERT(matrix.invert(&inverse));
scroggo 2014/03/26 23:13:09 I seemed to have overlooked this part. I take it t
Dominik Grewe 2014/03/27 14:27:20 Actually, if we add a SkBlitter::getShaderContext(
scroggo 2014/03/27 18:05:33 That seems even better to me.
+ return fDstToUnit.setConcat(im, inverse);
}
#include "SkColorPriv.h"
@@ -2411,11 +2444,23 @@ static int ScalarTo256(SkScalar v) {
return SkAlpha255To256(scale);
}
-void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
+
+SkTriColorShader::TriColorShaderContext::TriColorShaderContext(
+ const SkTriColorShader& shader, const SkBitmap& device,
scroggo 2014/03/24 21:24:46 nit: Parameters that fit on the same line should g
Dominik Grewe 2014/03/26 17:22:22 If I move the first one to the same line and line
+ const SkPaint& paint, const SkMatrix& matrix)
+ : INHERITED(shader, device, paint, matrix)
+ , fTriColorShader(shader) {}
+
+SkTriColorShader::TriColorShaderContext::~TriColorShaderContext() {}
+
+size_t SkTriColorShader::contextSize() const {
+ return sizeof(TriColorShaderContext);
+}
+void SkTriColorShader::TriColorShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
SkPoint src;
for (int i = 0; i < count; i++) {
- fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
+ fTriColorShader.fDstToUnit.mapXY(SkIntToScalar(x), SkIntToScalar(y), &src);
x += 1;
int scale1 = ScalarTo256(src.fX);
@@ -2430,9 +2475,9 @@ void SkTriColorShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) {
scale0 = 0;
}
- dstC[i] = SkAlphaMulQ(fColors[0], scale0) +
- SkAlphaMulQ(fColors[1], scale1) +
- SkAlphaMulQ(fColors[2], scale2);
+ dstC[i] = SkAlphaMulQ(fTriColorShader.fColors[0], scale0) +
+ SkAlphaMulQ(fTriColorShader.fColors[1], scale1) +
+ SkAlphaMulQ(fTriColorShader.fColors[2], scale2);
}
}
@@ -2518,8 +2563,8 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
}
SkAutoBlitterChoose blitter(*fBitmap, *fMatrix, p);
- // important that we abort early, as below we may manipulate the shader
- // and that is only valid if the shader returned true from setContext.
+ // Important that we abort early, as below we may manipulate the shader context
+ // and that is only valid if a context was successfully created from the shader.
// If it returned false, then our blitter will be the NullBlitter.
if (blitter->isNullBlitter()) {
return;
@@ -2536,30 +2581,19 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
savedLocalM = shader->getLocalMatrix();
}
- // setContext has already been called and verified to return true
- // by the constructor of SkAutoBlitterChoose
- bool prevContextSuccess = true;
while (vertProc(&state)) {
if (NULL != textures) {
if (texture_to_matrix(state, vertices, textures, &tempM)) {
tempM.postConcat(savedLocalM);
shader->setLocalMatrix(tempM);
- // Need to recall setContext since we changed the local matrix.
- // However, we also need to balance the calls this with a
- // call to endContext which requires tracking the result of
- // the previous call to setContext.
- if (prevContextSuccess) {
- shader->endContext();
- }
- prevContextSuccess = shader->setContext(*fBitmap, p, *fMatrix);
- if (!prevContextSuccess) {
+ if (!blitter->resetShaderContext(*fBitmap, p, *fMatrix)) {
Dominik Grewe 2014/03/21 12:52:50 Afaict, we want to create a new shader context her
scroggo 2014/03/24 21:24:46 This seems like a fine way to do it to me.
continue;
}
}
}
if (NULL != colors) {
if (!triShader.setup(vertices, colors,
- state.f0, state.f1, state.f2)) {
+ state.f0, state.f1, state.f2, *fMatrix)) {
continue;
}
}
@@ -2574,13 +2608,6 @@ void SkDraw::drawVertices(SkCanvas::VertexMode vmode, int count,
if (NULL != shader) {
shader->setLocalMatrix(savedLocalM);
}
-
- // If the final call to setContext fails we must make it suceed so that the
- // call to endContext in the destructor for SkAutoBlitterChoose is balanced.
- if (!prevContextSuccess) {
- prevContextSuccess = shader->setContext(*fBitmap, paint, SkMatrix::I());
- SkASSERT(prevContextSuccess);
- }
} else {
// no colors[] and no texture
HairProc hairProc = ChooseHairProc(paint.isAntiAlias());

Powered by Google App Engine
This is Rietveld 408576698