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