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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 ~RunBasedAdditiveBlitter(); | 266 ~RunBasedAdditiveBlitter(); |
267 | 267 |
268 SkBlitter* getRealBlitter(bool forceRealBlitter) override; | 268 SkBlitter* getRealBlitter(bool forceRealBlitter) override; |
269 | 269 |
270 void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override; | 270 void blitAntiH(int x, int y, const SkAlpha antialias[], int len) override; |
271 void blitAntiH(int x, int y, const SkAlpha alpha) override; | 271 void blitAntiH(int x, int y, const SkAlpha alpha) override; |
272 void blitAntiH(int x, int y, int width, const SkAlpha alpha) override; | 272 void blitAntiH(int x, int y, int width, const SkAlpha alpha) override; |
273 | 273 |
274 int getWidth() override; | 274 int getWidth() override; |
275 | 275 |
| 276 // This should only be called when forceRLE = true which implies that SkAACl
ip |
| 277 // is calling us. |
| 278 // SkAAClip requires that we blit in scan-line order so we have to flush |
| 279 // for each row in order. Without this, we may have the first row unflushed, |
| 280 // then blit the 2nd and the 3rd row with full alpha (so we won't flush the
first row); |
| 281 // finally when we blit the fourth row, we trigger the first row to flush, a
nd this |
| 282 // would cause SkAAClip to crash. |
| 283 inline void flush_if_y_changed(SkFixed y, SkFixed nextY) { |
| 284 if (SkFixedFloorToInt(y) != SkFixedFloorToInt(nextY)) { |
| 285 this->flush(); |
| 286 } |
| 287 } |
| 288 |
276 private: | 289 private: |
277 SkBlitter* fRealBlitter; | 290 SkBlitter* fRealBlitter; |
278 | 291 |
279 /// Current y coordinate | 292 /// Current y coordinate |
280 int fCurrY; | 293 int fCurrY; |
281 /// Widest row of region to be blitted | 294 /// Widest row of region to be blitted |
282 int fWidth; | 295 int fWidth; |
283 /// Leftmost x coordinate in any row | 296 /// Leftmost x coordinate in any row |
284 int fLeft; | 297 int fLeft; |
285 /// Initial y coordinate (top of bounds). | 298 /// Initial y coordinate (top of bounds). |
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 // We're going to use the left line ul-ll and the rite line ur-lr | 727 // We're going to use the left line ul-ll and the rite line ur-lr |
715 // to exclude the area that's not covered by the path. | 728 // to exclude the area that's not covered by the path. |
716 // Swapping (ul, ll) or (ur, lr) won't affect that exclusion | 729 // Swapping (ul, ll) or (ur, lr) won't affect that exclusion |
717 // so we'll do that for simplicity. | 730 // so we'll do that for simplicity. |
718 if (ul > ll) { SkTSwap(ul, ll); } | 731 if (ul > ll) { SkTSwap(ul, ll); } |
719 if (ur > lr) { SkTSwap(ur, lr); } | 732 if (ur > lr) { SkTSwap(ur, lr); } |
720 | 733 |
721 SkFixed joinLeft = SkFixedCeilToFixed(ll); | 734 SkFixed joinLeft = SkFixedCeilToFixed(ll); |
722 SkFixed joinRite = SkFixedFloorToFixed(ur); | 735 SkFixed joinRite = SkFixedFloorToFixed(ur); |
723 if (joinLeft <= joinRite) { // There's a rect from joinLeft to joinRite that
we can blit | 736 if (joinLeft <= joinRite) { // There's a rect from joinLeft to joinRite that
we can blit |
724 if (joinLeft < joinRite) { | |
725 blit_full_alpha(blitter, y, joinLeft >> 16, (joinRite - joinLeft) >>
16, fullAlpha, | |
726 maskRow, isUsingMask); | |
727 } | |
728 if (ul < joinLeft) { | 737 if (ul < joinLeft) { |
729 int len = SkFixedCeilToInt(joinLeft - ul); | 738 int len = SkFixedCeilToInt(joinLeft - ul); |
730 if (len == 1) { | 739 if (len == 1) { |
731 SkAlpha alpha = trapezoidToAlpha(joinLeft - ul, joinLeft - ll); | 740 SkAlpha alpha = trapezoidToAlpha(joinLeft - ul, joinLeft - ll); |
732 blit_single_alpha(blitter, y, ul >> 16, alpha, fullAlpha, maskRo
w, isUsingMask); | 741 blit_single_alpha(blitter, y, ul >> 16, alpha, fullAlpha, maskRo
w, isUsingMask); |
733 } else if (len == 2) { | 742 } else if (len == 2) { |
734 SkFixed first = joinLeft - SK_Fixed1 - ul; | 743 SkFixed first = joinLeft - SK_Fixed1 - ul; |
735 SkFixed second = ll - ul - first; | 744 SkFixed second = ll - ul - first; |
736 SkAlpha a1 = partialTriangleToAlpha(first, lDY); | 745 SkAlpha a1 = partialTriangleToAlpha(first, lDY); |
737 SkAlpha a2 = fullAlpha - partialTriangleToAlpha(second, lDY); | 746 SkAlpha a2 = fullAlpha - partialTriangleToAlpha(second, lDY); |
738 blit_two_alphas(blitter, y, ul >> 16, a1, a2, fullAlpha, maskRow
, isUsingMask); | 747 blit_two_alphas(blitter, y, ul >> 16, a1, a2, fullAlpha, maskRow
, isUsingMask); |
739 } else { | 748 } else { |
740 blit_aaa_trapezoid_row(blitter, y, ul, joinLeft, ll, joinLeft, l
DY, SK_MaxS32, | 749 blit_aaa_trapezoid_row(blitter, y, ul, joinLeft, ll, joinLeft, l
DY, SK_MaxS32, |
741 fullAlpha, maskRow, isUsingMask); | 750 fullAlpha, maskRow, isUsingMask); |
742 } | 751 } |
743 } | 752 } |
| 753 // SkAAClip requires that we blit from left to right. |
| 754 // Hence we must blit [ul, joinLeft] before blitting [joinLeft, joinRite
] |
| 755 if (joinLeft < joinRite) { |
| 756 blit_full_alpha(blitter, y, SkFixedFloorToInt(joinLeft), |
| 757 SkFixedFloorToInt(joinRite - joinLeft), |
| 758 fullAlpha, maskRow, isUsingMask); |
| 759 } |
744 if (lr > joinRite) { | 760 if (lr > joinRite) { |
745 int len = SkFixedCeilToInt(lr - joinRite); | 761 int len = SkFixedCeilToInt(lr - joinRite); |
746 if (len == 1) { | 762 if (len == 1) { |
747 SkAlpha alpha = trapezoidToAlpha(ur - joinRite, lr - joinRite); | 763 SkAlpha alpha = trapezoidToAlpha(ur - joinRite, lr - joinRite); |
748 blit_single_alpha(blitter, y, joinRite >> 16, alpha, fullAlpha,
maskRow, | 764 blit_single_alpha(blitter, y, joinRite >> 16, alpha, fullAlpha,
maskRow, |
749 isUsingMask); | 765 isUsingMask); |
750 } else if (len == 2) { | 766 } else if (len == 2) { |
751 SkFixed first = joinRite + SK_Fixed1 - ur; | 767 SkFixed first = joinRite + SK_Fixed1 - ur; |
752 SkFixed second = lr - ur - first; | 768 SkFixed second = lr - ur - first; |
753 SkAlpha a1 = fullAlpha - partialTriangleToAlpha(first, rDY); | 769 SkAlpha a1 = fullAlpha - partialTriangleToAlpha(first, rDY); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 return false; | 889 return false; |
874 } | 890 } |
875 if (*nextCurrE < *currE) { | 891 if (*nextCurrE < *currE) { |
876 SkTSwap(currE, nextCurrE); | 892 SkTSwap(currE, nextCurrE); |
877 } | 893 } |
878 return isSmoothEnough(leftE, currE, stop_y) && isSmoothEnough(riteE, nextCur
rE, stop_y); | 894 return isSmoothEnough(leftE, currE, stop_y) && isSmoothEnough(riteE, nextCur
rE, stop_y); |
879 } | 895 } |
880 | 896 |
881 static inline void aaa_walk_convex_edges(SkAnalyticEdge* prevHead, AdditiveBlitt
er* blitter, | 897 static inline void aaa_walk_convex_edges(SkAnalyticEdge* prevHead, AdditiveBlitt
er* blitter, |
882 int start_y, int stop_y, SkFixed leftBound, SkFixed r
iteBound, | 898 int start_y, int stop_y, SkFixed leftBound, SkFixed r
iteBound, |
883 bool isUsingMask) { | 899 bool isUsingMask, bool forceRLE) { |
884 validate_sort((SkAnalyticEdge*)prevHead->fNext); | 900 validate_sort((SkAnalyticEdge*)prevHead->fNext); |
885 | 901 |
886 SkAnalyticEdge* leftE = (SkAnalyticEdge*) prevHead->fNext; | 902 SkAnalyticEdge* leftE = (SkAnalyticEdge*) prevHead->fNext; |
887 SkAnalyticEdge* riteE = (SkAnalyticEdge*) leftE->fNext; | 903 SkAnalyticEdge* riteE = (SkAnalyticEdge*) leftE->fNext; |
888 SkAnalyticEdge* currE = (SkAnalyticEdge*) riteE->fNext; | 904 SkAnalyticEdge* currE = (SkAnalyticEdge*) riteE->fNext; |
889 | 905 |
890 SkFixed y = SkTMax(leftE->fUpperY, riteE->fUpperY); | 906 SkFixed y = SkTMax(leftE->fUpperY, riteE->fUpperY); |
891 | 907 |
892 #ifdef SK_DEBUG | 908 #ifdef SK_DEBUG |
893 int frac_y_cnt = 0; | 909 int frac_y_cnt = 0; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
954 int fullTop = SkFixedCeilToInt(y); | 970 int fullTop = SkFixedCeilToInt(y); |
955 int fullBot = SkFixedFloorToInt(local_bot_fixed); | 971 int fullBot = SkFixedFloorToInt(local_bot_fixed); |
956 SkFixed partialTop = SkIntToFixed(fullTop) - y; | 972 SkFixed partialTop = SkIntToFixed(fullTop) - y; |
957 SkFixed partialBot = local_bot_fixed - SkIntToFixed(fullBot); | 973 SkFixed partialBot = local_bot_fixed - SkIntToFixed(fullBot); |
958 if (fullTop > fullBot) { // The rectangle is within one pixel height
... | 974 if (fullTop > fullBot) { // The rectangle is within one pixel height
... |
959 partialTop -= (SK_Fixed1 - partialBot); | 975 partialTop -= (SK_Fixed1 - partialBot); |
960 partialBot = 0; | 976 partialBot = 0; |
961 } | 977 } |
962 | 978 |
963 if (fullRite >= fullLeft) { | 979 if (fullRite >= fullLeft) { |
| 980 if (partialTop > 0) { // blit first partial row |
| 981 if (partialLeft > 0) { |
| 982 blitter->blitAntiH(fullLeft - 1, fullTop - 1, |
| 983 f2a(SkFixedMul_lowprec(partialTop, partialLeft))
); |
| 984 } |
| 985 blitter->blitAntiH(fullLeft, fullTop - 1, fullRite - fullLef
t, |
| 986 f2a(partialTop)); |
| 987 if (partialRite > 0) { |
| 988 blitter->blitAntiH(fullRite, fullTop - 1, |
| 989 f2a(SkFixedMul_lowprec(partialTop, partialRite))
); |
| 990 } |
| 991 if (forceRLE) { |
| 992 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(
y, y + partialTop); |
| 993 } |
| 994 } |
| 995 |
964 // Blit all full-height rows from fullTop to fullBot | 996 // Blit all full-height rows from fullTop to fullBot |
965 if (fullBot > fullTop) { | 997 if (fullBot > fullTop) { |
966 blitter->getRealBlitter()->blitAntiRect(fullLeft - 1, fullTo
p, | 998 blitter->getRealBlitter()->blitAntiRect(fullLeft - 1, fullTo
p, |
967 fullRite - fullLeft,
fullBot - fullTop, | 999 fullRite - fullLeft,
fullBot - fullTop, |
968 f2a(partialLeft), f2
a(partialRite)); | 1000 f2a(partialLeft), f2
a(partialRite)); |
969 } | 1001 } |
970 | 1002 |
971 if (partialTop > 0) { // blit first partial row | |
972 if (partialLeft > 0) { | |
973 blitter->blitAntiH(fullLeft - 1, fullTop - 1, | |
974 f2a(SkFixedMul_lowprec(partialTop, partialLeft))
); | |
975 } | |
976 if (partialRite > 0) { | |
977 blitter->blitAntiH(fullRite, fullTop - 1, | |
978 f2a(SkFixedMul_lowprec(partialTop, partialRite))
); | |
979 } | |
980 blitter->blitAntiH(fullLeft, fullTop - 1, fullRite - fullLef
t, | |
981 f2a(partialTop)); | |
982 } | |
983 | |
984 if (partialBot > 0) { // blit last partial row | 1003 if (partialBot > 0) { // blit last partial row |
985 if (partialLeft > 0) { | 1004 if (partialLeft > 0) { |
986 blitter->blitAntiH(fullLeft - 1, fullBot, | 1005 blitter->blitAntiH(fullLeft - 1, fullBot, |
987 f2a(SkFixedMul_lowprec(partialBot, pa
rtialLeft))); | 1006 f2a(SkFixedMul_lowprec(partialBot, pa
rtialLeft))); |
988 } | 1007 } |
| 1008 blitter->blitAntiH(fullLeft, fullBot, fullRite - fullLeft, f
2a(partialBot)); |
989 if (partialRite > 0) { | 1009 if (partialRite > 0) { |
990 blitter->blitAntiH(fullRite, fullBot, | 1010 blitter->blitAntiH(fullRite, fullBot, |
991 f2a(SkFixedMul_lowprec(partialBot, pa
rtialRite))); | 1011 f2a(SkFixedMul_lowprec(partialBot, pa
rtialRite))); |
992 } | 1012 } |
993 blitter->blitAntiH(fullLeft, fullBot, fullRite - fullLeft, f
2a(partialBot)); | |
994 } | 1013 } |
995 } else { // left and rite are within the same pixel | 1014 } else { // left and rite are within the same pixel |
996 if (partialTop > 0) { | 1015 if (partialTop > 0) { |
997 blitter->getRealBlitter()->blitV(fullLeft - 1, fullTop - 1,
1, | 1016 blitter->getRealBlitter()->blitV(fullLeft - 1, fullTop - 1,
1, |
998 f2a(SkFixedMul_lowprec(partialTop, rite - left))); | 1017 f2a(SkFixedMul_lowprec(partialTop, rite - left))); |
| 1018 if (forceRLE) { |
| 1019 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(
y, y + partialTop); |
| 1020 } |
| 1021 } |
| 1022 if (fullBot >= fullTop) { |
| 1023 blitter->getRealBlitter()->blitV(fullLeft - 1, fullTop, full
Bot - fullTop, |
| 1024 f2a(rite - left)); |
999 } | 1025 } |
1000 if (partialBot > 0) { | 1026 if (partialBot > 0) { |
1001 blitter->getRealBlitter()->blitV(fullLeft - 1, fullBot, 1, | 1027 blitter->getRealBlitter()->blitV(fullLeft - 1, fullBot, 1, |
1002 f2a(SkFixedMul_lowprec(partialBot, rite - left))); | 1028 f2a(SkFixedMul_lowprec(partialBot, rite - left))); |
1003 } | 1029 } |
1004 if (fullBot >= fullTop) { | |
1005 blitter->getRealBlitter()->blitV(fullLeft - 1, fullTop, full
Bot - fullTop, | |
1006 f2a(rite - left)); | |
1007 } | |
1008 } | 1030 } |
1009 | 1031 |
1010 y = local_bot_fixed; | 1032 y = local_bot_fixed; |
1011 } else { | 1033 } else { |
1012 // The following constant are used to snap X | 1034 // The following constant are used to snap X |
1013 // We snap X mainly for speedup (no tiny triangle) and | 1035 // We snap X mainly for speedup (no tiny triangle) and |
1014 // avoiding edge cases caused by precision errors | 1036 // avoiding edge cases caused by precision errors |
1015 const SkFixed kSnapDigit = SK_Fixed1 >> 4; | 1037 const SkFixed kSnapDigit = SK_Fixed1 >> 4; |
1016 const SkFixed kSnapHalf = kSnapDigit >> 1; | 1038 const SkFixed kSnapHalf = kSnapDigit >> 1; |
1017 const SkFixed kSnapMask = (-1 ^ (kSnapDigit - 1)); | 1039 const SkFixed kSnapMask = (-1 ^ (kSnapDigit - 1)); |
(...skipping 23 matching lines...) Expand all Loading... |
1041 if (count > 1) { | 1063 if (count > 1) { |
1042 if ((int)(y & 0xFFFF0000) != y) { // There's a partial-row on th
e top | 1064 if ((int)(y & 0xFFFF0000) != y) { // There's a partial-row on th
e top |
1043 count--; | 1065 count--; |
1044 SkFixed nextY = SkFixedCeilToFixed(y + 1); | 1066 SkFixed nextY = SkFixedCeilToFixed(y + 1); |
1045 SkFixed dY = nextY - y; | 1067 SkFixed dY = nextY - y; |
1046 SkFixed nextLeft = left + SkFixedMul_lowprec(dLeft, dY); | 1068 SkFixed nextLeft = left + SkFixedMul_lowprec(dLeft, dY); |
1047 SkFixed nextRite = rite + SkFixedMul_lowprec(dRite, dY); | 1069 SkFixed nextRite = rite + SkFixedMul_lowprec(dRite, dY); |
1048 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite
& kSnapMask, | 1070 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite
& kSnapMask, |
1049 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->f
DY, riteE->fDY, | 1071 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->f
DY, riteE->fDY, |
1050 getPartialAlpha(0xFF, dY), maskRow, isUsingMask); | 1072 getPartialAlpha(0xFF, dY), maskRow, isUsingMask); |
| 1073 if (forceRLE) { |
| 1074 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(
y, nextY); |
| 1075 } |
1051 left = nextLeft; rite = nextRite; y = nextY; | 1076 left = nextLeft; rite = nextRite; y = nextY; |
1052 } | 1077 } |
1053 | 1078 |
1054 while (count > 1) { // Full rows in the middle | 1079 while (count > 1) { // Full rows in the middle |
1055 count--; | 1080 count--; |
1056 if (isUsingMask) { | 1081 if (isUsingMask) { |
1057 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->ge
tRow(y >> 16); | 1082 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->ge
tRow(y >> 16); |
1058 } | 1083 } |
1059 SkFixed nextY = y + SK_Fixed1, nextLeft = left + dLeft, next
Rite = rite + dRite; | 1084 SkFixed nextY = y + SK_Fixed1, nextLeft = left + dLeft, next
Rite = rite + dRite; |
1060 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite
& kSnapMask, | 1085 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite
& kSnapMask, |
1061 nextLeft & kSnapMask, nextRite & kSnapMask, | 1086 nextLeft & kSnapMask, nextRite & kSnapMask, |
1062 leftE->fDY, riteE->fDY, 0xFF, maskRow, isUsingMask); | 1087 leftE->fDY, riteE->fDY, 0xFF, maskRow, isUsingMask); |
| 1088 if (forceRLE) { |
| 1089 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(
y, nextY); |
| 1090 } |
1063 left = nextLeft; rite = nextRite; y = nextY; | 1091 left = nextLeft; rite = nextRite; y = nextY; |
1064 } | 1092 } |
1065 } | 1093 } |
1066 | 1094 |
1067 if (isUsingMask) { | 1095 if (isUsingMask) { |
1068 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y >
> 16); | 1096 maskRow = static_cast<MaskAdditiveBlitter*>(blitter)->getRow(y >
> 16); |
1069 } | 1097 } |
1070 | 1098 |
1071 SkFixed dY = local_bot_fixed - y; // partial-row on the bottom | 1099 SkFixed dY = local_bot_fixed - y; // partial-row on the bottom |
1072 SkASSERT(dY <= SK_Fixed1); | 1100 SkASSERT(dY <= SK_Fixed1); |
1073 // Smooth jumping to integer y may make the last nextLeft/nextRite o
ut of bound. | 1101 // Smooth jumping to integer y may make the last nextLeft/nextRite o
ut of bound. |
1074 // Take them back into the bound here. | 1102 // Take them back into the bound here. |
1075 SkFixed nextLeft = SkTMax(left + SkFixedMul_lowprec(dLeft, dY), left
Bound); | 1103 // Note that we substract kSnapHalf later so we have to add them to
leftBound/riteBound |
1076 SkFixed nextRite = SkTMin(rite + SkFixedMul_lowprec(dRite, dY), rite
Bound); | 1104 SkFixed nextLeft = SkTMax(left + SkFixedMul_lowprec(dLeft, dY), left
Bound + kSnapHalf); |
| 1105 SkFixed nextRite = SkTMin(rite + SkFixedMul_lowprec(dRite, dY), rite
Bound + kSnapHalf); |
1077 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapM
ask, | 1106 blit_trapezoid_row(blitter, y >> 16, left & kSnapMask, rite & kSnapM
ask, |
1078 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->fDY, rite
E->fDY, | 1107 nextLeft & kSnapMask, nextRite & kSnapMask, leftE->fDY, rite
E->fDY, |
1079 getPartialAlpha(0xFF, dY), maskRow, isUsingMask); | 1108 getPartialAlpha(0xFF, dY), maskRow, isUsingMask); |
| 1109 if (forceRLE) { |
| 1110 ((RunBasedAdditiveBlitter*)blitter)->flush_if_y_changed(y, local
_bot_fixed); |
| 1111 } |
1080 left = nextLeft; rite = nextRite; y = local_bot_fixed; | 1112 left = nextLeft; rite = nextRite; y = local_bot_fixed; |
1081 left -= kSnapHalf; rite -= kSnapHalf; | 1113 left -= kSnapHalf; rite -= kSnapHalf; |
1082 } | 1114 } |
1083 | 1115 |
1084 leftE->fX = left; | 1116 leftE->fX = left; |
1085 riteE->fX = rite; | 1117 riteE->fX = rite; |
1086 leftE->fY = riteE->fY = y; | 1118 leftE->fY = riteE->fY = y; |
1087 } | 1119 } |
1088 | 1120 |
1089 END_WALK: | 1121 END_WALK: |
1090 ; | 1122 ; |
1091 #ifdef SK_DEBUG | 1123 #ifdef SK_DEBUG |
1092 SkDebugf("frac_y_cnt = %d, total_y_cnt = %d\n", frac_y_cnt, total_y_cnt); | 1124 SkDebugf("frac_y_cnt = %d, total_y_cnt = %d\n", frac_y_cnt, total_y_cnt); |
1093 #endif | 1125 #endif |
1094 } | 1126 } |
1095 | 1127 |
1096 void SkScan::aaa_fill_path(const SkPath& path, const SkIRect* clipRect, Additive
Blitter* blitter, | 1128 void SkScan::aaa_fill_path(const SkPath& path, const SkIRect* clipRect, Additive
Blitter* blitter, |
1097 int start_y, int stop_y, const SkRegion& clipRgn, bool isUsin
gMask) { | 1129 int start_y, int stop_y, const SkRegion& clipRgn, bool isUsin
gMask, |
| 1130 bool forceRLE) { // forceRLE implies that SkAAClip is calling
us |
1098 SkASSERT(blitter); | 1131 SkASSERT(blitter); |
1099 | 1132 |
1100 if (path.isInverseFillType() || !path.isConvex()) { | 1133 if (path.isInverseFillType() || !path.isConvex()) { |
1101 // fall back to supersampling AA | 1134 // fall back to supersampling AA |
1102 SkScan::AntiFillPath(path, clipRgn, blitter->getRealBlitter(true), false
); | 1135 SkScan::AntiFillPath(path, clipRgn, blitter->getRealBlitter(true), false
); |
1103 return; | 1136 return; |
1104 } | 1137 } |
1105 | 1138 |
1106 SkEdgeBuilder builder; | 1139 SkEdgeBuilder builder; |
1107 | 1140 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 if (clipRect && start_y < clipRect->fTop) { | 1196 if (clipRect && start_y < clipRect->fTop) { |
1164 start_y = clipRect->fTop; | 1197 start_y = clipRect->fTop; |
1165 } | 1198 } |
1166 if (clipRect && stop_y > clipRect->fBottom) { | 1199 if (clipRect && stop_y > clipRect->fBottom) { |
1167 stop_y = clipRect->fBottom; | 1200 stop_y = clipRect->fBottom; |
1168 } | 1201 } |
1169 | 1202 |
1170 if (!path.isInverseFillType() && path.isConvex()) { | 1203 if (!path.isInverseFillType() && path.isConvex()) { |
1171 SkASSERT(count >= 2); // convex walker does not handle missing right e
dges | 1204 SkASSERT(count >= 2); // convex walker does not handle missing right e
dges |
1172 aaa_walk_convex_edges(&headEdge, blitter, start_y, stop_y, | 1205 aaa_walk_convex_edges(&headEdge, blitter, start_y, stop_y, |
1173 rect.fLeft << 16, rect.fRight << 16, isUsingMask); | 1206 rect.fLeft << 16, rect.fRight << 16, isUsingMask, |
| 1207 forceRLE); |
1174 } else { | 1208 } else { |
1175 SkFAIL("Concave AAA is not yet implemented!"); | 1209 SkFAIL("Concave AAA is not yet implemented!"); |
1176 } | 1210 } |
1177 } | 1211 } |
1178 | 1212 |
1179 /////////////////////////////////////////////////////////////////////////////// | 1213 /////////////////////////////////////////////////////////////////////////////// |
1180 | 1214 |
1181 void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter
* blitter) { | 1215 void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter
* blitter, |
| 1216 bool forceRLE) { |
1182 if (origClip.isEmpty()) { | 1217 if (origClip.isEmpty()) { |
1183 return; | 1218 return; |
1184 } | 1219 } |
1185 | 1220 |
1186 const bool isInverse = path.isInverseFillType(); | 1221 const bool isInverse = path.isInverseFillType(); |
1187 SkIRect ir; | 1222 SkIRect ir; |
1188 path.getBounds().roundOut(&ir); | 1223 path.getBounds().roundOut(&ir); |
1189 if (ir.isEmpty()) { | 1224 if (ir.isEmpty()) { |
1190 if (isInverse) { | 1225 if (isInverse) { |
1191 blitter->blitRegion(origClip); | 1226 blitter->blitRegion(origClip); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 blitter = clipper.getBlitter(); | 1272 blitter = clipper.getBlitter(); |
1238 | 1273 |
1239 if (isInverse) { | 1274 if (isInverse) { |
1240 // Currently, we use the old path to render the inverse path, | 1275 // Currently, we use the old path to render the inverse path, |
1241 // so we don't need this. | 1276 // so we don't need this. |
1242 // sk_blit_above(blitter, ir, *clipRgn); | 1277 // sk_blit_above(blitter, ir, *clipRgn); |
1243 } | 1278 } |
1244 | 1279 |
1245 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); | 1280 SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop); |
1246 | 1281 |
1247 if (MaskAdditiveBlitter::canHandleRect(ir) && !isInverse) { | 1282 if (MaskAdditiveBlitter::canHandleRect(ir) && !isInverse && !forceRLE) { |
1248 MaskAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse); | 1283 MaskAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse); |
1249 aaa_fill_path(path, clipRect, &additiveBlitter, ir.fTop, ir.fBottom, *cl
ipRgn, true); | 1284 aaa_fill_path(path, clipRect, &additiveBlitter, ir.fTop, ir.fBottom, *cl
ipRgn, true, |
| 1285 forceRLE); |
1250 } else { | 1286 } else { |
1251 RunBasedAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse
); | 1287 RunBasedAdditiveBlitter additiveBlitter(blitter, ir, *clipRgn, isInverse
); |
1252 aaa_fill_path(path, clipRect, &additiveBlitter, ir.fTop, ir.fBottom, *cl
ipRgn, false); | 1288 aaa_fill_path(path, clipRect, &additiveBlitter, ir.fTop, ir.fBottom, *cl
ipRgn, false, |
| 1289 forceRLE); |
1253 } | 1290 } |
1254 | 1291 |
1255 if (isInverse) { | 1292 if (isInverse) { |
1256 // Currently, we use the old path to render the inverse path, | 1293 // Currently, we use the old path to render the inverse path, |
1257 // so we don't need this. | 1294 // so we don't need this. |
1258 // sk_blit_below(blitter, ir, *clipRgn); | 1295 // sk_blit_below(blitter, ir, *clipRgn); |
1259 } | 1296 } |
1260 } | 1297 } |
1261 | 1298 |
1262 // This almost copies SkScan::AntiFillPath | 1299 // This almost copies SkScan::AntiFillPath |
1263 void SkScan::AAAFillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter
* blitter) { | 1300 void SkScan::AAAFillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter
* blitter) { |
1264 if (clip.isEmpty()) { | 1301 if (clip.isEmpty()) { |
1265 return; | 1302 return; |
1266 } | 1303 } |
1267 | 1304 |
1268 if (clip.isBW()) { | 1305 if (clip.isBW()) { |
1269 AAAFillPath(path, clip.bwRgn(), blitter); | 1306 AAAFillPath(path, clip.bwRgn(), blitter); |
1270 } else { | 1307 } else { |
1271 SkRegion tmp; | 1308 SkRegion tmp; |
1272 SkAAClipBlitter aaBlitter; | 1309 SkAAClipBlitter aaBlitter; |
1273 | 1310 |
1274 tmp.setRect(clip.getBounds()); | 1311 tmp.setRect(clip.getBounds()); |
1275 aaBlitter.init(blitter, &clip.aaRgn()); | 1312 aaBlitter.init(blitter, &clip.aaRgn()); |
1276 AAAFillPath(path, tmp, &aaBlitter); | 1313 AAAFillPath(path, tmp, &aaBlitter); |
1277 } | 1314 } |
1278 } | 1315 } |
OLD | NEW |