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

Side by Side Diff: src/core/SkShader.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: SkGradientShader Created 6 years, 8 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkBitmapProcShader.h" 8 #include "SkBitmapProcShader.h"
9 #include "SkReadBuffer.h" 9 #include "SkReadBuffer.h"
10 #include "SkMallocPixelRef.h" 10 #include "SkMallocPixelRef.h"
11 #include "SkPaint.h" 11 #include "SkPaint.h"
12 #include "SkScalar.h" 12 #include "SkScalar.h"
13 #include "SkShader.h" 13 #include "SkShader.h"
14 #include "SkWriteBuffer.h" 14 #include "SkWriteBuffer.h"
15 15
16 SkShader::SkShader() { 16 SkShader::SkShader() {
17 fLocalMatrix.reset(); 17 fLocalMatrix.reset();
18 SkDEBUGCODE(fInSetContext = false;)
19 } 18 }
20 19
21 SkShader::SkShader(SkReadBuffer& buffer) 20 SkShader::SkShader(SkReadBuffer& buffer)
22 : INHERITED(buffer) { 21 : INHERITED(buffer) {
23 if (buffer.readBool()) { 22 if (buffer.readBool()) {
24 buffer.readMatrix(&fLocalMatrix); 23 buffer.readMatrix(&fLocalMatrix);
25 } else { 24 } else {
26 fLocalMatrix.reset(); 25 fLocalMatrix.reset();
27 } 26 }
28
29 SkDEBUGCODE(fInSetContext = false;)
30 } 27 }
31 28
32 SkShader::~SkShader() { 29 SkShader::~SkShader() {
33 SkASSERT(!fInSetContext);
34 } 30 }
35 31
36 void SkShader::flatten(SkWriteBuffer& buffer) const { 32 void SkShader::flatten(SkWriteBuffer& buffer) const {
37 this->INHERITED::flatten(buffer); 33 this->INHERITED::flatten(buffer);
38 bool hasLocalM = this->hasLocalMatrix(); 34 bool hasLocalM = this->hasLocalMatrix();
39 buffer.writeBool(hasLocalM); 35 buffer.writeBool(hasLocalM);
40 if (hasLocalM) { 36 if (hasLocalM) {
41 buffer.writeMatrix(fLocalMatrix); 37 buffer.writeMatrix(fLocalMatrix);
42 } 38 }
43 } 39 }
44 40
45 bool SkShader::setContext(const SkBitmap& device, 41 bool SkShader::computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInvers e) const {
46 const SkPaint& paint,
47 const SkMatrix& matrix) {
48 SkASSERT(!this->setContextHasBeenCalled());
49
50 const SkMatrix* m = &matrix; 42 const SkMatrix* m = &matrix;
51 SkMatrix total; 43 SkMatrix total;
52 44
53 fPaintAlpha = paint.getAlpha();
54 if (this->hasLocalMatrix()) { 45 if (this->hasLocalMatrix()) {
55 total.setConcat(matrix, this->getLocalMatrix()); 46 total.setConcat(matrix, this->getLocalMatrix());
56 m = &total; 47 m = &total;
57 } 48 }
58 if (m->invert(&fTotalInverse)) { 49
59 fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 50 return m->invert(totalInverse);
60 SkDEBUGCODE(fInSetContext = true;)
61 return true;
62 }
63 return false;
64 } 51 }
65 52
66 void SkShader::endContext() { 53 bool SkShader::validContext(const SkBitmap& device,
67 SkASSERT(fInSetContext); 54 const SkPaint& paint,
68 SkDEBUGCODE(fInSetContext = false;) 55 const SkMatrix& matrix,
56 SkMatrix* totalInverse) const {
57 return this->computeTotalInverse(matrix, totalInverse);
69 } 58 }
70 59
71 SkShader::ShadeProc SkShader::asAShadeProc(void** ctx) { 60 SkShader::Context::Context(const SkShader& shader, const SkBitmap& device,
61 const SkPaint& paint, const SkMatrix& matrix)
62 : fShader(shader)
63 {
64 SkASSERT(fShader.validContext(device, paint, matrix));
65
66 // Because the context parameters must be valid at this point, we know that the matrix is
67 // invertible.
68 SkAssertResult(fShader.computeTotalInverse(matrix, &fTotalInverse));
69 fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
70
71 fPaintAlpha = paint.getAlpha();
72 }
73
74 SkShader::Context::~Context() {}
75
76 SkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) {
72 return NULL; 77 return NULL;
73 } 78 }
74 79
75 #include "SkColorPriv.h" 80 #include "SkColorPriv.h"
76 81
77 void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 82 void SkShader::Context::shadeSpan16(int x, int y, uint16_t span16[], int count) {
78 SkASSERT(span16); 83 SkASSERT(span16);
79 SkASSERT(count > 0); 84 SkASSERT(count > 0);
80 SkASSERT(this->canCallShadeSpan16()); 85 SkASSERT(this->canCallShadeSpan16());
81 86
82 // basically, if we get here, the subclass screwed up 87 // basically, if we get here, the subclass screwed up
83 SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 88 SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented");
84 } 89 }
85 90
86 #define kTempColorQuadCount 6 // balance between speed (larger) and saving sta ck-space 91 #define kTempColorQuadCount 6 // balance between speed (larger) and saving sta ck-space
87 #define kTempColorCount (kTempColorQuadCount << 2) 92 #define kTempColorCount (kTempColorQuadCount << 2)
88 93
89 #ifdef SK_CPU_BENDIAN 94 #ifdef SK_CPU_BENDIAN
90 #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 95 #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3))
91 #else 96 #else
92 #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 97 #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3)
93 #endif 98 #endif
94 99
95 void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 100 void SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
96 SkASSERT(count > 0); 101 SkASSERT(count > 0);
97 102
98 SkPMColor colors[kTempColorCount]; 103 SkPMColor colors[kTempColorCount];
99 104
100 while ((count -= kTempColorCount) >= 0) { 105 while ((count -= kTempColorCount) >= 0) {
101 this->shadeSpan(x, y, colors, kTempColorCount); 106 this->shadeSpan(x, y, colors, kTempColorCount);
102 x += kTempColorCount; 107 x += kTempColorCount;
103 108
104 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT); 109 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT);
105 int quads = kTempColorQuadCount; 110 int quads = kTempColorQuadCount;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 144
140 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT); 145 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT);
141 do { 146 do {
142 *alpha++ = *srcA; 147 *alpha++ = *srcA;
143 srcA += 4; 148 srcA += 4;
144 } while (--n != 0); 149 } while (--n != 0);
145 } while (count > 0); 150 } while (count > 0);
146 #endif 151 #endif
147 } 152 }
148 153
149 SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 154 SkShader::Context::MatrixClass
155 SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) {
150 MatrixClass mc = kLinear_MatrixClass; 156 MatrixClass mc = kLinear_MatrixClass;
151 157
152 if (mat.hasPerspective()) { 158 if (mat.hasPerspective()) {
153 if (mat.fixedStepInX(0, NULL, NULL)) { 159 if (mat.fixedStepInX(0, NULL, NULL)) {
154 mc = kFixedStepInX_MatrixClass; 160 mc = kFixedStepInX_MatrixClass;
155 } else { 161 } else {
156 mc = kPerspective_MatrixClass; 162 mc = kPerspective_MatrixClass;
157 } 163 }
158 } 164 }
159 return mc; 165 return mc;
160 } 166 }
161 167
162 ////////////////////////////////////////////////////////////////////////////// 168 //////////////////////////////////////////////////////////////////////////////
163 169
164 SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 170 SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) const {
165 TileMode*) const {
166 return kNone_BitmapType; 171 return kNone_BitmapType;
167 } 172 }
168 173
169 SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 174 SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
170 return kNone_GradientType; 175 return kNone_GradientType;
171 } 176 }
172 177
173 GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { 178 GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const {
174 return NULL; 179 return NULL;
175 } 180 }
(...skipping 10 matching lines...) Expand all
186 this->getLocalMatrix().toString(str); 191 this->getLocalMatrix().toString(str);
187 } 192 }
188 } 193 }
189 #endif 194 #endif
190 195
191 ////////////////////////////////////////////////////////////////////////////// 196 //////////////////////////////////////////////////////////////////////////////
192 197
193 #include "SkColorShader.h" 198 #include "SkColorShader.h"
194 #include "SkUtils.h" 199 #include "SkUtils.h"
195 200
196 SkColorShader::SkColorShader() { 201 SkColorShader::SkColorShader()
197 fFlags = 0; 202 : fColor()
198 fInheritColor = true; 203 , fInheritColor(true) {
199 } 204 }
200 205
201 SkColorShader::SkColorShader(SkColor c) { 206 SkColorShader::SkColorShader(SkColor c)
202 fFlags = 0; 207 : fColor(c)
203 fColor = c; 208 , fInheritColor(false) {
204 fInheritColor = false;
205 } 209 }
206 210
207 SkColorShader::~SkColorShader() {}
208
209 bool SkColorShader::isOpaque() const { 211 bool SkColorShader::isOpaque() const {
210 if (fInheritColor) { 212 if (fInheritColor) {
211 return true; // using paint's alpha 213 return true; // using paint's alpha
212 } 214 }
213 return SkColorGetA(fColor) == 255; 215 return SkColorGetA(fColor) == 255;
214 } 216 }
215 217
216 SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 218 SkFlattenable* SkColorShader::CreateProc(SkReadBuffer& b) {
217 fFlags = 0; // computed in setContext 219 if (b.readBool()) {
218 220 return SkNEW(SkColorShader);
219 fInheritColor = b.readBool();
220 if (fInheritColor) {
221 return;
222 } 221 }
223 fColor = b.readColor(); 222 return SkNEW_ARGS(SkColorShader, (b.readColor()));
224 } 223 }
225 224
226 void SkColorShader::flatten(SkWriteBuffer& buffer) const { 225 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
227 this->INHERITED::flatten(buffer); 226 this->INHERITED::flatten(buffer);
228 buffer.writeBool(fInheritColor); 227 buffer.writeBool(fInheritColor);
229 if (fInheritColor) { 228 if (fInheritColor) {
230 return; 229 return;
231 } 230 }
232 buffer.writeColor(fColor); 231 buffer.writeColor(fColor);
233 } 232 }
234 233
235 uint32_t SkColorShader::getFlags() { 234 uint32_t SkColorShader::ColorShaderContext::getFlags() const {
236 return fFlags; 235 return fFlags;
237 } 236 }
238 237
239 uint8_t SkColorShader::getSpan16Alpha() const { 238 uint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const {
240 return SkGetPackedA32(fPMColor); 239 return SkGetPackedA32(fPMColor);
241 } 240 }
242 241
243 bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 242 SkShader::Context* SkColorShader::createContext(const SkBitmap& device, const Sk Paint& paint,
244 const SkMatrix& matrix) { 243 const SkMatrix& matrix, void* st orage) const {
245 if (!this->INHERITED::setContext(device, paint, matrix)) { 244 if (!this->validContext(device, paint, matrix)) {
246 return false; 245 return NULL;
247 } 246 }
248 247
248 return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, device, pai nt, matrix));
249 }
250
251 SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shade r,
252 const SkBitmap& device,
253 const SkPaint& paint,
254 const SkMatrix& matrix)
255 : INHERITED(shader, device, paint, matrix)
256 {
249 unsigned a; 257 unsigned a;
250 258
251 if (fInheritColor) { 259 SkColor color;
252 fColor = paint.getColor(); 260 if (shader.fInheritColor) {
253 a = SkColorGetA(fColor); 261 color = paint.getColor();
262 a = SkColorGetA(color);
254 } else { 263 } else {
255 a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha())); 264 color = shader.fColor;
265 a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(paint.getAlpha()));
256 } 266 }
257 267
258 unsigned r = SkColorGetR(fColor); 268 unsigned r = SkColorGetR(color);
259 unsigned g = SkColorGetG(fColor); 269 unsigned g = SkColorGetG(color);
260 unsigned b = SkColorGetB(fColor); 270 unsigned b = SkColorGetB(color);
261 271
262 // we want this before we apply any alpha 272 // we want this before we apply any alpha
263 fColor16 = SkPack888ToRGB16(r, g, b); 273 fColor16 = SkPack888ToRGB16(r, g, b);
264 274
265 if (a != 255) { 275 if (a != 255) {
266 r = SkMulDiv255Round(r, a); 276 r = SkMulDiv255Round(r, a);
267 g = SkMulDiv255Round(g, a); 277 g = SkMulDiv255Round(g, a);
268 b = SkMulDiv255Round(b, a); 278 b = SkMulDiv255Round(b, a);
269 } 279 }
270 fPMColor = SkPackARGB32(a, r, g, b); 280 fPMColor = SkPackARGB32(a, r, g, b);
271 281
272 fFlags = kConstInY32_Flag; 282 fFlags = kConstInY32_Flag;
273 if (255 == a) { 283 if (255 == a) {
274 fFlags |= kOpaqueAlpha_Flag; 284 fFlags |= kOpaqueAlpha_Flag;
275 if (paint.isDither() == false) { 285 if (paint.isDither() == false) {
276 fFlags |= kHasSpan16_Flag; 286 fFlags |= kHasSpan16_Flag;
277 } 287 }
278 } 288 }
279
280 return true;
281 } 289 }
282 290
283 void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 291 void SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[] , int count) {
284 sk_memset32(span, fPMColor, count); 292 sk_memset32(span, fPMColor, count);
285 } 293 }
286 294
287 void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 295 void SkColorShader::ColorShaderContext::shadeSpan16(int x, int y, uint16_t span[ ], int count) {
288 sk_memset16(span, fColor16, count); 296 sk_memset16(span, fColor16, count);
289 } 297 }
290 298
291 void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 299 void SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alp ha[], int count) {
292 memset(alpha, SkGetPackedA32(fPMColor), count); 300 memset(alpha, SkGetPackedA32(fPMColor), count);
293 } 301 }
294 302
295 // if we had a asAColor method, that would be more efficient... 303 // if we had a asAColor method, that would be more efficient...
296 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix , 304 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix ,
297 TileMode modes[]) const { 305 TileMode modes[]) const {
298 return kNone_BitmapType; 306 return kNone_BitmapType;
299 } 307 }
300 308
301 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 309 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
(...skipping 21 matching lines...) Expand all
323 this->INHERITED::toString(str); 331 this->INHERITED::toString(str);
324 332
325 str->append(")"); 333 str->append(")");
326 } 334 }
327 #endif 335 #endif
328 336
329 /////////////////////////////////////////////////////////////////////////////// 337 ///////////////////////////////////////////////////////////////////////////////
330 338
331 #include "SkEmptyShader.h" 339 #include "SkEmptyShader.h"
332 340
333 uint32_t SkEmptyShader::getFlags() { return 0; }
334 uint8_t SkEmptyShader::getSpan16Alpha() const { return 0; }
335
336 bool SkEmptyShader::setContext(const SkBitmap&, const SkPaint&,
337 const SkMatrix&) { return false; }
338
339 void SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) {
340 SkDEBUGFAIL("should never get called, since setContext() returned false");
341 }
342
343 void SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) {
344 SkDEBUGFAIL("should never get called, since setContext() returned false");
345 }
346
347 void SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
348 SkDEBUGFAIL("should never get called, since setContext() returned false");
349 }
350
351 #ifdef SK_DEVELOPER 341 #ifdef SK_DEVELOPER
352 void SkEmptyShader::toString(SkString* str) const { 342 void SkEmptyShader::toString(SkString* str) const {
353 str->append("SkEmptyShader: ("); 343 str->append("SkEmptyShader: (");
354 344
355 this->INHERITED::toString(str); 345 this->INHERITED::toString(str);
356 346
357 str->append(")"); 347 str->append(")");
358 } 348 }
359 #endif 349 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698