Line data Source code
1 : /*
2 : * Copyright 2006 The Android Open Source Project
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 :
9 : #include "SkScanPriv.h"
10 : #include "SkPath.h"
11 : #include "SkMatrix.h"
12 : #include "SkBlitter.h"
13 : #include "SkRegion.h"
14 : #include "SkAntiRun.h"
15 :
16 : #define SHIFT 2
17 : #define SCALE (1 << SHIFT)
18 : #define MASK (SCALE - 1)
19 :
20 : /** @file
21 : We have two techniques for capturing the output of the supersampler:
22 : - SUPERMASK, which records a large mask-bitmap
23 : this is often faster for small, complex objects
24 : - RLE, which records a rle-encoded scanline
25 : this is often faster for large objects with big spans
26 :
27 : These blitters use two coordinate systems:
28 : - destination coordinates, scale equal to the output - often
29 : abbreviated with 'i' or 'I' in variable names
30 : - supersampled coordinates, scale equal to the output * SCALE
31 : */
32 :
33 : //#define FORCE_SUPERMASK
34 : //#define FORCE_RLE
35 :
36 : ///////////////////////////////////////////////////////////////////////////////
37 :
38 : /// Base class for a single-pass supersampled blitter.
39 40 : class BaseSuperBlitter : public SkBlitter {
40 : public:
41 : BaseSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir,
42 : const SkRegion& clip, bool isInverse);
43 :
44 : /// Must be explicitly defined on subclasses.
45 0 : virtual void blitAntiH(int x, int y, const SkAlpha antialias[],
46 : const int16_t runs[]) override {
47 0 : SkDEBUGFAIL("How did I get here?");
48 0 : }
49 : /// May not be called on BaseSuperBlitter because it blits out of order.
50 0 : void blitV(int x, int y, int height, SkAlpha alpha) override {
51 0 : SkDEBUGFAIL("How did I get here?");
52 0 : }
53 :
54 : protected:
55 : SkBlitter* fRealBlitter;
56 : /// Current y coordinate, in destination coordinates.
57 : int fCurrIY;
58 : /// Widest row of region to be blitted, in destination coordinates.
59 : int fWidth;
60 : /// Leftmost x coordinate in any row, in destination coordinates.
61 : int fLeft;
62 : /// Leftmost x coordinate in any row, in supersampled coordinates.
63 : int fSuperLeft;
64 :
65 : SkDEBUGCODE(int fCurrX;)
66 : /// Current y coordinate in supersampled coordinates.
67 : int fCurrY;
68 : /// Initial y coordinate (top of bounds).
69 : int fTop;
70 :
71 : SkIRect fSectBounds;
72 : };
73 :
74 40 : BaseSuperBlitter::BaseSuperBlitter(SkBlitter* realBlit, const SkIRect& ir, const SkRegion& clip,
75 40 : bool isInverse) {
76 40 : fRealBlitter = realBlit;
77 :
78 : SkIRect sectBounds;
79 40 : if (isInverse) {
80 : // We use the clip bounds instead of the ir, since we may be asked to
81 : //draw outside of the rect when we're a inverse filltype
82 0 : sectBounds = clip.getBounds();
83 : } else {
84 40 : if (!sectBounds.intersect(ir, clip.getBounds())) {
85 0 : sectBounds.setEmpty();
86 : }
87 : }
88 :
89 40 : const int left = sectBounds.left();
90 40 : const int right = sectBounds.right();
91 :
92 40 : fLeft = left;
93 40 : fSuperLeft = SkLeftShift(left, SHIFT);
94 40 : fWidth = right - left;
95 40 : fTop = sectBounds.top();
96 40 : fCurrIY = fTop - 1;
97 40 : fCurrY = SkLeftShift(fTop, SHIFT) - 1;
98 :
99 40 : SkDEBUGCODE(fCurrX = -1;)
100 40 : }
101 :
102 : /// Run-length-encoded supersampling antialiased blitter.
103 : class SuperBlitter : public BaseSuperBlitter {
104 : public:
105 : SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool isInverse);
106 :
107 18 : ~SuperBlitter() override {
108 9 : this->flush();
109 9 : }
110 :
111 : /// Once fRuns contains a complete supersampled row, flush() blits
112 : /// it out through the wrapped blitter.
113 : void flush();
114 :
115 : /// Blits a row of pixels, with location and width specified
116 : /// in supersampled coordinates.
117 : void blitH(int x, int y, int width) override;
118 : /// Blits a rectangle of pixels, with location and size specified
119 : /// in supersampled coordinates.
120 : void blitRect(int x, int y, int width, int height) override;
121 :
122 : private:
123 : // The next three variables are used to track a circular buffer that
124 : // contains the values used in SkAlphaRuns. These variables should only
125 : // ever be updated in advanceRuns(), and fRuns should always point to
126 : // a valid SkAlphaRuns...
127 : int fRunsToBuffer;
128 : void* fRunsBuffer;
129 : int fCurrentRun;
130 : SkAlphaRuns fRuns;
131 :
132 : // extra one to store the zero at the end
133 452 : int getRunsSz() const { return (fWidth + 1 + (fWidth + 2)/2) * sizeof(int16_t); }
134 :
135 : // This function updates the fRuns variable to point to the next buffer space
136 : // with adequate storage for a SkAlphaRuns. It mostly just advances fCurrentRun
137 : // and resets fRuns to point to an empty scanline.
138 443 : void advanceRuns() {
139 443 : const size_t kRunsSz = this->getRunsSz();
140 443 : fCurrentRun = (fCurrentRun + 1) % fRunsToBuffer;
141 443 : fRuns.fRuns = reinterpret_cast<int16_t*>(
142 443 : reinterpret_cast<uint8_t*>(fRunsBuffer) + fCurrentRun * kRunsSz);
143 443 : fRuns.fAlpha = reinterpret_cast<SkAlpha*>(fRuns.fRuns + fWidth + 1);
144 443 : fRuns.reset(fWidth);
145 443 : }
146 :
147 : int fOffsetX;
148 : };
149 :
150 9 : SuperBlitter::SuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
151 9 : bool isInverse)
152 9 : : BaseSuperBlitter(realBlitter, ir, clip, isInverse)
153 : {
154 9 : fRunsToBuffer = realBlitter->requestRowsPreserved();
155 9 : fRunsBuffer = realBlitter->allocBlitMemory(fRunsToBuffer * this->getRunsSz());
156 9 : fCurrentRun = -1;
157 :
158 9 : this->advanceRuns();
159 :
160 9 : fOffsetX = 0;
161 9 : }
162 :
163 443 : void SuperBlitter::flush() {
164 443 : if (fCurrIY >= fTop) {
165 :
166 434 : SkASSERT(fCurrentRun < fRunsToBuffer);
167 434 : if (!fRuns.empty()) {
168 : // SkDEBUGCODE(fRuns.dump();)
169 434 : fRealBlitter->blitAntiH(fLeft, fCurrIY, fRuns.fAlpha, fRuns.fRuns);
170 434 : this->advanceRuns();
171 434 : fOffsetX = 0;
172 : }
173 :
174 434 : fCurrIY = fTop - 1;
175 434 : SkDEBUGCODE(fCurrX = -1;)
176 : }
177 443 : }
178 :
179 : /** coverage_to_partial_alpha() is being used by SkAlphaRuns, which
180 : *accumulates* SCALE pixels worth of "alpha" in [0,(256/SCALE)]
181 : to produce a final value in [0, 255] and handles clamping 256->255
182 : itself, with the same (alpha - (alpha >> 8)) correction as
183 : coverage_to_exact_alpha().
184 : */
185 12674 : static inline int coverage_to_partial_alpha(int aa) {
186 12674 : aa <<= 8 - 2*SHIFT;
187 12674 : return aa;
188 : }
189 :
190 : /** coverage_to_exact_alpha() is being used by our blitter, which wants
191 : a final value in [0, 255].
192 : */
193 0 : static inline int coverage_to_exact_alpha(int aa) {
194 0 : int alpha = (256 >> SHIFT) * aa;
195 : // clamp 256->255
196 0 : return alpha - (alpha >> 8);
197 : }
198 :
199 2861 : void SuperBlitter::blitH(int x, int y, int width) {
200 2861 : SkASSERT(width > 0);
201 :
202 2861 : int iy = y >> SHIFT;
203 2861 : SkASSERT(iy >= fCurrIY);
204 :
205 2861 : x -= fSuperLeft;
206 : // hack, until I figure out why my cubics (I think) go beyond the bounds
207 2861 : if (x < 0) {
208 0 : width += x;
209 0 : x = 0;
210 : }
211 :
212 : #ifdef SK_DEBUG
213 2861 : SkASSERT(y != fCurrY || x >= fCurrX);
214 : #endif
215 2861 : SkASSERT(y >= fCurrY);
216 2861 : if (fCurrY != y) {
217 1732 : fOffsetX = 0;
218 1732 : fCurrY = y;
219 : }
220 :
221 2861 : if (iy != fCurrIY) { // new scanline
222 434 : this->flush();
223 434 : fCurrIY = iy;
224 : }
225 :
226 2861 : int start = x;
227 2861 : int stop = x + width;
228 :
229 2861 : SkASSERT(start >= 0 && stop > start);
230 : // integer-pixel-aligned ends of blit, rounded out
231 2861 : int fb = start & MASK;
232 2861 : int fe = stop & MASK;
233 2861 : int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
234 :
235 2861 : if (n < 0) {
236 2 : fb = fe - fb;
237 2 : n = 0;
238 2 : fe = 0;
239 : } else {
240 2859 : if (fb == 0) {
241 836 : n += 1;
242 : } else {
243 2023 : fb = SCALE - fb;
244 : }
245 : }
246 :
247 11444 : fOffsetX = fRuns.add(x >> SHIFT, coverage_to_partial_alpha(fb),
248 2861 : n, coverage_to_partial_alpha(fe),
249 2861 : (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT),
250 : fOffsetX);
251 :
252 : #ifdef SK_DEBUG
253 2861 : fRuns.assertValid(y & MASK, (1 << (8 - SHIFT)));
254 2861 : fCurrX = x + width;
255 : #endif
256 2861 : }
257 :
258 : #if 0 // UNUSED
259 : static void set_left_rite_runs(SkAlphaRuns& runs, int ileft, U8CPU leftA,
260 : int n, U8CPU riteA) {
261 : SkASSERT(leftA <= 0xFF);
262 : SkASSERT(riteA <= 0xFF);
263 :
264 : int16_t* run = runs.fRuns;
265 : uint8_t* aa = runs.fAlpha;
266 :
267 : if (ileft > 0) {
268 : run[0] = ileft;
269 : aa[0] = 0;
270 : run += ileft;
271 : aa += ileft;
272 : }
273 :
274 : SkASSERT(leftA < 0xFF);
275 : if (leftA > 0) {
276 : *run++ = 1;
277 : *aa++ = leftA;
278 : }
279 :
280 : if (n > 0) {
281 : run[0] = n;
282 : aa[0] = 0xFF;
283 : run += n;
284 : aa += n;
285 : }
286 :
287 : SkASSERT(riteA < 0xFF);
288 : if (riteA > 0) {
289 : *run++ = 1;
290 : *aa++ = riteA;
291 : }
292 : run[0] = 0;
293 : }
294 : #endif
295 :
296 0 : void SuperBlitter::blitRect(int x, int y, int width, int height) {
297 0 : SkASSERT(width > 0);
298 0 : SkASSERT(height > 0);
299 :
300 : // blit leading rows
301 0 : while ((y & MASK)) {
302 0 : this->blitH(x, y++, width);
303 0 : if (--height <= 0) {
304 0 : return;
305 : }
306 : }
307 0 : SkASSERT(height > 0);
308 :
309 : // Since this is a rect, instead of blitting supersampled rows one at a
310 : // time and then resolving to the destination canvas, we can blit
311 : // directly to the destintion canvas one row per SCALE supersampled rows.
312 0 : int start_y = y >> SHIFT;
313 0 : int stop_y = (y + height) >> SHIFT;
314 0 : int count = stop_y - start_y;
315 0 : if (count > 0) {
316 0 : y += count << SHIFT;
317 0 : height -= count << SHIFT;
318 :
319 : // save original X for our tail blitH() loop at the bottom
320 0 : int origX = x;
321 :
322 0 : x -= fSuperLeft;
323 : // hack, until I figure out why my cubics (I think) go beyond the bounds
324 0 : if (x < 0) {
325 0 : width += x;
326 0 : x = 0;
327 : }
328 :
329 : // There is always a left column, a middle, and a right column.
330 : // ileft is the destination x of the first pixel of the entire rect.
331 : // xleft is (SCALE - # of covered supersampled pixels) in that
332 : // destination pixel.
333 0 : int ileft = x >> SHIFT;
334 0 : int xleft = x & MASK;
335 : // irite is the destination x of the last pixel of the OPAQUE section.
336 : // xrite is the number of supersampled pixels extending beyond irite;
337 : // xrite/SCALE should give us alpha.
338 0 : int irite = (x + width) >> SHIFT;
339 0 : int xrite = (x + width) & MASK;
340 0 : if (!xrite) {
341 0 : xrite = SCALE;
342 0 : irite--;
343 : }
344 :
345 : // Need to call flush() to clean up pending draws before we
346 : // even consider blitV(), since otherwise it can look nonmonotonic.
347 0 : SkASSERT(start_y > fCurrIY);
348 0 : this->flush();
349 :
350 0 : int n = irite - ileft - 1;
351 0 : if (n < 0) {
352 : // If n < 0, we'll only have a single partially-transparent column
353 : // of pixels to render.
354 0 : xleft = xrite - xleft;
355 0 : SkASSERT(xleft <= SCALE);
356 0 : SkASSERT(xleft > 0);
357 0 : fRealBlitter->blitV(ileft + fLeft, start_y, count,
358 0 : coverage_to_exact_alpha(xleft));
359 : } else {
360 : // With n = 0, we have two possibly-transparent columns of pixels
361 : // to render; with n > 0, we have opaque columns between them.
362 :
363 0 : xleft = SCALE - xleft;
364 :
365 : // Using coverage_to_exact_alpha is not consistent with blitH()
366 0 : const int coverageL = coverage_to_exact_alpha(xleft);
367 0 : const int coverageR = coverage_to_exact_alpha(xrite);
368 :
369 0 : SkASSERT(coverageL > 0 || n > 0 || coverageR > 0);
370 0 : SkASSERT((coverageL != 0) + n + (coverageR != 0) <= fWidth);
371 :
372 0 : fRealBlitter->blitAntiRect(ileft + fLeft, start_y, n, count,
373 0 : coverageL, coverageR);
374 : }
375 :
376 : // preamble for our next call to blitH()
377 0 : fCurrIY = stop_y - 1;
378 0 : fOffsetX = 0;
379 0 : fCurrY = y - 1;
380 0 : fRuns.reset(fWidth);
381 0 : x = origX;
382 : }
383 :
384 : // catch any remaining few rows
385 0 : SkASSERT(height <= MASK);
386 0 : while (--height >= 0) {
387 0 : this->blitH(x, y++, width);
388 : }
389 : }
390 :
391 : ///////////////////////////////////////////////////////////////////////////////
392 :
393 : /// Masked supersampling antialiased blitter.
394 : class MaskSuperBlitter : public BaseSuperBlitter {
395 : public:
396 : MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion&, bool isInverse);
397 62 : ~MaskSuperBlitter() override {
398 31 : fRealBlitter->blitMask(fMask, fClipRect);
399 31 : }
400 :
401 : void blitH(int x, int y, int width) override;
402 :
403 71 : static bool CanHandleRect(const SkIRect& bounds) {
404 : #ifdef FORCE_RLE
405 : return false;
406 : #endif
407 71 : int width = bounds.width();
408 71 : int64_t rb = SkAlign4(width);
409 : // use 64bits to detect overflow
410 71 : int64_t storage = rb * bounds.height();
411 :
412 71 : return (width <= MaskSuperBlitter::kMAX_WIDTH) &&
413 71 : (storage <= MaskSuperBlitter::kMAX_STORAGE);
414 : }
415 :
416 : private:
417 : enum {
418 : #ifdef FORCE_SUPERMASK
419 : kMAX_WIDTH = 2048,
420 : kMAX_STORAGE = 1024 * 1024 * 2
421 : #else
422 : kMAX_WIDTH = 32, // so we don't try to do very wide things, where the RLE blitter would be faster
423 : kMAX_STORAGE = 1024
424 : #endif
425 : };
426 :
427 : SkMask fMask;
428 : SkIRect fClipRect;
429 : // we add 1 because add_aa_span can write (unchanged) 1 extra byte at the end, rather than
430 : // perform a test to see if stopAlpha != 0
431 : uint32_t fStorage[(kMAX_STORAGE >> 2) + 1];
432 : };
433 :
434 31 : MaskSuperBlitter::MaskSuperBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip,
435 31 : bool isInverse)
436 31 : : BaseSuperBlitter(realBlitter, ir, clip, isInverse)
437 : {
438 31 : SkASSERT(CanHandleRect(ir));
439 31 : SkASSERT(!isInverse);
440 :
441 31 : fMask.fImage = (uint8_t*)fStorage;
442 31 : fMask.fBounds = ir;
443 31 : fMask.fRowBytes = ir.width();
444 31 : fMask.fFormat = SkMask::kA8_Format;
445 :
446 31 : fClipRect = ir;
447 31 : if (!fClipRect.intersect(clip.getBounds())) {
448 0 : SkASSERT(0);
449 0 : fClipRect.setEmpty();
450 : }
451 :
452 : // For valgrind, write 1 extra byte at the end so we don't read
453 : // uninitialized memory. See comment in add_aa_span and fStorage[].
454 31 : memset(fStorage, 0, fMask.fBounds.height() * fMask.fRowBytes + 1);
455 31 : }
456 :
457 60 : static void add_aa_span(uint8_t* alpha, U8CPU startAlpha) {
458 : /* I should be able to just add alpha[x] + startAlpha.
459 : However, if the trailing edge of the previous span and the leading
460 : edge of the current span round to the same super-sampled x value,
461 : I might overflow to 256 with this add, hence the funny subtract.
462 : */
463 60 : unsigned tmp = *alpha + startAlpha;
464 60 : SkASSERT(tmp <= 256);
465 60 : *alpha = SkToU8(tmp - (tmp >> 8));
466 60 : }
467 :
468 567 : static inline uint32_t quadplicate_byte(U8CPU value) {
469 567 : uint32_t pair = (value << 8) | value;
470 567 : return (pair << 16) | pair;
471 : }
472 :
473 : // Perform this tricky subtract, to avoid overflowing to 256. Our caller should
474 : // only ever call us with at most enough to hit 256 (never larger), so it is
475 : // enough to just subtract the high-bit. Actually clamping with a branch would
476 : // be slower (e.g. if (tmp > 255) tmp = 255;)
477 : //
478 6892 : static inline void saturated_add(uint8_t* ptr, U8CPU add) {
479 6892 : unsigned tmp = *ptr + add;
480 6892 : SkASSERT(tmp <= 256);
481 6892 : *ptr = SkToU8(tmp - (tmp >> 8));
482 6892 : }
483 :
484 : // minimum count before we want to setup an inner loop, adding 4-at-a-time
485 : #define MIN_COUNT_FOR_QUAD_LOOP 16
486 :
487 3446 : static void add_aa_span(uint8_t* alpha, U8CPU startAlpha, int middleCount,
488 : U8CPU stopAlpha, U8CPU maxValue) {
489 3446 : SkASSERT(middleCount >= 0);
490 :
491 3446 : saturated_add(alpha, startAlpha);
492 3446 : alpha += 1;
493 :
494 3446 : if (middleCount >= MIN_COUNT_FOR_QUAD_LOOP) {
495 : // loop until we're quad-byte aligned
496 3111 : while (SkTCast<intptr_t>(alpha) & 0x3) {
497 1272 : alpha[0] = SkToU8(alpha[0] + maxValue);
498 1272 : alpha += 1;
499 1272 : middleCount -= 1;
500 : }
501 :
502 567 : int bigCount = middleCount >> 2;
503 567 : uint32_t* qptr = reinterpret_cast<uint32_t*>(alpha);
504 567 : uint32_t qval = quadplicate_byte(maxValue);
505 2903 : do {
506 2903 : *qptr++ += qval;
507 : } while (--bigCount > 0);
508 :
509 567 : middleCount &= 3;
510 567 : alpha = reinterpret_cast<uint8_t*> (qptr);
511 : // fall through to the following while-loop
512 : }
513 :
514 29676 : while (--middleCount >= 0) {
515 13115 : alpha[0] = SkToU8(alpha[0] + maxValue);
516 13115 : alpha += 1;
517 : }
518 :
519 : // potentially this can be off the end of our "legal" alpha values, but that
520 : // only happens if stopAlpha is also 0. Rather than test for stopAlpha != 0
521 : // every time (slow), we just do it, and ensure that we've allocated extra space
522 : // (see the + 1 comment in fStorage[]
523 3446 : saturated_add(alpha, stopAlpha);
524 3446 : }
525 :
526 3506 : void MaskSuperBlitter::blitH(int x, int y, int width) {
527 3506 : int iy = (y >> SHIFT);
528 :
529 3506 : SkASSERT(iy >= fMask.fBounds.fTop && iy < fMask.fBounds.fBottom);
530 3506 : iy -= fMask.fBounds.fTop; // make it relative to 0
531 :
532 : // This should never happen, but it does. Until the true cause is
533 : // discovered, let's skip this span instead of crashing.
534 : // See http://crbug.com/17569.
535 3506 : if (iy < 0) {
536 0 : return;
537 : }
538 :
539 : #ifdef SK_DEBUG
540 : {
541 3506 : int ix = x >> SHIFT;
542 3506 : SkASSERT(ix >= fMask.fBounds.fLeft && ix < fMask.fBounds.fRight);
543 : }
544 : #endif
545 :
546 3506 : x -= SkLeftShift(fMask.fBounds.fLeft, SHIFT);
547 :
548 : // hack, until I figure out why my cubics (I think) go beyond the bounds
549 3506 : if (x < 0) {
550 0 : width += x;
551 0 : x = 0;
552 : }
553 :
554 3506 : uint8_t* row = fMask.fImage + iy * fMask.fRowBytes + (x >> SHIFT);
555 :
556 3506 : int start = x;
557 3506 : int stop = x + width;
558 :
559 3506 : SkASSERT(start >= 0 && stop > start);
560 3506 : int fb = start & MASK;
561 3506 : int fe = stop & MASK;
562 3506 : int n = (stop >> SHIFT) - (start >> SHIFT) - 1;
563 :
564 :
565 3506 : if (n < 0) {
566 60 : SkASSERT(row >= fMask.fImage);
567 60 : SkASSERT(row < fMask.fImage + kMAX_STORAGE + 1);
568 60 : add_aa_span(row, coverage_to_partial_alpha(fe - fb));
569 : } else {
570 3446 : fb = SCALE - fb;
571 3446 : SkASSERT(row >= fMask.fImage);
572 3446 : SkASSERT(row + n + 1 < fMask.fImage + kMAX_STORAGE + 1);
573 6892 : add_aa_span(row, coverage_to_partial_alpha(fb),
574 3446 : n, coverage_to_partial_alpha(fe),
575 6892 : (1 << (8 - SHIFT)) - (((y & MASK) + 1) >> SHIFT));
576 : }
577 :
578 : #ifdef SK_DEBUG
579 3506 : fCurrX = x + width;
580 : #endif
581 : }
582 :
583 : ///////////////////////////////////////////////////////////////////////////////
584 :
585 40 : static bool fitsInsideLimit(const SkRect& r, SkScalar max) {
586 40 : const SkScalar min = -max;
587 120 : return r.fLeft > min && r.fTop > min &&
588 120 : r.fRight < max && r.fBottom < max;
589 : }
590 :
591 320 : static int overflows_short_shift(int value, int shift) {
592 320 : const int s = 16 + shift;
593 320 : return (SkLeftShift(value, s) >> s) - value;
594 : }
595 :
596 : /**
597 : Would any of the coordinates of this rectangle not fit in a short,
598 : when left-shifted by shift?
599 : */
600 40 : static int rect_overflows_short_shift(SkIRect rect, int shift) {
601 40 : SkASSERT(!overflows_short_shift(8191, SHIFT));
602 40 : SkASSERT(overflows_short_shift(8192, SHIFT));
603 40 : SkASSERT(!overflows_short_shift(32767, 0));
604 40 : SkASSERT(overflows_short_shift(32768, 0));
605 :
606 : // Since we expect these to succeed, we bit-or together
607 : // for a tiny extra bit of speed.
608 80 : return overflows_short_shift(rect.fLeft, SHIFT) |
609 80 : overflows_short_shift(rect.fRight, SHIFT) |
610 40 : overflows_short_shift(rect.fTop, SHIFT) |
611 40 : overflows_short_shift(rect.fBottom, SHIFT);
612 : }
613 :
614 40 : static bool safeRoundOut(const SkRect& src, SkIRect* dst, int32_t maxInt) {
615 40 : const SkScalar maxScalar = SkIntToScalar(maxInt);
616 :
617 40 : if (fitsInsideLimit(src, maxScalar)) {
618 40 : src.roundOut(dst);
619 40 : return true;
620 : }
621 0 : return false;
622 : }
623 :
624 40 : void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
625 : SkBlitter* blitter, bool forceRLE) {
626 40 : if (origClip.isEmpty()) {
627 0 : return;
628 : }
629 :
630 40 : const bool isInverse = path.isInverseFillType();
631 : SkIRect ir;
632 :
633 40 : if (!safeRoundOut(path.getBounds(), &ir, SK_MaxS32 >> SHIFT)) {
634 : #if 0
635 : const SkRect& r = path.getBounds();
636 : SkDebugf("--- bounds can't fit in SkIRect\n", r.fLeft, r.fTop, r.fRight, r.fBottom);
637 : #endif
638 0 : return;
639 : }
640 40 : if (ir.isEmpty()) {
641 0 : if (isInverse) {
642 0 : blitter->blitRegion(origClip);
643 : }
644 0 : return;
645 : }
646 :
647 : // If the intersection of the path bounds and the clip bounds
648 : // will overflow 32767 when << by SHIFT, we can't supersample,
649 : // so draw without antialiasing.
650 : SkIRect clippedIR;
651 40 : if (isInverse) {
652 : // If the path is an inverse fill, it's going to fill the entire
653 : // clip, and we care whether the entire clip exceeds our limits.
654 0 : clippedIR = origClip.getBounds();
655 : } else {
656 40 : if (!clippedIR.intersect(ir, origClip.getBounds())) {
657 0 : return;
658 : }
659 : }
660 40 : if (rect_overflows_short_shift(clippedIR, SHIFT)) {
661 0 : SkScan::FillPath(path, origClip, blitter);
662 0 : return;
663 : }
664 :
665 : // Our antialiasing can't handle a clip larger than 32767, so we restrict
666 : // the clip to that limit here. (the runs[] uses int16_t for its index).
667 : //
668 : // A more general solution (one that could also eliminate the need to
669 : // disable aa based on ir bounds (see overflows_short_shift) would be
670 : // to tile the clip/target...
671 80 : SkRegion tmpClipStorage;
672 40 : const SkRegion* clipRgn = &origClip;
673 : {
674 : static const int32_t kMaxClipCoord = 32767;
675 40 : const SkIRect& bounds = origClip.getBounds();
676 40 : if (bounds.fRight > kMaxClipCoord || bounds.fBottom > kMaxClipCoord) {
677 0 : SkIRect limit = { 0, 0, kMaxClipCoord, kMaxClipCoord };
678 0 : tmpClipStorage.op(origClip, limit, SkRegion::kIntersect_Op);
679 0 : clipRgn = &tmpClipStorage;
680 : }
681 : }
682 : // for here down, use clipRgn, not origClip
683 :
684 80 : SkScanClipper clipper(blitter, clipRgn, ir);
685 40 : const SkIRect* clipRect = clipper.getClipRect();
686 :
687 40 : if (clipper.getBlitter() == nullptr) { // clipped out
688 0 : if (isInverse) {
689 0 : blitter->blitRegion(*clipRgn);
690 : }
691 0 : return;
692 : }
693 :
694 40 : SkASSERT(clipper.getClipRect() == nullptr ||
695 : *clipper.getClipRect() == clipRgn->getBounds());
696 :
697 : // now use the (possibly wrapped) blitter
698 40 : blitter = clipper.getBlitter();
699 :
700 40 : if (isInverse) {
701 0 : sk_blit_above(blitter, ir, *clipRgn);
702 : }
703 :
704 40 : SkIRect superRect, *superClipRect = nullptr;
705 :
706 40 : if (clipRect) {
707 21 : superRect.set(SkLeftShift(clipRect->fLeft, SHIFT),
708 7 : SkLeftShift(clipRect->fTop, SHIFT),
709 7 : SkLeftShift(clipRect->fRight, SHIFT),
710 14 : SkLeftShift(clipRect->fBottom, SHIFT));
711 7 : superClipRect = &superRect;
712 : }
713 :
714 40 : SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
715 :
716 : // MaskSuperBlitter can't handle drawing outside of ir, so we can't use it
717 : // if we're an inverse filltype
718 40 : if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
719 62 : MaskSuperBlitter superBlit(blitter, ir, *clipRgn, isInverse);
720 31 : SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
721 31 : sk_fill_path(path, clipRgn->getBounds(), &superBlit, ir.fTop, ir.fBottom, SHIFT,
722 31 : superClipRect == nullptr);
723 : } else {
724 18 : SuperBlitter superBlit(blitter, ir, *clipRgn, isInverse);
725 9 : sk_fill_path(path, clipRgn->getBounds(), &superBlit, ir.fTop, ir.fBottom, SHIFT,
726 9 : superClipRect == nullptr);
727 : }
728 :
729 40 : if (isInverse) {
730 0 : sk_blit_below(blitter, ir, *clipRgn);
731 : }
732 : }
733 :
734 : ///////////////////////////////////////////////////////////////////////////////
735 :
736 : #include "SkRasterClip.h"
737 :
738 0 : void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip,
739 : SkBlitter* blitter) {
740 0 : if (clip.isEmpty()) {
741 0 : return;
742 : }
743 :
744 0 : if (clip.isBW()) {
745 0 : FillPath(path, clip.bwRgn(), blitter);
746 : } else {
747 0 : SkRegion tmp;
748 0 : SkAAClipBlitter aaBlitter;
749 :
750 0 : tmp.setRect(clip.getBounds());
751 0 : aaBlitter.init(blitter, &clip.aaRgn());
752 0 : SkScan::FillPath(path, tmp, &aaBlitter);
753 : }
754 : }
755 :
756 74 : static bool suitableForAAA(const SkPath& path) {
757 74 : if (gSkForceAnalyticAA.load()) {
758 0 : return true;
759 : }
760 74 : const SkRect& bounds = path.getBounds();
761 : // When the path have so many points compared to the size of its bounds/resolution,
762 : // it indicates that the path is not quite smooth in the current resolution:
763 : // the expected number of turning points in every pixel row/column is significantly greater than
764 : // zero. Hence Aanlytic AA is not likely to produce visible quality improvements, and Analytic
765 : // AA might be slower than supersampling.
766 74 : return path.countPoints() < SkTMax(bounds.width(), bounds.height()) / 2 - 10;
767 : }
768 :
769 74 : void SkScan::AntiFillPath(const SkPath& path, const SkRasterClip& clip,
770 : SkBlitter* blitter) {
771 : // Do not use AAA if path is too complicated:
772 : // there won't be any speedup or significant visual improvement.
773 74 : if (gSkUseAnalyticAA.load() && suitableForAAA(path)) {
774 34 : SkScan::AAAFillPath(path, clip, blitter);
775 34 : return;
776 : }
777 :
778 40 : if (clip.isEmpty()) {
779 0 : return;
780 : }
781 :
782 40 : if (clip.isBW()) {
783 40 : AntiFillPath(path, clip.bwRgn(), blitter);
784 : } else {
785 0 : SkRegion tmp;
786 0 : SkAAClipBlitter aaBlitter;
787 :
788 0 : tmp.setRect(clip.getBounds());
789 0 : aaBlitter.init(blitter, &clip.aaRgn());
790 0 : SkScan::AntiFillPath(path, tmp, &aaBlitter, true);
791 : }
792 : }
|