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 fTileModeX = (uint8_t)tmx; | 37 fState.fTileModeX = (uint8_t)tmx; |
38 fTileModeY = (uint8_t)tmy; | 38 fState.fTileModeY = (uint8_t)tmy; |
| 39 fFlags = 0; // computed in setContext |
39 } | 40 } |
40 | 41 |
41 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) | 42 SkBitmapProcShader::SkBitmapProcShader(SkReadBuffer& buffer) |
42 : INHERITED(buffer) { | 43 : INHERITED(buffer) { |
43 buffer.readBitmap(&fRawBitmap); | 44 buffer.readBitmap(&fRawBitmap); |
44 fRawBitmap.setImmutable(); | 45 fRawBitmap.setImmutable(); |
45 fTileModeX = buffer.readUInt(); | 46 fState.fTileModeX = buffer.readUInt(); |
46 fTileModeY = buffer.readUInt(); | 47 fState.fTileModeY = buffer.readUInt(); |
| 48 fFlags = 0; // computed in setContext |
47 } | 49 } |
48 | 50 |
49 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, | 51 SkShader::BitmapType SkBitmapProcShader::asABitmap(SkBitmap* texture, |
50 SkMatrix* texM, | 52 SkMatrix* texM, |
51 TileMode xy[]) const { | 53 TileMode xy[]) const { |
52 if (texture) { | 54 if (texture) { |
53 *texture = fRawBitmap; | 55 *texture = fRawBitmap; |
54 } | 56 } |
55 if (texM) { | 57 if (texM) { |
56 texM->reset(); | 58 texM->reset(); |
57 } | 59 } |
58 if (xy) { | 60 if (xy) { |
59 xy[0] = (TileMode)fTileModeX; | 61 xy[0] = (TileMode)fState.fTileModeX; |
60 xy[1] = (TileMode)fTileModeY; | 62 xy[1] = (TileMode)fState.fTileModeY; |
61 } | 63 } |
62 return kDefault_BitmapType; | 64 return kDefault_BitmapType; |
63 } | 65 } |
64 | 66 |
65 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { | 67 void SkBitmapProcShader::flatten(SkWriteBuffer& buffer) const { |
66 this->INHERITED::flatten(buffer); | 68 this->INHERITED::flatten(buffer); |
67 | 69 |
68 buffer.writeBitmap(fRawBitmap); | 70 buffer.writeBitmap(fRawBitmap); |
69 buffer.writeUInt(fTileModeX); | 71 buffer.writeUInt(fState.fTileModeX); |
70 buffer.writeUInt(fTileModeY); | 72 buffer.writeUInt(fState.fTileModeY); |
71 } | 73 } |
72 | 74 |
73 static bool only_scale_and_translate(const SkMatrix& matrix) { | 75 static bool only_scale_and_translate(const SkMatrix& matrix) { |
74 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; | 76 unsigned mask = SkMatrix::kTranslate_Mask | SkMatrix::kScale_Mask; |
75 return (matrix.getType() & ~mask) == 0; | 77 return (matrix.getType() & ~mask) == 0; |
76 } | 78 } |
77 | 79 |
78 bool SkBitmapProcShader::isOpaque() const { | 80 bool SkBitmapProcShader::isOpaque() const { |
79 return fRawBitmap.isOpaque(); | 81 return fRawBitmap.isOpaque(); |
80 } | 82 } |
81 | 83 |
82 static bool valid_for_drawing(const SkBitmap& bm) { | 84 static bool valid_for_drawing(const SkBitmap& bm) { |
83 if (0 == bm.width() || 0 == bm.height()) { | 85 if (0 == bm.width() || 0 == bm.height()) { |
84 return false; // nothing to draw | 86 return false; // nothing to draw |
85 } | 87 } |
86 if (NULL == bm.pixelRef()) { | 88 if (NULL == bm.pixelRef()) { |
87 return false; // no pixels to read | 89 return false; // no pixels to read |
88 } | 90 } |
89 if (kIndex_8_SkColorType == bm.colorType()) { | 91 if (kIndex_8_SkColorType == bm.colorType()) { |
90 // ugh, I have to lock-pixels to inspect the colortable | 92 // ugh, I have to lock-pixels to inspect the colortable |
91 SkAutoLockPixels alp(bm); | 93 SkAutoLockPixels alp(bm); |
92 if (!bm.getColorTable()) { | 94 if (!bm.getColorTable()) { |
93 return false; | 95 return false; |
94 } | 96 } |
95 } | 97 } |
96 return true; | 98 return true; |
97 } | 99 } |
98 | 100 |
99 bool SkBitmapProcShader::validInternal(const SkBitmap& device, | 101 bool SkBitmapProcShader::setContext(const SkBitmap& device, |
100 const SkPaint& paint, | 102 const SkPaint& paint, |
101 const SkMatrix& matrix, | 103 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 // Make sure we can use totalInverse as a cache. | 108 // do this first, so we have a correct inverse matrix |
109 SkMatrix totalInverseLocal; | 109 if (!this->INHERITED::setContext(device, paint, matrix)) { |
110 if (NULL == totalInverse) { | |
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)) { | |
116 return false; | 110 return false; |
117 } | 111 } |
118 | 112 |
119 SkASSERT(state); | 113 fState.fOrigBitmap = fRawBitmap; |
120 state->fTileModeX = fTileModeX; | 114 if (!fState.chooseProcs(this->getTotalInverse(), paint)) { |
121 state->fTileModeY = fTileModeY; | 115 this->INHERITED::endContext(); |
122 state->fOrigBitmap = fRawBitmap; | 116 return false; |
123 return state->chooseProcs(*totalInverse, paint); | |
124 } | |
125 | |
126 bool SkBitmapProcShader::validContext(const SkBitmap& device, | |
127 const SkPaint& paint, | |
128 const SkMatrix& matrix, | |
129 SkMatrix* totalInverse) const { | |
130 SkBitmapProcState state; | |
131 return this->validInternal(device, paint, matrix, totalInverse, &state); | |
132 } | |
133 | |
134 SkShader::Context* SkBitmapProcShader::createContext(const SkBitmap& device, con
st SkPaint& paint, | |
135 const SkMatrix& matrix, voi
d* storage) const { | |
136 void* stateStorage = (char*)storage + sizeof(BitmapProcShaderContext); | |
137 SkBitmapProcState* state = SkNEW_PLACEMENT(stateStorage, SkBitmapProcState); | |
138 if (!this->validInternal(device, paint, matrix, NULL, state)) { | |
139 state->~SkBitmapProcState(); | |
140 return NULL; | |
141 } | 117 } |
142 | 118 |
143 return SkNEW_PLACEMENT_ARGS(storage, BitmapProcShaderContext, | 119 const SkBitmap& bitmap = *fState.fBitmap; |
144 (*this, device, paint, matrix, state)); | |
145 } | |
146 | |
147 size_t SkBitmapProcShader::contextSize() const { | |
148 // The SkBitmapProcState is stored outside of the context object, with the c
ontext holding | |
149 // a pointer to it. | |
150 return sizeof(BitmapProcShaderContext) + sizeof(SkBitmapProcState); | |
151 } | |
152 | |
153 SkBitmapProcShader::BitmapProcShaderContext::BitmapProcShaderContext( | |
154 const SkBitmapProcShader& shader, const SkBitmap& device, | |
155 const SkPaint& paint, const SkMatrix& matrix, SkBitmapProcState* state) | |
156 : INHERITED(shader, device, paint, matrix) | |
157 , fState(state) | |
158 { | |
159 const SkBitmap& bitmap = *fState->fBitmap; | |
160 bool bitmapIsOpaque = bitmap.isOpaque(); | 120 bool bitmapIsOpaque = bitmap.isOpaque(); |
161 | 121 |
162 // update fFlags | 122 // update fFlags |
163 uint32_t flags = 0; | 123 uint32_t flags = 0; |
164 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { | 124 if (bitmapIsOpaque && (255 == this->getPaintAlpha())) { |
165 flags |= kOpaqueAlpha_Flag; | 125 flags |= kOpaqueAlpha_Flag; |
166 } | 126 } |
167 | 127 |
168 switch (bitmap.colorType()) { | 128 switch (bitmap.colorType()) { |
169 case kRGB_565_SkColorType: | 129 case kRGB_565_SkColorType: |
(...skipping 20 matching lines...) Expand all Loading... |
190 // if we're only 1-pixel high, and we don't rotate, then we can claim this | 150 // if we're only 1-pixel high, and we don't rotate, then we can claim this |
191 if (1 == bitmap.height() && | 151 if (1 == bitmap.height() && |
192 only_scale_and_translate(this->getTotalInverse())) { | 152 only_scale_and_translate(this->getTotalInverse())) { |
193 flags |= kConstInY32_Flag; | 153 flags |= kConstInY32_Flag; |
194 if (flags & kHasSpan16_Flag) { | 154 if (flags & kHasSpan16_Flag) { |
195 flags |= kConstInY16_Flag; | 155 flags |= kConstInY16_Flag; |
196 } | 156 } |
197 } | 157 } |
198 | 158 |
199 fFlags = flags; | 159 fFlags = flags; |
| 160 return true; |
200 } | 161 } |
201 | 162 |
202 SkBitmapProcShader::BitmapProcShaderContext::~BitmapProcShaderContext() { | 163 void SkBitmapProcShader::endContext() { |
203 // The bitmap proc state has been created outside of the context on memory t
hat will be freed | 164 fState.endContext(); |
204 // elsewhere. Only call the destructor but leave the freeing of the memory t
o the caller. | 165 this->INHERITED::endContext(); |
205 fState->~SkBitmapProcState(); | |
206 } | 166 } |
207 | 167 |
208 #define BUF_MAX 128 | 168 #define BUF_MAX 128 |
209 | 169 |
210 #define TEST_BUFFER_OVERRITEx | 170 #define TEST_BUFFER_OVERRITEx |
211 | 171 |
212 #ifdef TEST_BUFFER_OVERRITE | 172 #ifdef TEST_BUFFER_OVERRITE |
213 #define TEST_BUFFER_EXTRA 32 | 173 #define TEST_BUFFER_EXTRA 32 |
214 #define TEST_PATTERN 0x88888888 | 174 #define TEST_PATTERN 0x88888888 |
215 #else | 175 #else |
216 #define TEST_BUFFER_EXTRA 0 | 176 #define TEST_BUFFER_EXTRA 0 |
217 #endif | 177 #endif |
218 | 178 |
219 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMCo
lor dstC[], | 179 void SkBitmapProcShader::shadeSpan(int x, int y, SkPMColor dstC[], int count) { |
220 int count) { | 180 const SkBitmapProcState& state = fState; |
221 const SkBitmapProcState& state = *fState; | |
222 if (state.getShaderProc32()) { | 181 if (state.getShaderProc32()) { |
223 state.getShaderProc32()(state, x, y, dstC, count); | 182 state.getShaderProc32()(state, x, y, dstC, count); |
224 return; | 183 return; |
225 } | 184 } |
226 | 185 |
227 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; | 186 uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; |
228 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | 187 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
229 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); | 188 SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); |
230 int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); | 189 int max = fState.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); |
231 | 190 |
232 SkASSERT(state.fBitmap->getPixels()); | 191 SkASSERT(state.fBitmap->getPixels()); |
233 SkASSERT(state.fBitmap->pixelRef() == NULL || | 192 SkASSERT(state.fBitmap->pixelRef() == NULL || |
234 state.fBitmap->pixelRef()->isLocked()); | 193 state.fBitmap->pixelRef()->isLocked()); |
235 | 194 |
236 for (;;) { | 195 for (;;) { |
237 int n = count; | 196 int n = count; |
238 if (n > max) { | 197 if (n > max) { |
239 n = max; | 198 n = max; |
240 } | 199 } |
(...skipping 13 matching lines...) Expand all Loading... |
254 | 213 |
255 if ((count -= n) == 0) { | 214 if ((count -= n) == 0) { |
256 break; | 215 break; |
257 } | 216 } |
258 SkASSERT(count > 0); | 217 SkASSERT(count > 0); |
259 x += n; | 218 x += n; |
260 dstC += n; | 219 dstC += n; |
261 } | 220 } |
262 } | 221 } |
263 | 222 |
264 SkShader::Context::ShadeProc SkBitmapProcShader::BitmapProcShaderContext::asASha
deProc(void** ctx) { | 223 SkShader::ShadeProc SkBitmapProcShader::asAShadeProc(void** ctx) { |
265 if (fState->getShaderProc32()) { | 224 if (fState.getShaderProc32()) { |
266 *ctx = fState; | 225 *ctx = &fState; |
267 return (ShadeProc)fState->getShaderProc32(); | 226 return (ShadeProc)fState.getShaderProc32(); |
268 } | 227 } |
269 return NULL; | 228 return NULL; |
270 } | 229 } |
271 | 230 |
272 void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan16(int x, int y, uint
16_t dstC[], | 231 void SkBitmapProcShader::shadeSpan16(int x, int y, uint16_t dstC[], int count) { |
273 int count) { | 232 const SkBitmapProcState& state = fState; |
274 const SkBitmapProcState& state = *fState; | |
275 if (state.getShaderProc16()) { | 233 if (state.getShaderProc16()) { |
276 state.getShaderProc16()(state, x, y, dstC, count); | 234 state.getShaderProc16()(state, x, y, dstC, count); |
277 return; | 235 return; |
278 } | 236 } |
279 | 237 |
280 uint32_t buffer[BUF_MAX]; | 238 uint32_t buffer[BUF_MAX]; |
281 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); | 239 SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); |
282 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); | 240 SkBitmapProcState::SampleProc16 sproc = state.getSampleProc16(); |
283 int max = state.maxCountForBufferSize(sizeof(buffer)); | 241 int max = fState.maxCountForBufferSize(sizeof(buffer)); |
284 | 242 |
285 SkASSERT(state.fBitmap->getPixels()); | 243 SkASSERT(state.fBitmap->getPixels()); |
286 SkASSERT(state.fBitmap->pixelRef() == NULL || | 244 SkASSERT(state.fBitmap->pixelRef() == NULL || |
287 state.fBitmap->pixelRef()->isLocked()); | 245 state.fBitmap->pixelRef()->isLocked()); |
288 | 246 |
289 for (;;) { | 247 for (;;) { |
290 int n = count; | 248 int n = count; |
291 if (n > max) { | 249 if (n > max) { |
292 n = max; | 250 n = max; |
293 } | 251 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 | 335 |
378 #ifndef SK_IGNORE_TO_STRING | 336 #ifndef SK_IGNORE_TO_STRING |
379 void SkBitmapProcShader::toString(SkString* str) const { | 337 void SkBitmapProcShader::toString(SkString* str) const { |
380 static const char* gTileModeName[SkShader::kTileModeCount] = { | 338 static const char* gTileModeName[SkShader::kTileModeCount] = { |
381 "clamp", "repeat", "mirror" | 339 "clamp", "repeat", "mirror" |
382 }; | 340 }; |
383 | 341 |
384 str->append("BitmapShader: ("); | 342 str->append("BitmapShader: ("); |
385 | 343 |
386 str->appendf("(%s, %s)", | 344 str->appendf("(%s, %s)", |
387 gTileModeName[fTileModeX], | 345 gTileModeName[fState.fTileModeX], |
388 gTileModeName[fTileModeY]); | 346 gTileModeName[fState.fTileModeY]); |
389 | 347 |
390 str->append(" "); | 348 str->append(" "); |
391 fRawBitmap.toString(str); | 349 fRawBitmap.toString(str); |
392 | 350 |
393 this->INHERITED::toString(str); | 351 this->INHERITED::toString(str); |
394 | 352 |
395 str->append(")"); | 353 str->append(")"); |
396 } | 354 } |
397 #endif | 355 #endif |
398 | 356 |
(...skipping 20 matching lines...) Expand all Loading... |
419 SkMatrix matrix; | 377 SkMatrix matrix; |
420 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); | 378 matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); |
421 | 379 |
422 SkMatrix lmInverse; | 380 SkMatrix lmInverse; |
423 if (!this->getLocalMatrix().invert(&lmInverse)) { | 381 if (!this->getLocalMatrix().invert(&lmInverse)) { |
424 return NULL; | 382 return NULL; |
425 } | 383 } |
426 matrix.preConcat(lmInverse); | 384 matrix.preConcat(lmInverse); |
427 | 385 |
428 SkShader::TileMode tm[] = { | 386 SkShader::TileMode tm[] = { |
429 (TileMode)fTileModeX, | 387 (TileMode)fState.fTileModeX, |
430 (TileMode)fTileModeY, | 388 (TileMode)fState.fTileModeY, |
431 }; | 389 }; |
432 | 390 |
433 // Must set wrap and filter on the sampler before requesting a texture. In t
wo places below | 391 // Must set wrap and filter on the sampler before requesting a texture. In t
wo places below |
434 // we check the matrix scale factors to determine how to interpret the filte
r quality setting. | 392 // we check the matrix scale factors to determine how to interpret the filte
r quality setting. |
435 // This completely ignores the complexity of the drawVertices case where exp
licit local coords | 393 // This completely ignores the complexity of the drawVertices case where exp
licit local coords |
436 // are provided by the caller. | 394 // are provided by the caller. |
437 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); | 395 SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); |
438 GrTextureParams::FilterMode textureFilterMode; | 396 GrTextureParams::FilterMode textureFilterMode; |
439 switch(paintFilterLevel) { | 397 switch(paintFilterLevel) { |
440 case SkPaint::kNone_FilterLevel: | 398 case SkPaint::kNone_FilterLevel: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 GrEffectRef* effect = NULL; | 444 GrEffectRef* effect = NULL; |
487 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { | 445 if (paintFilterLevel == SkPaint::kHigh_FilterLevel) { |
488 effect = GrBicubicEffect::Create(texture, matrix, tm); | 446 effect = GrBicubicEffect::Create(texture, matrix, tm); |
489 } else { | 447 } else { |
490 effect = GrSimpleTextureEffect::Create(texture, matrix, params); | 448 effect = GrSimpleTextureEffect::Create(texture, matrix, params); |
491 } | 449 } |
492 GrUnlockAndUnrefCachedBitmapTexture(texture); | 450 GrUnlockAndUnrefCachedBitmapTexture(texture); |
493 return effect; | 451 return effect; |
494 } | 452 } |
495 #endif | 453 #endif |
OLD | NEW |