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

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

Powered by Google App Engine
This is Rietveld 408576698