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

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

Powered by Google App Engine
This is Rietveld 408576698