OLD | NEW |
| (Empty) |
1 /* Copyright 2006, The Android Open Source Project | |
2 ** | |
3 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
4 ** you may not use this file except in compliance with the License. | |
5 ** You may obtain a copy of the License at | |
6 ** | |
7 ** http://www.apache.org/licenses/LICENSE-2.0 | |
8 ** | |
9 ** Unless required by applicable law or agreed to in writing, software | |
10 ** distributed under the License is distributed on an "AS IS" BASIS, | |
11 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 ** See the License for the specific language governing permissions and | |
13 ** limitations under the License. | |
14 */ | |
15 | |
16 #if 0 | |
17 | |
18 #include "SkBitmapShader.h" | |
19 #include "SkBitmapSampler.h" | |
20 | |
21 #ifdef SK_SUPPORT_MIPMAP | |
22 static SkFixed find_mip_level(SkFixed dx, SkFixed dy) | |
23 { | |
24 dx = SkAbs32(dx); | |
25 dy = SkAbs32(dy); | |
26 if (dx < dy) | |
27 dx = dy; | |
28 | |
29 if (dx < SK_Fixed1) | |
30 return 0; | |
31 | |
32 int clz = SkCLZ(dx); | |
33 SkASSERT(clz >= 1 && clz <= 15); | |
34 return SkIntToFixed(15 - clz) + ((unsigned)(dx << (clz + 1)) >> 16); | |
35 } | |
36 #endif | |
37 | |
38 SkBitmapShader::SkBitmapShader(const SkBitmap& src, bool doFilter, | |
39 TileMode tmx, TileMode tmy) | |
40 : | |
41 #ifdef SK_SUPPORT_MIPMAP | |
42 fMipLevel(0), fMipSrcBitmap(src), | |
43 #endif | |
44 fOrigSrcBitmap(src) | |
45 | |
46 { | |
47 fFilterBitmap = doFilter; | |
48 fTileModeX = SkToU8(tmx); | |
49 fTileModeY = SkToU8(tmy); | |
50 } | |
51 | |
52 SkBitmapShader::SkBitmapShader(SkFlattenableReadBuffer& buffer) : | |
53 INHERITED(buffer) | |
54 { | |
55 Bitmap src; | |
56 buffer.readBitmap(&src); | |
57 #ifdef SK_SUPPORT_MIPMAP | |
58 fMipLevel = 0; | |
59 fMipSrcBitmap = src; | |
60 #endif | |
61 fOrigSrcBitmap = src; | |
62 fFilterBitmap = buffer.readU8(); | |
63 fTileModeX = buffer.readU8(); | |
64 fTileModeY = buffer.readU8(); | |
65 } | |
66 | |
67 void SkBitmapShader::flatten(SkFlattenableWriteBuffer& buffer) | |
68 { | |
69 this->INHERITED::flatten(buffer); | |
70 buffer.writeBitmap(&fOrigSrcBitmap); | |
71 buffer.write8(fFilterBitmap); | |
72 buffer.write8(fTileModeX); | |
73 buffer.write8(fTileModeY); | |
74 } | |
75 | |
76 bool SkBitmapShader::setContext(const SkBitmap& device, const SkPaint& paint, co
nst SkMatrix& matrix) | |
77 { | |
78 // do this first, so we have a correct inverse matrix | |
79 if (!this->INHERITED::setContext(device, paint, matrix)) | |
80 return false; | |
81 | |
82 if (fOrigSrcBitmap.getConfig() == SkBitmap::kNo_Config || | |
83 fOrigSrcBitmap.width() == 0 || | |
84 fOrigSrcBitmap.height() == 0) | |
85 return false; | |
86 | |
87 SkBitmap& bm = fOrigSrcBitmap; | |
88 | |
89 #ifdef SK_SUPPORT_MIPMAP | |
90 if (fOrigSrcBitmap.countMipLevels()) | |
91 { | |
92 const SkMatrix& inv = this->getTotalInverse(); | |
93 | |
94 fMipLevel = SkMin32(find_mip_level( SkScalarToFixed(inv.getScaleX()), | |
95 SkScalarToFixed(inv.getSkewY())), | |
96 SkIntToFixed(fOrigSrcBitmap.countMipLevels() - 1)); | |
97 | |
98 // SkDEBUGF(("BitmapShader miplevel=%x\n", fMipLevel)); | |
99 | |
100 const SkBitmap::MipLevel* mm = fOrigSrcBitmap.getMipLevel(fMipLevel >> 1
6); | |
101 | |
102 fMipSrcBitmap.setConfig(fOrigSrcBitmap.getConfig(), | |
103 mm->fWidth, | |
104 mm->fHeight, | |
105 mm->fRowBytes); | |
106 fMipSrcBitmap.setPixels(mm->fPixels); | |
107 bm = fMipSrcBitmap; | |
108 } | |
109 else | |
110 { | |
111 fMipLevel = 0; | |
112 fMipSrcBitmap = fOrigSrcBitmap; | |
113 } | |
114 #endif | |
115 | |
116 fFlags = 0; | |
117 if (paint.getAlpha() == 255 && bm.isOpaque()) | |
118 fFlags |= kOpaqueAlpha_Flag; | |
119 | |
120 return true; | |
121 } | |
122 | |
123 /////////////////////////////////////////////////////////////////////////// | |
124 | |
125 #include "SkColorPriv.h" | |
126 #include "SkBitmapSampler.h" | |
127 #include "SkPerspIter.h" | |
128 | |
129 class Sampler_BitmapShader : public SkBitmapShader { | |
130 public: | |
131 Sampler_BitmapShader(const SkBitmap& src, bool doFilter, | |
132 TileMode tmx, TileMode tmy) | |
133 : SkBitmapShader(src, doFilter, tmx, tmy) | |
134 { | |
135 // make sure to pass our copy of the src bitmap to the sampler, and not
the | |
136 // original parameter (which might go away). | |
137 fSampler = NULL; | |
138 } | |
139 | |
140 virtual ~Sampler_BitmapShader() | |
141 { | |
142 SkDELETE(fSampler); | |
143 } | |
144 | |
145 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const
SkMatrix& matrix) | |
146 { | |
147 if (this->INHERITED::setContext(device, paint, matrix)) | |
148 { | |
149 SkDELETE(fSampler); | |
150 fSampler = SkBitmapSampler::Create(this->getSrcBitmap(), this->getFi
lterBitmap(), | |
151 this->getTileModeX(), this->getTi
leModeY()); | |
152 fSampler->setPaint(paint); | |
153 return true; | |
154 } | |
155 return false; | |
156 } | |
157 | |
158 enum { | |
159 kMaxPointStorageCount = 32 | |
160 }; | |
161 | |
162 virtual void shadeSpan(int x, int y, SkPMColor dstC[], int count) | |
163 { | |
164 unsigned scale = SkAlpha255To256(this->getPaintAlpha()); | |
165 const SkMatrix& inv = this->getTotalInverse(); | |
166 SkMatrix::MapPtProc proc = this->getInverseMapPtProc(); | |
167 SkBitmapSampler* sampler = fSampler; | |
168 MatrixClass mc = this->getInverseClass(); | |
169 | |
170 SkPoint srcPt; | |
171 | |
172 if (mc != kPerspective_MatrixClass) | |
173 { | |
174 proc(inv, SkIntToScalar(x) + SK_ScalarHalf, | |
175 SkIntToScalar(y) + SK_ScalarHalf, &srcPt); | |
176 | |
177 SkFixed fx = SkScalarToFixed(srcPt.fX); | |
178 SkFixed fy = SkScalarToFixed(srcPt.fY); | |
179 SkFixed dx, dy; | |
180 | |
181 if (mc == kLinear_MatrixClass) | |
182 { | |
183 dx = SkScalarToFixed(inv.getScaleX()); | |
184 dy = SkScalarToFixed(inv.getSkewY()); | |
185 } | |
186 else | |
187 (void)inv.fixedStepInX(SkIntToScalar(y), &dx, &dy); | |
188 | |
189 #if defined(SK_SUPPORT_MIPMAP) | |
190 { int level = this->getMipLevel() >> 16; | |
191 fx >>= level; | |
192 fy >>= level; | |
193 dx >>= level; | |
194 dy >>= level; | |
195 } | |
196 #endif | |
197 if (scale == 256) | |
198 { | |
199 for (int i = 0; i < count; i++) | |
200 { | |
201 dstC[i] = sampler->sample(fx, fy); | |
202 fx += dx; | |
203 fy += dy; | |
204 } | |
205 } | |
206 else | |
207 { | |
208 for (int i = 0; i < count; i++) | |
209 { | |
210 uint32_t c = sampler->sample(fx, fy); | |
211 dstC[i] = SkAlphaMulQ(c, scale); | |
212 fx += dx; | |
213 fy += dy; | |
214 } | |
215 } | |
216 } | |
217 else | |
218 { | |
219 SkPerspIter iter(inv, SkIntToScalar(x) + SK_ScalarHalf, | |
220 SkIntToScalar(y) + SK_ScalarHalf, count); | |
221 if (scale == 256) | |
222 { | |
223 while ((count = iter.next()) != 0) | |
224 { | |
225 const SkFixed* src = iter.getXY(); | |
226 for (int i = 0; i < count; i++) | |
227 { | |
228 *dstC++ = sampler->sample(src[0], src[1]); | |
229 src += 2; | |
230 } | |
231 } | |
232 } | |
233 else | |
234 { | |
235 while ((count = iter.next()) != 0) | |
236 { | |
237 const SkFixed* src = iter.getXY(); | |
238 for (int i = 0; i < count; i++) | |
239 { | |
240 uint32_t c = sampler->sample(src[0] - SK_FixedHalf, src[
1] - SK_FixedHalf); | |
241 *dstC++ = SkAlphaMulQ(c, scale); | |
242 src += 2; | |
243 } | |
244 } | |
245 } | |
246 } | |
247 } | |
248 | |
249 protected: | |
250 | |
251 const SkMatrix& getUnitInverse() const { return fUnitInverse; } | |
252 SkMatrix::MapPtProc getUnitInverseProc() const { return fUnitInverseProc; } | |
253 | |
254 /* takes computed inverse (from setContext) and computes fUnitInverse, | |
255 taking srcBitmap width/height into account, so that fUnitInverse | |
256 walks 0...1, allowing the tile modes to all operate in a fast 16bit | |
257 space (no need for mod). The resulting coords need to be scaled by | |
258 width/height to get back into src space (coord * width >> 16). | |
259 */ | |
260 void computeUnitInverse() | |
261 { | |
262 const SkBitmap& src = getSrcBitmap(); | |
263 fUnitInverse = this->getTotalInverse(); | |
264 fUnitInverse.postIDiv(src.width(), src.height()); | |
265 fUnitInverseProc = fUnitInverse.getMapPtProc(); | |
266 } | |
267 | |
268 private: | |
269 SkBitmapSampler* fSampler; | |
270 SkMatrix fUnitInverse; | |
271 SkMatrix::MapPtProc fUnitInverseProc; | |
272 | |
273 typedef SkBitmapShader INHERITED; | |
274 }; | |
275 | |
276 /////////////////////////////////////////////////////////////////////////// | |
277 | |
278 class HasSpan16_Sampler_BitmapShader : public Sampler_BitmapShader { | |
279 public: | |
280 HasSpan16_Sampler_BitmapShader(const SkBitmap& src, bool doFilter, | |
281 TileMode tmx, TileMode tmy) | |
282 : Sampler_BitmapShader(src, doFilter, tmx, tmy) | |
283 { | |
284 } | |
285 | |
286 virtual uint32_t getFlags() | |
287 { | |
288 uint32_t flags = this->INHERITED::getFlags(); | |
289 | |
290 switch (this->getSrcBitmap().getConfig()) { | |
291 case SkBitmap::kRGB_565_Config: | |
292 flags |= kHasSpan16_Flag; | |
293 break; | |
294 case SkBitmap::kIndex8_Config: | |
295 case SkBitmap::kARGB_8888_Config: | |
296 if (this->getSrcBitmap().isOpaque()) | |
297 flags |= kHasSpan16_Flag; | |
298 break; | |
299 default: | |
300 break; | |
301 } | |
302 return flags; | |
303 } | |
304 | |
305 const SkBitmap& revealSrcBitmap() const { return this->getSrcBitmap(); } | |
306 uint8_t revealPaintAlpha() const { return this->getPaintAlpha(); } | |
307 const SkMatrix& revealTotalInverse() const { return this->getTotalInverse();
} | |
308 | |
309 private: | |
310 typedef Sampler_BitmapShader INHERITED; | |
311 }; | |
312 | |
313 /////////////////////////////////////////////////////////////////////////// | |
314 | |
315 static void Index8_RepeatTile_Sprite16(HasSpan16_Sampler_BitmapShader* shader, | |
316 int x, int y, uint16_t dstC[], int count) | |
317 { | |
318 const SkMatrix& inv = shader->revealTotalInverse(); | |
319 const SkBitmap& srcBitmap = shader->revealSrcBitmap(); | |
320 int width = srcBitmap.width(); | |
321 int height = srcBitmap.height(); | |
322 | |
323 SkColorTable* ctable = srcBitmap.getColorTable(); | |
324 const uint16_t* colors = ctable->lock16BitCache(); | |
325 | |
326 x += SkScalarRound(inv[SkMatrix::kMTransX]); | |
327 y += SkScalarRound(inv[SkMatrix::kMTransY]); | |
328 | |
329 x = do_repeat_mod(x, width - 1); | |
330 y = do_repeat_mod(y, height - 1); | |
331 const uint8_t* row = srcBitmap.getAddr8(0, y); | |
332 const uint8_t* src = row + x; | |
333 | |
334 // do the first partial run | |
335 int n = width - x; | |
336 if (n > count) n = count; | |
337 count -= n; | |
338 SkASSERT(n > 0); | |
339 do { | |
340 *dstC++ = colors[*src++]; | |
341 } while (--n > 0); | |
342 | |
343 // do 1 complete run | |
344 if (count >= width) | |
345 { | |
346 uint16_t* baseDstC = dstC; // remember the first complete run start | |
347 n = width; | |
348 count -= width; | |
349 src = row; | |
350 do { | |
351 *dstC++ = colors[*src++]; | |
352 } while (--n > 0); | |
353 | |
354 // do the rest of the complete runs | |
355 while (count >= width) | |
356 { | |
357 count -= width; | |
358 memcpy(dstC, baseDstC, width << 1); | |
359 dstC += width; | |
360 } | |
361 // do final partial run | |
362 if (count > 0) | |
363 memcpy(dstC, baseDstC, count << 1); | |
364 } | |
365 else // do final partial | |
366 { | |
367 if (count > 0) | |
368 { | |
369 src = row; | |
370 do { | |
371 *dstC++ = colors[*src++]; | |
372 } while (--count > 0); | |
373 } | |
374 } | |
375 | |
376 ctable->unlock16BitCache(); | |
377 } | |
378 | |
379 static void Index8_RepeatTile_Sprite32(HasSpan16_Sampler_BitmapShader* shader, | |
380 int x, int y, SkPMColor dstC[], int count
) | |
381 { | |
382 const SkMatrix& inv = shader->revealTotalInverse(); | |
383 const SkBitmap& srcBitmap = shader->revealSrcBitmap(); | |
384 int width = srcBitmap.width(); | |
385 int height = srcBitmap.height(); | |
386 | |
387 SkColorTable* ctable = srcBitmap.getColorTable(); | |
388 const SkPMColor* colors = ctable->lockColors(); | |
389 | |
390 x += SkScalarRound(inv[SkMatrix::kMTransX]); | |
391 y += SkScalarRound(inv[SkMatrix::kMTransY]); | |
392 | |
393 x = do_repeat_mod(x, width - 1); | |
394 y = do_repeat_mod(y, height - 1); | |
395 | |
396 const uint8_t* row = srcBitmap.getAddr8(0, y); | |
397 const uint8_t* src = row + x; | |
398 | |
399 // do the first partial run | |
400 int n = width - x; | |
401 if (n > count) n = count; | |
402 count -= n; | |
403 SkASSERT(n > 0); | |
404 do { | |
405 *dstC++ = colors[*src++]; | |
406 } while (--n > 0); | |
407 | |
408 // do 1 complete run | |
409 if (count >= width) | |
410 { | |
411 SkPMColor* baseDstC = dstC; // remember the first complete run start | |
412 n = width; | |
413 count -= width; | |
414 src = row; | |
415 do { | |
416 *dstC++ = colors[*src++]; | |
417 } while (--n > 0); | |
418 | |
419 // do the rest of the complete runs | |
420 while (count >= width) | |
421 { | |
422 count -= width; | |
423 memcpy(dstC, baseDstC, width << 2); | |
424 dstC += width; | |
425 } | |
426 // do final partial run | |
427 if (count > 0) | |
428 memcpy(dstC, baseDstC, count << 2); | |
429 } | |
430 else // do final partial | |
431 { | |
432 if (count > 0) | |
433 { | |
434 src = row; | |
435 do { | |
436 *dstC++ = colors[*src++]; | |
437 } while (--count > 0); | |
438 } | |
439 } | |
440 | |
441 ctable->unlockColors(false); | |
442 } | |
443 | |
444 static void RGB16_RepeatTile_Sprite16(HasSpan16_Sampler_BitmapShader* shader, | |
445 int x, int y, uint16_t dstC[], int count) | |
446 { | |
447 SkASSERT(count > 0); | |
448 | |
449 const SkMatrix& inv = shader->revealTotalInverse(); | |
450 const SkBitmap& srcBitmap = shader->revealSrcBitmap(); | |
451 int width = srcBitmap.width(); | |
452 int height = srcBitmap.height(); | |
453 | |
454 SkASSERT(width > 0 && height > 0); | |
455 | |
456 x += SkScalarRound(inv[SkMatrix::kMTransX]); | |
457 y += SkScalarRound(inv[SkMatrix::kMTransY]); | |
458 | |
459 x = do_repeat_mod(x, width - 1); | |
460 y = do_repeat_mod(y, height - 1); | |
461 | |
462 const uint16_t* row = srcBitmap.getAddr16(0, y); | |
463 const uint16_t* src = row + x; | |
464 | |
465 int n = SkMin32(width - x, count); | |
466 | |
467 for (;;) | |
468 { | |
469 SkASSERT(n > 0 && count >= n); | |
470 memcpy(dstC, src, n << 1); | |
471 count -= n; | |
472 if (count == 0) | |
473 break; | |
474 dstC += n; | |
475 src = row; | |
476 n = SkMin32(width, count); | |
477 } | |
478 } | |
479 | |
480 static void RGB16_RepeatTile_Sprite32(HasSpan16_Sampler_BitmapShader* shader, | |
481 int x, int y, SkPMColor dstC[], int count
) | |
482 { | |
483 SkASSERT(count > 0); | |
484 | |
485 const SkMatrix& inv = shader->revealTotalInverse(); | |
486 const SkBitmap& srcBitmap = shader->revealSrcBitmap(); | |
487 int width = srcBitmap.width(); | |
488 int height = srcBitmap.height(); | |
489 | |
490 SkASSERT(width > 0 && height > 0); | |
491 | |
492 x += SkScalarRound(inv[SkMatrix::kMTransX]); | |
493 y += SkScalarRound(inv[SkMatrix::kMTransY]); | |
494 | |
495 x = do_repeat_mod(x, width - 1); | |
496 y = do_repeat_mod(y, height - 1); | |
497 | |
498 const uint16_t* row = srcBitmap.getAddr16(0, y); | |
499 const uint16_t* src = row + x; | |
500 | |
501 int n = SkMin32(width - x, count); | |
502 | |
503 // do the first partial run | |
504 count -= n; | |
505 SkASSERT(n > 0); | |
506 do { | |
507 *dstC++ = SkPixel16ToPixel32(*src++); | |
508 } while (--n > 0); | |
509 | |
510 // do 1 complete run | |
511 if (count >= width) | |
512 { | |
513 SkPMColor* baseDstC = dstC; // remember the first complete run start | |
514 n = width; | |
515 count -= width; | |
516 src = row; | |
517 do { | |
518 *dstC++ = SkPixel16ToPixel32(*src++); | |
519 } while (--n > 0); | |
520 | |
521 // do the rest of the complete runs | |
522 while (count >= width) | |
523 { | |
524 count -= width; | |
525 memcpy(dstC, baseDstC, width << 2); | |
526 dstC += width; | |
527 } | |
528 // do final partial run | |
529 if (count > 0) | |
530 memcpy(dstC, baseDstC, count << 2); | |
531 } | |
532 else // do final partial | |
533 { | |
534 if (count > 0) | |
535 { | |
536 src = row; | |
537 do { | |
538 *dstC++ = SkPixel16ToPixel32(*src++);; | |
539 } while (--count > 0); | |
540 } | |
541 } | |
542 } | |
543 | |
544 static void ARGB32_RepeatTile_Sprite16(HasSpan16_Sampler_BitmapShader* shader, | |
545 int x, int y, uint16_t dstC[], int count) | |
546 { | |
547 SkASSERT(count > 0); | |
548 | |
549 const SkMatrix& inv = shader->revealTotalInverse(); | |
550 const SkBitmap& srcBitmap = shader->revealSrcBitmap(); | |
551 int width = srcBitmap.width(); | |
552 int height = srcBitmap.height(); | |
553 | |
554 SkASSERT(width > 0 && height > 0); | |
555 | |
556 x += SkScalarRound(inv[SkMatrix::kMTransX]); | |
557 y += SkScalarRound(inv[SkMatrix::kMTransY]); | |
558 | |
559 x = do_repeat_mod(x, width - 1); | |
560 y = do_repeat_mod(y, height - 1); | |
561 | |
562 const SkPMColor* row = srcBitmap.getAddr32(0, y); | |
563 const SkPMColor* src = row + x; | |
564 | |
565 int n = SkMin32(width - x, count); | |
566 | |
567 // do the first partial run | |
568 count -= n; | |
569 SkASSERT(n > 0); | |
570 do { | |
571 *dstC++ = SkPixel32ToPixel16(*src++); | |
572 } while (--n > 0); | |
573 | |
574 // do 1 complete run | |
575 if (count >= width) | |
576 { | |
577 uint16_t* baseDstC = dstC; // remember the first complete run start | |
578 n = width; | |
579 count -= width; | |
580 src = row; | |
581 do { | |
582 *dstC++ = SkPixel32ToPixel16(*src++); | |
583 } while (--n > 0); | |
584 | |
585 // do the rest of the complete runs | |
586 while (count >= width) | |
587 { | |
588 count -= width; | |
589 memcpy(dstC, baseDstC, width << 1); | |
590 dstC += width; | |
591 } | |
592 // do final partial run | |
593 if (count > 0) | |
594 memcpy(dstC, baseDstC, count << 1); | |
595 } | |
596 else // do final partial | |
597 { | |
598 if (count > 0) | |
599 { | |
600 src = row; | |
601 do { | |
602 *dstC++ = SkPixel32ToPixel16(*src++);; | |
603 } while (--count > 0); | |
604 } | |
605 } | |
606 } | |
607 | |
608 static void ARGB32_RepeatTile_Sprite32(HasSpan16_Sampler_BitmapShader* shader, | |
609 int x, int y, SkPMColor dstC[], int count
) | |
610 { | |
611 SkASSERT(count > 0); | |
612 | |
613 const SkMatrix& inv = shader->revealTotalInverse(); | |
614 const SkBitmap& srcBitmap = shader->revealSrcBitmap(); | |
615 int width = srcBitmap.width(); | |
616 int height = srcBitmap.height(); | |
617 | |
618 SkASSERT(width > 0 && height > 0); | |
619 | |
620 x += SkScalarRound(inv[SkMatrix::kMTransX]); | |
621 y += SkScalarRound(inv[SkMatrix::kMTransY]); | |
622 | |
623 x = do_repeat_mod(x, width - 1); | |
624 y = do_repeat_mod(y, height - 1); | |
625 | |
626 const SkPMColor* row = srcBitmap.getAddr32(0, y); | |
627 const SkPMColor* src = row + x; | |
628 | |
629 int n = SkMin32(width - x, count); | |
630 | |
631 for (;;) | |
632 { | |
633 SkASSERT(n > 0 && count >= n); | |
634 memcpy(dstC, src, n << 2); | |
635 count -= n; | |
636 if (count == 0) | |
637 break; | |
638 dstC += n; | |
639 src = row; | |
640 n = SkMin32(width, count); | |
641 } | |
642 } | |
643 | |
644 /////////////////////////////////////////////////////////////////////////// | |
645 | |
646 #define NOFILTER_BITMAP_SHADER_CLASS Index8_NoFilter_RepeatTi
le_BitmapShader | |
647 #define NOFILTER_BITMAP_SHADER_TILEMODE SkShader::kRepeat_TileMo
de | |
648 #define NOFILTER_BITMAP_SHADER_TILEPROC(x, max) (fixed_repeat(x) * (max
+ 1) >> 16) | |
649 #define NOFILTER_BITMAP_SHADER_TYPE uint8_t | |
650 #define NOFILTER_BITMAP_SHADER_SAMPLE_X(p, x) colors32[p[x]] | |
651 #define NOFILTER_BITMAP_SHADER_SAMPLE_XY(p, x, y, rb) colors32[p[x + y * rb]] | |
652 #define NOFILTER_BITMAP_SHADER_PREAMBLE(bitmap, rb) const SkPMColor* colors3
2 = bitmap.getColorTable()->lockColors() | |
653 #define NOFILTER_BITMAP_SHADER_POSTAMBLE(bitmap) bitmap.getColorTable()->
unlockColors(false) | |
654 #define NOFILTER_BITMAP_SHADER_SAMPLE_X16(p, x) colors16[p[x]] | |
655 #define NOFILTER_BITMAP_SHADER_SAMPLE_XY16(p, x, y, rb) colors16[p[x + y * rb]] | |
656 #define NOFILTER_BITMAP_SHADER_PREAMBLE16(bitmap, rb) const uint16_t* colors16
= bitmap.getColorTable()->lock16BitCache() | |
657 #define NOFILTER_BITMAP_SHADER_POSTAMBLE16(bitmap) bitmap.getColorTable()->
unlock16BitCache() | |
658 #define NOFILTER_BITMAP_SHADER_USE_UNITINVERSE | |
659 #define NOFILTER_BITMAP_SHADER_SPRITEPROC16 Index8_RepeatTile_Sprite
16 | |
660 #define NOFILTER_BITMAP_SHADER_SPRITEPROC32 Index8_RepeatTile_Sprite
32 | |
661 #include "SkBitmapShaderTemplate.h" | |
662 | |
663 #define NOFILTER_BITMAP_SHADER_CLASS U16_NoFilter_RepeatTile_
BitmapShader | |
664 #define NOFILTER_BITMAP_SHADER_TILEMODE SkShader::kRepeat_TileMo
de | |
665 #define NOFILTER_BITMAP_SHADER_TILEPROC(x, max) (fixed_repeat(x) * (max
+ 1) >> 16) | |
666 #define NOFILTER_BITMAP_SHADER_TYPE uint16_t | |
667 #define NOFILTER_BITMAP_SHADER_SAMPLE_X(p, x) SkPixel16ToPixel32(p[x]) | |
668 #define NOFILTER_BITMAP_SHADER_SAMPLE_XY(p, x, y, rb) SkPixel16ToPixel32(*(con
st uint16_t*)((const char*)p + y * rb + (x << 1))) | |
669 #define NOFILTER_BITMAP_SHADER_SAMPLE_X16(p, x) p[x] | |
670 #define NOFILTER_BITMAP_SHADER_SAMPLE_XY16(p, x, y, rb) *(const uint16_t*)((cons
t char*)p + y * rb + (x << 1)) | |
671 #define NOFILTER_BITMAP_SHADER_USE_UNITINVERSE | |
672 #define NOFILTER_BITMAP_SHADER_SPRITEPROC16 RGB16_RepeatTile_Sprite1
6 | |
673 #define NOFILTER_BITMAP_SHADER_SPRITEPROC32 RGB16_RepeatTile_Sprite3
2 | |
674 #include "SkBitmapShaderTemplate.h" | |
675 | |
676 #define NOFILTER_BITMAP_SHADER_CLASS U32_NoFilter_RepeatTile_
BitmapShader | |
677 #define NOFILTER_BITMAP_SHADER_TILEMODE SkShader::kRepeat_TileMo
de | |
678 #define NOFILTER_BITMAP_SHADER_TILEPROC(x, max) (fixed_repeat(x) * (max
+ 1) >> 16) | |
679 #define NOFILTER_BITMAP_SHADER_TYPE uint32_t | |
680 #define NOFILTER_BITMAP_SHADER_SAMPLE_X(p, x) p[x] | |
681 #define NOFILTER_BITMAP_SHADER_SAMPLE_XY(p, x, y, rb) *(const uint32_t*)((cons
t char*)p + y * rb + (x << 2)) | |
682 #define NOFILTER_BITMAP_SHADER_SAMPLE_X16(p, x) SkPixel32ToPixel16_ToU16
(p[x]) | |
683 #define NOFILTER_BITMAP_SHADER_SAMPLE_XY16(p, x, y, rb) SkPixel32ToPixel16_ToU16
(*(const uint32_t*)((const char*)p + y * rb + (x << 2))) | |
684 #define NOFILTER_BITMAP_SHADER_USE_UNITINVERSE | |
685 #define NOFILTER_BITMAP_SHADER_SPRITEPROC16 ARGB32_RepeatTile_Sprite
16 | |
686 #define NOFILTER_BITMAP_SHADER_SPRITEPROC32 ARGB32_RepeatTile_Sprite
32 | |
687 #include "SkBitmapShaderTemplate.h" | |
688 | |
689 ////////////////////////////////////////////////////////////////////////////////
/////////////////////// | |
690 | |
691 static inline SkPMColor expanded_rgb16_to_8888(uint32_t c, U8CPU alpha) | |
692 { | |
693 // GGGG Gggg gggR RRRR rrrr r|BB BBBb bbbb | |
694 SkASSERT(alpha <= 255); | |
695 | |
696 #if 1 | |
697 int scale = SkAlpha255To256(alpha); | |
698 int r = (c & 0xF800) * scale >> 16; | |
699 int g = ((c >> 21) & 0x3F) * scale >> 6; | |
700 int b = (c & 0x1F) * scale >> 5; | |
701 return SkPackARGB32(alpha, r, g, b); | |
702 #else | |
703 int scale = SkAlpha255To256(alpha) >> 3; | |
704 c &= 0x07E0F81F; | |
705 c = c * scale; | |
706 int r = (c >> 13) & 0xFF; | |
707 int g = (c >> 24) & 0xFF; | |
708 int b = (c >> 2) & 0xFF; | |
709 return SkPackARGB32(alpha, r, g, b); | |
710 #endif | |
711 } | |
712 | |
713 #define BILERP_BITMAP16_SHADER_CLASS U16_Bilerp_BitmapShader | |
714 #define BILERP_BITMAP16_SHADER_TYPE uint16_t | |
715 #define BILERP_BITMAP16_SHADER_PREAMBLE(bm) | |
716 #define BILERP_BITMAP16_SHADER_PIXEL(c) (c) | |
717 #define BILERP_BITMAP16_SHADER_POSTAMBLE(bm) | |
718 #include "SkBitmapShader16BilerpTemplate.h" | |
719 | |
720 #define BILERP_BITMAP16_SHADER_CLASS Index8_Bilerp_BitmapShader | |
721 #define BILERP_BITMAP16_SHADER_TYPE uint8_t | |
722 #define BILERP_BITMAP16_SHADER_PREAMBLE(bm) SkColorTable* ctable = (bm).getC
olorTable(); const uint16_t* colors16 = ctable->lock16BitCache() | |
723 #define BILERP_BITMAP16_SHADER_PIXEL(c) colors16[c] | |
724 #define BILERP_BITMAP16_SHADER_POSTAMBLE(bm) ctable->unlock16BitCache() | |
725 #include "SkBitmapShader16BilerpTemplate.h" | |
726 | |
727 #include "ARGB32_Clamp_Bilinear_BitmapShader.h" | |
728 | |
729 /////////////////////////////////////////////////////////////////////////// | |
730 /////////////////////////////////////////////////////////////////////////// | |
731 | |
732 #include "SkBitmapProcShader.h" | |
733 | |
734 /////////////////////////////////////////////////////////////////////////// | |
735 /////////////////////////////////////////////////////////////////////////// | |
736 | |
737 #include "SkTemplatesPriv.h" | |
738 | |
739 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, | |
740 bool doFilter, | |
741 TileMode tmx, TileMode tmy, | |
742 void* storage, size_t storageSize) | |
743 { | |
744 #if 1 | |
745 | |
746 SkShader* shader; | |
747 SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, | |
748 storageSize, (src, doFilter, tmx, tmy)); | |
749 return shader; | |
750 #else | |
751 | |
752 if (!doFilter) | |
753 { | |
754 if (kClamp_TileMode == tmx && kClamp_TileMode == tmy) | |
755 { | |
756 SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, | |
757 storageSize, (src, doFilter, tmx, tmy)); | |
758 } | |
759 else if (kRepeat_TileMode == tmx && kRepeat_TileMode == tmy) | |
760 { | |
761 #if 1 | |
762 SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, | |
763 storageSize, (src, doFilter, tmx, tmy)); | |
764 #else | |
765 switch (src.getConfig()) { | |
766 case SkBitmap::kIndex8_Config: | |
767 SK_PLACEMENT_NEW_ARGS(shader, Index8_NoFilter_RepeatTile_BitmapS
hader, storage, storageSize, (src)); | |
768 break; | |
769 case SkBitmap::kRGB_565_Config: | |
770 SK_PLACEMENT_NEW_ARGS(shader, U16_NoFilter_RepeatTile_BitmapShad
er, storage, storageSize, (src)); | |
771 break; | |
772 case SkBitmap::kARGB_8888_Config: | |
773 SK_PLACEMENT_NEW_ARGS(shader, U32_NoFilter_RepeatTile_BitmapShad
er, storage, storageSize, (src)); | |
774 break; | |
775 default: | |
776 break; | |
777 } | |
778 #endif | |
779 } | |
780 } | |
781 else if (kClamp_TileMode == tmx && kClamp_TileMode == tmy) | |
782 { | |
783 #if 1 | |
784 if (SkBitmapProcShader::CanDo(src, tmx, tmy)) | |
785 { | |
786 SK_PLACEMENT_NEW_ARGS(shader, SkBitmapProcShader, storage, | |
787 storageSize, (src, doFilter, tmx, tmy)); | |
788 } | |
789 #else | |
790 switch (src.getConfig()) { | |
791 case SkBitmap::kIndex8_Config: | |
792 if (src.isOpaque()) | |
793 SK_PLACEMENT_NEW_ARGS(shader, Index8_Bilerp_BitmapShader, storag
e, storageSize, (src)); | |
794 break; | |
795 case SkBitmap::kRGB_565_Config: | |
796 SK_PLACEMENT_NEW_ARGS(shader, U16_Bilerp_BitmapShader, storage, stor
ageSize, (src)); | |
797 break; | |
798 case SkBitmap::kARGB_8888_Config: | |
799 SK_PLACEMENT_NEW_ARGS(shader, ARGB32_Clamp_Bilinear_BitmapShader, st
orage, storageSize, (src)); | |
800 break; | |
801 default: | |
802 break; | |
803 } | |
804 #endif | |
805 } | |
806 | |
807 // if shader is null, then none of the special cases could handle the reques
t | |
808 // so fall through to our slow-general case | |
809 if (shader == NULL) | |
810 SK_PLACEMENT_NEW_ARGS(shader, Sampler_BitmapShader, storage, storageSize
, | |
811 (src, doFilter, tmx, tmy)); | |
812 return shader; | |
813 #endif | |
814 } | |
815 | |
816 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, bool doFilter, | |
817 TileMode tmx, TileMode tmy) | |
818 { | |
819 return SkShader::CreateBitmapShader(src, doFilter, tmx, tmy, NULL, 0); | |
820 } | |
821 | |
822 #endif | |
OLD | NEW |