Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/core/SkScan_AAAPath.cpp

Issue 2482193004: Tighten SkAAClip Bounds by Path Bounds (Closed)
Patch Set: Fix 100 line limit Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/PathTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2016 The Android Open Source Project 2 * Copyright 2016 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkAntiRun.h" 8 #include "SkAntiRun.h"
9 #include "SkBlitter.h" 9 #include "SkBlitter.h"
10 #include "SkEdge.h" 10 #include "SkEdge.h"
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 SkBlitter* fRealBlitter; 183 SkBlitter* fRealBlitter;
184 SkMask fMask; 184 SkMask fMask;
185 SkIRect fClipRect; 185 SkIRect fClipRect;
186 // we add 2 because we can write 1 extra byte at either end due to precision error 186 // we add 2 because we can write 1 extra byte at either end due to precision error
187 uint32_t fStorage[(kMAX_STORAGE >> 2) + 2]; 187 uint32_t fStorage[(kMAX_STORAGE >> 2) + 2];
188 188
189 uint8_t* fRow; 189 uint8_t* fRow;
190 int fY; 190 int fY;
191 }; 191 };
192 192
193 MaskAdditiveBlitter::MaskAdditiveBlitter(SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, 193 MaskAdditiveBlitter::MaskAdditiveBlitter(
194 bool isInverse) { 194 SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool is Inverse) {
195 SkASSERT(canHandleRect(ir)); 195 SkASSERT(canHandleRect(ir));
196 SkASSERT(!isInverse); 196 SkASSERT(!isInverse);
197 197
198 fRealBlitter = realBlitter; 198 fRealBlitter = realBlitter;
199 199
200 fMask.fImage = (uint8_t*)fStorage + 1; // There's 1 extra byte at either end of fStorage 200 fMask.fImage = (uint8_t*)fStorage + 1; // There's 1 extra byte at either end of fStorage
201 fMask.fBounds = ir; 201 fMask.fBounds = ir;
202 fMask.fRowBytes = ir.width(); 202 fMask.fRowBytes = ir.width();
203 fMask.fFormat = SkMask::kA8_Format; 203 fMask.fFormat = SkMask::kA8_Format;
204 204
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 } 360 }
361 361
362 inline void checkY(int y) { 362 inline void checkY(int y) {
363 if (y != fCurrY) { 363 if (y != fCurrY) {
364 this->flush(); 364 this->flush();
365 fCurrY = y; 365 fCurrY = y;
366 } 366 }
367 } 367 }
368 }; 368 };
369 369
370 RunBasedAdditiveBlitter::RunBasedAdditiveBlitter(SkBlitter* realBlitter, const S kIRect& ir, const SkRegion& clip, 370 RunBasedAdditiveBlitter::RunBasedAdditiveBlitter(
371 bool isInverse) { 371 SkBlitter* realBlitter, const SkIRect& ir, const SkRegion& clip, bool is Inverse) {
372 fRealBlitter = realBlitter; 372 fRealBlitter = realBlitter;
373 373
374 SkIRect sectBounds; 374 SkIRect sectBounds;
375 if (isInverse) { 375 if (isInverse) {
376 // We use the clip bounds instead of the ir, since we may be asked to 376 // We use the clip bounds instead of the ir, since we may be asked to
377 //draw outside of the rect when we're a inverse filltype 377 //draw outside of the rect when we're a inverse filltype
378 sectBounds = clip.getBounds(); 378 sectBounds = clip.getBounds();
379 } else { 379 } else {
380 if (!sectBounds.intersect(ir, clip.getBounds())) { 380 if (!sectBounds.intersect(ir, clip.getBounds())) {
381 sectBounds.setEmpty(); 381 sectBounds.setEmpty();
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 SkFixed alpha16 = firstH + (dY >> 1); // rectangle plus triangle 526 SkFixed alpha16 = firstH + (dY >> 1); // rectangle plus triangle
527 for (int i = 1; i < R - 1; i++) { 527 for (int i = 1; i < R - 1; i++) {
528 alphas[i] = alpha16 >> 8; 528 alphas[i] = alpha16 >> 8;
529 alpha16 += dY; 529 alpha16 += dY;
530 } 530 }
531 alphas[R - 1] = fullAlpha - partialTriangleToAlpha(last, dY); 531 alphas[R - 1] = fullAlpha - partialTriangleToAlpha(last, dY);
532 } 532 }
533 } 533 }
534 534
535 // Here we always send in l < SK_Fixed1, and the first alpha we want to compute is alphas[0] 535 // Here we always send in l < SK_Fixed1, and the first alpha we want to compute is alphas[0]
536 static inline void computeAlphaBelowLine(SkAlpha* alphas, SkFixed l, SkFixed r, SkFixed dY, SkAlpha fullAlpha) { 536 static inline void computeAlphaBelowLine(
537 SkAlpha* alphas, SkFixed l, SkFixed r, SkFixed dY, SkAlpha fullAlpha) {
537 SkASSERT(l <= r); 538 SkASSERT(l <= r);
538 SkASSERT(l >> 16 == 0); 539 SkASSERT(l >> 16 == 0);
539 int R = SkFixedCeilToInt(r); 540 int R = SkFixedCeilToInt(r);
540 if (R == 0) { 541 if (R == 0) {
541 return; 542 return;
542 } else if (R == 1) { 543 } else if (R == 1) {
543 alphas[0] = getPartialAlpha(trapezoidToAlpha(l, r), fullAlpha); 544 alphas[0] = getPartialAlpha(trapezoidToAlpha(l, r), fullAlpha);
544 } else { 545 } else {
545 SkFixed first = SK_Fixed1 - l; // horizontal edge length of the left-mos t triangle 546 SkFixed first = SK_Fixed1 - l; // horizontal edge length of the left-mos t triangle
546 SkFixed last = r - ((R - 1) << 16); // horizontal edge length of the rig ht-most triangle 547 SkFixed last = r - ((R - 1) << 16); // horizontal edge length of the rig ht-most triangle
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 SkFixed local_bot_fixed = SkMin32(leftE->fLowerY, riteE->fLowerY); 959 SkFixed local_bot_fixed = SkMin32(leftE->fLowerY, riteE->fLowerY);
959 // Skip the fractional y if edges are changing smoothly. 960 // Skip the fractional y if edges are changing smoothly.
960 // If forceRLE is true, we won't skip the fractional y because it 961 // If forceRLE is true, we won't skip the fractional y because it
961 // implies that SkAAClip is calling us and there are strict 962 // implies that SkAAClip is calling us and there are strict
962 // assertions inside SkAAClip. 963 // assertions inside SkAAClip.
963 if (isSmoothEnough(leftE, riteE, currE, stop_y) && !forceRLE) { 964 if (isSmoothEnough(leftE, riteE, currE, stop_y) && !forceRLE) {
964 local_bot_fixed = SkFixedCeilToFixed(local_bot_fixed); 965 local_bot_fixed = SkFixedCeilToFixed(local_bot_fixed);
965 } 966 }
966 local_bot_fixed = SkMin32(local_bot_fixed, SkIntToFixed(stop_y)); 967 local_bot_fixed = SkMin32(local_bot_fixed, SkIntToFixed(stop_y));
967 968
968 SkFixed left = leftE->fX; 969 SkFixed left = SkTMax(leftBound, leftE->fX);
969 SkFixed dLeft = leftE->fDX; 970 SkFixed dLeft = leftE->fDX;
970 SkFixed rite = riteE->fX; 971 SkFixed rite = SkTMin(riteBound, riteE->fX);
971 SkFixed dRite = riteE->fDX; 972 SkFixed dRite = riteE->fDX;
972 if (0 == (dLeft | dRite)) { 973 if (0 == (dLeft | dRite)) {
973 int fullLeft = SkFixedCeilToInt(left); 974 int fullLeft = SkFixedCeilToInt(left);
974 int fullRite = SkFixedFloorToInt(rite); 975 int fullRite = SkFixedFloorToInt(rite);
975 SkFixed partialLeft = SkIntToFixed(fullLeft) - left; 976 SkFixed partialLeft = SkIntToFixed(fullLeft) - left;
976 SkFixed partialRite = rite - SkIntToFixed(fullRite); 977 SkFixed partialRite = rite - SkIntToFixed(fullRite);
977 int fullTop = SkFixedCeilToInt(y); 978 int fullTop = SkFixedCeilToInt(y);
978 int fullBot = SkFixedFloorToInt(local_bot_fixed); 979 int fullBot = SkFixedFloorToInt(local_bot_fixed);
979 SkFixed partialTop = SkIntToFixed(fullTop) - y; 980 SkFixed partialTop = SkIntToFixed(fullTop) - y;
980 SkFixed partialBot = local_bot_fixed - SkIntToFixed(fullBot); 981 SkFixed partialBot = local_bot_fixed - SkIntToFixed(fullBot);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // and full-row trapezoid_row together, we use the following 3-stage flow to 1071 // and full-row trapezoid_row together, we use the following 3-stage flow to
1071 // handle partial-row blit and full-row blit separately. It will sav e us much time 1072 // handle partial-row blit and full-row blit separately. It will sav e us much time
1072 // on changing y, left, and rite. 1073 // on changing y, left, and rite.
1073 if (count > 1) { 1074 if (count > 1) {
1074 if ((int)(y & 0xFFFF0000) != y) { // There's a partial-row on th e top 1075 if ((int)(y & 0xFFFF0000) != y) { // There's a partial-row on th e top
1075 count--; 1076 count--;
1076 SkFixed nextY = SkFixedCeilToFixed(y + 1); 1077 SkFixed nextY = SkFixedCeilToFixed(y + 1);
1077 SkFixed dY = nextY - y; 1078 SkFixed dY = nextY - y;
1078 SkFixed nextLeft = left + SkFixedMul_lowprec(dLeft, dY); 1079 SkFixed nextLeft = left + SkFixedMul_lowprec(dLeft, dY);
1079 SkFixed nextRite = rite + SkFixedMul_lowprec(dRite, dY); 1080 SkFixed nextRite = rite + SkFixedMul_lowprec(dRite, dY);
1081 SkASSERT((left & kSnapMask) >= leftBound && (rite & kSnapMas k) <= riteBound &&
1082 (nextLeft & kSnapMask) >= leftBound &&
1083 (nextRite & kSnapMask) <= riteBound);
1080 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask, 1084 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask,
1081 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->f DY, riteE->fDY, 1085 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->f DY, riteE->fDY,
1082 getPartialAlpha(0xFF, dY), maskRow, isUsingMask); 1086 getPartialAlpha(0xFF, dY), maskRow, isUsingMask);
1083 if (forceRLE) { 1087 if (forceRLE) {
1084 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed( y, nextY); 1088 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed( y, nextY);
1085 } 1089 }
1086 left = nextLeft; rite = nextRite; y = nextY; 1090 left = nextLeft; rite = nextRite; y = nextY;
1087 } 1091 }
1088 1092
1089 while (count > 1) { // Full rows in the middle 1093 while (count > 1) { // Full rows in the middle
1090 count--; 1094 count--;
1091 if (isUsingMask) { 1095 if (isUsingMask) {
1092 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->ge tRow(y >> 16); 1096 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->ge tRow(y >> 16);
1093 } 1097 }
1094 SkFixed nextY = y + SK_Fixed1, nextLeft = left + dLeft, next Rite = rite + dRite; 1098 SkFixed nextY = y + SK_Fixed1, nextLeft = left + dLeft, next Rite = rite + dRite;
1099 SkASSERT((left & kSnapMask) >= leftBound && (rite & kSnapMas k) <= riteBound &&
1100 (nextLeft & kSnapMask) >= leftBound &&
1101 (nextRite & kSnapMask) <= riteBound);
1095 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask, 1102 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapMask,
1096 nextLeft & kSnapMask, nextRite & kSnapMask, 1103 nextLeft & kSnapMask, nextRite & kSnapMask,
1097 leftE->fDY, riteE->fDY, 0xFF, maskRow, isUsingMask); 1104 leftE->fDY, riteE->fDY, 0xFF, maskRow, isUsingMask);
1098 if (forceRLE) { 1105 if (forceRLE) {
1099 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed( y, nextY); 1106 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed( y, nextY);
1100 } 1107 }
1101 left = nextLeft; rite = nextRite; y = nextY; 1108 left = nextLeft; rite = nextRite; y = nextY;
1102 } 1109 }
1103 } 1110 }
1104 1111
1105 if (isUsingMask) { 1112 if (isUsingMask) {
1106 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y > > 16); 1113 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y > > 16);
1107 } 1114 }
1108 1115
1109 SkFixed dY = local_bot_fixed - y; // partial-row on the bottom 1116 SkFixed dY = local_bot_fixed - y; // partial-row on the bottom
1110 SkASSERT(dY <= SK_Fixed1); 1117 SkASSERT(dY <= SK_Fixed1);
1111 // Smooth jumping to integer y may make the last nextLeft/nextRite o ut of bound. 1118 // Smooth jumping to integer y may make the last nextLeft/nextRite o ut of bound.
1112 // Take them back into the bound here. 1119 // Take them back into the bound here.
1113 // Note that we substract kSnapHalf later so we have to add them to leftBound/riteBound 1120 // Note that we substract kSnapHalf later so we have to add them to leftBound/riteBound
1114 SkFixed nextLeft = SkTMax(left + SkFixedMul_lowprec(dLeft, dY), left Bound + kSnapHalf); 1121 SkFixed nextLeft = SkTMax(left + SkFixedMul_lowprec(dLeft, dY), left Bound + kSnapHalf);
1115 SkFixed nextRite = SkTMin(rite + SkFixedMul_lowprec(dRite, dY), rite Bound + kSnapHalf); 1122 SkFixed nextRite = SkTMin(rite + SkFixedMul_lowprec(dRite, dY), rite Bound + kSnapHalf);
1123 SkASSERT((left & kSnapMask) >= leftBound && (rite & kSnapMask) <= ri teBound &&
1124 (nextLeft & kSnapMask) >= leftBound && (nextRite & kSnapMask ) <= riteBound);
1116 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapM ask, 1125 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapM ask,
1117 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->fDY, rite E->fDY, 1126 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->fDY, rite E->fDY,
1118 getPartialAlpha(0xFF, dY), maskRow, isUsingMask); 1127 getPartialAlpha(0xFF, dY), maskRow, isUsingMask);
1119 if (forceRLE) { 1128 if (forceRLE) {
1120 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(y, local _bot_fixed); 1129 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(y, local _bot_fixed);
1121 } 1130 }
1122 left = nextLeft; rite = nextRite; y = local_bot_fixed; 1131 left = nextLeft; rite = nextRite; y = local_bot_fixed;
1123 left -= kSnapHalf; rite -= kSnapHalf; 1132 left -= kSnapHalf; rite -= kSnapHalf;
1124 } 1133 }
1125 1134
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1348 AAAFillPath(path, clip.bwRgn(), blitter); 1357 AAAFillPath(path, clip.bwRgn(), blitter);
1349 } else { 1358 } else {
1350 SkRegion tmp; 1359 SkRegion tmp;
1351 SkAAClipBlitter aaBlitter; 1360 SkAAClipBlitter aaBlitter;
1352 1361
1353 tmp.setRect(clip.getBounds()); 1362 tmp.setRect(clip.getBounds());
1354 aaBlitter.init(blitter, &clip.aaRgn()); 1363 aaBlitter.init(blitter, &clip.aaRgn());
1355 AAAFillPath(path, tmp, &aaBlitter, true); 1364 AAAFillPath(path, tmp, &aaBlitter, true);
1356 } 1365 }
1357 } 1366 }
OLDNEW
« no previous file with comments | « no previous file | tests/PathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698