• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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