1 /* libs/graphics/sgl/SkBlitter.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "SkBlitter.h"
19 #include "SkAntiRun.h"
20 #include "SkColor.h"
21 #include "SkColorFilter.h"
22 #include "SkMask.h"
23 #include "SkMaskFilter.h"
24 #include "SkTemplatesPriv.h"
25 #include "SkUtils.h"
26 #include "SkXfermode.h"
27
~SkBlitter()28 SkBlitter::~SkBlitter()
29 {
30 }
31
justAnOpaqueColor(uint32_t * value)32 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value)
33 {
34 return NULL;
35 }
36
blitH(int x,int y,int width)37 void SkBlitter::blitH(int x, int y, int width)
38 {
39 SkASSERT(!"unimplemented");
40 }
41
blitAntiH(int x,int y,const SkAlpha antialias[],const int16_t runs[])42 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
43 {
44 SkASSERT(!"unimplemented");
45 }
46
blitV(int x,int y,int height,SkAlpha alpha)47 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha)
48 {
49 if (alpha == 255)
50 this->blitRect(x, y, 1, height);
51 else
52 {
53 int16_t runs[2];
54 runs[0] = 1;
55 runs[1] = 0;
56
57 while (--height >= 0)
58 this->blitAntiH(x, y++, &alpha, runs);
59 }
60 }
61
blitRect(int x,int y,int width,int height)62 void SkBlitter::blitRect(int x, int y, int width, int height)
63 {
64 while (--height >= 0)
65 this->blitH(x, y++, width);
66 }
67
68 //////////////////////////////////////////////////////////////////////////////
69
bits_to_runs(SkBlitter * blitter,int x,int y,const uint8_t bits[],U8CPU left_mask,int rowBytes,U8CPU right_mask)70 static inline void bits_to_runs(SkBlitter* blitter, int x, int y, const uint8_t bits[],
71 U8CPU left_mask, int rowBytes, U8CPU right_mask)
72 {
73 int inFill = 0;
74 int pos = 0;
75
76 while (--rowBytes >= 0)
77 {
78 unsigned b = *bits++ & left_mask;
79 if (rowBytes == 0)
80 b &= right_mask;
81
82 for (unsigned test = 0x80; test != 0; test >>= 1)
83 {
84 if (b & test)
85 {
86 if (!inFill)
87 {
88 pos = x;
89 inFill = true;
90 }
91 }
92 else
93 {
94 if (inFill)
95 {
96 blitter->blitH(pos, y, x - pos);
97 inFill = false;
98 }
99 }
100 x += 1;
101 }
102 left_mask = 0xFF;
103 }
104
105 // final cleanup
106 if (inFill)
107 blitter->blitH(pos, y, x - pos);
108 }
109
blitMask(const SkMask & mask,const SkIRect & clip)110 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
111 {
112 SkASSERT(mask.fBounds.contains(clip));
113
114 if (mask.fFormat == SkMask::kBW_Format)
115 {
116 int cx = clip.fLeft;
117 int cy = clip.fTop;
118 int maskLeft = mask.fBounds.fLeft;
119 int mask_rowBytes = mask.fRowBytes;
120 int height = clip.height();
121
122 const uint8_t* bits = mask.getAddr1(cx, cy);
123
124 if (cx == maskLeft && clip.fRight == mask.fBounds.fRight)
125 {
126 while (--height >= 0)
127 {
128 bits_to_runs(this, cx, cy, bits, 0xFF, mask_rowBytes, 0xFF);
129 bits += mask_rowBytes;
130 cy += 1;
131 }
132 }
133 else
134 {
135 int left_edge = cx - maskLeft;
136 SkASSERT(left_edge >= 0);
137 int rite_edge = clip.fRight - maskLeft;
138 SkASSERT(rite_edge > left_edge);
139
140 int left_mask = 0xFF >> (left_edge & 7);
141 int rite_mask = 0xFF << (8 - (rite_edge & 7));
142 int full_runs = (rite_edge >> 3) - ((left_edge + 7) >> 3);
143
144 // check for empty right mask, so we don't read off the end (or go slower than we need to)
145 if (rite_mask == 0)
146 {
147 SkASSERT(full_runs >= 0);
148 full_runs -= 1;
149 rite_mask = 0xFF;
150 }
151 if (left_mask == 0xFF)
152 full_runs -= 1;
153
154 // back up manually so we can keep in sync with our byte-aligned src
155 // have cx reflect our actual starting x-coord
156 cx -= left_edge & 7;
157
158 if (full_runs < 0)
159 {
160 SkASSERT((left_mask & rite_mask) != 0);
161 while (--height >= 0)
162 {
163 bits_to_runs(this, cx, cy, bits, left_mask, 1, rite_mask);
164 bits += mask_rowBytes;
165 cy += 1;
166 }
167 }
168 else
169 {
170 while (--height >= 0)
171 {
172 bits_to_runs(this, cx, cy, bits, left_mask, full_runs + 2, rite_mask);
173 bits += mask_rowBytes;
174 cy += 1;
175 }
176 }
177 }
178 }
179 else
180 {
181 int width = clip.width();
182 SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
183 int16_t* runs = runStorage.get();
184 const uint8_t* aa = mask.getAddr(clip.fLeft, clip.fTop);
185
186 sk_memset16((uint16_t*)runs, 1, width);
187 runs[width] = 0;
188
189 int height = clip.height();
190 int y = clip.fTop;
191 while (--height >= 0)
192 {
193 this->blitAntiH(clip.fLeft, y, aa, runs);
194 aa += mask.fRowBytes;
195 y += 1;
196 }
197 }
198 }
199
200 /////////////////////// these guys are not virtual, just a helpers
201
blitMaskRegion(const SkMask & mask,const SkRegion & clip)202 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
203 if (clip.quickReject(mask.fBounds)) {
204 return;
205 }
206
207 SkRegion::Cliperator clipper(clip, mask.fBounds);
208
209 while (!clipper.done()) {
210 const SkIRect& cr = clipper.rect();
211 this->blitMask(mask, cr);
212 clipper.next();
213 }
214 }
215
blitRectRegion(const SkIRect & rect,const SkRegion & clip)216 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
217 SkRegion::Cliperator clipper(clip, rect);
218
219 while (!clipper.done()) {
220 const SkIRect& cr = clipper.rect();
221 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
222 clipper.next();
223 }
224 }
225
blitRegion(const SkRegion & clip)226 void SkBlitter::blitRegion(const SkRegion& clip) {
227 SkRegion::Iterator iter(clip);
228
229 while (!iter.done()) {
230 const SkIRect& cr = iter.rect();
231 this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
232 iter.next();
233 }
234 }
235
236 ///////////////////////////////////////////////////////////////////////////////////////
237 ///////////////////////////////////////////////////////////////////////////////////////
238
blitH(int x,int y,int width)239 void SkNullBlitter::blitH(int x, int y, int width)
240 {
241 }
242
blitAntiH(int x,int y,const SkAlpha antialias[],const int16_t runs[])243 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
244 {
245 }
246
blitV(int x,int y,int height,SkAlpha alpha)247 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha)
248 {
249 }
250
blitRect(int x,int y,int width,int height)251 void SkNullBlitter::blitRect(int x, int y, int width, int height)
252 {
253 }
254
blitMask(const SkMask & mask,const SkIRect & clip)255 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
256 {
257 }
258
justAnOpaqueColor(uint32_t * value)259 const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value)
260 {
261 return NULL;
262 }
263
264 ///////////////////////////////////////////////////////////////////////////////////////
265 ///////////////////////////////////////////////////////////////////////////////////////
266
compute_anti_width(const int16_t runs[])267 static int compute_anti_width(const int16_t runs[])
268 {
269 int width = 0;
270
271 for (;;)
272 {
273 int count = runs[0];
274
275 SkASSERT(count >= 0);
276 if (count == 0)
277 break;
278 width += count;
279 runs += count;
280
281 SkASSERT(width < 20000);
282 }
283 return width;
284 }
285
y_in_rect(int y,const SkIRect & rect)286 static inline bool y_in_rect(int y, const SkIRect& rect)
287 {
288 return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
289 }
290
x_in_rect(int x,const SkIRect & rect)291 static inline bool x_in_rect(int x, const SkIRect& rect)
292 {
293 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
294 }
295
blitH(int left,int y,int width)296 void SkRectClipBlitter::blitH(int left, int y, int width)
297 {
298 SkASSERT(width > 0);
299
300 if (!y_in_rect(y, fClipRect))
301 return;
302
303 int right = left + width;
304
305 if (left < fClipRect.fLeft)
306 left = fClipRect.fLeft;
307 if (right > fClipRect.fRight)
308 right = fClipRect.fRight;
309
310 width = right - left;
311 if (width > 0)
312 fBlitter->blitH(left, y, width);
313 }
314
blitAntiH(int left,int y,const SkAlpha aa[],const int16_t runs[])315 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], const int16_t runs[])
316 {
317 if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight)
318 return;
319
320 int x0 = left;
321 int x1 = left + compute_anti_width(runs);
322
323 if (x1 <= fClipRect.fLeft)
324 return;
325
326 SkASSERT(x0 < x1);
327 if (x0 < fClipRect.fLeft)
328 {
329 int dx = fClipRect.fLeft - x0;
330 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
331 runs += dx;
332 aa += dx;
333 x0 = fClipRect.fLeft;
334 }
335
336 SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
337 if (x1 > fClipRect.fRight)
338 {
339 x1 = fClipRect.fRight;
340 SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
341 ((int16_t*)runs)[x1 - x0] = 0;
342 }
343
344 SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
345 SkASSERT(compute_anti_width(runs) == x1 - x0);
346
347 fBlitter->blitAntiH(x0, y, aa, runs);
348 }
349
blitV(int x,int y,int height,SkAlpha alpha)350 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha)
351 {
352 SkASSERT(height > 0);
353
354 if (!x_in_rect(x, fClipRect))
355 return;
356
357 int y0 = y;
358 int y1 = y + height;
359
360 if (y0 < fClipRect.fTop)
361 y0 = fClipRect.fTop;
362 if (y1 > fClipRect.fBottom)
363 y1 = fClipRect.fBottom;
364
365 if (y0 < y1)
366 fBlitter->blitV(x, y0, y1 - y0, alpha);
367 }
368
blitRect(int left,int y,int width,int height)369 void SkRectClipBlitter::blitRect(int left, int y, int width, int height)
370 {
371 SkIRect r;
372
373 r.set(left, y, left + width, y + height);
374 if (r.intersect(fClipRect))
375 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
376 }
377
blitMask(const SkMask & mask,const SkIRect & clip)378 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
379 {
380 SkASSERT(mask.fBounds.contains(clip));
381
382 SkIRect r = clip;
383
384 if (r.intersect(fClipRect))
385 fBlitter->blitMask(mask, r);
386 }
387
justAnOpaqueColor(uint32_t * value)388 const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value)
389 {
390 return fBlitter->justAnOpaqueColor(value);
391 }
392
393 ///////////////////////////////////////////////////////////////////////////////////////
394 ///////////////////////////////////////////////////////////////////////////////////////
395
blitH(int x,int y,int width)396 void SkRgnClipBlitter::blitH(int x, int y, int width)
397 {
398 SkRegion::Spanerator span(*fRgn, y, x, x + width);
399 int left, right;
400
401 while (span.next(&left, &right))
402 {
403 SkASSERT(left < right);
404 fBlitter->blitH(left, y, right - left);
405 }
406 }
407
blitAntiH(int x,int y,const SkAlpha aa[],const int16_t runs[])408 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[])
409 {
410 int width = compute_anti_width(runs);
411 SkRegion::Spanerator span(*fRgn, y, x, x + width);
412 int left, right;
413 SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
414
415 int prevRite = x;
416 while (span.next(&left, &right))
417 {
418 SkASSERT(x <= left);
419 SkASSERT(left < right);
420 SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
421
422 SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
423
424 // now zero before left
425 if (left > prevRite)
426 {
427 int index = prevRite - x;
428 ((uint8_t*)aa)[index] = 0; // skip runs after right
429 ((int16_t*)runs)[index] = SkToS16(left - prevRite);
430 }
431
432 prevRite = right;
433 }
434
435 if (prevRite > x)
436 {
437 ((int16_t*)runs)[prevRite - x] = 0;
438
439 if (x < 0) {
440 int skip = runs[0];
441 SkASSERT(skip >= -x);
442 aa += skip;
443 runs += skip;
444 x += skip;
445 }
446 fBlitter->blitAntiH(x, y, aa, runs);
447 }
448 }
449
blitV(int x,int y,int height,SkAlpha alpha)450 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha)
451 {
452 SkIRect bounds;
453 bounds.set(x, y, x + 1, y + height);
454
455 SkRegion::Cliperator iter(*fRgn, bounds);
456
457 while (!iter.done())
458 {
459 const SkIRect& r = iter.rect();
460 SkASSERT(bounds.contains(r));
461
462 fBlitter->blitV(x, r.fTop, r.height(), alpha);
463 iter.next();
464 }
465 }
466
blitRect(int x,int y,int width,int height)467 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height)
468 {
469 SkIRect bounds;
470 bounds.set(x, y, x + width, y + height);
471
472 SkRegion::Cliperator iter(*fRgn, bounds);
473
474 while (!iter.done())
475 {
476 const SkIRect& r = iter.rect();
477 SkASSERT(bounds.contains(r));
478
479 fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
480 iter.next();
481 }
482 }
483
blitMask(const SkMask & mask,const SkIRect & clip)484 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip)
485 {
486 SkASSERT(mask.fBounds.contains(clip));
487
488 SkRegion::Cliperator iter(*fRgn, clip);
489 const SkIRect& r = iter.rect();
490 SkBlitter* blitter = fBlitter;
491
492 while (!iter.done())
493 {
494 blitter->blitMask(mask, r);
495 iter.next();
496 }
497 }
498
justAnOpaqueColor(uint32_t * value)499 const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value)
500 {
501 return fBlitter->justAnOpaqueColor(value);
502 }
503
504 ///////////////////////////////////////////////////////////////////////////////////////
505 ///////////////////////////////////////////////////////////////////////////////////////
506
apply(SkBlitter * blitter,const SkRegion * clip,const SkIRect * ir)507 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, const SkIRect* ir)
508 {
509 if (clip)
510 {
511 const SkIRect& clipR = clip->getBounds();
512
513 if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir)))
514 blitter = &fNullBlitter;
515 else if (clip->isRect())
516 {
517 if (ir == NULL || !clipR.contains(*ir))
518 {
519 fRectBlitter.init(blitter, clipR);
520 blitter = &fRectBlitter;
521 }
522 }
523 else
524 {
525 fRgnBlitter.init(blitter, clip);
526 blitter = &fRgnBlitter;
527 }
528 }
529 return blitter;
530 }
531
532 ///////////////////////////////////////////////////////////////////////////////////////
533 ///////////////////////////////////////////////////////////////////////////////////////
534
535 #include "SkColorShader.h"
536 #include "SkColorPriv.h"
537
538 class Sk3DShader : public SkShader {
539 public:
Sk3DShader(SkShader * proxy)540 Sk3DShader(SkShader* proxy) : fProxy(proxy)
541 {
542 proxy->safeRef();
543 fMask = NULL;
544 }
~Sk3DShader()545 virtual ~Sk3DShader()
546 {
547 fProxy->safeUnref();
548 }
setMask(const SkMask * mask)549 void setMask(const SkMask* mask) { fMask = mask; }
550
setContext(const SkBitmap & device,const SkPaint & paint,const SkMatrix & matrix)551 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, const SkMatrix& matrix)
552 {
553 if (fProxy)
554 return fProxy->setContext(device, paint, matrix);
555 else
556 {
557 fPMColor = SkPreMultiplyColor(paint.getColor());
558 return this->INHERITED::setContext(device, paint, matrix);
559 }
560 }
shadeSpan(int x,int y,SkPMColor span[],int count)561 virtual void shadeSpan(int x, int y, SkPMColor span[], int count)
562 {
563 if (fProxy)
564 fProxy->shadeSpan(x, y, span, count);
565
566 if (fMask == NULL)
567 {
568 if (fProxy == NULL)
569 sk_memset32(span, fPMColor, count);
570 return;
571 }
572
573 SkASSERT(fMask->fBounds.contains(x, y));
574 SkASSERT(fMask->fBounds.contains(x + count - 1, y));
575
576 size_t size = fMask->computeImageSize();
577 const uint8_t* alpha = fMask->getAddr(x, y);
578 const uint8_t* mulp = alpha + size;
579 const uint8_t* addp = mulp + size;
580
581 if (fProxy)
582 {
583 for (int i = 0; i < count; i++)
584 {
585 if (alpha[i])
586 {
587 SkPMColor c = span[i];
588 if (c)
589 {
590 unsigned a = SkGetPackedA32(c);
591 unsigned r = SkGetPackedR32(c);
592 unsigned g = SkGetPackedG32(c);
593 unsigned b = SkGetPackedB32(c);
594
595 unsigned mul = SkAlpha255To256(mulp[i]);
596 unsigned add = addp[i];
597
598 r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
599 g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
600 b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
601
602 span[i] = SkPackARGB32(a, r, g, b);
603 }
604 }
605 else
606 span[i] = 0;
607 }
608 }
609 else // color
610 {
611 unsigned a = SkGetPackedA32(fPMColor);
612 unsigned r = SkGetPackedR32(fPMColor);
613 unsigned g = SkGetPackedG32(fPMColor);
614 unsigned b = SkGetPackedB32(fPMColor);
615 for (int i = 0; i < count; i++)
616 {
617 if (alpha[i])
618 {
619 unsigned mul = SkAlpha255To256(mulp[i]);
620 unsigned add = addp[i];
621
622 span[i] = SkPackARGB32( a,
623 SkFastMin32(SkAlphaMul(r, mul) + add, a),
624 SkFastMin32(SkAlphaMul(g, mul) + add, a),
625 SkFastMin32(SkAlphaMul(b, mul) + add, a));
626 }
627 else
628 span[i] = 0;
629 }
630 }
631 }
632
beginSession()633 virtual void beginSession()
634 {
635 this->INHERITED::beginSession();
636 if (fProxy)
637 fProxy->beginSession();
638 }
639
endSession()640 virtual void endSession()
641 {
642 if (fProxy)
643 fProxy->endSession();
644 this->INHERITED::endSession();
645 }
646
647 protected:
Sk3DShader(SkFlattenableReadBuffer & buffer)648 Sk3DShader(SkFlattenableReadBuffer& buffer) :
649 INHERITED(buffer)
650 {
651 fProxy = static_cast<SkShader*>(buffer.readFlattenable());
652 fPMColor = buffer.readU32();
653 fMask = NULL;
654 }
655
flatten(SkFlattenableWriteBuffer & buffer)656 virtual void flatten(SkFlattenableWriteBuffer& buffer)
657 {
658 this->INHERITED::flatten(buffer);
659 buffer.writeFlattenable(fProxy);
660 buffer.write32(fPMColor);
661 }
662
getFactory()663 virtual Factory getFactory()
664 {
665 return CreateProc;
666 }
667
668 private:
CreateProc(SkFlattenableReadBuffer & buffer)669 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer)
670 {
671 return SkNEW_ARGS(Sk3DShader, (buffer));
672 }
673
674 SkShader* fProxy;
675 SkPMColor fPMColor;
676 const SkMask* fMask;
677
678 typedef SkShader INHERITED;
679 };
680
681 class Sk3DBlitter : public SkBlitter {
682 public:
Sk3DBlitter(SkBlitter * proxy,Sk3DShader * shader,void (* killProc)(void *))683 Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*))
684 : fProxy(proxy), f3DShader(shader), fKillProc(killProc)
685 {
686 shader->ref();
687 }
~Sk3DBlitter()688 virtual ~Sk3DBlitter()
689 {
690 f3DShader->unref();
691 fKillProc(fProxy);
692 }
693
blitH(int x,int y,int width)694 virtual void blitH(int x, int y, int width)
695 {
696 fProxy->blitH(x, y, width);
697 }
blitAntiH(int x,int y,const SkAlpha antialias[],const int16_t runs[])698 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
699 {
700 fProxy->blitAntiH(x, y, antialias, runs);
701 }
blitV(int x,int y,int height,SkAlpha alpha)702 virtual void blitV(int x, int y, int height, SkAlpha alpha)
703 {
704 fProxy->blitV(x, y, height, alpha);
705 }
blitRect(int x,int y,int width,int height)706 virtual void blitRect(int x, int y, int width, int height)
707 {
708 fProxy->blitRect(x, y, width, height);
709 }
blitMask(const SkMask & mask,const SkIRect & clip)710 virtual void blitMask(const SkMask& mask, const SkIRect& clip)
711 {
712 if (mask.fFormat == SkMask::k3D_Format)
713 {
714 f3DShader->setMask(&mask);
715
716 ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
717 fProxy->blitMask(mask, clip);
718 ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
719
720 f3DShader->setMask(NULL);
721 }
722 else
723 fProxy->blitMask(mask, clip);
724 }
725 private:
726 SkBlitter* fProxy;
727 Sk3DShader* f3DShader;
728 void (*fKillProc)(void*);
729 };
730
731 ///////////////////////////////////////////////////////////////////////////////////////
732 ///////////////////////////////////////////////////////////////////////////////////////
733
734 #include "SkCoreBlitters.h"
735
736 class SkAutoRestoreShader {
737 public:
SkAutoRestoreShader(const SkPaint & p)738 SkAutoRestoreShader(const SkPaint& p) : fPaint((SkPaint*)&p)
739 {
740 fShader = fPaint->getShader();
741 fShader->safeRef();
742 }
~SkAutoRestoreShader()743 ~SkAutoRestoreShader()
744 {
745 fPaint->setShader(fShader);
746 fShader->safeUnref();
747 }
748 private:
749 SkPaint* fPaint;
750 SkShader* fShader;
751 };
752
753 class SkAutoCallProc {
754 public:
755 typedef void (*Proc)(void*);
SkAutoCallProc(void * obj,Proc proc)756 SkAutoCallProc(void* obj, Proc proc)
757 : fObj(obj), fProc(proc)
758 {
759 }
~SkAutoCallProc()760 ~SkAutoCallProc()
761 {
762 if (fObj && fProc)
763 fProc(fObj);
764 }
get() const765 void* get() const { return fObj; }
detach()766 void* detach()
767 {
768 void* obj = fObj;
769 fObj = NULL;
770 return obj;
771 }
772 private:
773 void* fObj;
774 Proc fProc;
775 };
776
destroy_blitter(void * blitter)777 static void destroy_blitter(void* blitter)
778 {
779 ((SkBlitter*)blitter)->~SkBlitter();
780 }
781
delete_blitter(void * blitter)782 static void delete_blitter(void* blitter)
783 {
784 SkDELETE((SkBlitter*)blitter);
785 }
786
Choose(const SkBitmap & device,const SkMatrix & matrix,const SkPaint & paint,void * storage,size_t storageSize)787 SkBlitter* SkBlitter::Choose(const SkBitmap& device,
788 const SkMatrix& matrix,
789 const SkPaint& paint,
790 void* storage, size_t storageSize)
791 {
792 SkASSERT(storageSize == 0 || storage != NULL);
793
794 SkBlitter* blitter = NULL;
795
796 // which check, in case we're being called by a client with a dummy device
797 // (e.g. they have a bounder that always aborts the draw)
798 if (SkBitmap::kNo_Config == device.getConfig())
799 {
800 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
801 return blitter;
802 }
803
804 SkAutoRestoreShader restore(paint);
805 SkShader* shader = paint.getShader();
806
807 Sk3DShader* shader3D = NULL;
808 if (paint.getMaskFilter() != NULL && paint.getMaskFilter()->getFormat() == SkMask::k3D_Format)
809 {
810 shader3D = SkNEW_ARGS(Sk3DShader, (shader));
811 ((SkPaint*)&paint)->setShader(shader3D)->unref();
812 shader = shader3D;
813 }
814
815 SkXfermode* mode = paint.getXfermode();
816 if (NULL == shader && (NULL != mode || paint.getColorFilter() != NULL))
817 {
818 // xfermodes require shaders for our current set of blitters
819 shader = SkNEW(SkColorShader);
820 ((SkPaint*)&paint)->setShader(shader)->unref();
821 }
822
823 if (paint.getColorFilter() != NULL)
824 {
825 SkASSERT(shader);
826 shader = SkNEW_ARGS(SkFilterShader, (shader, paint.getColorFilter()));
827 ((SkPaint*)&paint)->setShader(shader)->unref();
828 }
829
830 bool doDither = paint.isDither();
831
832 if (shader)
833 {
834 if (!shader->setContext(device, paint, matrix))
835 return SkNEW(SkNullBlitter);
836
837 // disable dither if our shader is natively 16bit (no need to upsample)
838 if (shader->getFlags() & SkShader::kIntrinsicly16_Flag)
839 doDither = false;
840 }
841
842 switch (device.getConfig()) {
843 case SkBitmap::kA1_Config:
844 SK_PLACEMENT_NEW_ARGS(blitter, SkA1_Blitter, storage, storageSize, (device, paint));
845 break;
846
847 case SkBitmap::kA8_Config:
848 if (shader)
849 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, storage, storageSize, (device, paint));
850 else
851 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Blitter, storage, storageSize, (device, paint));
852 break;
853
854 case SkBitmap::kARGB_4444_Config:
855 blitter = SkBlitter_ChooseD4444(device, paint, storage, storageSize);
856 break;
857
858 case SkBitmap::kRGB_565_Config:
859 if (shader)
860 {
861 if (mode)
862 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Xfermode_Blitter, storage, storageSize, (device, paint));
863 else if (SkShader::CanCallShadeSpan16(shader->getFlags()) && !doDither)
864 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader16_Blitter, storage, storageSize, (device, paint));
865 else
866 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Shader_Blitter, storage, storageSize, (device, paint));
867 }
868 else if (paint.getColor() == SK_ColorBLACK)
869 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Black_Blitter, storage, storageSize, (device, paint));
870 else
871 SK_PLACEMENT_NEW_ARGS(blitter, SkRGB16_Blitter, storage, storageSize, (device, paint));
872 break;
873
874 case SkBitmap::kARGB_8888_Config:
875 if (shader)
876 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Shader_Blitter, storage, storageSize, (device, paint));
877 else if (paint.getColor() == SK_ColorBLACK)
878 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, storage, storageSize, (device, paint));
879 else if (paint.getAlpha() == 0xFF)
880 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, storage, storageSize, (device, paint));
881 else
882 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, storage, storageSize, (device, paint));
883 break;
884
885 default:
886 SkASSERT(!"unsupported device config");
887 SK_PLACEMENT_NEW(blitter, SkNullBlitter, storage, storageSize);
888 }
889
890 if (shader3D)
891 {
892 void (*proc)(void*) = ((void*)storage == (void*)blitter) ? destroy_blitter : delete_blitter;
893 SkAutoCallProc tmp(blitter, proc);
894
895 blitter = SkNEW_ARGS(Sk3DBlitter, (blitter, shader3D, proc));
896 (void)tmp.detach();
897 }
898 return blitter;
899 }
900
901 //////////////////////////////////////////////////////////////////////////////////////////////////////
902
903 const uint16_t gMask_0F0F = 0xF0F;
904 const uint32_t gMask_00FF00FF = 0xFF00FF;
905
906 //////////////////////////////////////////////////////////////////////////////////////////////////////
907
SkShaderBlitter(const SkBitmap & device,const SkPaint & paint)908 SkShaderBlitter::SkShaderBlitter(const SkBitmap& device, const SkPaint& paint)
909 : INHERITED(device)
910 {
911 fShader = paint.getShader();
912 SkASSERT(fShader);
913
914 fShader->ref();
915 fShader->beginSession();
916 }
917
~SkShaderBlitter()918 SkShaderBlitter::~SkShaderBlitter()
919 {
920 fShader->endSession();
921 fShader->unref();
922 }
923
924