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 |