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