OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkColorPriv.h" | 8 #include "SkColorPriv.h" |
9 #include "SkReadBuffer.h" | 9 #include "SkReadBuffer.h" |
10 #include "SkWriteBuffer.h" | 10 #include "SkWriteBuffer.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
27 return true; | 27 return true; |
28 default: | 28 default: |
29 break; | 29 break; |
30 } | 30 } |
31 return false; | 31 return false; |
32 } | 32 } |
33 | 33 |
34 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, | 34 SkBitmapProcShader::SkBitmapProcShader(const SkBitmap& src, |
35 TileMode tmx, TileMode tmy) { | 35 TileMode tmx, TileMode tmy) { |
36 fRawBitmap = src; | 36 fRawBitmap = src; |
37 fState.fTileModeX = (uint8_t)tmx; | 37 fTileModeX = (uint8_t)tmx; |
38 fState.fTileModeY = (uint8_t)tmy; | 38 fTileModeY = (uint8_t)tmy; |
39 fFlags = 0; // computed in setContext | |
40 } | 39 } |
41 | 40 |
42 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) | 41 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) |
43 : INHERITED(buffer) { | 42 : INHERITED(buffer) { |
44 buffer.readBitmap(&fRawBitmap); | 43 buffer.readBitmap(&fRawBitmap); |
45 fRawBitmap.setImmutable(); | 44 fRawBitmap.setImmutable(); |
46 fState.fTileModeX = buffer.readUInt(); | 45 fTileModeX = buffer.readUInt(); |
47 fState.fTileModeY = buffer.readUInt(); | 46 fTileModeY = buffer.readUInt(); |
48 fFlags = 0; // computed in setContext | |
49 } | 47 } |
50 | 48 |
51 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, | 49 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, |
52 SkMatrix* texM, | 50 SkMatrix* texM, |
53 TileMode xy[]) const { | 51 TileMode xy[]) const { |
54 if (texture) { | 52 if (texture) { |
55 *texture = fRawBitmap; | 53 *texture = fRawBitmap; |
56 } | 54 } |
57 if (texM) { | 55 if (texM) { |
58 texM->reset(); | 56 texM->reset(); |
59 } | 57 } |
60 if (xy) { | 58 if (xy) { |
61 xy[0] = (TileMode)fState.fTileModeX; | 59 xy[0] = (TileMode)fTileModeX; |
62 xy[1] = (TileMode)fState.fTileModeY; | 60 xy[1] = (TileMode)fTileModeY; |
63 } | 61 } |
64 return kDefault_BitmapType; | 62 return kDefault_BitmapType; |
65 } | 63 } |
66 | 64 |
67 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { | 65 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
68 this->INHERITED::flatten(buffer); | 66 this->INHERITED::flatten(buffer); |
69 | 67 |
70 buffer.writeBitmap(fRawBitmap); | 68 buffer.writeBitmap(fRawBitmap); |
71 buffer.writeUInt(fState.fTileModeX); | 69 buffer.writeUInt(fTileModeX); |
72 buffer.writeUInt(fState.fTileModeY); | 70 buffer.writeUInt(fTileModeY); |
73 } | 71 } |
74 | 72 |
75 static bool only_scale_and_translate(const SkMatrix& matrix) { | 73 static bool only_scale_and_translate(const SkMatrix& matrix) { |
76 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; | 74 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
77 return (matrix.getType() & ~mask) == 0; | 75 return (matrix.getType() & ~mask) == 0; |
78 } | 76 } |
79 | 77 |
80 bool SkBitmapProcShader::isOpaque() const { | 78 bool SkBitmapProcShader::isOpaque() const { |
81 return fRawBitmap.isOpaque(); | 79 return fRawBitmap.isOpaque(); |
82 } | 80 } |
83 | 81 |
84 static bool valid_for_drawing(const SkBitmap& bm) { | 82 static bool valid_for_drawing(const SkBitmap& bm) { |
85 if (0 == bm.width() || 0 == bm.height()) { | 83 if (0 == bm.width() || 0 == bm.height()) { |
86 return false; // nothing to draw | 84 return false; // nothing to draw |
87 } | 85 } |
88 if (NULL == bm.pixelRef()) { | 86 if (NULL == bm.pixelRef()) { |
89 return false; // no pixels to read | 87 return false; // no pixels to read |
90 } | 88 } |
91 if (kIndex_8_SkColorType == bm.colorType()) { | 89 if (kIndex_8_SkColorType == bm.colorType()) { |
92 // ugh, I have to lock-pixels to inspect the colortable | 90 // ugh, I have to lock-pixels to inspect the colortable |
93 SkAutoLockPixels alp(bm); | 91 SkAutoLockPixels alp(bm); |
94 if (!bm.getColorTable()) { | 92 if (!bm.getColorTable()) { |
95 return false; | 93 return false; |
96 } | 94 } |
97 } | 95 } |
98 return true; | 96 return true; |
99 } | 97 } |
100 | 98 |
101 bool SkBitmapProcShader::setContext(const SkBitmap& device, | 99 bool SkBitmapProcShader::validInternal(const SkBitmap& device, |
102 const SkPaint& paint, | 100 const SkPaint& paint, |
103 const SkMatrix& matrix) { | 101 const SkMatrix& matrix, |
102 SkMatrix* totalInverse, | |
103 SkBitmapProcState* state) const { | |
104 if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { | 104 if (!fRawBitmap.getTexture() && !valid_for_drawing(fRawBitmap)) { |
105 return false; | 105 return false; |
106 } | 106 } |
107 | 107 |
108 // do this first, so we have a correct inverse matrix | 108 // Make sure we can use totalInverse as a cache. |
109 if (!this->INHERITED::setContext(device, paint, matrix)) { | 109 SkMatrix totalInverseLocal; |
110 if (totalInverse == NULL) { | |
scroggo
2014/03/28 20:50:08
nit: Prefer putting NULL on the left of this check
Dominik Grewe
2014/04/01 10:49:55
Done.
| |
111 totalInverse = &totalInverseLocal; | |
112 } | |
113 | |
114 // Do this first, so we know the matrix can be inverted. | |
115 if (!this->INHERITED::validContext(device, paint, matrix, totalInverse)) { | |
110 return false; | 116 return false; |
111 } | 117 } |
112 | 118 |
113 fState.fOrigBitmap = fRawBitmap; | 119 SkASSERT(state); |
114 if (!fState.chooseProcs(this->getTotalInverse(), paint)) { | 120 state->fTileModeX = fTileModeX; |
115 this->INHERITED::endContext(); | 121 state->fTileModeY = fTileModeY; |
122 state->fOrigBitmap = fRawBitmap; | |
123 if (!state->chooseProcs(*totalInverse, paint)) { | |
scroggo
2014/03/28 20:50:08
return state->chooseProcs(*totalInverse, paint);
Dominik Grewe
2014/04/01 10:49:55
Done.
| |
116 return false; | 124 return false; |
117 } | 125 } |
118 | 126 |
127 return true; | |
128 } | |
129 | |
130 bool SkBitmapProcShader::validContext(const SkBitmap& device, | |
131 const SkPaint& paint, | |
132 const SkMatrix& matrix, | |
133 SkMatrix* totalInverse) const { | |
134 SkBitmapProcState state; | |
135 return this->validInternal(device, paint, matrix, totalInverse, &state); | |
136 } | |
137 | |
138 SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, con st SkPaint& paint, | |
139 const SkMatrix& matrix, voi d* storage) const { | |
140 SkBitmapProcState state; | |
141 if (!this->validInternal(device, paint, matrix, NULL, &state)) { | |
142 return NULL; | |
143 } | |
144 | |
145 return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, (*this, device , paint, matrix, state)); | |
scroggo
2014/03/28 20:50:08
nit: 100 chars.
Dominik Grewe
2014/04/01 10:49:55
Done.
| |
146 } | |
147 | |
148 size_t SkBitmapProcShader::contextSize() const { | |
149 return sizeof(BitmapProcShaderContext); | |
150 } | |
151 | |
152 SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext( | |
153 const SkBitmapProcShader& shader, const SkBitmap& device, | |
154 const SkPaint& paint, const SkMatrix& matrix, const SkBitmapProcState& s tate) | |
155 : INHERITED(shader, device, paint, matrix), fState(state) | |
156 { | |
119 const SkBitmap& bitmap = *fState.fBitmap; | 157 const SkBitmap& bitmap = *fState.fBitmap; |
120 bool bitmapIsOpaque = bitmap.isOpaque(); | 158 bool bitmapIsOpaque = bitmap.isOpaque(); |
121 | 159 |
122 // update fFlags | 160 // update fFlags |
123 uint32_t flags = 0; | 161 uint32_t flags = 0; |
124 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { | 162 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { |
125 flags |= kOpaqueAlpha_Flag; | 163 flags |= kOpaqueAlpha_Flag; |
126 } | 164 } |
127 | 165 |
128 switch (bitmap.colorType()) { | 166 switch (bitmap.colorType()) { |
(...skipping 21 matching lines...) Expand all Loading... | |
150 // if we're only 1-pixel high, and we don't rotate, then we can claim this | 188 // if we're only 1-pixel high, and we don't rotate, then we can claim this |
151 if (1 == bitmap.height() && | 189 if (1 == bitmap.height() && |
152 only_scale_and_translate(this->getTotalInverse())) { | 190 only_scale_and_translate(this->getTotalInverse())) { |
153 flags |= kConstInY32_Flag; | 191 flags |= kConstInY32_Flag; |
154 if (flags & kHasSpan16_Flag) { | 192 if (flags & kHasSpan16_Flag) { |
155 flags |= kConstInY16_Flag; | 193 flags |= kConstInY16_Flag; |
156 } | 194 } |
157 } | 195 } |
158 | 196 |
159 fFlags = flags; | 197 fFlags = flags; |
160 return true; | |
161 } | |
162 | |
163 void SkBitmapProcShader::endContext() { | |
164 fState.endContext(); | |
165 this->INHERITED::endContext(); | |
166 } | 198 } |
167 | 199 |
168 #define BUF_MAX 128 | 200 #define BUF_MAX 128 |
169 | 201 |
170 #define TEST_BUFFER_OVERRITEx | 202 #define TEST_BUFFER_OVERRITEx |
171 | 203 |
172 #ifdef TEST_BUFFER_OVERRITE | 204 #ifdef TEST_BUFFER_OVERRITE |
173 #define TEST_BUFFER_EXTRA 32 | 205 #define TEST_BUFFER_EXTRA 32 |
174 #define TEST_PATTERN 0x88888888 | 206 #define TEST_PATTERN 0x88888888 |
175 #else | 207 #else |
176 #define TEST_BUFFER_EXTRA 0 | 208 #define TEST_BUFFER_EXTRA 0 |
177 #endif | 209 #endif |
178 | 210 |
179 void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { | 211 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMCo lor dstC[], |
212 int count) { | |
180 const SkBitmapProcState& state = fState; | 213 const SkBitmapProcState& state = fState; |
181 if (state.getShaderProc32()) { | 214 if (state.getShaderProc32()) { |
182 state.getShaderProc32()(state, x, y, dstC, count); | 215 state.getShaderProc32()(state, x, y, dstC, count); |
183 return; | 216 return; |
184 } | 217 } |
185 | 218 |
186 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; | 219 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; |
187 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | 220 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
188 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); | 221 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); |
189 int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); | 222 int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); |
(...skipping 23 matching lines...) Expand all Loading... | |
213 | 246 |
214 if ((count -= n) == 0) { | 247 if ((count -= n) == 0) { |
215 break; | 248 break; |
216 } | 249 } |
217 SkASSERT(count > 0); | 250 SkASSERT(count > 0); |
218 x += n; | 251 x += n; |
219 dstC += n; | 252 dstC += n; |
220 } | 253 } |
221 } | 254 } |
222 | 255 |
223 SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { | 256 SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asASha deProc(void** ctx) { |
224 if (fState.getShaderProc32()) { | 257 if (fState.getShaderProc32()) { |
225 *ctx = &fState; | 258 *ctx = &fState; |
226 return (ShadeProc)fState.getShaderProc32(); | 259 return (ShadeProc)fState.getShaderProc32(); |
227 } | 260 } |
228 return NULL; | 261 return NULL; |
229 } | 262 } |
230 | 263 |
231 void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { | 264 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint 16_t dstC[], |
265 int count) { | |
232 const SkBitmapProcState& state = fState; | 266 const SkBitmapProcState& state = fState; |
233 if (state.getShaderProc16()) { | 267 if (state.getShaderProc16()) { |
234 state.getShaderProc16()(state, x, y, dstC, count); | 268 state.getShaderProc16()(state, x, y, dstC, count); |
235 return; | 269 return; |
236 } | 270 } |
237 | 271 |
238 uint32_t buffer[BUF_MAX]; | 272 uint32_t buffer[BUF_MAX]; |
239 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | 273 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
240 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); | 274 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); |
241 int max = fState.maxCountForBufferSize(sizeof(buffer)); | 275 int max = fState.maxCountForBufferSize(sizeof(buffer)); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 | 369 |
336 #ifdef SK_DEVELOPER | 370 #ifdef SK_DEVELOPER |
337 void SkBitmapProcShader::toString(SkString* str) const { | 371 void SkBitmapProcShader::toString(SkString* str) const { |
338 static const char* gTileModeName[SkShader::kTileModeCount] = { | 372 static const char* gTileModeName[SkShader::kTileModeCount] = { |
339 "clamp", "repeat", "mirror" | 373 "clamp", "repeat", "mirror" |
340 }; | 374 }; |
341 | 375 |
342 str->append("BitmapShader: ("); | 376 str->append("BitmapShader: ("); |
343 | 377 |
344 str->appendf("(%s, %s)", | 378 str->appendf("(%s, %s)", |
345 gTileModeName[fState.fTileModeX], | 379 gTileModeName[fTileModeX], |
346 gTileModeName[fState.fTileModeY]); | 380 gTileModeName[fTileModeY]); |
347 | 381 |
348 str->append(" "); | 382 str->append(" "); |
349 fRawBitmap.toString(str); | 383 fRawBitmap.toString(str); |
350 | 384 |
351 this->INHERITED::toString(str); | 385 this->INHERITED::toString(str); |
352 | 386 |
353 str->append(")"); | 387 str->append(")"); |
354 } | 388 } |
355 #endif | 389 #endif |
356 | 390 |
(...skipping 20 matching lines...) Expand all Loading... | |
377 SkMatrix matrix; | 411 SkMatrix matrix; |
378 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); | 412 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); |
379 | 413 |
380 SkMatrix lmInverse; | 414 SkMatrix lmInverse; |
381 if (!this->getLocalMatrix().invert(&lmInverse)) { | 415 if (!this->getLocalMatrix().invert(&lmInverse)) { |
382 return NULL; | 416 return NULL; |
383 } | 417 } |
384 matrix.preConcat(lmInverse); | 418 matrix.preConcat(lmInverse); |
385 | 419 |
386 SkShader::TileMode tm[] = { | 420 SkShader::TileMode tm[] = { |
387 (TileMode)fState.fTileModeX, | 421 (TileMode)fTileModeX, |
388 (TileMode)fState.fTileModeY, | 422 (TileMode)fTileModeY, |
389 }; | 423 }; |
390 | 424 |
391 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below | 425 // Must set wrap and filter on the sampler before requesting a texture. In t wo places below |
392 // we check the matrix scale factors to determine how to interpret the filte r quality setting. | 426 // we check the matrix scale factors to determine how to interpret the filte r quality setting. |
393 // This completely ignores the complexity of the drawVertices case where exp licit local coords | 427 // This completely ignores the complexity of the drawVertices case where exp licit local coords |
394 // are provided by the caller. | 428 // are provided by the caller. |
395 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); | 429 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); |
396 GrTextureParams::FilterMode textureFilterMode; | 430 GrTextureParams::FilterMode textureFilterMode; |
397 switch(paintFilterLevel) { | 431 switch(paintFilterLevel) { |
398 case SkPaint::kNone_FilterLevel: | 432 case SkPaint::kNone_FilterLevel: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 GrEffectRef* effect = NULL; | 478 GrEffectRef* effect = NULL; |
445 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { | 479 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { |
446 effect = GrBicubicEffect::Create(texture, matrix, tm); | 480 effect = GrBicubicEffect::Create(texture, matrix, tm); |
447 } else { | 481 } else { |
448 effect = GrSimpleTextureEffect::Create(texture, matrix, params); | 482 effect = GrSimpleTextureEffect::Create(texture, matrix, params); |
449 } | 483 } |
450 GrUnlockAndUnrefCachedBitmapTexture(texture); | 484 GrUnlockAndUnrefCachedBitmapTexture(texture); |
451 return effect; | 485 return effect; |
452 } | 486 } |
453 #endif | 487 #endif |
OLD | NEW |