3 * Copyright 2006 The Android Open Source Project
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
10 #include "SkScanPriv.h"
13 #include "SkBlitter.h"
15 #include "SkAntiRun.h"
18 #define SCALE (1 << SHIFT)
19 #define MASK (SCALE - 1)
22 We have two techniques for capturing the output of the supersampler:
23 - SUPERMASK, which records a large mask-bitmap
24 this is often faster for small, complex objects
25 - RLE, which records a rle-encoded scanline
26 this is often faster for large objects with big spans
28 These blitters use two coordinate systems:
29 - destination coordinates, scale equal to the output - often
30 abbreviated with 'i' or 'I' in variable names
31 - supersampled coordinates, scale equal to the output * SCALE
34 //#define FORCE_SUPERMASK
37 ///////////////////////////////////////////////////////////////////////////////
39 /// Base class for a single-pass supersampled blitter.
40 class BaseSuperBlitter : public SkBlitter {
42 BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
43 const SkRegion& clip, bool isInverse);
45 /// Must be explicitly defined on subclasses.
46 virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
47 const int16_t runs[]) override {
48 SkDEBUGFAIL("How did I get here?");
50 /// May not be called on BaseSuperBlitter because it blits out of order.
51 void blitV(int x, int y, int height, SkAlpha alpha) override {
52 SkDEBUGFAIL("How did I get here?");
56 SkBlitter* fRealBlitter;
57 /// Current y coordinate, in destination coordinates.
59 /// Widest row of region to be blitted, in destination coordinates.
61 /// Leftmost x coordinate in any row, in destination coordinates.
63 /// Leftmost x coordinate in any row, in supersampled coordinates.
66 SkDEBUGCODE(int fCurrX;)
67 /// Current y coordinate in supersampled coordinates.
69 /// Initial y coordinate (top of bounds).
75 BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlit, const SkIRect& ir, const SkRegion& clip,
77 fRealBlitter = realBlit;
81 // We use the clip bounds instead of the ir, since we may be asked to
82 //draw outside of the rect when we're a inverse filltype
83 sectBounds = clip.getBounds();
85 if (!sectBounds.intersect(ir, clip.getBounds())) {
86 sectBounds.setEmpty();
90 const int left = sectBounds.left();
91 const int right = sectBounds.right();
94 fSuperLeft = left << SHIFT;
95 fWidth = right - left;
96 fTop = sectBounds.top();
98 fCurrY = (fTop << SHIFT) - 1;
100 SkDEBUGCODE(fCurrX = -1;)
103 /// Run-length-encoded supersampling antialiased blitter.
104 class SuperBlitter : public BaseSuperBlitter {
106 SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse);
108 virtual ~SuperBlitter() {
112 /// Once fRuns contains a complete supersampled row, flush() blits
113 /// it out through the wrapped blitter.
116 /// Blits a row of pixels, with location and width specified
117 /// in supersampled coordinates.
118 void blitH(int x, int y, int width) override;
119 /// Blits a rectangle of pixels, with location and size specified
120 /// in supersampled coordinates.
121 void blitRect(int x, int y, int width, int height) override;
124 // The next three variables are used to track a circular buffer that
125 // contains the values used in SkAlphaRuns. These variables should only
126 // ever be updated in advanceRuns(), and fRuns should always point to
127 // a valid SkAlphaRuns...
133 // extra one to store the zero at the end
134 int getRunsSz() const { return (fWidth + 1 + (fWidth + 2)/2) * sizeof(int16_t); }
136 // This function updates the fRuns variable to point to the next buffer space
137 // with adequate storage for a SkAlphaRuns. It mostly just advances fCurrentRun
138 // and resets fRuns to point to an empty scanline.
140 const size_t kRunsSz = this->getRunsSz();
141 fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer;
142 fRuns.fRuns = reinterpret_cast<int16_t*>(
143 reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz);
144 fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1);
151 SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
153 : BaseSuperBlitter(realBlitter, ir, clip, isInverse)
155 fRunsToBuffer = realBlitter->requestRowsPreserved();
156 fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz());
164 void SuperBlitter::flush() {
165 if (fCurrIY >= fTop) {
167 SkASSERT(fCurrentRun < fRunsToBuffer);
168 if (!fRuns.empty()) {
169 // SkDEBUGCODE(fRuns.dump();)
170 fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
176 SkDEBUGCODE(fCurrX = -1;)
180 /** coverage_to_partial_alpha() is being used by SkAlphaRuns, which
181 *accumulates* SCALE pixels worth of "alpha" in [0,(256/SCALE)]
182 to produce a final value in [0, 255] and handles clamping 256->255
183 itself, with the same (alpha - (alpha >> 8)) correction as
184 coverage_to_exact_alpha().
186 static inline int coverage_to_partial_alpha(int aa) {
191 /** coverage_to_exact_alpha() is being used by our blitter, which wants
192 a final value in [0, 255].
194 static inline int coverage_to_exact_alpha(int aa) {
195 int alpha = (256 >> SHIFT) * aa;
197 return alpha - (alpha >> 8);
200 void SuperBlitter::blitH(int x, int y, int width) {
204 SkASSERT(iy >= fCurrIY);
207 // hack, until I figure out why my cubics (I think) go beyond the bounds
214 SkASSERT(y != fCurrY || x >= fCurrX);
216 SkASSERT(y >= fCurrY);
222 if (iy != fCurrIY) { // new scanline
228 int stop = x + width;
230 SkASSERT(start >= 0 && stop > start);
231 // integer-pixel-aligned ends of blit, rounded out
232 int fb = start & MASK;
233 int fe = stop & MASK;
234 int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
248 fOffsetX = fRuns.add(x >> SHIFT, coverage_to_partial_alpha(fb),
249 n, coverage_to_partial_alpha(fe),
250 (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT),
254 fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));
260 static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
261 int n, U8CPU riteA) {
262 SkASSERT(leftA <= 0xFF);
263 SkASSERT(riteA <= 0xFF);
265 int16_t* run = runs.fRuns;
266 uint8_t* aa = runs.fAlpha;
275 SkASSERT(leftA < 0xFF);
288 SkASSERT(riteA < 0xFF);
297 void SuperBlitter::blitRect(int x, int y, int width, int height) {
299 SkASSERT(height > 0);
303 this->blitH(x, y++, width);
308 SkASSERT(height > 0);
310 // Since this is a rect, instead of blitting supersampled rows one at a
311 // time and then resolving to the destination canvas, we can blit
312 // directly to the destintion canvas one row per SCALE supersampled rows.
313 int start_y = y >> SHIFT;
314 int stop_y = (y + height) >> SHIFT;
315 int count = stop_y - start_y;
318 height -= count << SHIFT;
320 // save original X for our tail blitH() loop at the bottom
324 // hack, until I figure out why my cubics (I think) go beyond the bounds
330 // There is always a left column, a middle, and a right column.
331 // ileft is the destination x of the first pixel of the entire rect.
332 // xleft is (SCALE - # of covered supersampled pixels) in that
333 // destination pixel.
334 int ileft = x >> SHIFT;
335 int xleft = x & MASK;
336 // irite is the destination x of the last pixel of the OPAQUE section.
337 // xrite is the number of supersampled pixels extending beyond irite;
338 // xrite/SCALE should give us alpha.
339 int irite = (x + width) >> SHIFT;
340 int xrite = (x + width) & MASK;
346 // Need to call flush() to clean up pending draws before we
347 // even consider blitV(), since otherwise it can look nonmonotonic.
348 SkASSERT(start_y > fCurrIY);
351 int n = irite - ileft - 1;
353 // If n < 0, we'll only have a single partially-transparent column
354 // of pixels to render.
355 xleft = xrite - xleft;
356 SkASSERT(xleft <= SCALE);
359 fRealBlitter->blitV(ileft + fLeft, start_y, count,
360 coverage_to_exact_alpha(xleft));
362 // With n = 0, we have two possibly-transparent columns of pixels
363 // to render; with n > 0, we have opaque columns between them.
365 xleft = SCALE - xleft;
367 // Using coverage_to_exact_alpha is not consistent with blitH()
368 const int coverageL = coverage_to_exact_alpha(xleft);
369 const int coverageR = coverage_to_exact_alpha(xrite);
371 SkASSERT(coverageL > 0 || n > 0 || coverageR > 0);
372 SkASSERT((coverageL != 0) + n + (coverageR != 0) <= fWidth);
374 fRealBlitter->blitAntiRect(ileft + fLeft, start_y, n, count,
375 coverageL, coverageR);
378 // preamble for our next call to blitH()
379 fCurrIY = stop_y - 1;
386 // catch any remaining few rows
387 SkASSERT(height <= MASK);
388 while (--height >= 0) {
389 this->blitH(x, y++, width);
393 ///////////////////////////////////////////////////////////////////////////////
395 /// Masked supersampling antialiased blitter.
396 class MaskSuperBlitter : public BaseSuperBlitter {
398 MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion&, bool isInverse);
399 virtual ~MaskSuperBlitter() {
400 fRealBlitter->blitMask(fMask, fClipRect);
403 void blitH(int x, int y, int width) override;
405 static bool CanHandleRect(const SkIRect& bounds) {
409 int width = bounds.width();
410 int64_t rb = SkAlign4(width);
411 // use 64bits to detect overflow
412 int64_t storage = rb * bounds.height();
414 return (width <= MaskSuperBlitter::kMAX_WIDTH) &&
415 (storage <= MaskSuperBlitter::kMAX_STORAGE);
420 #ifdef FORCE_SUPERMASK
422 kMAX_STORAGE = 1024 * 1024 * 2
424 kMAX_WIDTH = 32, // so we don't try to do very wide things, where the RLE blitter would be faster
431 // we add 1 because add_aa_span can write (unchanged) 1 extra byte at the end, rather than
432 // perform a test to see if stopAlpha != 0
433 uint32_t fStorage[(kMAX_STORAGE >> 2) + 1];
436 MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
438 : BaseSuperBlitter(realBlitter, ir, clip, isInverse)
440 SkASSERT(CanHandleRect(ir));
441 SkASSERT(!isInverse);
443 fMask.fImage = (uint8_t*)fStorage;
445 fMask.fRowBytes = ir.width();
446 fMask.fFormat = SkMask::kA8_Format;
449 if (!fClipRect.intersect(clip.getBounds())) {
451 fClipRect.setEmpty();
454 // For valgrind, write 1 extra byte at the end so we don't read
455 // uninitialized memory. See comment in add_aa_span and fStorage[].
456 memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 1);
459 static void add_aa_span(uint8_t* alpha, U8CPU startAlpha) {
460 /* I should be able to just add alpha[x] + startAlpha.
461 However, if the trailing edge of the previous span and the leading
462 edge of the current span round to the same super-sampled x value,
463 I might overflow to 256 with this add, hence the funny subtract.
465 unsigned tmp = *alpha + startAlpha;
466 SkASSERT(tmp <= 256);
467 *alpha = SkToU8(tmp - (tmp >> 8));
470 static inline uint32_t quadplicate_byte(U8CPU value) {
471 uint32_t pair = (value << 8) | value;
472 return (pair << 16) | pair;
475 // Perform this tricky subtract, to avoid overflowing to 256. Our caller should
476 // only ever call us with at most enough to hit 256 (never larger), so it is
477 // enough to just subtract the high-bit. Actually clamping with a branch would
478 // be slower (e.g. if (tmp > 255) tmp = 255;)
480 static inline void saturated_add(uint8_t* ptr, U8CPU add) {
481 unsigned tmp = *ptr + add;
482 SkASSERT(tmp <= 256);
483 *ptr = SkToU8(tmp - (tmp >> 8));
486 // minimum count before we want to setup an inner loop, adding 4-at-a-time
487 #define MIN_COUNT_FOR_QUAD_LOOP 16
489 static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount,
490 U8CPU stopAlpha, U8CPU maxValue) {
491 SkASSERT(middleCount >= 0);
493 saturated_add(alpha, startAlpha);
496 if (middleCount >= MIN_COUNT_FOR_QUAD_LOOP) {
497 // loop until we're quad-byte aligned
498 while (SkTCast<intptr_t>(alpha) & 0x3) {
499 alpha[0] = SkToU8(alpha[0] + maxValue);
504 int bigCount = middleCount >> 2;
505 uint32_t* qptr = reinterpret_cast<uint32_t*>(alpha);
506 uint32_t qval = quadplicate_byte(maxValue);
509 } while (--bigCount > 0);
512 alpha = reinterpret_cast<uint8_t*> (qptr);
513 // fall through to the following while-loop
516 while (--middleCount >= 0) {
517 alpha[0] = SkToU8(alpha[0] + maxValue);
521 // potentially this can be off the end of our "legal" alpha values, but that
522 // only happens if stopAlpha is also 0. Rather than test for stopAlpha != 0
523 // every time (slow), we just do it, and ensure that we've allocated extra space
524 // (see the + 1 comment in fStorage[]
525 saturated_add(alpha, stopAlpha);
528 void MaskSuperBlitter::blitH(int x, int y, int width) {
529 int iy = (y >> SHIFT);
531 SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
532 iy -= fMask.fBounds.fTop; // make it relative to 0
534 // This should never happen, but it does. Until the true cause is
535 // discovered, let's skip this span instead of crashing.
536 // See http://crbug.com/17569.
544 SkASSERT(ix >= fMask.fBounds.fLeft && ix < fMask.fBounds.fRight);
548 x -= (fMask.fBounds.fLeft << SHIFT);
550 // hack, until I figure out why my cubics (I think) go beyond the bounds
556 uint8_t* row = fMask.fImage + iy * fMask.fRowBytes + (x >> SHIFT);
559 int stop = x + width;
561 SkASSERT(start >= 0 && stop > start);
562 int fb = start & MASK;
563 int fe = stop & MASK;
564 int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
568 SkASSERT(row >= fMask.fImage);
569 SkASSERT(row < fMask.fImage + kMAX_STORAGE + 1);
570 add_aa_span(row, coverage_to_partial_alpha(fe - fb));
573 SkASSERT(row >= fMask.fImage);
574 SkASSERT(row + n + 1 < fMask.fImage + kMAX_STORAGE + 1);
575 add_aa_span(row, coverage_to_partial_alpha(fb),
576 n, coverage_to_partial_alpha(fe),
577 (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT));
585 ///////////////////////////////////////////////////////////////////////////////
587 static bool fitsInsideLimit(const SkRect& r, SkScalar max) {
588 const SkScalar min = -max;
589 return r.fLeft > min && r.fTop > min &&
590 r.fRight < max && r.fBottom < max;
593 static int overflows_short_shift(int value, int shift) {
594 const int s = 16 + shift;
595 return (value << s >> s) - value;
599 Would any of the coordinates of this rectangle not fit in a short,
600 when left-shifted by shift?
602 static int rect_overflows_short_shift(SkIRect rect, int shift) {
603 SkASSERT(!overflows_short_shift(8191, SHIFT));
604 SkASSERT(overflows_short_shift(8192, SHIFT));
605 SkASSERT(!overflows_short_shift(32767, 0));
606 SkASSERT(overflows_short_shift(32768, 0));
608 // Since we expect these to succeed, we bit-or together
609 // for a tiny extra bit of speed.
610 return overflows_short_shift(rect.fLeft, SHIFT) |
611 overflows_short_shift(rect.fRight, SHIFT) |
612 overflows_short_shift(rect.fTop, SHIFT) |
613 overflows_short_shift(rect.fBottom, SHIFT);
616 static bool safeRoundOut(const SkRect& src, SkIRect* dst, int32_t maxInt) {
617 const SkScalar maxScalar = SkIntToScalar(maxInt);
619 if (fitsInsideLimit(src, maxScalar)) {
626 void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
627 SkBlitter* blitter, bool forceRLE) {
628 if (origClip.isEmpty()) {
632 const bool isInverse = path.isInverseFillType();
635 if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) {
637 const SkRect& r = path.getBounds();
638 SkDebugf("--- bounds can't fit in SkIRect\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
644 blitter->blitRegion(origClip);
649 // If the intersection of the path bounds and the clip bounds
650 // will overflow 32767 when << by SHIFT, we can't supersample,
651 // so draw without antialiasing.
654 // If the path is an inverse fill, it's going to fill the entire
655 // clip, and we care whether the entire clip exceeds our limits.
656 clippedIR = origClip.getBounds();
658 if (!clippedIR.intersect(ir, origClip.getBounds())) {
662 if (rect_overflows_short_shift(clippedIR, SHIFT)) {
663 SkScan::FillPath(path, origClip, blitter);
667 // Our antialiasing can't handle a clip larger than 32767, so we restrict
668 // the clip to that limit here. (the runs[] uses int16_t for its index).
670 // A more general solution (one that could also eliminate the need to
671 // disable aa based on ir bounds (see overflows_short_shift) would be
672 // to tile the clip/target...
673 SkRegion tmpClipStorage;
674 const SkRegion* clipRgn = &origClip;
676 static const int32_t kMaxClipCoord = 32767;
677 const SkIRect& bounds = origClip.getBounds();
678 if (bounds.fRight > kMaxClipCoord || bounds.fBottom > kMaxClipCoord) {
679 SkIRect limit = { 0, 0, kMaxClipCoord, kMaxClipCoord };
680 tmpClipStorage.op(origClip, limit, SkRegion::kIntersect_Op);
681 clipRgn = &tmpClipStorage;
684 // for here down, use clipRgn, not origClip
686 SkScanClipper clipper(blitter, clipRgn, ir);
687 const SkIRect* clipRect = clipper.getClipRect();
689 if (clipper.getBlitter() == NULL) { // clipped out
691 blitter->blitRegion(*clipRgn);
696 // now use the (possibly wrapped) blitter
697 blitter = clipper.getBlitter();
700 sk_blit_above(blitter, ir, *clipRgn);
703 SkIRect superRect, *superClipRect = NULL;
706 superRect.set( clipRect->fLeft << SHIFT, clipRect->fTop << SHIFT,
707 clipRect->fRight << SHIFT, clipRect->fBottom << SHIFT);
708 superClipRect = &superRect;
711 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
713 // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
714 // if we're an inverse filltype
715 if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
716 MaskSuperBlitter superBlit(blitter, ir, *clipRgn, isInverse);
717 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
718 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, *clipRgn);
720 SuperBlitter superBlit(blitter, ir, *clipRgn, isInverse);
721 sk_fill_path(path, superClipRect, &superBlit, ir.fTop, ir.fBottom, SHIFT, *clipRgn);
725 sk_blit_below(blitter, ir, *clipRgn);
729 ///////////////////////////////////////////////////////////////////////////////
731 #include "SkRasterClip.h"
733 void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip,
734 SkBlitter* blitter) {
735 if (clip.isEmpty()) {
740 FillPath(path, clip.bwRgn(), blitter);
743 SkAAClipBlitter aaBlitter;
745 tmp.setRect(clip.getBounds());
746 aaBlitter.init(blitter, &clip.aaRgn());
747 SkScan::FillPath(path, tmp, &aaBlitter);
751 void SkScan::AntiFillPath(const SkPath& path, const SkRasterClip& clip,
752 SkBlitter* blitter) {
753 if (clip.isEmpty()) {
758 AntiFillPath(path, clip.bwRgn(), blitter);
761 SkAAClipBlitter aaBlitter;
763 tmp.setRect(clip.getBounds());
764 aaBlitter.init(blitter, &clip.aaRgn());
765 SkScan::AntiFillPath(path, tmp, &aaBlitter, true);