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

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: rebase & cleanup 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 SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) {
217 fFlags = 0; // computed in setContext
218
219 fInheritColor = b.readBool(); 219 fInheritColor = b.readBool();
220 if (fInheritColor) { 220 if (fInheritColor) {
221 return; 221 return;
222 } 222 }
223 fColor = b.readColor(); 223 fColor = b.readColor();
224 } 224 }
225 225
226 void SkColorShader::flatten(SkWriteBuffer& buffer) const { 226 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
227 this->INHERITED::flatten(buffer); 227 this->INHERITED::flatten(buffer);
228 buffer.writeBool(fInheritColor); 228 buffer.writeBool(fInheritColor);
229 if (fInheritColor) { 229 if (fInheritColor) {
230 return; 230 return;
231 } 231 }
232 buffer.writeColor(fColor); 232 buffer.writeColor(fColor);
233 } 233 }
234 234
235 uint32_t SkColorShader::getFlags() { 235 uint32_t SkColorShader::ColorShaderContext::getFlags() const {
236 return fFlags; 236 return fFlags;
237 } 237 }
238 238
239 uint8_t SkColorShader::getSpan16Alpha() const { 239 uint8_t SkColorShader::ColorShaderContext::getSpan16Alpha() const {
240 return SkGetPackedA32(fPMColor); 240 return SkGetPackedA32(fPMColor);
241 } 241 }
242 242
243 bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 243 SkShader::Context* SkColorShader::createContext(const SkBitmap& device, const Sk Paint& paint,
244 const SkMatrix& matrix) { 244 const SkMatrix& matrix, void* st orage) const {
245 if (!this->INHERITED::setContext(device, paint, matrix)) { 245 if (!this->validContext(device, paint, matrix)) {
246 return false; 246 return NULL;
247 } 247 }
248 248
249 return SkNEW_PLACEMENT_ARGS(storage, ColorShaderContext, (*this, device, pai nt, matrix));
250 }
251
252 SkColorShader::ColorShaderContext::ColorShaderContext(const SkColorShader& shade r,
253 const SkBitmap& device,
254 const SkPaint& paint,
255 const SkMatrix& matrix)
256 : INHERITED(shader, device, paint, matrix)
257 {
249 unsigned a; 258 unsigned a;
250 259
251 if (fInheritColor) { 260 SkColor color;
252 fColor = paint.getColor(); 261 if (shader.fInheritColor) {
253 a = SkColorGetA(fColor); 262 color = paint.getColor();
263 a = SkColorGetA(color);
254 } else { 264 } else {
255 a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha())); 265 color = shader.fColor;
266 a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(paint.getAlpha()));
256 } 267 }
257 268
258 unsigned r = SkColorGetR(fColor); 269 unsigned r = SkColorGetR(color);
259 unsigned g = SkColorGetG(fColor); 270 unsigned g = SkColorGetG(color);
260 unsigned b = SkColorGetB(fColor); 271 unsigned b = SkColorGetB(color);
261 272
262 // we want this before we apply any alpha 273 // we want this before we apply any alpha
263 fColor16 = SkPack888ToRGB16(r, g, b); 274 fColor16 = SkPack888ToRGB16(r, g, b);
264 275
265 if (a != 255) { 276 if (a != 255) {
266 r = SkMulDiv255Round(r, a); 277 r = SkMulDiv255Round(r, a);
267 g = SkMulDiv255Round(g, a); 278 g = SkMulDiv255Round(g, a);
268 b = SkMulDiv255Round(b, a); 279 b = SkMulDiv255Round(b, a);
269 } 280 }
270 fPMColor = SkPackARGB32(a, r, g, b); 281 fPMColor = SkPackARGB32(a, r, g, b);
271 282
272 fFlags = kConstInY32_Flag; 283 fFlags = kConstInY32_Flag;
273 if (255 == a) { 284 if (255 == a) {
274 fFlags |= kOpaqueAlpha_Flag; 285 fFlags |= kOpaqueAlpha_Flag;
275 if (paint.isDither() == false) { 286 if (paint.isDither() == false) {
276 fFlags |= kHasSpan16_Flag; 287 fFlags |= kHasSpan16_Flag;
277 } 288 }
278 } 289 }
279
280 return true;
281 } 290 }
282 291
283 void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 292 void SkColorShader::ColorShaderContext::shadeSpan(int x, int y, SkPMColor span[] , int count) {
284 sk_memset32(span, fPMColor, count); 293 sk_memset32(span, fPMColor, count);
285 } 294 }
286 295
287 void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 296 void SkColorShader::ColorShaderContext::shadeSpan16(int x, int y, uint16_t span[ ], int count) {
288 sk_memset16(span, fColor16, count); 297 sk_memset16(span, fColor16, count);
289 } 298 }
290 299
291 void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 300 void SkColorShader::ColorShaderContext::shadeSpanAlpha(int x, int y, uint8_t alp ha[], int count) {
292 memset(alpha, SkGetPackedA32(fPMColor), count); 301 memset(alpha, SkGetPackedA32(fPMColor), count);
293 } 302 }
294 303
295 // if we had a asAColor method, that would be more efficient... 304 // if we had a asAColor method, that would be more efficient...
296 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix , 305 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix ,
297 TileMode modes[]) const { 306 TileMode modes[]) const {
298 return kNone_BitmapType; 307 return kNone_BitmapType;
299 } 308 }
300 309
301 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 310 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const {
(...skipping 19 matching lines...) Expand all
321 } 330 }
322 331
323 this->INHERITED::toString(str); 332 this->INHERITED::toString(str);
324 333
325 str->append(")"); 334 str->append(")");
326 } 335 }
327 #endif 336 #endif
328 337
329 /////////////////////////////////////////////////////////////////////////////// 338 ///////////////////////////////////////////////////////////////////////////////
330 339
331 #include "SkEmptyShader.h" 340 #include "SkEmptyShader.h"
scroggo 2014/04/03 15:35:54 nit: This could be inside SK_IGNORE_TO_STRING, now
Dominik Grewe 2014/04/04 10:59:41 Done.
332 341
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 #ifndef SK_IGNORE_TO_STRING 342 #ifndef SK_IGNORE_TO_STRING
352 void SkEmptyShader::toString(SkString* str) const { 343 void SkEmptyShader::toString(SkString* str) const {
353 str->append("SkEmptyShader: ("); 344 str->append("SkEmptyShader: (");
354 345
355 this->INHERITED::toString(str); 346 this->INHERITED::toString(str);
356 347
357 str->append(")"); 348 str->append(")");
358 } 349 }
359 #endif 350 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698