| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 #include "SkComposeShader.h" | 10 #include "SkComposeShader.h" |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 newRec.fMatrix = &tmpM; | 93 newRec.fMatrix = &tmpM; |
| 94 | 94 |
| 95 return fShaderA->validContext(newRec) && fShaderB->validContext(newRec); | 95 return fShaderA->validContext(newRec) && fShaderB->validContext(newRec); |
| 96 } | 96 } |
| 97 | 97 |
| 98 SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* s
torage) const { | 98 SkShader::Context* SkComposeShader::createContext(const ContextRec& rec, void* s
torage) const { |
| 99 if (!this->validContext(rec)) { | 99 if (!this->validContext(rec)) { |
| 100 return NULL; | 100 return NULL; |
| 101 } | 101 } |
| 102 | 102 |
| 103 // TODO : must fix this to not "cheat" and modify fPaint | |
| 104 SkAutoAlphaRestore restore(const_cast<SkPaint*>(rec.fPaint), 0xFF); | |
| 105 | |
| 106 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); | 103 char* aStorage = (char*) storage + sizeof(ComposeShaderContext); |
| 107 char* bStorage = aStorage + fShaderA->contextSize(); | 104 char* bStorage = aStorage + fShaderA->contextSize(); |
| 108 | 105 |
| 109 // we preconcat our localMatrix (if any) with the device matrix | 106 // we preconcat our localMatrix (if any) with the device matrix |
| 110 // before calling our sub-shaders | 107 // before calling our sub-shaders |
| 111 | |
| 112 SkMatrix tmpM; | 108 SkMatrix tmpM; |
| 113 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); | 109 tmpM.setConcat(*rec.fMatrix, this->getLocalMatrix()); |
| 114 | 110 |
| 111 // Our sub-shaders need to see opaque, so by combining them we don't double-
alphatize the |
| 112 // result. ComposeShader itself will respect the alpha, and post-apply it af
ter calling the |
| 113 // sub-shaders. |
| 114 SkPaint opaquePaint(*rec.fPaint); |
| 115 opaquePaint.setAlpha(0xFF); |
| 116 |
| 115 ContextRec newRec(rec); | 117 ContextRec newRec(rec); |
| 116 newRec.fMatrix = &tmpM; | 118 newRec.fMatrix = &tmpM; |
| 119 newRec.fPaint = &opaquePaint; |
| 117 | 120 |
| 118 SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); | 121 SkShader::Context* contextA = fShaderA->createContext(newRec, aStorage); |
| 119 SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); | 122 SkShader::Context* contextB = fShaderB->createContext(newRec, bStorage); |
| 120 | 123 |
| 121 // Both functions must succeed; otherwise validContext should have returned | 124 // Both functions must succeed; otherwise validContext should have returned |
| 122 // false. | 125 // false. |
| 123 SkASSERT(contextA); | 126 SkASSERT(contextA); |
| 124 SkASSERT(contextB); | 127 SkASSERT(contextB); |
| 125 | 128 |
| 126 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, cont
extA, contextB)); | 129 return SkNEW_PLACEMENT_ARGS(storage, ComposeShaderContext, (*this, rec, cont
extA, contextB)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 141 // larger is better (fewer times we have to loop), but we shouldn't | 144 // larger is better (fewer times we have to loop), but we shouldn't |
| 142 // take up too much stack-space (each element is 4 bytes) | 145 // take up too much stack-space (each element is 4 bytes) |
| 143 #define TMP_COLOR_COUNT 64 | 146 #define TMP_COLOR_COUNT 64 |
| 144 | 147 |
| 145 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re
sult[], int count) { | 148 void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor re
sult[], int count) { |
| 146 SkShader::Context* shaderContextA = fShaderContextA; | 149 SkShader::Context* shaderContextA = fShaderContextA; |
| 147 SkShader::Context* shaderContextB = fShaderContextB; | 150 SkShader::Context* shaderContextB = fShaderContextB; |
| 148 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode
; | 151 SkXfermode* mode = static_cast<const SkComposeShader&>(fShader).fMode
; |
| 149 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); | 152 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); |
| 150 | 153 |
| 154 #ifdef SK_BUILD_FOR_ANDROID |
| 155 scale = 256; // ugh -- maintain old bug/behavior for now |
| 156 #endif |
| 157 |
| 151 SkPMColor tmp[TMP_COLOR_COUNT]; | 158 SkPMColor tmp[TMP_COLOR_COUNT]; |
| 152 | 159 |
| 153 if (NULL == mode) { // implied SRC_OVER | 160 if (NULL == mode) { // implied SRC_OVER |
| 154 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 | 161 // TODO: when we have a good test-case, should use SkBlitRow::Proc32 |
| 155 // for these loops | 162 // for these loops |
| 156 do { | 163 do { |
| 157 int n = count; | 164 int n = count; |
| 158 if (n > TMP_COLOR_COUNT) { | 165 if (n > TMP_COLOR_COUNT) { |
| 159 n = TMP_COLOR_COUNT; | 166 n = TMP_COLOR_COUNT; |
| 160 } | 167 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 181 do { | 188 do { |
| 182 int n = count; | 189 int n = count; |
| 183 if (n > TMP_COLOR_COUNT) { | 190 if (n > TMP_COLOR_COUNT) { |
| 184 n = TMP_COLOR_COUNT; | 191 n = TMP_COLOR_COUNT; |
| 185 } | 192 } |
| 186 | 193 |
| 187 shaderContextA->shadeSpan(x, y, result, n); | 194 shaderContextA->shadeSpan(x, y, result, n); |
| 188 shaderContextB->shadeSpan(x, y, tmp, n); | 195 shaderContextB->shadeSpan(x, y, tmp, n); |
| 189 mode->xfer32(result, tmp, n, NULL); | 196 mode->xfer32(result, tmp, n, NULL); |
| 190 | 197 |
| 191 if (256 == scale) { | 198 if (256 != scale) { |
| 192 for (int i = 0; i < n; i++) { | 199 for (int i = 0; i < n; i++) { |
| 193 result[i] = SkAlphaMulQ(result[i], scale); | 200 result[i] = SkAlphaMulQ(result[i], scale); |
| 194 } | 201 } |
| 195 } | 202 } |
| 196 | 203 |
| 197 result += n; | 204 result += n; |
| 198 x += n; | 205 x += n; |
| 199 count -= n; | 206 count -= n; |
| 200 } while (count > 0); | 207 } while (count > 0); |
| 201 } | 208 } |
| 202 } | 209 } |
| 203 | 210 |
| 204 #ifndef SK_IGNORE_TO_STRING | 211 #ifndef SK_IGNORE_TO_STRING |
| 205 void SkComposeShader::toString(SkString* str) const { | 212 void SkComposeShader::toString(SkString* str) const { |
| 206 str->append("SkComposeShader: ("); | 213 str->append("SkComposeShader: ("); |
| 207 | 214 |
| 208 str->append("ShaderA: "); | 215 str->append("ShaderA: "); |
| 209 fShaderA->toString(str); | 216 fShaderA->toString(str); |
| 210 str->append(" ShaderB: "); | 217 str->append(" ShaderB: "); |
| 211 fShaderB->toString(str); | 218 fShaderB->toString(str); |
| 212 str->append(" Xfermode: "); | 219 str->append(" Xfermode: "); |
| 213 fMode->toString(str); | 220 fMode->toString(str); |
| 214 | 221 |
| 215 this->INHERITED::toString(str); | 222 this->INHERITED::toString(str); |
| 216 | 223 |
| 217 str->append(")"); | 224 str->append(")"); |
| 218 } | 225 } |
| 219 #endif | 226 #endif |
| OLD | NEW |