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

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

Issue 2430343003: Use Analytic AA in SkAAClip (Closed)
Patch Set: Nit Created 4 years, 2 months 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
« src/core/SkAnalyticEdge.h ('K') | « src/core/SkScan.h ('k') | no next file » | 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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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 }
OLDNEW
« src/core/SkAnalyticEdge.h ('K') | « src/core/SkScan.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698