Index: src/core/SkComposeShader.cpp |
diff --git a/src/core/SkComposeShader.cpp b/src/core/SkComposeShader.cpp |
index b5ea63c24c5ed7e60dbe54d671ef9f59c076953d..f4152e16e72fd41327daaf7ddd1eaa6642663577 100644 |
--- a/src/core/SkComposeShader.cpp |
+++ b/src/core/SkComposeShader.cpp |
@@ -69,6 +69,20 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const { |
buffer.writeFlattenable(fMode); |
} |
+struct ComposeContext { |
+ SkShader::Context* fContextA; |
+ SkShader::Context* fContextB; |
+}; |
+ |
+// Helper function to get the ComposeContext from the Context. |
+static ComposeContext* get_compose_context(SkShader::Context* c, const SkShader& shader) { |
+ return (ComposeContext*) shader.getMyContext(c); |
+} |
+ |
+size_t SkComposeShader::getMySpaceNeededForContext() const { |
+ return sizeof(ComposeContext); |
+} |
+ |
/* We call setContext on our two worker shaders. However, we |
always let them see opaque alpha, and if the paint really |
is translucent, then we apply that after the fact. |
@@ -76,10 +90,10 @@ void SkComposeShader::flatten(SkWriteBuffer& buffer) const { |
We need to keep the calls to setContext/endContext balanced, since if we |
return false, our endContext() will not be called. |
*/ |
-bool SkComposeShader::setContext(const SkBitmap& device, |
- const SkPaint& paint, |
- const SkMatrix& matrix) { |
- if (!this->INHERITED::setContext(device, paint, matrix)) { |
+bool SkComposeShader::onSetContext(Context* c, const SkBitmap& device, |
+ const SkPaint& paint, |
+ const SkMatrix& matrix) { |
+ if (!this->INHERITED::onSetContext(c, device, paint, matrix)) { |
return false; |
} |
@@ -88,43 +102,51 @@ bool SkComposeShader::setContext(const SkBitmap& device, |
SkMatrix tmpM; |
+ // Will come from the paint. |
tmpM.setConcat(matrix, this->getLocalMatrix()); |
SkAutoAlphaRestore restore(const_cast<SkPaint*>(&paint), 0xFF); |
- bool setContextA = fShaderA->setContext(device, paint, tmpM); |
- bool setContextB = fShaderB->setContext(device, paint, tmpM); |
- if (!setContextA || !setContextB) { |
- if (setContextB) { |
- fShaderB->endContext(); |
- } |
- else if (setContextA) { |
- fShaderA->endContext(); |
- } |
- this->INHERITED::endContext(); |
+ SkShader::Context* contextA = fShaderA->setContext(device, paint, tmpM); |
+ if (!contextA) { |
return false; |
} |
+ |
+ SkShader::Context* contextB = fShaderB->setContext(device, paint, tmpM); |
+ if (!contextB) { |
+ SkDELETE(contextA); |
+ return false; |
+ } |
+ |
+ ComposeContext* composeContext = get_compose_context(c, *this); |
+ composeContext->fContextA = contextA; |
+ composeContext->fContextB = contextB; |
+ |
return true; |
} |
-void SkComposeShader::endContext() { |
- fShaderB->endContext(); |
- fShaderA->endContext(); |
- this->INHERITED::endContext(); |
+void SkComposeShader::endContext(Context* c) { |
+ ComposeContext* composeContext = get_compose_context(c, *this); |
+ |
+ fShaderB->endContext(c->fContextA); |
+ fShaderA->endContext(c->fContextB); |
+ this->INHERITED::endContext(c); |
} |
// larger is better (fewer times we have to loop), but we shouldn't |
// take up too much stack-space (each element is 4 bytes) |
#define TMP_COLOR_COUNT 64 |
-void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) { |
+void SkComposeShader::shadeSpan(Context* c, int x, int y, SkPMColor result[], int count) { |
SkShader* shaderA = fShaderA; |
SkShader* shaderB = fShaderB; |
SkXfermode* mode = fMode; |
- unsigned scale = SkAlpha255To256(this->getPaintAlpha()); |
+ unsigned scale = SkAlpha255To256(c->getPaintAlpha()); |
SkPMColor tmp[TMP_COLOR_COUNT]; |
+ ComposeContext* composeContext = get_compose_context(c, *this); |
+ |
if (NULL == mode) { // implied SRC_OVER |
// TODO: when we have a good test-case, should use SkBlitRow::Proc32 |
// for these loops |
@@ -134,8 +156,8 @@ void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) { |
n = TMP_COLOR_COUNT; |
} |
- shaderA->shadeSpan(x, y, result, n); |
- shaderB->shadeSpan(x, y, tmp, n); |
+ shaderA->shadeSpan(composeContext->fContextA, x, y, result, n); |
+ shaderB->shadeSpan(composeContext->fContextB, x, y, tmp, n); |
if (256 == scale) { |
for (int i = 0; i < n; i++) { |
@@ -159,8 +181,8 @@ void SkComposeShader::shadeSpan(int x, int y, SkPMColor result[], int count) { |
n = TMP_COLOR_COUNT; |
} |
- shaderA->shadeSpan(x, y, result, n); |
- shaderB->shadeSpan(x, y, tmp, n); |
+ shaderA->shadeSpan(composeContext->fContextA, x, y, result, n); |
+ shaderB->shadeSpan(composeContext->fContextB, x, y, tmp, n); |
mode->xfer32(result, tmp, n, NULL); |
if (256 == scale) { |