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