| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |