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 |