1 2 /* 3 * Copyright 2011 Google Inc. 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 #include "SkAAClip.h" 10 #include "SkBlitter.h" 11 #include "SkColorPriv.h" 12 #include "SkPath.h" 13 #include "SkScan.h" 14 #include "SkThread.h" 15 #include "SkUtils.h" 16 17 class AutoAAClipValidate { 18 public: 19 AutoAAClipValidate(const SkAAClip& clip) : fClip(clip) { 20 fClip.validate(); 21 } 22 ~AutoAAClipValidate() { 23 fClip.validate(); 24 } 25 private: 26 const SkAAClip& fClip; 27 }; 28 29 #ifdef SK_DEBUG 30 #define AUTO_AACLIP_VALIDATE(clip) AutoAAClipValidate acv(clip) 31 #else 32 #define AUTO_AACLIP_VALIDATE(clip) 33 #endif 34 35 /////////////////////////////////////////////////////////////////////////////// 36 37 #define kMaxInt32 0x7FFFFFFF 38 39 #ifdef SK_DEBUG 40 static inline bool x_in_rect(int x, const SkIRect& rect) { 41 return (unsigned)(x - rect.fLeft) < (unsigned)rect.width(); 42 } 43 #endif 44 45 static inline bool y_in_rect(int y, const SkIRect& rect) { 46 return (unsigned)(y - rect.fTop) < (unsigned)rect.height(); 47 } 48 49 /* 50 * Data runs are packed [count, alpha] 51 */ 52 53 struct SkAAClip::YOffset { 54 int32_t fY; 55 uint32_t fOffset; 56 }; 57 58 struct SkAAClip::RunHead { 59 int32_t fRefCnt; 60 int32_t fRowCount; 61 size_t fDataSize; 62 63 YOffset* yoffsets() { 64 return (YOffset*)((char*)this + sizeof(RunHead)); 65 } 66 const YOffset* yoffsets() const { 67 return (const YOffset*)((const char*)this + sizeof(RunHead)); 68 } 69 uint8_t* data() { 70 return (uint8_t*)(this->yoffsets() + fRowCount); 71 } 72 const uint8_t* data() const { 73 return (const uint8_t*)(this->yoffsets() + fRowCount); 74 } 75 76 static RunHead* Alloc(int rowCount, size_t dataSize) { 77 size_t size = sizeof(RunHead) + rowCount * sizeof(YOffset) + dataSize; 78 RunHead* head = (RunHead*)sk_malloc_throw(size); 79 head->fRefCnt = 1; 80 head->fRowCount = rowCount; 81 head->fDataSize = dataSize; 82 return head; 83 } 84 85 static int ComputeRowSizeForWidth(int width) { 86 // 2 bytes per segment, where each segment can store up to 255 for count 87 int segments = 0; 88 while (width > 0) { 89 segments += 1; 90 int n = SkMin32(width, 255); 91 width -= n; 92 } 93 return segments * 2; // each segment is row[0] + row[1] (n + alpha) 94 } 95 96 static RunHead* AllocRect(const SkIRect& bounds) { 97 SkASSERT(!bounds.isEmpty()); 98 int width = bounds.width(); 99 size_t rowSize = ComputeRowSizeForWidth(width); 100 RunHead* head = RunHead::Alloc(1, rowSize); 101 YOffset* yoff = head->yoffsets(); 102 yoff->fY = bounds.height() - 1; 103 yoff->fOffset = 0; 104 uint8_t* row = head->data(); 105 while (width > 0) { 106 int n = SkMin32(width, 255); 107 row[0] = n; 108 row[1] = 0xFF; 109 width -= n; 110 row += 2; 111 } 112 return head; 113 } 114 }; 115 116 class SkAAClip::Iter { 117 public: 118 Iter(const SkAAClip&); 119 120 bool done() const { return fDone; } 121 int top() const { return fTop; } 122 int bottom() const { return fBottom; } 123 const uint8_t* data() const { return fData; } 124 void next(); 125 126 private: 127 const YOffset* fCurrYOff; 128 const YOffset* fStopYOff; 129 const uint8_t* fData; 130 131 int fTop, fBottom; 132 bool fDone; 133 }; 134 135 SkAAClip::Iter::Iter(const SkAAClip& clip) { 136 if (clip.isEmpty()) { 137 fDone = true; 138 fTop = fBottom = clip.fBounds.fBottom; 139 fData = NULL; 140 fCurrYOff = NULL; 141 fStopYOff = NULL; 142 return; 143 } 144 145 const RunHead* head = clip.fRunHead; 146 fCurrYOff = head->yoffsets(); 147 fStopYOff = fCurrYOff + head->fRowCount; 148 fData = head->data() + fCurrYOff->fOffset; 149 150 // setup first value 151 fTop = clip.fBounds.fTop; 152 fBottom = clip.fBounds.fTop + fCurrYOff->fY + 1; 153 fDone = false; 154 } 155 156 void SkAAClip::Iter::next() { 157 if (!fDone) { 158 const YOffset* prev = fCurrYOff; 159 const YOffset* curr = prev + 1; 160 SkASSERT(curr <= fStopYOff); 161 162 fTop = fBottom; 163 if (curr >= fStopYOff) { 164 fDone = true; 165 fBottom = kMaxInt32; 166 fData = NULL; 167 } else { 168 fBottom += curr->fY - prev->fY; 169 fData += curr->fOffset - prev->fOffset; 170 fCurrYOff = curr; 171 } 172 } 173 } 174 175 #ifdef SK_DEBUG 176 // assert we're exactly width-wide, and then return the number of bytes used 177 static size_t compute_row_length(const uint8_t row[], int width) { 178 const uint8_t* origRow = row; 179 while (width > 0) { 180 int n = row[0]; 181 SkASSERT(n > 0); 182 SkASSERT(n <= width); 183 row += 2; 184 width -= n; 185 } 186 SkASSERT(0 == width); 187 return row - origRow; 188 } 189 190 void SkAAClip::validate() const { 191 if (NULL == fRunHead) { 192 SkASSERT(fBounds.isEmpty()); 193 return; 194 } 195 196 const RunHead* head = fRunHead; 197 SkASSERT(head->fRefCnt > 0); 198 SkASSERT(head->fRowCount > 0); 199 200 const YOffset* yoff = head->yoffsets(); 201 const YOffset* ystop = yoff + head->fRowCount; 202 const int lastY = fBounds.height() - 1; 203 204 // Y and offset must be monotonic 205 int prevY = -1; 206 int32_t prevOffset = -1; 207 while (yoff < ystop) { 208 SkASSERT(prevY < yoff->fY); 209 SkASSERT(yoff->fY <= lastY); 210 prevY = yoff->fY; 211 SkASSERT(prevOffset < (int32_t)yoff->fOffset); 212 prevOffset = yoff->fOffset; 213 const uint8_t* row = head->data() + yoff->fOffset; 214 size_t rowLength = compute_row_length(row, fBounds.width()); 215 SkASSERT(yoff->fOffset + rowLength <= head->fDataSize); 216 yoff += 1; 217 } 218 // check the last entry; 219 --yoff; 220 SkASSERT(yoff->fY == lastY); 221 } 222 #endif 223 224 /////////////////////////////////////////////////////////////////////////////// 225 226 // Count the number of zeros on the left and right edges of the passed in 227 // RLE row. If 'row' is all zeros return 'width' in both variables. 228 static void count_left_right_zeros(const uint8_t* row, int width, 229 int* leftZ, int* riteZ) { 230 int zeros = 0; 231 do { 232 if (row[1]) { 233 break; 234 } 235 int n = row[0]; 236 SkASSERT(n > 0); 237 SkASSERT(n <= width); 238 zeros += n; 239 row += 2; 240 width -= n; 241 } while (width > 0); 242 *leftZ = zeros; 243 244 if (0 == width) { 245 // this line is completely empty return 'width' in both variables 246 *riteZ = *leftZ; 247 return; 248 } 249 250 zeros = 0; 251 while (width > 0) { 252 int n = row[0]; 253 SkASSERT(n > 0); 254 if (0 == row[1]) { 255 zeros += n; 256 } else { 257 zeros = 0; 258 } 259 row += 2; 260 width -= n; 261 } 262 *riteZ = zeros; 263 } 264 265 #ifdef SK_DEBUG 266 static void test_count_left_right_zeros() { 267 static bool gOnce; 268 if (gOnce) { 269 return; 270 } 271 gOnce = true; 272 273 const uint8_t data0[] = { 0, 0, 10, 0xFF }; 274 const uint8_t data1[] = { 0, 0, 5, 0xFF, 2, 0, 3, 0xFF }; 275 const uint8_t data2[] = { 7, 0, 5, 0, 2, 0, 3, 0xFF }; 276 const uint8_t data3[] = { 0, 5, 5, 0xFF, 2, 0, 3, 0 }; 277 const uint8_t data4[] = { 2, 3, 2, 0, 5, 0xFF, 3, 0 }; 278 const uint8_t data5[] = { 10, 10, 10, 0 }; 279 const uint8_t data6[] = { 2, 2, 2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 }; 280 281 const uint8_t* array[] = { 282 data0, data1, data2, data3, data4, data5, data6 283 }; 284 285 for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) { 286 const uint8_t* data = array[i]; 287 const int expectedL = *data++; 288 const int expectedR = *data++; 289 int L = 12345, R = 12345; 290 count_left_right_zeros(data, 10, &L, &R); 291 SkASSERT(expectedL == L); 292 SkASSERT(expectedR == R); 293 } 294 } 295 #endif 296 297 // modify row in place, trimming off (zeros) from the left and right sides. 298 // return the number of bytes that were completely eliminated from the left 299 static int trim_row_left_right(uint8_t* row, int width, int leftZ, int riteZ) { 300 int trim = 0; 301 while (leftZ > 0) { 302 SkASSERT(0 == row[1]); 303 int n = row[0]; 304 SkASSERT(n > 0); 305 SkASSERT(n <= width); 306 width -= n; 307 row += 2; 308 if (n > leftZ) { 309 row[-2] = n - leftZ; 310 break; 311 } 312 trim += 2; 313 leftZ -= n; 314 SkASSERT(leftZ >= 0); 315 } 316 317 if (riteZ) { 318 // walk row to the end, and then we'll back up to trim riteZ 319 while (width > 0) { 320 int n = row[0]; 321 SkASSERT(n <= width); 322 width -= n; 323 row += 2; 324 } 325 // now skip whole runs of zeros 326 do { 327 row -= 2; 328 SkASSERT(0 == row[1]); 329 int n = row[0]; 330 SkASSERT(n > 0); 331 if (n > riteZ) { 332 row[0] = n - riteZ; 333 break; 334 } 335 riteZ -= n; 336 SkASSERT(riteZ >= 0); 337 } while (riteZ > 0); 338 } 339 340 return trim; 341 } 342 343 #ifdef SK_DEBUG 344 // assert that this row is exactly this width 345 static void assert_row_width(const uint8_t* row, int width) { 346 while (width > 0) { 347 int n = row[0]; 348 SkASSERT(n > 0); 349 SkASSERT(n <= width); 350 width -= n; 351 row += 2; 352 } 353 SkASSERT(0 == width); 354 } 355 356 static void test_trim_row_left_right() { 357 static bool gOnce; 358 if (gOnce) { 359 return; 360 } 361 gOnce = true; 362 363 uint8_t data0[] = { 0, 0, 0, 10, 10, 0xFF }; 364 uint8_t data1[] = { 2, 0, 0, 10, 5, 0, 2, 0, 3, 0xFF }; 365 uint8_t data2[] = { 5, 0, 2, 10, 5, 0, 2, 0, 3, 0xFF }; 366 uint8_t data3[] = { 6, 0, 2, 10, 5, 0, 2, 0, 3, 0xFF }; 367 uint8_t data4[] = { 0, 0, 0, 10, 2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 }; 368 uint8_t data5[] = { 1, 0, 0, 10, 2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 }; 369 uint8_t data6[] = { 0, 1, 0, 10, 2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 }; 370 uint8_t data7[] = { 1, 1, 0, 10, 2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 }; 371 uint8_t data8[] = { 2, 2, 2, 10, 2, 0, 2, 0xFF, 2, 0, 2, 0xFF, 2, 0 }; 372 uint8_t data9[] = { 5, 2, 4, 10, 2, 0, 2, 0, 2, 0, 2, 0xFF, 2, 0 }; 373 uint8_t data10[] ={ 74, 0, 4, 150, 9, 0, 65, 0, 76, 0xFF }; 374 375 uint8_t* array[] = { 376 data0, data1, data2, data3, data4, 377 data5, data6, data7, data8, data9, 378 data10 379 }; 380 381 for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) { 382 uint8_t* data = array[i]; 383 const int trimL = *data++; 384 const int trimR = *data++; 385 const int expectedSkip = *data++; 386 const int origWidth = *data++; 387 assert_row_width(data, origWidth); 388 int skip = trim_row_left_right(data, origWidth, trimL, trimR); 389 SkASSERT(expectedSkip == skip); 390 int expectedWidth = origWidth - trimL - trimR; 391 assert_row_width(data + skip, expectedWidth); 392 } 393 } 394 #endif 395 396 bool SkAAClip::trimLeftRight() { 397 SkDEBUGCODE(test_trim_row_left_right();) 398 399 if (this->isEmpty()) { 400 return false; 401 } 402 403 AUTO_AACLIP_VALIDATE(*this); 404 405 const int width = fBounds.width(); 406 RunHead* head = fRunHead; 407 YOffset* yoff = head->yoffsets(); 408 YOffset* stop = yoff + head->fRowCount; 409 uint8_t* base = head->data(); 410 411 // After this loop, 'leftZeros' & 'rightZeros' will contain the minimum 412 // number of zeros on the left and right of the clip. This information 413 // can be used to shrink the bounding box. 414 int leftZeros = width; 415 int riteZeros = width; 416 while (yoff < stop) { 417 int L, R; 418 count_left_right_zeros(base + yoff->fOffset, width, &L, &R); 419 SkASSERT(L + R < width || (L == width && R == width)); 420 if (L < leftZeros) { 421 leftZeros = L; 422 } 423 if (R < riteZeros) { 424 riteZeros = R; 425 } 426 if (0 == (leftZeros | riteZeros)) { 427 // no trimming to do 428 return true; 429 } 430 yoff += 1; 431 } 432 433 SkASSERT(leftZeros || riteZeros); 434 if (width == leftZeros) { 435 SkASSERT(width == riteZeros); 436 return this->setEmpty(); 437 } 438 439 this->validate(); 440 441 fBounds.fLeft += leftZeros; 442 fBounds.fRight -= riteZeros; 443 SkASSERT(!fBounds.isEmpty()); 444 445 // For now we don't realloc the storage (for time), we just shrink in place 446 // This means we don't have to do any memmoves either, since we can just 447 // play tricks with the yoff->fOffset for each row 448 yoff = head->yoffsets(); 449 while (yoff < stop) { 450 uint8_t* row = base + yoff->fOffset; 451 SkDEBUGCODE((void)compute_row_length(row, width);) 452 yoff->fOffset += trim_row_left_right(row, width, leftZeros, riteZeros); 453 SkDEBUGCODE((void)compute_row_length(base + yoff->fOffset, width - leftZeros - riteZeros);) 454 yoff += 1; 455 } 456 return true; 457 } 458 459 static bool row_is_all_zeros(const uint8_t* row, int width) { 460 SkASSERT(width > 0); 461 do { 462 if (row[1]) { 463 return false; 464 } 465 int n = row[0]; 466 SkASSERT(n <= width); 467 width -= n; 468 row += 2; 469 } while (width > 0); 470 SkASSERT(0 == width); 471 return true; 472 } 473 474 bool SkAAClip::trimTopBottom() { 475 if (this->isEmpty()) { 476 return false; 477 } 478 479 this->validate(); 480 481 const int width = fBounds.width(); 482 RunHead* head = fRunHead; 483 YOffset* yoff = head->yoffsets(); 484 YOffset* stop = yoff + head->fRowCount; 485 const uint8_t* base = head->data(); 486 487 // Look to trim away empty rows from the top. 488 // 489 int skip = 0; 490 while (yoff < stop) { 491 const uint8_t* data = base + yoff->fOffset; 492 if (!row_is_all_zeros(data, width)) { 493 break; 494 } 495 skip += 1; 496 yoff += 1; 497 } 498 SkASSERT(skip <= head->fRowCount); 499 if (skip == head->fRowCount) { 500 return this->setEmpty(); 501 } 502 if (skip > 0) { 503 // adjust fRowCount and fBounds.fTop, and slide all the data up 504 // as we remove [skip] number of YOffset entries 505 yoff = head->yoffsets(); 506 int dy = yoff[skip - 1].fY + 1; 507 for (int i = skip; i < head->fRowCount; ++i) { 508 SkASSERT(yoff[i].fY >= dy); 509 yoff[i].fY -= dy; 510 } 511 YOffset* dst = head->yoffsets(); 512 size_t size = head->fRowCount * sizeof(YOffset) + head->fDataSize; 513 memmove(dst, dst + skip, size - skip * sizeof(YOffset)); 514 515 fBounds.fTop += dy; 516 SkASSERT(!fBounds.isEmpty()); 517 head->fRowCount -= skip; 518 SkASSERT(head->fRowCount > 0); 519 520 this->validate(); 521 // need to reset this after the memmove 522 base = head->data(); 523 } 524 525 // Look to trim away empty rows from the bottom. 526 // We know that we have at least one non-zero row, so we can just walk 527 // backwards without checking for running past the start. 528 // 529 stop = yoff = head->yoffsets() + head->fRowCount; 530 do { 531 yoff -= 1; 532 } while (row_is_all_zeros(base + yoff->fOffset, width)); 533 skip = stop - yoff - 1; 534 SkASSERT(skip >= 0 && skip < head->fRowCount); 535 if (skip > 0) { 536 // removing from the bottom is easier than from the top, as we don't 537 // have to adjust any of the Y values, we just have to trim the array 538 memmove(stop - skip, stop, head->fDataSize); 539 540 fBounds.fBottom = fBounds.fTop + yoff->fY + 1; 541 SkASSERT(!fBounds.isEmpty()); 542 head->fRowCount -= skip; 543 SkASSERT(head->fRowCount > 0); 544 } 545 this->validate(); 546 547 return true; 548 } 549 550 // can't validate before we're done, since trimming is part of the process of 551 // making us valid after the Builder. Since we build from top to bottom, its 552 // possible our fBounds.fBottom is bigger than our last scanline of data, so 553 // we trim fBounds.fBottom back up. 554 // 555 // TODO: check for duplicates in X and Y to further compress our data 556 // 557 bool SkAAClip::trimBounds() { 558 if (this->isEmpty()) { 559 return false; 560 } 561 562 const RunHead* head = fRunHead; 563 const YOffset* yoff = head->yoffsets(); 564 565 SkASSERT(head->fRowCount > 0); 566 const YOffset& lastY = yoff[head->fRowCount - 1]; 567 SkASSERT(lastY.fY + 1 <= fBounds.height()); 568 fBounds.fBottom = fBounds.fTop + lastY.fY + 1; 569 SkASSERT(lastY.fY + 1 == fBounds.height()); 570 SkASSERT(!fBounds.isEmpty()); 571 572 return this->trimTopBottom() && this->trimLeftRight(); 573 } 574 575 /////////////////////////////////////////////////////////////////////////////// 576 577 void SkAAClip::freeRuns() { 578 if (fRunHead) { 579 SkASSERT(fRunHead->fRefCnt >= 1); 580 if (1 == sk_atomic_dec(&fRunHead->fRefCnt)) { 581 sk_free(fRunHead); 582 } 583 } 584 } 585 586 SkAAClip::SkAAClip() { 587 fBounds.setEmpty(); 588 fRunHead = NULL; 589 } 590 591 SkAAClip::SkAAClip(const SkAAClip& src) { 592 SkDEBUGCODE(fBounds.setEmpty();) // need this for validate 593 fRunHead = NULL; 594 *this = src; 595 } 596 597 SkAAClip::~SkAAClip() { 598 this->freeRuns(); 599 } 600 601 SkAAClip& SkAAClip::operator=(const SkAAClip& src) { 602 AUTO_AACLIP_VALIDATE(*this); 603 src.validate(); 604 605 if (this != &src) { 606 this->freeRuns(); 607 fBounds = src.fBounds; 608 fRunHead = src.fRunHead; 609 if (fRunHead) { 610 sk_atomic_inc(&fRunHead->fRefCnt); 611 } 612 } 613 return *this; 614 } 615 616 bool operator==(const SkAAClip& a, const SkAAClip& b) { 617 a.validate(); 618 b.validate(); 619 620 if (&a == &b) { 621 return true; 622 } 623 if (a.fBounds != b.fBounds) { 624 return false; 625 } 626 627 const SkAAClip::RunHead* ah = a.fRunHead; 628 const SkAAClip::RunHead* bh = b.fRunHead; 629 630 // this catches empties and rects being equal 631 if (ah == bh) { 632 return true; 633 } 634 635 // now we insist that both are complex (but different ptrs) 636 if (!a.fRunHead || !b.fRunHead) { 637 return false; 638 } 639 640 return ah->fRowCount == bh->fRowCount && 641 ah->fDataSize == bh->fDataSize && 642 !memcmp(ah->data(), bh->data(), ah->fDataSize); 643 } 644 645 void SkAAClip::swap(SkAAClip& other) { 646 AUTO_AACLIP_VALIDATE(*this); 647 other.validate(); 648 649 SkTSwap(fBounds, other.fBounds); 650 SkTSwap(fRunHead, other.fRunHead); 651 } 652 653 bool SkAAClip::set(const SkAAClip& src) { 654 *this = src; 655 return !this->isEmpty(); 656 } 657 658 bool SkAAClip::setEmpty() { 659 this->freeRuns(); 660 fBounds.setEmpty(); 661 fRunHead = NULL; 662 return false; 663 } 664 665 bool SkAAClip::setRect(const SkIRect& bounds) { 666 if (bounds.isEmpty()) { 667 return this->setEmpty(); 668 } 669 670 AUTO_AACLIP_VALIDATE(*this); 671 672 #if 0 673 SkRect r; 674 r.set(bounds); 675 SkPath path; 676 path.addRect(r); 677 return this->setPath(path); 678 #else 679 this->freeRuns(); 680 fBounds = bounds; 681 fRunHead = RunHead::AllocRect(bounds); 682 SkASSERT(!this->isEmpty()); 683 return true; 684 #endif 685 } 686 687 bool SkAAClip::setRect(const SkRect& r, bool doAA) { 688 if (r.isEmpty()) { 689 return this->setEmpty(); 690 } 691 692 AUTO_AACLIP_VALIDATE(*this); 693 694 // TODO: special case this 695 696 SkPath path; 697 path.addRect(r); 698 return this->setPath(path, NULL, doAA); 699 } 700 701 static void append_run(SkTDArray<uint8_t>& array, uint8_t value, int count) { 702 SkASSERT(count >= 0); 703 while (count > 0) { 704 int n = count; 705 if (n > 255) { 706 n = 255; 707 } 708 uint8_t* data = array.append(2); 709 data[0] = n; 710 data[1] = value; 711 count -= n; 712 } 713 } 714 715 bool SkAAClip::setRegion(const SkRegion& rgn) { 716 if (rgn.isEmpty()) { 717 return this->setEmpty(); 718 } 719 if (rgn.isRect()) { 720 return this->setRect(rgn.getBounds()); 721 } 722 723 #if 0 724 SkAAClip clip; 725 SkRegion::Iterator iter(rgn); 726 for (; !iter.done(); iter.next()) { 727 clip.op(iter.rect(), SkRegion::kUnion_Op); 728 } 729 this->swap(clip); 730 return !this->isEmpty(); 731 #else 732 const SkIRect& bounds = rgn.getBounds(); 733 const int offsetX = bounds.fLeft; 734 const int offsetY = bounds.fTop; 735 736 SkTDArray<YOffset> yArray; 737 SkTDArray<uint8_t> xArray; 738 739 yArray.setReserve(SkMin32(bounds.height(), 1024)); 740 xArray.setReserve(SkMin32(bounds.width() * 128, 64 * 1024)); 741 742 SkRegion::Iterator iter(rgn); 743 int prevRight = 0; 744 int prevBot = 0; 745 YOffset* currY = NULL; 746 747 for (; !iter.done(); iter.next()) { 748 const SkIRect& r = iter.rect(); 749 SkASSERT(bounds.contains(r)); 750 751 int bot = r.fBottom - offsetY; 752 SkASSERT(bot >= prevBot); 753 if (bot > prevBot) { 754 if (currY) { 755 // flush current row 756 append_run(xArray, 0, bounds.width() - prevRight); 757 } 758 // did we introduce an empty-gap from the prev row? 759 int top = r.fTop - offsetY; 760 if (top > prevBot) { 761 currY = yArray.append(); 762 currY->fY = top - 1; 763 currY->fOffset = xArray.count(); 764 append_run(xArray, 0, bounds.width()); 765 } 766 // create a new record for this Y value 767 currY = yArray.append(); 768 currY->fY = bot - 1; 769 currY->fOffset = xArray.count(); 770 prevRight = 0; 771 prevBot = bot; 772 } 773 774 int x = r.fLeft - offsetX; 775 append_run(xArray, 0, x - prevRight); 776 777 int w = r.fRight - r.fLeft; 778 append_run(xArray, 0xFF, w); 779 prevRight = x + w; 780 SkASSERT(prevRight <= bounds.width()); 781 } 782 // flush last row 783 append_run(xArray, 0, bounds.width() - prevRight); 784 785 // now pack everything into a RunHead 786 RunHead* head = RunHead::Alloc(yArray.count(), xArray.bytes()); 787 memcpy(head->yoffsets(), yArray.begin(), yArray.bytes()); 788 memcpy(head->data(), xArray.begin(), xArray.bytes()); 789 790 this->setEmpty(); 791 fBounds = bounds; 792 fRunHead = head; 793 this->validate(); 794 return true; 795 #endif 796 } 797 798 /////////////////////////////////////////////////////////////////////////////// 799 800 const uint8_t* SkAAClip::findRow(int y, int* lastYForRow) const { 801 SkASSERT(fRunHead); 802 803 if (!y_in_rect(y, fBounds)) { 804 return NULL; 805 } 806 y -= fBounds.y(); // our yoffs values are relative to the top 807 808 const YOffset* yoff = fRunHead->yoffsets(); 809 while (yoff->fY < y) { 810 yoff += 1; 811 SkASSERT(yoff - fRunHead->yoffsets() < fRunHead->fRowCount); 812 } 813 814 if (lastYForRow) { 815 *lastYForRow = fBounds.y() + yoff->fY; 816 } 817 return fRunHead->data() + yoff->fOffset; 818 } 819 820 const uint8_t* SkAAClip::findX(const uint8_t data[], int x, int* initialCount) const { 821 SkASSERT(x_in_rect(x, fBounds)); 822 x -= fBounds.x(); 823 824 // first skip up to X 825 for (;;) { 826 int n = data[0]; 827 if (x < n) { 828 if (initialCount) { 829 *initialCount = n - x; 830 } 831 break; 832 } 833 data += 2; 834 x -= n; 835 } 836 return data; 837 } 838 839 bool SkAAClip::quickContains(int left, int top, int right, int bottom) const { 840 if (this->isEmpty()) { 841 return false; 842 } 843 if (!fBounds.contains(left, top, right, bottom)) { 844 return false; 845 } 846 #if 0 847 if (this->isRect()) { 848 return true; 849 } 850 #endif 851 852 int lastY SK_INIT_TO_AVOID_WARNING; 853 const uint8_t* row = this->findRow(top, &lastY); 854 if (lastY < bottom) { 855 return false; 856 } 857 // now just need to check in X 858 int count; 859 row = this->findX(row, left, &count); 860 #if 0 861 return count >= (right - left) && 0xFF == row[1]; 862 #else 863 int rectWidth = right - left; 864 while (0xFF == row[1]) { 865 if (count >= rectWidth) { 866 return true; 867 } 868 rectWidth -= count; 869 row += 2; 870 count = row[0]; 871 } 872 return false; 873 #endif 874 } 875 876 /////////////////////////////////////////////////////////////////////////////// 877 878 class SkAAClip::Builder { 879 SkIRect fBounds; 880 struct Row { 881 int fY; 882 int fWidth; 883 SkTDArray<uint8_t>* fData; 884 }; 885 SkTDArray<Row> fRows; 886 Row* fCurrRow; 887 int fPrevY; 888 int fWidth; 889 int fMinY; 890 891 public: 892 Builder(const SkIRect& bounds) : fBounds(bounds) { 893 fPrevY = -1; 894 fWidth = bounds.width(); 895 fCurrRow = NULL; 896 fMinY = bounds.fTop; 897 } 898 899 ~Builder() { 900 Row* row = fRows.begin(); 901 Row* stop = fRows.end(); 902 while (row < stop) { 903 delete row->fData; 904 row += 1; 905 } 906 } 907 908 const SkIRect& getBounds() const { return fBounds; } 909 910 void addRun(int x, int y, U8CPU alpha, int count) { 911 SkASSERT(count > 0); 912 SkASSERT(fBounds.contains(x, y)); 913 SkASSERT(fBounds.contains(x + count - 1, y)); 914 915 x -= fBounds.left(); 916 y -= fBounds.top(); 917 918 Row* row = fCurrRow; 919 if (y != fPrevY) { 920 SkASSERT(y > fPrevY); 921 fPrevY = y; 922 row = this->flushRow(true); 923 row->fY = y; 924 row->fWidth = 0; 925 SkASSERT(row->fData); 926 SkASSERT(0 == row->fData->count()); 927 fCurrRow = row; 928 } 929 930 SkASSERT(row->fWidth <= x); 931 SkASSERT(row->fWidth < fBounds.width()); 932 933 SkTDArray<uint8_t>& data = *row->fData; 934 935 int gap = x - row->fWidth; 936 if (gap) { 937 AppendRun(data, 0, gap); 938 row->fWidth += gap; 939 SkASSERT(row->fWidth < fBounds.width()); 940 } 941 942 AppendRun(data, alpha, count); 943 row->fWidth += count; 944 SkASSERT(row->fWidth <= fBounds.width()); 945 } 946 947 void addColumn(int x, int y, U8CPU alpha, int height) { 948 SkASSERT(fBounds.contains(x, y + height - 1)); 949 950 this->addRun(x, y, alpha, 1); 951 this->flushRowH(fCurrRow); 952 y -= fBounds.fTop; 953 SkASSERT(y == fCurrRow->fY); 954 fCurrRow->fY = y + height - 1; 955 } 956 957 void addRectRun(int x, int y, int width, int height) { 958 SkASSERT(fBounds.contains(x + width - 1, y + height - 1)); 959 this->addRun(x, y, 0xFF, width); 960 961 // we assum the rect must be all we'll see for these scanlines 962 // so we ensure our row goes all the way to our right 963 this->flushRowH(fCurrRow); 964 965 y -= fBounds.fTop; 966 SkASSERT(y == fCurrRow->fY); 967 fCurrRow->fY = y + height - 1; 968 } 969 970 void addAntiRectRun(int x, int y, int width, int height, 971 SkAlpha leftAlpha, SkAlpha rightAlpha) { 972 SkASSERT(fBounds.contains(x + width - 1 + 973 (leftAlpha > 0 ? 1 : 0) + (rightAlpha > 0 ? 1 : 0), 974 y + height - 1)); 975 SkASSERT(width >= 0); 976 977 // Conceptually we're always adding 3 runs, but we should 978 // merge or omit them if possible. 979 if (leftAlpha == 0xFF) { 980 width++; 981 } else if (leftAlpha > 0) { 982 this->addRun(x++, y, leftAlpha, 1); 983 } 984 if (rightAlpha == 0xFF) { 985 width++; 986 } 987 if (width > 0) { 988 this->addRun(x, y, 0xFF, width); 989 } 990 if (rightAlpha > 0 && rightAlpha < 255) { 991 this->addRun(x + width, y, rightAlpha, 1); 992 } 993 994 // we assume the rect must be all we'll see for these scanlines 995 // so we ensure our row goes all the way to our right 996 this->flushRowH(fCurrRow); 997 998 y -= fBounds.fTop; 999 SkASSERT(y == fCurrRow->fY); 1000 fCurrRow->fY = y + height - 1; 1001 } 1002 1003 bool finish(SkAAClip* target) { 1004 this->flushRow(false); 1005 1006 const Row* row = fRows.begin(); 1007 const Row* stop = fRows.end(); 1008 1009 size_t dataSize = 0; 1010 while (row < stop) { 1011 dataSize += row->fData->count(); 1012 row += 1; 1013 } 1014 1015 if (0 == dataSize) { 1016 return target->setEmpty(); 1017 } 1018 1019 SkASSERT(fMinY >= fBounds.fTop); 1020 SkASSERT(fMinY < fBounds.fBottom); 1021 int adjustY = fMinY - fBounds.fTop; 1022 fBounds.fTop = fMinY; 1023 1024 RunHead* head = RunHead::Alloc(fRows.count(), dataSize); 1025 YOffset* yoffset = head->yoffsets(); 1026 uint8_t* data = head->data(); 1027 uint8_t* baseData = data; 1028 1029 row = fRows.begin(); 1030 SkDEBUGCODE(int prevY = row->fY - 1;) 1031 while (row < stop) { 1032 SkASSERT(prevY < row->fY); // must be monotonic 1033 SkDEBUGCODE(prevY = row->fY); 1034 1035 yoffset->fY = row->fY - adjustY; 1036 yoffset->fOffset = data - baseData; 1037 yoffset += 1; 1038 1039 size_t n = row->fData->count(); 1040 memcpy(data, row->fData->begin(), n); 1041 #ifdef SK_DEBUG 1042 size_t bytesNeeded = compute_row_length(data, fBounds.width()); 1043 SkASSERT(bytesNeeded == n); 1044 #endif 1045 data += n; 1046 1047 row += 1; 1048 } 1049 1050 target->freeRuns(); 1051 target->fBounds = fBounds; 1052 target->fRunHead = head; 1053 return target->trimBounds(); 1054 } 1055 1056 void dump() { 1057 this->validate(); 1058 int y; 1059 for (y = 0; y < fRows.count(); ++y) { 1060 const Row& row = fRows[y]; 1061 SkDebugf("Y:%3d W:%3d", row.fY, row.fWidth); 1062 const SkTDArray<uint8_t>& data = *row.fData; 1063 int count = data.count(); 1064 SkASSERT(!(count & 1)); 1065 const uint8_t* ptr = data.begin(); 1066 for (int x = 0; x < count; x += 2) { 1067 SkDebugf(" [%3d:%02X]", ptr[0], ptr[1]); 1068 ptr += 2; 1069 } 1070 SkDebugf("\n"); 1071 } 1072 } 1073 1074 void validate() { 1075 #ifdef SK_DEBUG 1076 if (false) { // avoid bit rot, suppress warning 1077 test_count_left_right_zeros(); 1078 } 1079 int prevY = -1; 1080 for (int i = 0; i < fRows.count(); ++i) { 1081 const Row& row = fRows[i]; 1082 SkASSERT(prevY < row.fY); 1083 SkASSERT(fWidth == row.fWidth); 1084 int count = row.fData->count(); 1085 const uint8_t* ptr = row.fData->begin(); 1086 SkASSERT(!(count & 1)); 1087 int w = 0; 1088 for (int x = 0; x < count; x += 2) { 1089 int n = ptr[0]; 1090 SkASSERT(n > 0); 1091 w += n; 1092 SkASSERT(w <= fWidth); 1093 ptr += 2; 1094 } 1095 SkASSERT(w == fWidth); 1096 prevY = row.fY; 1097 } 1098 #endif 1099 } 1100 1101 // only called by BuilderBlitter 1102 void setMinY(int y) { 1103 fMinY = y; 1104 } 1105 1106 private: 1107 void flushRowH(Row* row) { 1108 // flush current row if needed 1109 if (row->fWidth < fWidth) { 1110 AppendRun(*row->fData, 0, fWidth - row->fWidth); 1111 row->fWidth = fWidth; 1112 } 1113 } 1114 1115 Row* flushRow(bool readyForAnother) { 1116 Row* next = NULL; 1117 int count = fRows.count(); 1118 if (count > 0) { 1119 this->flushRowH(&fRows[count - 1]); 1120 } 1121 if (count > 1) { 1122 // are our last two runs the same? 1123 Row* prev = &fRows[count - 2]; 1124 Row* curr = &fRows[count - 1]; 1125 SkASSERT(prev->fWidth == fWidth); 1126 SkASSERT(curr->fWidth == fWidth); 1127 if (*prev->fData == *curr->fData) { 1128 prev->fY = curr->fY; 1129 if (readyForAnother) { 1130 curr->fData->rewind(); 1131 next = curr; 1132 } else { 1133 delete curr->fData; 1134 fRows.removeShuffle(count - 1); 1135 } 1136 } else { 1137 if (readyForAnother) { 1138 next = fRows.append(); 1139 next->fData = new SkTDArray<uint8_t>; 1140 } 1141 } 1142 } else { 1143 if (readyForAnother) { 1144 next = fRows.append(); 1145 next->fData = new SkTDArray<uint8_t>; 1146 } 1147 } 1148 return next; 1149 } 1150 1151 static void AppendRun(SkTDArray<uint8_t>& data, U8CPU alpha, int count) { 1152 do { 1153 int n = count; 1154 if (n > 255) { 1155 n = 255; 1156 } 1157 uint8_t* ptr = data.append(2); 1158 ptr[0] = n; 1159 ptr[1] = alpha; 1160 count -= n; 1161 } while (count > 0); 1162 } 1163 }; 1164 1165 class SkAAClip::BuilderBlitter : public SkBlitter { 1166 int fLastY; 1167 1168 /* 1169 If we see a gap of 1 or more empty scanlines while building in Y-order, 1170 we inject an explicit empty scanline (alpha==0) 1171 1172 See AAClipTest.cpp : test_path_with_hole() 1173 */ 1174 void checkForYGap(int y) { 1175 SkASSERT(y >= fLastY); 1176 if (fLastY > -SK_MaxS32) { 1177 int gap = y - fLastY; 1178 if (gap > 1) { 1179 fBuilder->addRun(fLeft, y - 1, 0, fRight - fLeft); 1180 } 1181 } 1182 fLastY = y; 1183 } 1184 1185 public: 1186 1187 BuilderBlitter(Builder* builder) { 1188 fBuilder = builder; 1189 fLeft = builder->getBounds().fLeft; 1190 fRight = builder->getBounds().fRight; 1191 fMinY = SK_MaxS32; 1192 fLastY = -SK_MaxS32; // sentinel 1193 } 1194 1195 void finish() { 1196 if (fMinY < SK_MaxS32) { 1197 fBuilder->setMinY(fMinY); 1198 } 1199 } 1200 1201 /** 1202 Must evaluate clips in scan-line order, so don't want to allow blitV(), 1203 but an AAClip can be clipped down to a single pixel wide, so we 1204 must support it (given AntiRect semantics: minimum width is 2). 1205 Instead we'll rely on the runtime asserts to guarantee Y monotonicity; 1206 any failure cases that misses may have minor artifacts. 1207 */ 1208 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE { 1209 this->recordMinY(y); 1210 fBuilder->addColumn(x, y, alpha, height); 1211 fLastY = y + height - 1; 1212 } 1213 1214 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE { 1215 this->recordMinY(y); 1216 this->checkForYGap(y); 1217 fBuilder->addRectRun(x, y, width, height); 1218 fLastY = y + height - 1; 1219 } 1220 1221 virtual void blitAntiRect(int x, int y, int width, int height, 1222 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE { 1223 this->recordMinY(y); 1224 this->checkForYGap(y); 1225 fBuilder->addAntiRectRun(x, y, width, height, leftAlpha, rightAlpha); 1226 fLastY = y + height - 1; 1227 } 1228 1229 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE 1230 { unexpected(); } 1231 1232 virtual const SkBitmap* justAnOpaqueColor(uint32_t*) SK_OVERRIDE { 1233 return NULL; 1234 } 1235 1236 virtual void blitH(int x, int y, int width) SK_OVERRIDE { 1237 this->recordMinY(y); 1238 this->checkForYGap(y); 1239 fBuilder->addRun(x, y, 0xFF, width); 1240 } 1241 1242 virtual void blitAntiH(int x, int y, const SkAlpha alpha[], 1243 const int16_t runs[]) SK_OVERRIDE { 1244 this->recordMinY(y); 1245 this->checkForYGap(y); 1246 for (;;) { 1247 int count = *runs; 1248 if (count <= 0) { 1249 return; 1250 } 1251 1252 // The supersampler's buffer can be the width of the device, so 1253 // we may have to trim the run to our bounds. If so, we assert that 1254 // the extra spans are always alpha==0 1255 int localX = x; 1256 int localCount = count; 1257 if (x < fLeft) { 1258 SkASSERT(0 == *alpha); 1259 int gap = fLeft - x; 1260 SkASSERT(gap <= count); 1261 localX += gap; 1262 localCount -= gap; 1263 } 1264 int right = x + count; 1265 if (right > fRight) { 1266 SkASSERT(0 == *alpha); 1267 localCount -= right - fRight; 1268 SkASSERT(localCount >= 0); 1269 } 1270 1271 if (localCount) { 1272 fBuilder->addRun(localX, y, *alpha, localCount); 1273 } 1274 // Next run 1275 runs += count; 1276 alpha += count; 1277 x += count; 1278 } 1279 } 1280 1281 private: 1282 Builder* fBuilder; 1283 int fLeft; // cache of builder's bounds' left edge 1284 int fRight; 1285 int fMinY; 1286 1287 /* 1288 * We track this, in case the scan converter skipped some number of 1289 * scanlines at the (relative to the bounds it was given). This allows 1290 * the builder, during its finish, to trip its bounds down to the "real" 1291 * top. 1292 */ 1293 void recordMinY(int y) { 1294 if (y < fMinY) { 1295 fMinY = y; 1296 } 1297 } 1298 1299 void unexpected() { 1300 SkDebugf("---- did not expect to get called here"); 1301 sk_throw(); 1302 } 1303 }; 1304 1305 bool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) { 1306 AUTO_AACLIP_VALIDATE(*this); 1307 1308 if (clip && clip->isEmpty()) { 1309 return this->setEmpty(); 1310 } 1311 1312 SkIRect ibounds; 1313 path.getBounds().roundOut(&ibounds); 1314 1315 SkRegion tmpClip; 1316 if (NULL == clip) { 1317 tmpClip.setRect(ibounds); 1318 clip = &tmpClip; 1319 } 1320 1321 if (path.isInverseFillType()) { 1322 ibounds = clip->getBounds(); 1323 } else { 1324 if (ibounds.isEmpty() || !ibounds.intersect(clip->getBounds())) { 1325 return this->setEmpty(); 1326 } 1327 } 1328 1329 Builder builder(ibounds); 1330 BuilderBlitter blitter(&builder); 1331 1332 if (doAA) { 1333 SkScan::AntiFillPath(path, *clip, &blitter, true); 1334 } else { 1335 SkScan::FillPath(path, *clip, &blitter); 1336 } 1337 1338 blitter.finish(); 1339 return builder.finish(this); 1340 } 1341 1342 /////////////////////////////////////////////////////////////////////////////// 1343 1344 typedef void (*RowProc)(SkAAClip::Builder&, int bottom, 1345 const uint8_t* rowA, const SkIRect& rectA, 1346 const uint8_t* rowB, const SkIRect& rectB); 1347 1348 typedef U8CPU (*AlphaProc)(U8CPU alphaA, U8CPU alphaB); 1349 1350 static U8CPU sectAlphaProc(U8CPU alphaA, U8CPU alphaB) { 1351 // Multiply 1352 return SkMulDiv255Round(alphaA, alphaB); 1353 } 1354 1355 static U8CPU unionAlphaProc(U8CPU alphaA, U8CPU alphaB) { 1356 // SrcOver 1357 return alphaA + alphaB - SkMulDiv255Round(alphaA, alphaB); 1358 } 1359 1360 static U8CPU diffAlphaProc(U8CPU alphaA, U8CPU alphaB) { 1361 // SrcOut 1362 return SkMulDiv255Round(alphaA, 0xFF - alphaB); 1363 } 1364 1365 static U8CPU xorAlphaProc(U8CPU alphaA, U8CPU alphaB) { 1366 // XOR 1367 return alphaA + alphaB - 2 * SkMulDiv255Round(alphaA, alphaB); 1368 } 1369 1370 static AlphaProc find_alpha_proc(SkRegion::Op op) { 1371 switch (op) { 1372 case SkRegion::kIntersect_Op: 1373 return sectAlphaProc; 1374 case SkRegion::kDifference_Op: 1375 return diffAlphaProc; 1376 case SkRegion::kUnion_Op: 1377 return unionAlphaProc; 1378 case SkRegion::kXOR_Op: 1379 return xorAlphaProc; 1380 default: 1381 SkDEBUGFAIL("unexpected region op"); 1382 return sectAlphaProc; 1383 } 1384 } 1385 1386 class RowIter { 1387 public: 1388 RowIter(const uint8_t* row, const SkIRect& bounds) { 1389 fRow = row; 1390 fLeft = bounds.fLeft; 1391 fBoundsRight = bounds.fRight; 1392 if (row) { 1393 fRight = bounds.fLeft + row[0]; 1394 SkASSERT(fRight <= fBoundsRight); 1395 fAlpha = row[1]; 1396 fDone = false; 1397 } else { 1398 fDone = true; 1399 fRight = kMaxInt32; 1400 fAlpha = 0; 1401 } 1402 } 1403 1404 bool done() const { return fDone; } 1405 int left() const { return fLeft; } 1406 int right() const { return fRight; } 1407 U8CPU alpha() const { return fAlpha; } 1408 void next() { 1409 if (!fDone) { 1410 fLeft = fRight; 1411 if (fRight == fBoundsRight) { 1412 fDone = true; 1413 fRight = kMaxInt32; 1414 fAlpha = 0; 1415 } else { 1416 fRow += 2; 1417 fRight += fRow[0]; 1418 fAlpha = fRow[1]; 1419 SkASSERT(fRight <= fBoundsRight); 1420 } 1421 } 1422 } 1423 1424 private: 1425 const uint8_t* fRow; 1426 int fLeft; 1427 int fRight; 1428 int fBoundsRight; 1429 bool fDone; 1430 uint8_t fAlpha; 1431 }; 1432 1433 static void adjust_row(RowIter& iter, int& leftA, int& riteA, int rite) { 1434 if (rite == riteA) { 1435 iter.next(); 1436 leftA = iter.left(); 1437 riteA = iter.right(); 1438 } 1439 } 1440 1441 #if 0 // UNUSED 1442 static bool intersect(int& min, int& max, int boundsMin, int boundsMax) { 1443 SkASSERT(min < max); 1444 SkASSERT(boundsMin < boundsMax); 1445 if (min >= boundsMax || max <= boundsMin) { 1446 return false; 1447 } 1448 if (min < boundsMin) { 1449 min = boundsMin; 1450 } 1451 if (max > boundsMax) { 1452 max = boundsMax; 1453 } 1454 return true; 1455 } 1456 #endif 1457 1458 static void operatorX(SkAAClip::Builder& builder, int lastY, 1459 RowIter& iterA, RowIter& iterB, 1460 AlphaProc proc, const SkIRect& bounds) { 1461 int leftA = iterA.left(); 1462 int riteA = iterA.right(); 1463 int leftB = iterB.left(); 1464 int riteB = iterB.right(); 1465 1466 int prevRite = bounds.fLeft; 1467 1468 do { 1469 U8CPU alphaA = 0; 1470 U8CPU alphaB = 0; 1471 int left, rite; 1472 1473 if (leftA < leftB) { 1474 left = leftA; 1475 alphaA = iterA.alpha(); 1476 if (riteA <= leftB) { 1477 rite = riteA; 1478 } else { 1479 rite = leftA = leftB; 1480 } 1481 } else if (leftB < leftA) { 1482 left = leftB; 1483 alphaB = iterB.alpha(); 1484 if (riteB <= leftA) { 1485 rite = riteB; 1486 } else { 1487 rite = leftB = leftA; 1488 } 1489 } else { 1490 left = leftA; // or leftB, since leftA == leftB 1491 rite = leftA = leftB = SkMin32(riteA, riteB); 1492 alphaA = iterA.alpha(); 1493 alphaB = iterB.alpha(); 1494 } 1495 1496 if (left >= bounds.fRight) { 1497 break; 1498 } 1499 if (rite > bounds.fRight) { 1500 rite = bounds.fRight; 1501 } 1502 1503 if (left >= bounds.fLeft) { 1504 SkASSERT(rite > left); 1505 builder.addRun(left, lastY, proc(alphaA, alphaB), rite - left); 1506 prevRite = rite; 1507 } 1508 1509 adjust_row(iterA, leftA, riteA, rite); 1510 adjust_row(iterB, leftB, riteB, rite); 1511 } while (!iterA.done() || !iterB.done()); 1512 1513 if (prevRite < bounds.fRight) { 1514 builder.addRun(prevRite, lastY, 0, bounds.fRight - prevRite); 1515 } 1516 } 1517 1518 static void adjust_iter(SkAAClip::Iter& iter, int& topA, int& botA, int bot) { 1519 if (bot == botA) { 1520 iter.next(); 1521 topA = botA; 1522 SkASSERT(botA == iter.top()); 1523 botA = iter.bottom(); 1524 } 1525 } 1526 1527 static void operateY(SkAAClip::Builder& builder, const SkAAClip& A, 1528 const SkAAClip& B, SkRegion::Op op) { 1529 AlphaProc proc = find_alpha_proc(op); 1530 const SkIRect& bounds = builder.getBounds(); 1531 1532 SkAAClip::Iter iterA(A); 1533 SkAAClip::Iter iterB(B); 1534 1535 SkASSERT(!iterA.done()); 1536 int topA = iterA.top(); 1537 int botA = iterA.bottom(); 1538 SkASSERT(!iterB.done()); 1539 int topB = iterB.top(); 1540 int botB = iterB.bottom(); 1541 1542 do { 1543 const uint8_t* rowA = NULL; 1544 const uint8_t* rowB = NULL; 1545 int top, bot; 1546 1547 if (topA < topB) { 1548 top = topA; 1549 rowA = iterA.data(); 1550 if (botA <= topB) { 1551 bot = botA; 1552 } else { 1553 bot = topA = topB; 1554 } 1555 1556 } else if (topB < topA) { 1557 top = topB; 1558 rowB = iterB.data(); 1559 if (botB <= topA) { 1560 bot = botB; 1561 } else { 1562 bot = topB = topA; 1563 } 1564 } else { 1565 top = topA; // or topB, since topA == topB 1566 bot = topA = topB = SkMin32(botA, botB); 1567 rowA = iterA.data(); 1568 rowB = iterB.data(); 1569 } 1570 1571 if (top >= bounds.fBottom) { 1572 break; 1573 } 1574 1575 if (bot > bounds.fBottom) { 1576 bot = bounds.fBottom; 1577 } 1578 SkASSERT(top < bot); 1579 1580 if (!rowA && !rowB) { 1581 builder.addRun(bounds.fLeft, bot - 1, 0, bounds.width()); 1582 } else if (top >= bounds.fTop) { 1583 SkASSERT(bot <= bounds.fBottom); 1584 RowIter rowIterA(rowA, rowA ? A.getBounds() : bounds); 1585 RowIter rowIterB(rowB, rowB ? B.getBounds() : bounds); 1586 operatorX(builder, bot - 1, rowIterA, rowIterB, proc, bounds); 1587 } 1588 1589 adjust_iter(iterA, topA, botA, bot); 1590 adjust_iter(iterB, topB, botB, bot); 1591 } while (!iterA.done() || !iterB.done()); 1592 } 1593 1594 bool SkAAClip::op(const SkAAClip& clipAOrig, const SkAAClip& clipBOrig, 1595 SkRegion::Op op) { 1596 AUTO_AACLIP_VALIDATE(*this); 1597 1598 if (SkRegion::kReplace_Op == op) { 1599 return this->set(clipBOrig); 1600 } 1601 1602 const SkAAClip* clipA = &clipAOrig; 1603 const SkAAClip* clipB = &clipBOrig; 1604 1605 if (SkRegion::kReverseDifference_Op == op) { 1606 SkTSwap(clipA, clipB); 1607 op = SkRegion::kDifference_Op; 1608 } 1609 1610 bool a_empty = clipA->isEmpty(); 1611 bool b_empty = clipB->isEmpty(); 1612 1613 SkIRect bounds; 1614 switch (op) { 1615 case SkRegion::kDifference_Op: 1616 if (a_empty) { 1617 return this->setEmpty(); 1618 } 1619 if (b_empty || !SkIRect::Intersects(clipA->fBounds, clipB->fBounds)) { 1620 return this->set(*clipA); 1621 } 1622 bounds = clipA->fBounds; 1623 break; 1624 1625 case SkRegion::kIntersect_Op: 1626 if ((a_empty | b_empty) || !bounds.intersect(clipA->fBounds, 1627 clipB->fBounds)) { 1628 return this->setEmpty(); 1629 } 1630 break; 1631 1632 case SkRegion::kUnion_Op: 1633 case SkRegion::kXOR_Op: 1634 if (a_empty) { 1635 return this->set(*clipB); 1636 } 1637 if (b_empty) { 1638 return this->set(*clipA); 1639 } 1640 bounds = clipA->fBounds; 1641 bounds.join(clipB->fBounds); 1642 break; 1643 1644 default: 1645 SkDEBUGFAIL("unknown region op"); 1646 return !this->isEmpty(); 1647 } 1648 1649 SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds)); 1650 SkASSERT(SkIRect::Intersects(bounds, clipB->fBounds)); 1651 1652 Builder builder(bounds); 1653 operateY(builder, *clipA, *clipB, op); 1654 1655 return builder.finish(this); 1656 } 1657 1658 /* 1659 * It can be expensive to build a local aaclip before applying the op, so 1660 * we first see if we can restrict the bounds of new rect to our current 1661 * bounds, or note that the new rect subsumes our current clip. 1662 */ 1663 1664 bool SkAAClip::op(const SkIRect& rOrig, SkRegion::Op op) { 1665 SkIRect rStorage; 1666 const SkIRect* r = &rOrig; 1667 1668 switch (op) { 1669 case SkRegion::kIntersect_Op: 1670 if (!rStorage.intersect(rOrig, fBounds)) { 1671 // no overlap, so we're empty 1672 return this->setEmpty(); 1673 } 1674 if (rStorage == fBounds) { 1675 // we were wholly inside the rect, no change 1676 return !this->isEmpty(); 1677 } 1678 if (this->quickContains(rStorage)) { 1679 // the intersection is wholly inside us, we're a rect 1680 return this->setRect(rStorage); 1681 } 1682 r = &rStorage; // use the intersected bounds 1683 break; 1684 case SkRegion::kDifference_Op: 1685 break; 1686 case SkRegion::kUnion_Op: 1687 if (rOrig.contains(fBounds)) { 1688 return this->setRect(rOrig); 1689 } 1690 break; 1691 default: 1692 break; 1693 } 1694 1695 SkAAClip clip; 1696 clip.setRect(*r); 1697 return this->op(*this, clip, op); 1698 } 1699 1700 bool SkAAClip::op(const SkRect& rOrig, SkRegion::Op op, bool doAA) { 1701 SkRect rStorage, boundsStorage; 1702 const SkRect* r = &rOrig; 1703 1704 boundsStorage.set(fBounds); 1705 switch (op) { 1706 case SkRegion::kIntersect_Op: 1707 case SkRegion::kDifference_Op: 1708 if (!rStorage.intersect(rOrig, boundsStorage)) { 1709 if (SkRegion::kIntersect_Op == op) { 1710 return this->setEmpty(); 1711 } else { // kDifference 1712 return !this->isEmpty(); 1713 } 1714 } 1715 r = &rStorage; // use the intersected bounds 1716 break; 1717 case SkRegion::kUnion_Op: 1718 if (rOrig.contains(boundsStorage)) { 1719 return this->setRect(rOrig); 1720 } 1721 break; 1722 default: 1723 break; 1724 } 1725 1726 SkAAClip clip; 1727 clip.setRect(*r, doAA); 1728 return this->op(*this, clip, op); 1729 } 1730 1731 bool SkAAClip::op(const SkAAClip& clip, SkRegion::Op op) { 1732 return this->op(*this, clip, op); 1733 } 1734 1735 /////////////////////////////////////////////////////////////////////////////// 1736 1737 bool SkAAClip::translate(int dx, int dy, SkAAClip* dst) const { 1738 if (NULL == dst) { 1739 return !this->isEmpty(); 1740 } 1741 1742 if (this->isEmpty()) { 1743 return dst->setEmpty(); 1744 } 1745 1746 if (this != dst) { 1747 sk_atomic_inc(&fRunHead->fRefCnt); 1748 dst->freeRuns(); 1749 dst->fRunHead = fRunHead; 1750 dst->fBounds = fBounds; 1751 } 1752 dst->fBounds.offset(dx, dy); 1753 return true; 1754 } 1755 1756 static void expand_row_to_mask(uint8_t* SK_RESTRICT mask, 1757 const uint8_t* SK_RESTRICT row, 1758 int width) { 1759 while (width > 0) { 1760 int n = row[0]; 1761 SkASSERT(width >= n); 1762 memset(mask, row[1], n); 1763 mask += n; 1764 row += 2; 1765 width -= n; 1766 } 1767 SkASSERT(0 == width); 1768 } 1769 1770 void SkAAClip::copyToMask(SkMask* mask) const { 1771 mask->fFormat = SkMask::kA8_Format; 1772 if (this->isEmpty()) { 1773 mask->fBounds.setEmpty(); 1774 mask->fImage = NULL; 1775 mask->fRowBytes = 0; 1776 return; 1777 } 1778 1779 mask->fBounds = fBounds; 1780 mask->fRowBytes = fBounds.width(); 1781 size_t size = mask->computeImageSize(); 1782 mask->fImage = SkMask::AllocImage(size); 1783 1784 Iter iter(*this); 1785 uint8_t* dst = mask->fImage; 1786 const int width = fBounds.width(); 1787 1788 int y = fBounds.fTop; 1789 while (!iter.done()) { 1790 do { 1791 expand_row_to_mask(dst, iter.data(), width); 1792 dst += mask->fRowBytes; 1793 } while (++y < iter.bottom()); 1794 iter.next(); 1795 } 1796 } 1797 1798 /////////////////////////////////////////////////////////////////////////////// 1799 /////////////////////////////////////////////////////////////////////////////// 1800 1801 static void expandToRuns(const uint8_t* SK_RESTRICT data, int initialCount, int width, 1802 int16_t* SK_RESTRICT runs, SkAlpha* SK_RESTRICT aa) { 1803 // we don't read our initial n from data, since the caller may have had to 1804 // clip it, hence the initialCount parameter. 1805 int n = initialCount; 1806 for (;;) { 1807 if (n > width) { 1808 n = width; 1809 } 1810 SkASSERT(n > 0); 1811 runs[0] = n; 1812 runs += n; 1813 1814 aa[0] = data[1]; 1815 aa += n; 1816 1817 data += 2; 1818 width -= n; 1819 if (0 == width) { 1820 break; 1821 } 1822 // load the next count 1823 n = data[0]; 1824 } 1825 runs[0] = 0; // sentinel 1826 } 1827 1828 SkAAClipBlitter::~SkAAClipBlitter() { 1829 sk_free(fScanlineScratch); 1830 } 1831 1832 void SkAAClipBlitter::ensureRunsAndAA() { 1833 if (NULL == fScanlineScratch) { 1834 // add 1 so we can store the terminating run count of 0 1835 int count = fAAClipBounds.width() + 1; 1836 // we use this either for fRuns + fAA, or a scaline of a mask 1837 // which may be as deep as 32bits 1838 fScanlineScratch = sk_malloc_throw(count * sizeof(SkPMColor)); 1839 fRuns = (int16_t*)fScanlineScratch; 1840 fAA = (SkAlpha*)(fRuns + count); 1841 } 1842 } 1843 1844 void SkAAClipBlitter::blitH(int x, int y, int width) { 1845 SkASSERT(width > 0); 1846 SkASSERT(fAAClipBounds.contains(x, y)); 1847 SkASSERT(fAAClipBounds.contains(x + width - 1, y)); 1848 1849 const uint8_t* row = fAAClip->findRow(y); 1850 int initialCount; 1851 row = fAAClip->findX(row, x, &initialCount); 1852 1853 if (initialCount >= width) { 1854 SkAlpha alpha = row[1]; 1855 if (0 == alpha) { 1856 return; 1857 } 1858 if (0xFF == alpha) { 1859 fBlitter->blitH(x, y, width); 1860 return; 1861 } 1862 } 1863 1864 this->ensureRunsAndAA(); 1865 expandToRuns(row, initialCount, width, fRuns, fAA); 1866 1867 fBlitter->blitAntiH(x, y, fAA, fRuns); 1868 } 1869 1870 static void merge(const uint8_t* SK_RESTRICT row, int rowN, 1871 const SkAlpha* SK_RESTRICT srcAA, 1872 const int16_t* SK_RESTRICT srcRuns, 1873 SkAlpha* SK_RESTRICT dstAA, 1874 int16_t* SK_RESTRICT dstRuns, 1875 int width) { 1876 SkDEBUGCODE(int accumulated = 0;) 1877 int srcN = srcRuns[0]; 1878 // do we need this check? 1879 if (0 == srcN) { 1880 return; 1881 } 1882 1883 for (;;) { 1884 SkASSERT(rowN > 0); 1885 SkASSERT(srcN > 0); 1886 1887 unsigned newAlpha = SkMulDiv255Round(srcAA[0], row[1]); 1888 int minN = SkMin32(srcN, rowN); 1889 dstRuns[0] = minN; 1890 dstRuns += minN; 1891 dstAA[0] = newAlpha; 1892 dstAA += minN; 1893 1894 if (0 == (srcN -= minN)) { 1895 srcN = srcRuns[0]; // refresh 1896 srcRuns += srcN; 1897 srcAA += srcN; 1898 srcN = srcRuns[0]; // reload 1899 if (0 == srcN) { 1900 break; 1901 } 1902 } 1903 if (0 == (rowN -= minN)) { 1904 row += 2; 1905 rowN = row[0]; // reload 1906 } 1907 1908 SkDEBUGCODE(accumulated += minN;) 1909 SkASSERT(accumulated <= width); 1910 } 1911 dstRuns[0] = 0; 1912 } 1913 1914 void SkAAClipBlitter::blitAntiH(int x, int y, const SkAlpha aa[], 1915 const int16_t runs[]) { 1916 1917 const uint8_t* row = fAAClip->findRow(y); 1918 int initialCount; 1919 row = fAAClip->findX(row, x, &initialCount); 1920 1921 this->ensureRunsAndAA(); 1922 1923 merge(row, initialCount, aa, runs, fAA, fRuns, fAAClipBounds.width()); 1924 fBlitter->blitAntiH(x, y, fAA, fRuns); 1925 } 1926 1927 void SkAAClipBlitter::blitV(int x, int y, int height, SkAlpha alpha) { 1928 if (fAAClip->quickContains(x, y, x + 1, y + height)) { 1929 fBlitter->blitV(x, y, height, alpha); 1930 return; 1931 } 1932 1933 for (;;) { 1934 int lastY SK_INIT_TO_AVOID_WARNING; 1935 const uint8_t* row = fAAClip->findRow(y, &lastY); 1936 int dy = lastY - y + 1; 1937 if (dy > height) { 1938 dy = height; 1939 } 1940 height -= dy; 1941 1942 row = fAAClip->findX(row, x); 1943 SkAlpha newAlpha = SkMulDiv255Round(alpha, row[1]); 1944 if (newAlpha) { 1945 fBlitter->blitV(x, y, dy, newAlpha); 1946 } 1947 SkASSERT(height >= 0); 1948 if (height <= 0) { 1949 break; 1950 } 1951 y = lastY + 1; 1952 } 1953 } 1954 1955 void SkAAClipBlitter::blitRect(int x, int y, int width, int height) { 1956 if (fAAClip->quickContains(x, y, x + width, y + height)) { 1957 fBlitter->blitRect(x, y, width, height); 1958 return; 1959 } 1960 1961 while (--height >= 0) { 1962 this->blitH(x, y, width); 1963 y += 1; 1964 } 1965 } 1966 1967 typedef void (*MergeAAProc)(const void* src, int width, const uint8_t* row, 1968 int initialRowCount, void* dst); 1969 1970 static void small_memcpy(void* dst, const void* src, size_t n) { 1971 memcpy(dst, src, n); 1972 } 1973 1974 static void small_bzero(void* dst, size_t n) { 1975 sk_bzero(dst, n); 1976 } 1977 1978 static inline uint8_t mergeOne(uint8_t value, unsigned alpha) { 1979 return SkMulDiv255Round(value, alpha); 1980 } 1981 static inline uint16_t mergeOne(uint16_t value, unsigned alpha) { 1982 unsigned r = SkGetPackedR16(value); 1983 unsigned g = SkGetPackedG16(value); 1984 unsigned b = SkGetPackedB16(value); 1985 return SkPackRGB16(SkMulDiv255Round(r, alpha), 1986 SkMulDiv255Round(g, alpha), 1987 SkMulDiv255Round(b, alpha)); 1988 } 1989 static inline SkPMColor mergeOne(SkPMColor value, unsigned alpha) { 1990 unsigned a = SkGetPackedA32(value); 1991 unsigned r = SkGetPackedR32(value); 1992 unsigned g = SkGetPackedG32(value); 1993 unsigned b = SkGetPackedB32(value); 1994 return SkPackARGB32(SkMulDiv255Round(a, alpha), 1995 SkMulDiv255Round(r, alpha), 1996 SkMulDiv255Round(g, alpha), 1997 SkMulDiv255Round(b, alpha)); 1998 } 1999 2000 template <typename T> void mergeT(const T* SK_RESTRICT src, int srcN, 2001 const uint8_t* SK_RESTRICT row, int rowN, 2002 T* SK_RESTRICT dst) { 2003 for (;;) { 2004 SkASSERT(rowN > 0); 2005 SkASSERT(srcN > 0); 2006 2007 int n = SkMin32(rowN, srcN); 2008 unsigned rowA = row[1]; 2009 if (0xFF == rowA) { 2010 small_memcpy(dst, src, n * sizeof(T)); 2011 } else if (0 == rowA) { 2012 small_bzero(dst, n * sizeof(T)); 2013 } else { 2014 for (int i = 0; i < n; ++i) { 2015 dst[i] = mergeOne(src[i], rowA); 2016 } 2017 } 2018 2019 if (0 == (srcN -= n)) { 2020 break; 2021 } 2022 2023 src += n; 2024 dst += n; 2025 2026 SkASSERT(rowN == n); 2027 row += 2; 2028 rowN = row[0]; 2029 } 2030 } 2031 2032 static MergeAAProc find_merge_aa_proc(SkMask::Format format) { 2033 switch (format) { 2034 case SkMask::kBW_Format: 2035 SkDEBUGFAIL("unsupported"); 2036 return NULL; 2037 case SkMask::kA8_Format: 2038 case SkMask::k3D_Format: { 2039 void (*proc8)(const uint8_t*, int, const uint8_t*, int, uint8_t*) = mergeT; 2040 return (MergeAAProc)proc8; 2041 } 2042 case SkMask::kLCD16_Format: { 2043 void (*proc16)(const uint16_t*, int, const uint8_t*, int, uint16_t*) = mergeT; 2044 return (MergeAAProc)proc16; 2045 } 2046 case SkMask::kLCD32_Format: { 2047 void (*proc32)(const SkPMColor*, int, const uint8_t*, int, SkPMColor*) = mergeT; 2048 return (MergeAAProc)proc32; 2049 } 2050 default: 2051 SkDEBUGFAIL("unsupported"); 2052 return NULL; 2053 } 2054 } 2055 2056 static U8CPU bit2byte(int bitInAByte) { 2057 SkASSERT(bitInAByte <= 0xFF); 2058 // negation turns any non-zero into 0xFFFFFF??, so we just shift down 2059 // some value >= 8 to get a full FF value 2060 return -bitInAByte >> 8; 2061 } 2062 2063 static void upscaleBW2A8(SkMask* dstMask, const SkMask& srcMask) { 2064 SkASSERT(SkMask::kBW_Format == srcMask.fFormat); 2065 SkASSERT(SkMask::kA8_Format == dstMask->fFormat); 2066 2067 const int width = srcMask.fBounds.width(); 2068 const int height = srcMask.fBounds.height(); 2069 2070 const uint8_t* SK_RESTRICT src = (const uint8_t*)srcMask.fImage; 2071 const size_t srcRB = srcMask.fRowBytes; 2072 uint8_t* SK_RESTRICT dst = (uint8_t*)dstMask->fImage; 2073 const size_t dstRB = dstMask->fRowBytes; 2074 2075 const int wholeBytes = width >> 3; 2076 const int leftOverBits = width & 7; 2077 2078 for (int y = 0; y < height; ++y) { 2079 uint8_t* SK_RESTRICT d = dst; 2080 for (int i = 0; i < wholeBytes; ++i) { 2081 int srcByte = src[i]; 2082 d[0] = bit2byte(srcByte & (1 << 7)); 2083 d[1] = bit2byte(srcByte & (1 << 6)); 2084 d[2] = bit2byte(srcByte & (1 << 5)); 2085 d[3] = bit2byte(srcByte & (1 << 4)); 2086 d[4] = bit2byte(srcByte & (1 << 3)); 2087 d[5] = bit2byte(srcByte & (1 << 2)); 2088 d[6] = bit2byte(srcByte & (1 << 1)); 2089 d[7] = bit2byte(srcByte & (1 << 0)); 2090 d += 8; 2091 } 2092 if (leftOverBits) { 2093 int srcByte = src[wholeBytes]; 2094 for (int x = 0; x < leftOverBits; ++x) { 2095 *d++ = bit2byte(srcByte & 0x80); 2096 srcByte <<= 1; 2097 } 2098 } 2099 src += srcRB; 2100 dst += dstRB; 2101 } 2102 } 2103 2104 void SkAAClipBlitter::blitMask(const SkMask& origMask, const SkIRect& clip) { 2105 SkASSERT(fAAClip->getBounds().contains(clip)); 2106 2107 if (fAAClip->quickContains(clip)) { 2108 fBlitter->blitMask(origMask, clip); 2109 return; 2110 } 2111 2112 const SkMask* mask = &origMask; 2113 2114 // if we're BW, we need to upscale to A8 (ugh) 2115 SkMask grayMask; 2116 grayMask.fImage = NULL; 2117 if (SkMask::kBW_Format == origMask.fFormat) { 2118 grayMask.fFormat = SkMask::kA8_Format; 2119 grayMask.fBounds = origMask.fBounds; 2120 grayMask.fRowBytes = origMask.fBounds.width(); 2121 size_t size = grayMask.computeImageSize(); 2122 grayMask.fImage = (uint8_t*)fGrayMaskScratch.reset(size, 2123 SkAutoMalloc::kReuse_OnShrink); 2124 2125 upscaleBW2A8(&grayMask, origMask); 2126 mask = &grayMask; 2127 } 2128 2129 this->ensureRunsAndAA(); 2130 2131 // HACK -- we are devolving 3D into A8, need to copy the rest of the 3D 2132 // data into a temp block to support it better (ugh) 2133 2134 const void* src = mask->getAddr(clip.fLeft, clip.fTop); 2135 const size_t srcRB = mask->fRowBytes; 2136 const int width = clip.width(); 2137 MergeAAProc mergeProc = find_merge_aa_proc(mask->fFormat); 2138 2139 SkMask rowMask; 2140 rowMask.fFormat = SkMask::k3D_Format == mask->fFormat ? SkMask::kA8_Format : mask->fFormat; 2141 rowMask.fBounds.fLeft = clip.fLeft; 2142 rowMask.fBounds.fRight = clip.fRight; 2143 rowMask.fRowBytes = mask->fRowBytes; // doesn't matter, since our height==1 2144 rowMask.fImage = (uint8_t*)fScanlineScratch; 2145 2146 int y = clip.fTop; 2147 const int stopY = y + clip.height(); 2148 2149 do { 2150 int localStopY SK_INIT_TO_AVOID_WARNING; 2151 const uint8_t* row = fAAClip->findRow(y, &localStopY); 2152 // findRow returns last Y, not stop, so we add 1 2153 localStopY = SkMin32(localStopY + 1, stopY); 2154 2155 int initialCount; 2156 row = fAAClip->findX(row, clip.fLeft, &initialCount); 2157 do { 2158 mergeProc(src, width, row, initialCount, rowMask.fImage); 2159 rowMask.fBounds.fTop = y; 2160 rowMask.fBounds.fBottom = y + 1; 2161 fBlitter->blitMask(rowMask, rowMask.fBounds); 2162 src = (const void*)((const char*)src + srcRB); 2163 } while (++y < localStopY); 2164 } while (y < stopY); 2165 } 2166 2167 const SkBitmap* SkAAClipBlitter::justAnOpaqueColor(uint32_t* value) { 2168 return NULL; 2169 } 2170