| 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) {
|
|
|