OLD | NEW |
| (Empty) |
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 | |
28 SkBlitter::~SkBlitter() | |
29 { | |
30 } | |
31 | |
32 const SkBitmap* SkBlitter::justAnOpaqueColor(uint32_t* value) | |
33 { | |
34 return NULL; | |
35 } | |
36 | |
37 void SkBlitter::blitH(int x, int y, int width) | |
38 { | |
39 SkASSERT(!"unimplemented"); | |
40 } | |
41 | |
42 void SkBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t
runs[]) | |
43 { | |
44 SkASSERT(!"unimplemented"); | |
45 } | |
46 | |
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 | |
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 | |
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 | |
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 s
lower 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, r
ite_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 | |
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 | |
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 | |
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 | |
239 void SkNullBlitter::blitH(int x, int y, int width) | |
240 { | |
241 } | |
242 | |
243 void SkNullBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int
16_t runs[]) | |
244 { | |
245 } | |
246 | |
247 void SkNullBlitter::blitV(int x, int y, int height, SkAlpha alpha) | |
248 { | |
249 } | |
250 | |
251 void SkNullBlitter::blitRect(int x, int y, int width, int height) | |
252 { | |
253 } | |
254 | |
255 void SkNullBlitter::blitMask(const SkMask& mask, const SkIRect& clip) | |
256 { | |
257 } | |
258 | |
259 const SkBitmap* SkNullBlitter::justAnOpaqueColor(uint32_t* value) | |
260 { | |
261 return NULL; | |
262 } | |
263 | |
264 ////////////////////////////////////////////////////////////////////////////////
/////// | |
265 ////////////////////////////////////////////////////////////////////////////////
/////// | |
266 | |
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 | |
286 static inline bool y_in_rect(int y, const SkIRect& rect) | |
287 { | |
288 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); | |
289 } | |
290 | |
291 static inline bool x_in_rect(int x, const SkIRect& rect) | |
292 { | |
293 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); | |
294 } | |
295 | |
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 | |
315 void SkRectClipBlitter::blitAntiH(int left, int y, const SkAlpha aa[], const int
16_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 | |
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 | |
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 | |
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 | |
388 const SkBitmap* SkRectClipBlitter::justAnOpaqueColor(uint32_t* value) | |
389 { | |
390 return fBlitter->justAnOpaqueColor(value); | |
391 } | |
392 | |
393 ////////////////////////////////////////////////////////////////////////////////
/////// | |
394 ////////////////////////////////////////////////////////////////////////////////
/////// | |
395 | |
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 | |
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 | |
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 | |
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 | |
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 | |
499 const SkBitmap* SkRgnClipBlitter::justAnOpaqueColor(uint32_t* value) | |
500 { | |
501 return fBlitter->justAnOpaqueColor(value); | |
502 } | |
503 | |
504 ////////////////////////////////////////////////////////////////////////////////
/////// | |
505 ////////////////////////////////////////////////////////////////////////////////
/////// | |
506 | |
507 SkBlitter* SkBlitterClipper::apply(SkBlitter* blitter, const SkRegion* clip, con
st 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: | |
540 Sk3DShader(SkShader* proxy) : fProxy(proxy) | |
541 { | |
542 proxy->safeRef(); | |
543 fMask = NULL; | |
544 } | |
545 virtual ~Sk3DShader() | |
546 { | |
547 fProxy->safeUnref(); | |
548 } | |
549 void setMask(const SkMask* mask) { fMask = mask; } | |
550 | |
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 } | |
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 | |
633 virtual void beginSession() | |
634 { | |
635 this->INHERITED::beginSession(); | |
636 if (fProxy) | |
637 fProxy->beginSession(); | |
638 } | |
639 | |
640 virtual void endSession() | |
641 { | |
642 if (fProxy) | |
643 fProxy->endSession(); | |
644 this->INHERITED::endSession(); | |
645 } | |
646 | |
647 protected: | |
648 Sk3DShader(SkFlattenableReadBuffer& buffer) : | |
649 INHERITED(buffer) | |
650 { | |
651 fProxy = static_cast<SkShader*>(buffer.readFlattenable()); | |
652 fPMColor = buffer.readU32(); | |
653 fMask = NULL; | |
654 } | |
655 | |
656 virtual void flatten(SkFlattenableWriteBuffer& buffer) | |
657 { | |
658 this->INHERITED::flatten(buffer); | |
659 buffer.writeFlattenable(fProxy); | |
660 buffer.write32(fPMColor); | |
661 } | |
662 | |
663 virtual Factory getFactory() | |
664 { | |
665 return CreateProc; | |
666 } | |
667 | |
668 private: | |
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: | |
683 Sk3DBlitter(SkBlitter* proxy, Sk3DShader* shader, void (*killProc)(void*)) | |
684 : fProxy(proxy), f3DShader(shader), fKillProc(killProc) | |
685 { | |
686 shader->ref(); | |
687 } | |
688 virtual ~Sk3DBlitter() | |
689 { | |
690 f3DShader->unref(); | |
691 fKillProc(fProxy); | |
692 } | |
693 | |
694 virtual void blitH(int x, int y, int width) | |
695 { | |
696 fProxy->blitH(x, y, width); | |
697 } | |
698 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_
t runs[]) | |
699 { | |
700 fProxy->blitAntiH(x, y, antialias, runs); | |
701 } | |
702 virtual void blitV(int x, int y, int height, SkAlpha alpha) | |
703 { | |
704 fProxy->blitV(x, y, height, alpha); | |
705 } | |
706 virtual void blitRect(int x, int y, int width, int height) | |
707 { | |
708 fProxy->blitRect(x, y, width, height); | |
709 } | |
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: | |
738 SkAutoRestoreShader(const SkPaint& p) : fPaint((SkPaint*)&p) | |
739 { | |
740 fShader = fPaint->getShader(); | |
741 fShader->safeRef(); | |
742 } | |
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*); | |
756 SkAutoCallProc(void* obj, Proc proc) | |
757 : fObj(obj), fProc(proc) | |
758 { | |
759 } | |
760 ~SkAutoCallProc() | |
761 { | |
762 if (fObj && fProc) | |
763 fProc(fObj); | |
764 } | |
765 void* get() const { return fObj; } | |
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 | |
777 static void destroy_blitter(void* blitter) | |
778 { | |
779 ((SkBlitter*)blitter)->~SkBlitter(); | |
780 } | |
781 | |
782 static void delete_blitter(void* blitter) | |
783 { | |
784 SkDELETE((SkBlitter*)blitter); | |
785 } | |
786 | |
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() == S
kMask::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, (devi
ce, paint)); | |
845 break; | |
846 | |
847 case SkBitmap::kA8_Config: | |
848 if (shader) | |
849 SK_PLACEMENT_NEW_ARGS(blitter, SkA8_Shader_Blitter, storage, storage
Size, (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()) && !doDith
er) | |
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, stora
geSize, (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, sto
rageSize, (device, paint)); | |
877 else if (paint.getColor() == SK_ColorBLACK) | |
878 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Black_Blitter, storage, stor
ageSize, (device, paint)); | |
879 else if (paint.getAlpha() == 0xFF) | |
880 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Opaque_Blitter, storage, sto
rageSize, (device, paint)); | |
881 else | |
882 SK_PLACEMENT_NEW_ARGS(blitter, SkARGB32_Blitter, storage, storageSiz
e, (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_blitt
er : 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 | |
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 | |
918 SkShaderBlitter::~SkShaderBlitter() | |
919 { | |
920 fShader->endSession(); | |
921 fShader->unref(); | |
922 } | |
923 | |
OLD | NEW |