1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkArenaAlloc.h"
9 #include "SkBlitter.h"
10 #include "SkAntiRun.h"
11 #include "SkColor.h"
12 #include "SkColorFilter.h"
13 #include "SkReadBuffer.h"
14 #include "SkWriteBuffer.h"
15 #include "SkMask.h"
16 #include "SkMaskFilter.h"
17 #include "SkString.h"
18 #include "SkTLazy.h"
19 #include "SkUtils.h"
20 #include "SkXfermodeInterpretation.h"
21 
22 // define this for testing srgb blits
23 //#define SK_FORCE_PM4f_FOR_L32_BLITS
24 
~SkBlitter()25 SkBlitter::~SkBlitter() {}
26 
isNullBlitter() const27 bool SkBlitter::isNullBlitter() const { return false; }
28 
justAnOpaqueColor(uint32_t * value)29 const SkPixmap* SkBlitter::justAnOpaqueColor(uint32_t* value) {
30     return nullptr;
31 }
32 
33 /*
34 void SkBlitter::blitH(int x, int y, int width) {
35     SkDEBUGFAIL("unimplemented");
36 }
37 
38 
39 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
40                           const int16_t runs[]) {
41     SkDEBUGFAIL("unimplemented");
42 }
43  */
44 
blitV(int x,int y,int height,SkAlpha alpha)45 void SkBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
46     if (alpha == 255) {
47         this->blitRect(x, y, 1, height);
48     } else {
49         int16_t runs[2];
50         runs[0] = 1;
51         runs[1] = 0;
52 
53         while (--height >= 0) {
54             this->blitAntiH(x, y++, &alpha, runs);
55         }
56     }
57 }
58 
blitRect(int x,int y,int width,int height)59 void SkBlitter::blitRect(int x, int y, int width, int height) {
60     SkASSERT(width > 0);
61     while (--height >= 0) {
62         this->blitH(x, y++, width);
63     }
64 }
65 
66 /// Default implementation doesn't check for easy optimizations
67 /// such as alpha == 255; also uses blitV(), which some subclasses
68 /// may not support.
blitAntiRect(int x,int y,int width,int height,SkAlpha leftAlpha,SkAlpha rightAlpha)69 void SkBlitter::blitAntiRect(int x, int y, int width, int height,
70                              SkAlpha leftAlpha, SkAlpha rightAlpha) {
71     if (leftAlpha > 0) { // we may send in x = -1 with leftAlpha = 0
72         this->blitV(x, y, height, leftAlpha);
73     }
74     x++;
75     if (width > 0) {
76         this->blitRect(x, y, width, height);
77         x += width;
78     }
79     if (rightAlpha > 0) {
80         this->blitV(x, y, height, rightAlpha);
81     }
82 }
83 
84 //////////////////////////////////////////////////////////////////////////////
85 
bits_to_runs(SkBlitter * blitter,int x,int y,const uint8_t bits[],uint8_t left_mask,ptrdiff_t rowBytes,uint8_t right_mask)86 static inline void bits_to_runs(SkBlitter* blitter, int x, int y,
87                                 const uint8_t bits[],
88                                 uint8_t left_mask, ptrdiff_t rowBytes,
89                                 uint8_t right_mask) {
90     int inFill = 0;
91     int pos = 0;
92 
93     while (--rowBytes >= 0) {
94         uint8_t b = *bits++ & left_mask;
95         if (rowBytes == 0) {
96             b &= right_mask;
97         }
98 
99         for (uint8_t test = 0x80U; test != 0; test >>= 1) {
100             if (b & test) {
101                 if (!inFill) {
102                     pos = x;
103                     inFill = true;
104                 }
105             } else {
106                 if (inFill) {
107                     blitter->blitH(pos, y, x - pos);
108                     inFill = false;
109                 }
110             }
111             x += 1;
112         }
113         left_mask = 0xFFU;
114     }
115 
116     // final cleanup
117     if (inFill) {
118         blitter->blitH(pos, y, x - pos);
119     }
120 }
121 
122 // maskBitCount is the number of 1's to place in the mask. It must be in the range between 1 and 8.
generate_right_mask(int maskBitCount)123 static uint8_t generate_right_mask(int maskBitCount) {
124     return static_cast<uint8_t>(0xFF00U >> maskBitCount);
125 }
126 
blitMask(const SkMask & mask,const SkIRect & clip)127 void SkBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
128     SkASSERT(mask.fBounds.contains(clip));
129 
130     if (mask.fFormat == SkMask::kLCD16_Format) {
131         return; // needs to be handled by subclass
132     }
133 
134     if (mask.fFormat == SkMask::kBW_Format) {
135         int cx = clip.fLeft;
136         int cy = clip.fTop;
137         int maskLeft = mask.fBounds.fLeft;
138         int maskRowBytes = mask.fRowBytes;
139         int height = clip.height();
140 
141         const uint8_t* bits = mask.getAddr1(cx, cy);
142 
143         SkDEBUGCODE(const uint8_t* endOfImage =
144             mask.fImage + (mask.fBounds.height() - 1) * maskRowBytes
145             + ((mask.fBounds.width() + 7) >> 3));
146 
147         if (cx == maskLeft && clip.fRight == mask.fBounds.fRight) {
148             while (--height >= 0) {
149                 int affectedRightBit = mask.fBounds.width() - 1;
150                 ptrdiff_t rowBytes = (affectedRightBit >> 3) + 1;
151                 SkASSERT(bits + rowBytes <= endOfImage);
152                 U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
153                 bits_to_runs(this, cx, cy, bits, 0xFF, rowBytes, rightMask);
154                 bits += maskRowBytes;
155                 cy += 1;
156             }
157         } else {
158             // Bits is calculated as the offset into the mask at the point {cx, cy} therefore, all
159             // addressing into the bit mask is relative to that point. Since this is an address
160             // calculated from a arbitrary bit in that byte, calculate the left most bit.
161             int bitsLeft = cx - ((cx - maskLeft) & 7);
162 
163             // Everything is relative to the bitsLeft.
164             int leftEdge = cx - bitsLeft;
165             SkASSERT(leftEdge >= 0);
166             int rightEdge = clip.fRight - bitsLeft;
167             SkASSERT(rightEdge > leftEdge);
168 
169             // Calculate left byte and mask
170             const uint8_t* leftByte = bits;
171             U8CPU leftMask = 0xFFU >> (leftEdge & 7);
172 
173             // Calculate right byte and mask
174             int affectedRightBit = rightEdge - 1;
175             const uint8_t* rightByte = bits + (affectedRightBit >> 3);
176             U8CPU rightMask = generate_right_mask((affectedRightBit & 7) + 1);
177 
178             // leftByte and rightByte are byte locations therefore, to get a count of bytes the
179             // code must add one.
180             ptrdiff_t rowBytes = rightByte - leftByte + 1;
181 
182             while (--height >= 0) {
183                 SkASSERT(bits + rowBytes <= endOfImage);
184                 bits_to_runs(this, bitsLeft, cy, bits, leftMask, rowBytes, rightMask);
185                 bits += maskRowBytes;
186                 cy += 1;
187             }
188         }
189     } else {
190         int                         width = clip.width();
191         SkAutoSTMalloc<64, int16_t> runStorage(width + 1);
192         int16_t*                    runs = runStorage.get();
193         const uint8_t*              aa = mask.getAddr8(clip.fLeft, clip.fTop);
194 
195         sk_memset16((uint16_t*)runs, 1, width);
196         runs[width] = 0;
197 
198         int height = clip.height();
199         int y = clip.fTop;
200         while (--height >= 0) {
201             this->blitAntiH(clip.fLeft, y, aa, runs);
202             aa += mask.fRowBytes;
203             y += 1;
204         }
205     }
206 }
207 
208 /////////////////////// these guys are not virtual, just a helpers
209 
blitMaskRegion(const SkMask & mask,const SkRegion & clip)210 void SkBlitter::blitMaskRegion(const SkMask& mask, const SkRegion& clip) {
211     if (clip.quickReject(mask.fBounds)) {
212         return;
213     }
214 
215     SkRegion::Cliperator clipper(clip, mask.fBounds);
216 
217     while (!clipper.done()) {
218         const SkIRect& cr = clipper.rect();
219         this->blitMask(mask, cr);
220         clipper.next();
221     }
222 }
223 
blitRectRegion(const SkIRect & rect,const SkRegion & clip)224 void SkBlitter::blitRectRegion(const SkIRect& rect, const SkRegion& clip) {
225     SkRegion::Cliperator clipper(clip, rect);
226 
227     while (!clipper.done()) {
228         const SkIRect& cr = clipper.rect();
229         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
230         clipper.next();
231     }
232 }
233 
blitRegion(const SkRegion & clip)234 void SkBlitter::blitRegion(const SkRegion& clip) {
235     SkRegion::Iterator iter(clip);
236 
237     while (!iter.done()) {
238         const SkIRect& cr = iter.rect();
239         this->blitRect(cr.fLeft, cr.fTop, cr.width(), cr.height());
240         iter.next();
241     }
242 }
243 
244 ///////////////////////////////////////////////////////////////////////////////
245 
blitH(int x,int y,int width)246 void SkNullBlitter::blitH(int x, int y, int width) {}
247 
blitAntiH(int x,int y,const SkAlpha antialias[],const int16_t runs[])248 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[],
249                               const int16_t runs[]) {}
250 
blitV(int x,int y,int height,SkAlpha alpha)251 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) {}
252 
blitRect(int x,int y,int width,int height)253 void SkNullBlitter::blitRect(int x, int y, int width, int height) {}
254 
blitMask(const SkMask & mask,const SkIRect & clip)255 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {}
256 
justAnOpaqueColor(uint32_t * value)257 const SkPixmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) {
258     return nullptr;
259 }
260 
isNullBlitter() const261 bool SkNullBlitter::isNullBlitter() const { return true; }
262 
263 ///////////////////////////////////////////////////////////////////////////////
264 
compute_anti_width(const int16_t runs[])265 static int compute_anti_width(const int16_t runs[]) {
266     int width = 0;
267 
268     for (;;) {
269         int count = runs[0];
270 
271         SkASSERT(count >= 0);
272         if (count == 0) {
273             break;
274         }
275         width += count;
276         runs += count;
277     }
278     return width;
279 }
280 
y_in_rect(int y,const SkIRect & rect)281 static inline bool y_in_rect(int y, const SkIRect& rect) {
282     return (unsigned)(y - rect.fTop) < (unsigned)rect.height();
283 }
284 
x_in_rect(int x,const SkIRect & rect)285 static inline bool x_in_rect(int x, const SkIRect& rect) {
286     return (unsigned)(x - rect.fLeft) < (unsigned)rect.width();
287 }
288 
blitH(int left,int y,int width)289 void SkRectClipBlitter::blitH(int left, int y, int width) {
290     SkASSERT(width > 0);
291 
292     if (!y_in_rect(y, fClipRect)) {
293         return;
294     }
295 
296     int right = left + width;
297 
298     if (left < fClipRect.fLeft) {
299         left = fClipRect.fLeft;
300     }
301     if (right > fClipRect.fRight) {
302         right = fClipRect.fRight;
303     }
304 
305     width = right - left;
306     if (width > 0) {
307         fBlitter->blitH(left, y, width);
308     }
309 }
310 
blitAntiH(int left,int y,const SkAlpha aa[],const int16_t runs[])311 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[],
312                                   const int16_t runs[]) {
313     if (!y_in_rect(y, fClipRect) || left >= fClipRect.fRight) {
314         return;
315     }
316 
317     int x0 = left;
318     int x1 = left + compute_anti_width(runs);
319 
320     if (x1 <= fClipRect.fLeft) {
321         return;
322     }
323 
324     SkASSERT(x0 < x1);
325     if (x0 < fClipRect.fLeft) {
326         int dx = fClipRect.fLeft - x0;
327         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, dx);
328         runs += dx;
329         aa += dx;
330         x0 = fClipRect.fLeft;
331     }
332 
333     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
334     if (x1 > fClipRect.fRight) {
335         x1 = fClipRect.fRight;
336         SkAlphaRuns::BreakAt((int16_t*)runs, (uint8_t*)aa, x1 - x0);
337         ((int16_t*)runs)[x1 - x0] = 0;
338     }
339 
340     SkASSERT(x0 < x1 && runs[x1 - x0] == 0);
341     SkASSERT(compute_anti_width(runs) == x1 - x0);
342 
343     fBlitter->blitAntiH(x0, y, aa, runs);
344 }
345 
blitV(int x,int y,int height,SkAlpha alpha)346 void SkRectClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
347     SkASSERT(height > 0);
348 
349     if (!x_in_rect(x, fClipRect)) {
350         return;
351     }
352 
353     int y0 = y;
354     int y1 = y + height;
355 
356     if (y0 < fClipRect.fTop) {
357         y0 = fClipRect.fTop;
358     }
359     if (y1 > fClipRect.fBottom) {
360         y1 = fClipRect.fBottom;
361     }
362 
363     if (y0 < y1) {
364         fBlitter->blitV(x, y0, y1 - y0, alpha);
365     }
366 }
367 
blitRect(int left,int y,int width,int height)368 void SkRectClipBlitter::blitRect(int left, int y, int width, int height) {
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 }
376 
blitAntiRect(int left,int y,int width,int height,SkAlpha leftAlpha,SkAlpha rightAlpha)377 void SkRectClipBlitter::blitAntiRect(int left, int y, int width, int height,
378                                      SkAlpha leftAlpha, SkAlpha rightAlpha) {
379     SkIRect    r;
380 
381     // The *true* width of the rectangle blitted is width+2:
382     r.set(left, y, left + width + 2, y + height);
383     if (r.intersect(fClipRect)) {
384         if (r.fLeft != left) {
385             SkASSERT(r.fLeft > left);
386             leftAlpha = 255;
387         }
388         if (r.fRight != left + width + 2) {
389             SkASSERT(r.fRight < left + width + 2);
390             rightAlpha = 255;
391         }
392         if (255 == leftAlpha && 255 == rightAlpha) {
393             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
394         } else if (1 == r.width()) {
395             if (r.fLeft == left) {
396                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), leftAlpha);
397             } else {
398                 SkASSERT(r.fLeft == left + width + 1);
399                 fBlitter->blitV(r.fLeft, r.fTop, r.height(), rightAlpha);
400             }
401         } else {
402             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
403                                    leftAlpha, rightAlpha);
404         }
405     }
406 }
407 
blitMask(const SkMask & mask,const SkIRect & clip)408 void SkRectClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
409     SkASSERT(mask.fBounds.contains(clip));
410 
411     SkIRect    r = clip;
412 
413     if (r.intersect(fClipRect)) {
414         fBlitter->blitMask(mask, r);
415     }
416 }
417 
justAnOpaqueColor(uint32_t * value)418 const SkPixmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) {
419     return fBlitter->justAnOpaqueColor(value);
420 }
421 
422 ///////////////////////////////////////////////////////////////////////////////
423 
blitH(int x,int y,int width)424 void SkRgnClipBlitter::blitH(int x, int y, int width) {
425     SkRegion::Spanerator span(*fRgn, y, x, x + width);
426     int left, right;
427 
428     while (span.next(&left, &right)) {
429         SkASSERT(left < right);
430         fBlitter->blitH(left, y, right - left);
431     }
432 }
433 
blitAntiH(int x,int y,const SkAlpha aa[],const int16_t runs[])434 void SkRgnClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[],
435                                  const int16_t runs[]) {
436     int width = compute_anti_width(runs);
437     SkRegion::Spanerator span(*fRgn, y, x, x + width);
438     int left, right;
439     SkDEBUGCODE(const SkIRect& bounds = fRgn->getBounds();)
440 
441     int prevRite = x;
442     while (span.next(&left, &right)) {
443         SkASSERT(x <= left);
444         SkASSERT(left < right);
445         SkASSERT(left >= bounds.fLeft && right <= bounds.fRight);
446 
447         SkAlphaRuns::Break((int16_t*)runs, (uint8_t*)aa, left - x, right - left);
448 
449         // now zero before left
450         if (left > prevRite) {
451             int index = prevRite - x;
452             ((uint8_t*)aa)[index] = 0;   // skip runs after right
453             ((int16_t*)runs)[index] = SkToS16(left - prevRite);
454         }
455 
456         prevRite = right;
457     }
458 
459     if (prevRite > x) {
460         ((int16_t*)runs)[prevRite - x] = 0;
461 
462         if (x < 0) {
463             int skip = runs[0];
464             SkASSERT(skip >= -x);
465             aa += skip;
466             runs += skip;
467             x += skip;
468         }
469         fBlitter->blitAntiH(x, y, aa, runs);
470     }
471 }
472 
blitV(int x,int y,int height,SkAlpha alpha)473 void SkRgnClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
474     SkIRect    bounds;
475     bounds.set(x, y, x + 1, y + height);
476 
477     SkRegion::Cliperator    iter(*fRgn, bounds);
478 
479     while (!iter.done()) {
480         const SkIRect& r = iter.rect();
481         SkASSERT(bounds.contains(r));
482 
483         fBlitter->blitV(x, r.fTop, r.height(), alpha);
484         iter.next();
485     }
486 }
487 
blitRect(int x,int y,int width,int height)488 void SkRgnClipBlitter::blitRect(int x, int y, int width, int height) {
489     SkIRect    bounds;
490     bounds.set(x, y, x + width, y + height);
491 
492     SkRegion::Cliperator    iter(*fRgn, bounds);
493 
494     while (!iter.done()) {
495         const SkIRect& r = iter.rect();
496         SkASSERT(bounds.contains(r));
497 
498         fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
499         iter.next();
500     }
501 }
502 
blitAntiRect(int x,int y,int width,int height,SkAlpha leftAlpha,SkAlpha rightAlpha)503 void SkRgnClipBlitter::blitAntiRect(int x, int y, int width, int height,
504                                     SkAlpha leftAlpha, SkAlpha rightAlpha) {
505     // The *true* width of the rectangle to blit is width + 2
506     SkIRect    bounds;
507     bounds.set(x, y, x + width + 2, y + height);
508 
509     SkRegion::Cliperator    iter(*fRgn, bounds);
510 
511     while (!iter.done()) {
512         const SkIRect& r = iter.rect();
513         SkASSERT(bounds.contains(r));
514         SkASSERT(r.fLeft >= x);
515         SkASSERT(r.fRight <= x + width + 2);
516 
517         SkAlpha effectiveLeftAlpha = (r.fLeft == x) ? leftAlpha : 255;
518         SkAlpha effectiveRightAlpha = (r.fRight == x + width + 2) ?
519                                       rightAlpha : 255;
520 
521         if (255 == effectiveLeftAlpha && 255 == effectiveRightAlpha) {
522             fBlitter->blitRect(r.fLeft, r.fTop, r.width(), r.height());
523         } else if (1 == r.width()) {
524             if (r.fLeft == x) {
525                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
526                                 effectiveLeftAlpha);
527             } else {
528                 SkASSERT(r.fLeft == x + width + 1);
529                 fBlitter->blitV(r.fLeft, r.fTop, r.height(),
530                                 effectiveRightAlpha);
531             }
532         } else {
533             fBlitter->blitAntiRect(r.fLeft, r.fTop, r.width() - 2, r.height(),
534                                    effectiveLeftAlpha, effectiveRightAlpha);
535         }
536         iter.next();
537     }
538 }
539 
540 
blitMask(const SkMask & mask,const SkIRect & clip)541 void SkRgnClipBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
542     SkASSERT(mask.fBounds.contains(clip));
543 
544     SkRegion::Cliperator iter(*fRgn, clip);
545     const SkIRect&       r = iter.rect();
546     SkBlitter*           blitter = fBlitter;
547 
548     while (!iter.done()) {
549         blitter->blitMask(mask, r);
550         iter.next();
551     }
552 }
553 
justAnOpaqueColor(uint32_t * value)554 const SkPixmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) {
555     return fBlitter->justAnOpaqueColor(value);
556 }
557 
558 ///////////////////////////////////////////////////////////////////////////////
559 
apply(SkBlitter * blitter,const SkRegion * clip,const SkIRect * ir)560 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip,
561                                    const SkIRect* ir) {
562     if (clip) {
563         const SkIRect& clipR = clip->getBounds();
564 
565         if (clip->isEmpty() || (ir && !SkIRect::Intersects(clipR, *ir))) {
566             blitter = &fNullBlitter;
567         } else if (clip->isRect()) {
568             if (ir == nullptr || !clipR.contains(*ir)) {
569                 fRectBlitter.init(blitter, clipR);
570                 blitter = &fRectBlitter;
571             }
572         } else {
573             fRgnBlitter.init(blitter, clip);
574             blitter = &fRgnBlitter;
575         }
576     }
577     return blitter;
578 }
579 
580 ///////////////////////////////////////////////////////////////////////////////
581 
582 #include "SkColorShader.h"
583 #include "SkColorPriv.h"
584 
585 class Sk3DShader : public SkShader {
586 public:
Sk3DShader(sk_sp<SkShader> proxy)587     Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {}
588 
onMakeContext(const ContextRec & rec,SkArenaAlloc * alloc) const589     Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override {
590         SkShader::Context* proxyContext = nullptr;
591         if (fProxy) {
592             proxyContext = fProxy->makeContext(rec, alloc);
593             if (!proxyContext) {
594                 return nullptr;
595             }
596         }
597         return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext);
598     }
599 
600     class Sk3DShaderContext : public SkShader::Context {
601     public:
602         // Calls proxyContext's destructor but will NOT free its memory.
Sk3DShaderContext(const Sk3DShader & shader,const ContextRec & rec,SkShader::Context * proxyContext)603         Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
604                           SkShader::Context* proxyContext)
605             : INHERITED(shader, rec)
606             , fMask(nullptr)
607             , fProxyContext(proxyContext)
608         {
609             if (!fProxyContext) {
610                 fPMColor = SkPreMultiplyColor(rec.fPaint->getColor());
611             }
612         }
613 
~Sk3DShaderContext()614         ~Sk3DShaderContext() override {
615             if (fProxyContext) {
616                 fProxyContext->~Context();
617             }
618         }
619 
set3DMask(const SkMask * mask)620         void set3DMask(const SkMask* mask) override { fMask = mask; }
621 
shadeSpan(int x,int y,SkPMColor span[],int count)622         void shadeSpan(int x, int y, SkPMColor span[], int count) override {
623             if (fProxyContext) {
624                 fProxyContext->shadeSpan(x, y, span, count);
625             }
626 
627             if (fMask == nullptr) {
628                 if (fProxyContext == nullptr) {
629                     sk_memset32(span, fPMColor, count);
630                 }
631                 return;
632             }
633 
634             SkASSERT(fMask->fBounds.contains(x, y));
635             SkASSERT(fMask->fBounds.contains(x + count - 1, y));
636 
637             size_t          size = fMask->computeImageSize();
638             const uint8_t*  alpha = fMask->getAddr8(x, y);
639             const uint8_t*  mulp = alpha + size;
640             const uint8_t*  addp = mulp + size;
641 
642             if (fProxyContext) {
643                 for (int i = 0; i < count; i++) {
644                     if (alpha[i]) {
645                         SkPMColor c = span[i];
646                         if (c) {
647                             unsigned a = SkGetPackedA32(c);
648                             unsigned r = SkGetPackedR32(c);
649                             unsigned g = SkGetPackedG32(c);
650                             unsigned b = SkGetPackedB32(c);
651 
652                             unsigned mul = SkAlpha255To256(mulp[i]);
653                             unsigned add = addp[i];
654 
655                             r = SkFastMin32(SkAlphaMul(r, mul) + add, a);
656                             g = SkFastMin32(SkAlphaMul(g, mul) + add, a);
657                             b = SkFastMin32(SkAlphaMul(b, mul) + add, a);
658 
659                             span[i] = SkPackARGB32(a, r, g, b);
660                         }
661                     } else {
662                         span[i] = 0;
663                     }
664                 }
665             } else {    // color
666                 unsigned a = SkGetPackedA32(fPMColor);
667                 unsigned r = SkGetPackedR32(fPMColor);
668                 unsigned g = SkGetPackedG32(fPMColor);
669                 unsigned b = SkGetPackedB32(fPMColor);
670                 for (int i = 0; i < count; i++) {
671                     if (alpha[i]) {
672                         unsigned mul = SkAlpha255To256(mulp[i]);
673                         unsigned add = addp[i];
674 
675                         span[i] = SkPackARGB32( a,
676                                         SkFastMin32(SkAlphaMul(r, mul) + add, a),
677                                         SkFastMin32(SkAlphaMul(g, mul) + add, a),
678                                         SkFastMin32(SkAlphaMul(b, mul) + add, a));
679                     } else {
680                         span[i] = 0;
681                     }
682                 }
683             }
684         }
685 
686     private:
687         // Unowned.
688         const SkMask*       fMask;
689         // Memory is unowned, but we need to call the destructor.
690         SkShader::Context*  fProxyContext;
691         SkPMColor           fPMColor;
692 
693         typedef SkShader::Context INHERITED;
694     };
695 
696 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const697     void toString(SkString* str) const override {
698         str->append("Sk3DShader: (");
699 
700         if (fProxy) {
701             str->append("Proxy: ");
702             fProxy->toString(str);
703         }
704 
705         this->INHERITED::toString(str);
706 
707         str->append(")");
708     }
709 #endif
710 
711     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Sk3DShader)
712 
713 protected:
flatten(SkWriteBuffer & buffer) const714     void flatten(SkWriteBuffer& buffer) const override {
715         buffer.writeFlattenable(fProxy.get());
716     }
717 
718 private:
719     sk_sp<SkShader> fProxy;
720 
721     typedef SkShader INHERITED;
722 };
723 
CreateProc(SkReadBuffer & buffer)724 sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) {
725     return sk_make_sp<Sk3DShader>(buffer.readShader());
726 }
727 
728 class Sk3DBlitter : public SkBlitter {
729 public:
Sk3DBlitter(SkBlitter * proxy,SkShader::Context * shaderContext)730     Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
731         : fProxy(proxy)
732         , fShaderContext(shaderContext)
733     {}
734 
blitH(int x,int y,int width)735     void blitH(int x, int y, int width) override {
736         fProxy->blitH(x, y, width);
737     }
738 
blitAntiH(int x,int y,const SkAlpha antialias[],const int16_t runs[])739     void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override {
740         fProxy->blitAntiH(x, y, antialias, runs);
741     }
742 
blitV(int x,int y,int height,SkAlpha alpha)743     void blitV(int x, int y, int height, SkAlpha alpha) override {
744         fProxy->blitV(x, y, height, alpha);
745     }
746 
blitRect(int x,int y,int width,int height)747     void blitRect(int x, int y, int width, int height) override {
748         fProxy->blitRect(x, y, width, height);
749     }
750 
blitMask(const SkMask & mask,const SkIRect & clip)751     void blitMask(const SkMask& mask, const SkIRect& clip) override {
752         if (mask.fFormat == SkMask::k3D_Format) {
753             fShaderContext->set3DMask(&mask);
754 
755             ((SkMask*)&mask)->fFormat = SkMask::kA8_Format;
756             fProxy->blitMask(mask, clip);
757             ((SkMask*)&mask)->fFormat = SkMask::k3D_Format;
758 
759             fShaderContext->set3DMask(nullptr);
760         } else {
761             fProxy->blitMask(mask, clip);
762         }
763     }
764 
765 private:
766     // Both pointers are unowned. They will be deleted by SkSmallAllocator.
767     SkBlitter*          fProxy;
768     SkShader::Context*  fShaderContext;
769 };
770 
771 ///////////////////////////////////////////////////////////////////////////////
772 
773 #include "SkCoreBlitters.h"
774 
PreferredShaderDest(const SkImageInfo & dstInfo)775 SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) {
776 #ifdef SK_FORCE_PM4f_FOR_L32_BLITS
777     return SkShader::ContextRec::kPM4f_DstType;
778 #else
779     return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType)
780             ? SkShader::ContextRec::kPM4f_DstType
781             : SkShader::ContextRec::kPMColor_DstType;
782 #endif
783 }
784 
Choose(const SkPixmap & device,const SkMatrix & matrix,const SkPaint & origPaint,SkArenaAlloc * alloc,bool drawCoverage)785 SkBlitter* SkBlitter::Choose(const SkPixmap& device,
786                              const SkMatrix& matrix,
787                              const SkPaint& origPaint,
788                              SkArenaAlloc* alloc,
789                              bool drawCoverage) {
790     SkASSERT(alloc != nullptr);
791 
792     // which check, in case we're being called by a client with a dummy device
793     // (e.g. they have a bounder that always aborts the draw)
794     if (kUnknown_SkColorType == device.colorType() ||
795             (drawCoverage && (kAlpha_8_SkColorType != device.colorType()))) {
796         return alloc->make<SkNullBlitter>();
797     }
798 
799     SkShader* shader = origPaint.getShader();
800     SkColorFilter* cf = origPaint.getColorFilter();
801     SkBlendMode mode = origPaint.getBlendMode();
802     sk_sp<Sk3DShader> shader3D;
803 
804     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
805 
806     if (origPaint.getMaskFilter() != nullptr &&
807             origPaint.getMaskFilter()->getFormat() == SkMask::k3D_Format) {
808         shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader));
809         // we know we haven't initialized lazyPaint yet, so just do it
810         paint.writable()->setShader(shader3D);
811         shader = shader3D.get();
812     }
813 
814     if (mode != SkBlendMode::kSrcOver) {
815         bool deviceIsOpaque = kRGB_565_SkColorType == device.colorType();
816         switch (SkInterpretXfermode(*paint, deviceIsOpaque)) {
817             case kSrcOver_SkXfermodeInterpretation:
818                 mode = SkBlendMode::kSrcOver;
819                 paint.writable()->setBlendMode(mode);
820                 break;
821             case kSkipDrawing_SkXfermodeInterpretation:{
822                 return alloc->make<SkNullBlitter>();
823             }
824             default:
825                 break;
826         }
827     }
828 
829     /*
830      *  If the xfermode is CLEAR, then we can completely ignore the installed
831      *  color/shader/colorfilter, and just pretend we're SRC + color==0. This
832      *  will fall into our optimizations for SRC mode.
833      */
834     if (mode == SkBlendMode::kClear) {
835         SkPaint* p = paint.writable();
836         p->setShader(nullptr);
837         shader = nullptr;
838         p->setColorFilter(nullptr);
839         cf = nullptr;
840         p->setBlendMode(mode = SkBlendMode::kSrc);
841         p->setColor(0);
842     }
843 
844     if (kAlpha_8_SkColorType == device.colorType() && drawCoverage) {
845         SkASSERT(nullptr == shader);
846         SkASSERT(paint->isSrcOver());
847         return alloc->make<SkA8_Coverage_Blitter>(device, *paint);
848     }
849 
850     if (SkBlitter* blitter = SkCreateRasterPipelineBlitter(device, *paint, matrix, alloc)) {
851         return blitter;
852     }
853 
854     if (nullptr == shader) {
855         if (mode != SkBlendMode::kSrcOver) {
856             // xfermodes (and filters) require shaders for our current blitters
857             paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor()));
858             paint.writable()->setAlpha(0xFF);
859             shader = paint->getShader();
860         } else if (cf) {
861             // if no shader && no xfermode, we just apply the colorfilter to
862             // our color and move on.
863             SkPaint* writablePaint = paint.writable();
864             writablePaint->setColor(cf->filterColor(paint->getColor()));
865             writablePaint->setColorFilter(nullptr);
866             cf = nullptr;
867         }
868     }
869 
870     if (cf) {
871         SkASSERT(shader);
872         paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf)));
873         shader = paint->getShader();
874         // blitters should ignore the presence/absence of a filter, since
875         // if there is one, the shader will take care of it.
876     }
877 
878     /*
879      *  We create a SkShader::Context object, and store it on the blitter.
880      */
881     SkShader::Context* shaderContext = nullptr;
882     if (shader) {
883         const SkShader::ContextRec rec(*paint, matrix, nullptr,
884                                        PreferredShaderDest(device.info()),
885                                        device.colorSpace());
886         // Try to create the ShaderContext
887         shaderContext = shader->makeContext(rec, alloc);
888         if (!shaderContext) {
889             return alloc->make<SkNullBlitter>();
890         }
891         SkASSERT(shaderContext);
892     }
893 
894     SkBlitter*  blitter = nullptr;
895     switch (device.colorType()) {
896         case kAlpha_8_SkColorType:
897             SkASSERT(!drawCoverage);  // Handled above.
898             if (shader) {
899                 blitter = alloc->make<SkA8_Shader_Blitter>(device, *paint, shaderContext);
900             } else {
901                 blitter = alloc->make<SkA8_Blitter>(device, *paint);
902             }
903             break;
904 
905         case kRGB_565_SkColorType:
906             blitter = SkBlitter_ChooseD565(device, *paint, shaderContext, alloc);
907             break;
908 
909         case kN32_SkColorType:
910 #ifdef SK_FORCE_PM4f_FOR_L32_BLITS
911             if (true)
912 #else
913             if (device.info().gammaCloseToSRGB())
914 #endif
915             {
916                 blitter = SkBlitter_ARGB32_Create(device, *paint, shaderContext, alloc);
917             } else {
918                 if (shader) {
919                         blitter = alloc->make<SkARGB32_Shader_Blitter>(
920                                 device, *paint, shaderContext);
921                 } else if (paint->getColor() == SK_ColorBLACK) {
922                     blitter = alloc->make<SkARGB32_Black_Blitter>(device, *paint);
923                 } else if (paint->getAlpha() == 0xFF) {
924                     blitter = alloc->make<SkARGB32_Opaque_Blitter>(device, *paint);
925                 } else {
926                     blitter = alloc->make<SkARGB32_Blitter>(device, *paint);
927                 }
928             }
929             break;
930 
931         case kRGBA_F16_SkColorType:
932             blitter = SkBlitter_F16_Create(device, *paint, shaderContext, alloc);
933             break;
934 
935         default:
936             break;
937     }
938 
939     if (!blitter) {
940         blitter = alloc->make<SkNullBlitter>();
941     }
942 
943     if (shader3D) {
944         SkBlitter* innerBlitter = blitter;
945         // FIXME - comment about allocator
946         // innerBlitter was allocated by allocator, which will delete it.
947         // We know shaderContext or its proxies is of type Sk3DShaderContext, so we need to
948         // wrapper the blitter to notify it when we see an emboss mask.
949         blitter = alloc->make<Sk3DBlitter>(innerBlitter, shaderContext);
950     }
951     return blitter;
952 }
953 
954 ///////////////////////////////////////////////////////////////////////////////
955 
956 class SkZeroShaderContext : public SkShader::Context {
957 public:
SkZeroShaderContext(const SkShader & shader,const SkShader::ContextRec & rec)958     SkZeroShaderContext(const SkShader& shader, const SkShader::ContextRec& rec)
959         // Override rec with the identity matrix, so it is guaranteed to be invertible.
960         : INHERITED(shader, SkShader::ContextRec(*rec.fPaint, SkMatrix::I(), nullptr,
961                                                  rec.fPreferredDstType, rec.fDstColorSpace)) {}
962 
shadeSpan(int x,int y,SkPMColor colors[],int count)963     void shadeSpan(int x, int y, SkPMColor colors[], int count) override {
964         sk_bzero(colors, count * sizeof(SkPMColor));
965     }
966 
967 private:
968     typedef SkShader::Context INHERITED;
969 };
970 
SkShaderBlitter(const SkPixmap & device,const SkPaint & paint,SkShader::Context * shaderContext)971 SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint,
972                                  SkShader::Context* shaderContext)
973         : INHERITED(device)
974         , fShader(paint.getShader())
975         , fShaderContext(shaderContext) {
976     SkASSERT(fShader);
977     SkASSERT(fShaderContext);
978 
979     fShader->ref();
980     fShaderFlags = fShaderContext->getFlags();
981     fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag);
982 }
983 
~SkShaderBlitter()984 SkShaderBlitter::~SkShaderBlitter() {
985     fShader->unref();
986 }
987 
988 ///////////////////////////////////////////////////////////////////////////////////////////////////
989 
990 #ifdef SK_DEBUG
991 
blitH(int x,int y,int width)992 void SkRectClipCheckBlitter::blitH(int x, int y, int width) {
993     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1)));
994     fBlitter->blitH(x, y, width);
995 }
996 
blitAntiH(int x,int y,const SkAlpha aa[],const int16_t runs[])997 void SkRectClipCheckBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) {
998     const int16_t* iter = runs;
999     for (; *iter; iter += *iter)
1000         ;
1001     int width = iter - runs;
1002     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, 1)));
1003     fBlitter->blitAntiH(x, y, aa, runs);
1004 }
1005 
blitV(int x,int y,int height,SkAlpha alpha)1006 void SkRectClipCheckBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
1007     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, height)));
1008     fBlitter->blitV(x, y, height, alpha);
1009 }
1010 
blitRect(int x,int y,int width,int height)1011 void SkRectClipCheckBlitter::blitRect(int x, int y, int width, int height) {
1012     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, width, height)));
1013     fBlitter->blitRect(x, y, width, height);
1014 }
1015 
blitAntiRect(int x,int y,int width,int height,SkAlpha leftAlpha,SkAlpha rightAlpha)1016 void SkRectClipCheckBlitter::blitAntiRect(int x, int y, int width, int height,
1017                                      SkAlpha leftAlpha, SkAlpha rightAlpha) {
1018     bool skipLeft = !leftAlpha;
1019     bool skipRight = !rightAlpha;
1020     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x + skipLeft, y,
1021             width + 2 - skipRight - skipLeft, height)));
1022     fBlitter->blitAntiRect(x, y, width, height, leftAlpha, rightAlpha);
1023 }
1024 
blitMask(const SkMask & mask,const SkIRect & clip)1025 void SkRectClipCheckBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
1026     SkASSERT(mask.fBounds.contains(clip));
1027     SkASSERT(fClipRect.contains(clip));
1028     fBlitter->blitMask(mask, clip);
1029 }
1030 
justAnOpaqueColor(uint32_t * value)1031 const SkPixmap* SkRectClipCheckBlitter::justAnOpaqueColor(uint32_t* value) {
1032     return fBlitter->justAnOpaqueColor(value);
1033 }
1034 
blitAntiH2(int x,int y,U8CPU a0,U8CPU a1)1035 void SkRectClipCheckBlitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
1036     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 2, 1)));
1037     fBlitter->blitAntiH2(x, y, a0, a1);
1038 }
1039 
blitAntiV2(int x,int y,U8CPU a0,U8CPU a1)1040 void SkRectClipCheckBlitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
1041     SkASSERT(fClipRect.contains(SkIRect::MakeXYWH(x, y, 1, 2)));
1042     fBlitter->blitAntiV2(x, y, a0, a1);
1043 }
1044 
1045 #endif
1046