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

Side by Side Diff: src/core/SkShader.cpp

Issue 198193005: Work (in progress) to make SkShader immutable. (Closed) Base URL: https://skia.googlesource.com/skia.git@shaderGenerator
Patch Set: 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
« no previous file with comments | « src/core/SkCoreBlitters.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 SkShaderGenerator::SkShaderGenerator() {
17 fLocalMatrix.reset(); 17 fLocalMatrix.reset();
18 SkDEBUGCODE(fInSetContext = false;)
19 } 18 }
20 19
21 SkShader::SkShader(SkReadBuffer& buffer) 20 SkShaderGenerator::SkShaderGenerator(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 SkShaderGenerator::~SkShaderGenerator() {
33 SkASSERT(!fInSetContext);
34 } 30 }
35 31
36 void SkShader::flatten(SkWriteBuffer& buffer) const { 32 void SkShaderGenerator::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 SkShaderGenerator::validContext(const SkBitmap& device,
46 const SkPaint& paint, 42 const SkPaint& paint,
47 const SkMatrix& matrix) { 43 const SkMatrix& matrix) const
48 SkASSERT(!this->setContextHasBeenCalled()); 44 {
49
50 const SkMatrix* m = &matrix; 45 const SkMatrix* m = &matrix;
51 SkMatrix total; 46 SkMatrix total;
52 47
53 fPaintAlpha = paint.getAlpha();
54 if (this->hasLocalMatrix()) { 48 if (this->hasLocalMatrix()) {
55 total.setConcat(matrix, this->getLocalMatrix()); 49 total.setConcat(matrix, this->getLocalMatrix());
56 m = &total; 50 m = &total;
57 } 51 }
58 if (m->invert(&fTotalInverse)) { 52 if (m->invert(&fTotalInverse)) {
59 fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 53 fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
Dominik Grewe 2014/03/14 16:00:40 These variables should be temporary rather than me
scroggo 2014/03/17 15:11:56 Oh yes, of course.
60 SkDEBUGCODE(fInSetContext = true;)
61 return true; 54 return true;
62 } 55 }
63 return false; 56 return false;
64 } 57 }
65 58
66 void SkShader::endContext() { 59 SkShaderGenerator::ShaderImpl::ShaderImpl(
67 SkASSERT(fInSetContext); 60 const SkShaderGenerator& shader, const SkBitmap& unused,
68 SkDEBUGCODE(fInSetContext = false;) 61 const SkPaint& paint const SkMatrix& matrix)
62 : fShader(shader)
63 {
64 SkASSERT(fShader.validContext(device, paint, matrix));
65
66 const SkMatrix* m = &matrix;
67 SkMatrix total;
68
69 fPaintAlpha = paint.getAlpha();
70 if (fShader.hasLocalMatrix()) {
71 total.setConcat(matrix, fShader.getLocalMatrix());
72 m = &total;
73 }
74 // If this fails, SkShaderGenerator::validContext was not called.
75 SkAssertResult(m->invert(&fTotalInverse));
76 fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse);
69 } 77 }
70 78
71 SkShader::ShadeProc SkShader::asAShadeProc(void** ctx) { 79 SkShaderGenerator::ShadeProc SkShaderGenerator::asAShadeProc(void** ctx) {
72 return NULL; 80 return NULL;
73 } 81 }
74 82
75 #include "SkColorPriv.h" 83 #include "SkColorPriv.h"
76 84
77 void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 85 void ShaderImpl::shadeSpan16(int x, int y, uint16_t span16[], int count) {
78 SkASSERT(span16); 86 SkASSERT(span16);
79 SkASSERT(count > 0); 87 SkASSERT(count > 0);
80 SkASSERT(this->canCallShadeSpan16()); 88 SkASSERT(this->canCallShadeSpan16());
81 89
82 // basically, if we get here, the subclass screwed up 90 // basically, if we get here, the subclass screwed up
83 SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 91 SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented");
84 } 92 }
85 93
86 #define kTempColorQuadCount 6 // balance between speed (larger) and saving sta ck-space 94 #define kTempColorQuadCount 6 // balance between speed (larger) and saving sta ck-space
87 #define kTempColorCount (kTempColorQuadCount << 2) 95 #define kTempColorCount (kTempColorQuadCount << 2)
88 96
89 #ifdef SK_CPU_BENDIAN 97 #ifdef SK_CPU_BENDIAN
90 #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 98 #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3))
91 #else 99 #else
92 #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 100 #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3)
93 #endif 101 #endif
94 102
95 void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 103 void ShaderImpl::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
96 SkASSERT(count > 0); 104 SkASSERT(count > 0);
97 105
98 SkPMColor colors[kTempColorCount]; 106 SkPMColor colors[kTempColorCount];
99 107
100 while ((count -= kTempColorCount) >= 0) { 108 while ((count -= kTempColorCount) >= 0) {
101 this->shadeSpan(x, y, colors, kTempColorCount); 109 this->shadeSpan(x, y, colors, kTempColorCount);
102 x += kTempColorCount; 110 x += kTempColorCount;
103 111
104 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT); 112 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT);
105 int quads = kTempColorQuadCount; 113 int quads = kTempColorQuadCount;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 147
140 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT); 148 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset (SK_A32_SHIFT);
141 do { 149 do {
142 *alpha++ = *srcA; 150 *alpha++ = *srcA;
143 srcA += 4; 151 srcA += 4;
144 } while (--n != 0); 152 } while (--n != 0);
145 } while (count > 0); 153 } while (count > 0);
146 #endif 154 #endif
147 } 155 }
148 156
149 SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 157 SkShaderGenerator::ShaderImpl::MatrixClass
158 SkShaderGenerator::ShaderImpl::ComputeMatrixClass(const SkMatrix& mat) {
150 MatrixClass mc = kLinear_MatrixClass; 159 MatrixClass mc = kLinear_MatrixClass;
151 160
152 if (mat.hasPerspective()) { 161 if (mat.hasPerspective()) {
153 if (mat.fixedStepInX(0, NULL, NULL)) { 162 if (mat.fixedStepInX(0, NULL, NULL)) {
154 mc = kFixedStepInX_MatrixClass; 163 mc = kFixedStepInX_MatrixClass;
155 } else { 164 } else {
156 mc = kPerspective_MatrixClass; 165 mc = kPerspective_MatrixClass;
157 } 166 }
158 } 167 }
159 return mc; 168 return mc;
160 } 169 }
161 170
162 ////////////////////////////////////////////////////////////////////////////// 171 //////////////////////////////////////////////////////////////////////////////
163 172
164 SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 173 SkShaderGenerator::BitmapType SkShaderGenerator::asABitmap(SkBitmap*, SkMatrix*,
165 TileMode*) const { 174 TileMode*) const {
166 return kNone_BitmapType; 175 return kNone_BitmapType;
167 } 176 }
168 177
169 SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 178 SkShaderGenerator::GradientType SkShaderGenerator::asAGradient(GradientInfo* inf o) const {
170 return kNone_GradientType; 179 return kNone_GradientType;
171 } 180 }
172 181
173 GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { 182 GrEffectRef* SkShaderGenerator::asNewEffect(GrContext*, const SkPaint&) const {
174 return NULL; 183 return NULL;
175 } 184 }
176 185
177 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 186 SkShaderGenerator* SkShaderGenerator::CreateBitmapShader(const SkBitmap& src,
178 TileMode tmx, TileMode tmy) { 187 TileMode tmx, TileMode tmy) {
179 return ::CreateBitmapShader(src, tmx, tmy, NULL); 188 return ::CreateBitmapShader(src, tmx, tmy, NULL);
180 } 189 }
181 190
182 #ifdef SK_DEVELOPER 191 #ifdef SK_DEVELOPER
183 void SkShader::toString(SkString* str) const { 192 void SkShaderGenerator::toString(SkString* str) const {
184 if (this->hasLocalMatrix()) { 193 if (this->hasLocalMatrix()) {
185 str->append(" "); 194 str->append(" ");
186 this->getLocalMatrix().toString(str); 195 this->getLocalMatrix().toString(str);
187 } 196 }
188 } 197 }
189 #endif 198 #endif
190 199
191 ////////////////////////////////////////////////////////////////////////////// 200 //////////////////////////////////////////////////////////////////////////////
192 201
193 #include "SkColorShader.h" 202 #include "SkColorShader.h"
194 #include "SkUtils.h" 203 #include "SkUtils.h"
195 204
196 SkColorShader::SkColorShader() { 205 SkColorShader::SkColorShader()
197 fFlags = 0; 206 : fColor()
198 fInheritColor = true; 207 , fInheritColor(true) {
199 } 208 }
200 209
201 SkColorShader::SkColorShader(SkColor c) { 210 SkColorShader::SkColorShader(SkColor c)
202 fFlags = 0; 211 : fColor(c)
203 fColor = c; 212 , fInheritColor(false) {
204 fInheritColor = false;
205 } 213 }
206 214
207 SkColorShader::~SkColorShader() {}
208
209 bool SkColorShader::isOpaque() const { 215 bool SkColorShader::isOpaque() const {
210 if (fInheritColor) { 216 if (fInheritColor) {
211 return true; // using paint's alpha 217 return true; // using paint's alpha
212 } 218 }
213 return SkColorGetA(fColor) == 255; 219 return SkColorGetA(fColor) == 255;
214 } 220 }
215 221
216 SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 222 SkColorShader* SkColorShader::CreateProc(SkReadBuffer& b) {
217 fFlags = 0; // computed in setContext 223 if (b.readBool()) {
218 224 return SkNEW(SkColorShader);
219 fInheritColor = b.readBool();
220 if (fInheritColor) {
221 return;
222 } 225 }
223 fColor = b.readColor(); 226 return SkNEW_ARGS(SkColorShader, (b.readColor()));
224 } 227 }
225 228
226 void SkColorShader::flatten(SkWriteBuffer& buffer) const { 229 void SkColorShader::flatten(SkWriteBuffer& buffer) const {
227 this->INHERITED::flatten(buffer); 230 this->INHERITED::flatten(buffer);
228 buffer.writeBool(fInheritColor); 231 buffer.writeBool(fInheritColor);
229 if (fInheritColor) { 232 if (fInheritColor) {
230 return; 233 return;
231 } 234 }
232 buffer.writeColor(fColor); 235 buffer.writeColor(fColor);
233 } 236 }
234 237
235 uint32_t SkColorShader::getFlags() { 238 uint32_t SkColorShader::CSImpl::getFlags() {
236 return fFlags; 239 return fFlags;
237 } 240 }
238 241
239 uint8_t SkColorShader::getSpan16Alpha() const { 242 uint8_t SkColorShader::CSImpl::getSpan16Alpha() const {
240 return SkGetPackedA32(fPMColor); 243 return SkGetPackedA32(fPMColor);
241 } 244 }
242 245
243 bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 246 SkColorShader::CSImpl* SkColorShader::createShaderImpl(const SkBitmap& device,
244 const SkMatrix& matrix) { 247 const SkPaint& paint,
245 if (!this->INHERITED::setContext(device, paint, matrix)) { 248 const SkMatrix& matrix,
246 return false; 249 void* storage) const
250 {
251 SkASSERT(this->contextValid(device, paint, matrix));
Dominik Grewe 2014/03/14 16:00:40 Could we just call validContext() here and return
scroggo 2014/03/17 15:11:56 The problem with that is that SkSmallAllocator has
Dominik Grewe 2014/03/17 16:07:07 Good point. Not sure which way is best. If we have
252
253 return SkNEW_ARGS(SkColorShader::CSImpl, (*this, device, paint, matrix));
254 }
255
256 SkColorShader::CSImpl::CSImpl(const SkColorShader& shader, const SkBitmap& devic e,
257 const SkPaint& paint, const SkMatrix& matrix)
258 : INHERITED(shader, device, paint, matrix)
259 {
260 unsigned a;
261
262 SkColor color
263 if (shader.fInheritColor) {
264 color = paint.getColor();
265 a = SkColorGetA(color);
266 } else {
267 color = shader.fColor;
268 a = SkAlphaMul(SkColorGetA(color), SkAlpha255To256(paint.getAlpha()));
247 } 269 }
248 270
249 unsigned a; 271 unsigned r = SkColorGetR(color);
250 272 unsigned g = SkColorGetG(color);
251 if (fInheritColor) { 273 unsigned b = SkColorGetB(cnolor);
252 fColor = paint.getColor();
253 a = SkColorGetA(fColor);
254 } else {
255 a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha()));
256 }
257
258 unsigned r = SkColorGetR(fColor);
259 unsigned g = SkColorGetG(fColor);
260 unsigned b = SkColorGetB(fColor);
261 274
262 // we want this before we apply any alpha 275 // we want this before we apply any alpha
263 fColor16 = SkPack888ToRGB16(r, g, b); 276 fColor16 = SkPack888ToRGB16(r, g, b);
264 277
265 if (a != 255) { 278 if (a != 255) {
266 r = SkMulDiv255Round(r, a); 279 r = SkMulDiv255Round(r, a);
267 g = SkMulDiv255Round(g, a); 280 g = SkMulDiv255Round(g, a);
268 b = SkMulDiv255Round(b, a); 281 b = SkMulDiv255Round(b, a);
269 } 282 }
270 fPMColor = SkPackARGB32(a, r, g, b); 283 fPMColor = SkPackARGB32(a, r, g, b);
271 284
272 fFlags = kConstInY32_Flag; 285 fFlags = kConstInY32_Flag;
273 if (255 == a) { 286 if (255 == a) {
274 fFlags |= kOpaqueAlpha_Flag; 287 fFlags |= kOpaqueAlpha_Flag;
275 if (paint.isDither() == false) { 288 if (paint.isDither() == false) {
276 fFlags |= kHasSpan16_Flag; 289 fFlags |= kHasSpan16_Flag;
277 } 290 }
278 } 291 }
279 292
280 return true; 293 return true;
281 } 294 }
282 295
283 void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 296 void SkColorShader::CSImpl::shadeSpan(int x, int y, SkPMColor span[], int count) {
284 sk_memset32(span, fPMColor, count); 297 sk_memset32(span, fPMColor, count);
285 } 298 }
286 299
287 void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 300 void SkColorShader::CSImpl::shadeSpan16(int x, int y, uint16_t span[], int count ) {
288 sk_memset16(span, fColor16, count); 301 sk_memset16(span, fColor16, count);
289 } 302 }
290 303
291 void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 304 void SkColorShader::CSImpl::shadeSpanAlpha(int x, int y, uint8_t alpha[], int co unt) {
292 memset(alpha, SkGetPackedA32(fPMColor), count); 305 memset(alpha, SkGetPackedA32(fPMColor), count);
293 } 306 }
294 307
295 // if we had a asAColor method, that would be more efficient... 308 // if we had a asAColor method, that would be more efficient...
296 SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix , 309 SkShaderGenerator::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatri x* matrix,
297 TileMode modes[]) const { 310 TileMode modes[]) const {
298 return kNone_BitmapType; 311 return kNone_BitmapType;
299 } 312 }
300 313
301 SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 314 SkShaderGenerator::GradientType SkColorShader::asAGradient(GradientInfo* info) c onst {
302 if (info) { 315 if (info) {
303 if (info->fColors && info->fColorCount >= 1) { 316 if (info->fColors && info->fColorCount >= 1) {
304 info->fColors[0] = fColor; 317 info->fColors[0] = fColor;
305 } 318 }
306 info->fColorCount = 1; 319 info->fColorCount = 1;
307 info->fTileMode = SkShader::kRepeat_TileMode; 320 info->fTileMode = SkShaderGenerator::kRepeat_TileMode;
308 } 321 }
309 return kColor_GradientType; 322 return kColor_GradientType;
310 } 323 }
311 324
312 #ifdef SK_DEVELOPER 325 #ifdef SK_DEVELOPER
313 void SkColorShader::toString(SkString* str) const { 326 void SkColorShader::toString(SkString* str) const {
314 str->append("SkColorShader: ("); 327 str->append("SkColorShader: (");
315 328
316 if (fInheritColor) { 329 if (fInheritColor) {
317 str->append("Color: inherited from paint"); 330 str->append("Color: inherited from paint");
318 } else { 331 } else {
319 str->append("Color: "); 332 str->append("Color: ");
320 str->appendHex(fColor); 333 str->appendHex(fColor);
321 } 334 }
322 335
323 this->INHERITED::toString(str); 336 this->INHERITED::toString(str);
324 337
325 str->append(")"); 338 str->append(")");
326 } 339 }
327 #endif 340 #endif
328 341
329 /////////////////////////////////////////////////////////////////////////////// 342 ///////////////////////////////////////////////////////////////////////////////
330 343
331 #include "SkEmptyShader.h" 344 #include "SkEmptyShader.h"
332 345
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 346 #ifdef SK_DEVELOPER
352 void SkEmptyShader::toString(SkString* str) const { 347 void SkEmptyShader::toString(SkString* str) const {
353 str->append("SkEmptyShader: ("); 348 str->append("SkEmptyShader: (");
354 349
355 this->INHERITED::toString(str); 350 this->INHERITED::toString(str);
356 351
357 str->append(")"); 352 str->append(")");
358 } 353 }
359 #endif 354 #endif
OLDNEW
« no previous file with comments | « src/core/SkCoreBlitters.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698