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