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