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 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1205 aaa_walk_convex_edges(&headEdge, blitter, start_y, stop_y, | 1205 aaa_walk_convex_edges(&headEdge, blitter, start_y, stop_y, |
1206 rect.fLeft << 16, rect.fRight << 16, isUsingMask, | 1206 rect.fLeft << 16, rect.fRight << 16, isUsingMask, |
1207 forceRLE); | 1207 forceRLE); |
1208 } else { | 1208 } else { |
1209 SkFAIL("Concave AAA is not yet implemented!"); | 1209 SkFAIL("Concave AAA is not yet implemented!"); |
1210 } | 1210 } |
1211 } | 1211 } |
1212 | 1212 |
1213 /////////////////////////////////////////////////////////////////////////////// | 1213 /////////////////////////////////////////////////////////////////////////////// |
1214 | 1214 |
| 1215 static int overflows_short_shift(int value, int shift) { |
| 1216 const int s = 16 + shift; |
| 1217 return (SkLeftShift(value, s) >> s) - value; |
| 1218 } |
| 1219 |
| 1220 /** |
| 1221 Would any of the coordinates of this rectangle not fit in a short, |
| 1222 when left-shifted by shift? |
| 1223 */ |
| 1224 static int rect_overflows_short_shift(SkIRect rect, int shift) { |
| 1225 SkASSERT(!overflows_short_shift(8191, 2)); |
| 1226 SkASSERT(overflows_short_shift(8192, 2)); |
| 1227 SkASSERT(!overflows_short_shift(32767, 0)); |
| 1228 SkASSERT(overflows_short_shift(32768, 0)); |
| 1229 |
| 1230 // Since we expect these to succeed, we bit-or together |
| 1231 // for a tiny extra bit of speed. |
| 1232 return overflows_short_shift(rect.fLeft, 2) | |
| 1233 overflows_short_shift(rect.fRight, 2) | |
| 1234 overflows_short_shift(rect.fTop, 2) | |
| 1235 overflows_short_shift(rect.fBottom, 2); |
| 1236 } |
| 1237 |
1215 void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter
* blitter, | 1238 void SkScan::AAAFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter
* blitter, |
1216 bool forceRLE) { | 1239 bool forceRLE) { |
1217 if (origClip.isEmpty()) { | 1240 if (origClip.isEmpty()) { |
1218 return; | 1241 return; |
1219 } | 1242 } |
1220 if (path.isInverseFillType() || !path.isConvex()) { | 1243 if (path.isInverseFillType() || !path.isConvex()) { |
1221 // Fall back as we only implemented the algorithm for convex shapes yet. | 1244 // Fall back as we only implemented the algorithm for convex shapes yet. |
1222 SkScan::AntiFillPath(path, origClip, blitter, forceRLE); | 1245 SkScan::AntiFillPath(path, origClip, blitter, forceRLE); |
1223 return; | 1246 return; |
1224 } | 1247 } |
(...skipping 11 matching lines...) Expand all Loading... |
1236 SkIRect clippedIR; | 1259 SkIRect clippedIR; |
1237 if (isInverse) { | 1260 if (isInverse) { |
1238 // If the path is an inverse fill, it's going to fill the entire | 1261 // If the path is an inverse fill, it's going to fill the entire |
1239 // clip, and we care whether the entire clip exceeds our limits. | 1262 // clip, and we care whether the entire clip exceeds our limits. |
1240 clippedIR = origClip.getBounds(); | 1263 clippedIR = origClip.getBounds(); |
1241 } else { | 1264 } else { |
1242 if (!clippedIR.intersect(ir, origClip.getBounds())) { | 1265 if (!clippedIR.intersect(ir, origClip.getBounds())) { |
1243 return; | 1266 return; |
1244 } | 1267 } |
1245 } | 1268 } |
| 1269 // If the intersection of the path bounds and the clip bounds |
| 1270 // will overflow 32767 when << by 2, our SkFixed will overflow, |
| 1271 // so draw without antialiasing. |
| 1272 if (rect_overflows_short_shift(clippedIR, 2)) { |
| 1273 SkScan::FillPath(path, origClip, blitter); |
| 1274 return; |
| 1275 } |
1246 | 1276 |
1247 // Our antialiasing can't handle a clip larger than 32767, so we restrict | 1277 // Our antialiasing can't handle a clip larger than 32767, so we restrict |
1248 // the clip to that limit here. (the runs[] uses int16_t for its index). | 1278 // the clip to that limit here. (the runs[] uses int16_t for its index). |
1249 // | 1279 // |
1250 // A more general solution (one that could also eliminate the need to | 1280 // A more general solution (one that could also eliminate the need to |
1251 // disable aa based on ir bounds (see overflows_short_shift) would be | 1281 // disable aa based on ir bounds (see overflows_short_shift) would be |
1252 // to tile the clip/target... | 1282 // to tile the clip/target... |
1253 SkRegion tmpClipStorage; | 1283 SkRegion tmpClipStorage; |
1254 const SkRegion* clipRgn = &origClip; | 1284 const SkRegion* clipRgn = &origClip; |
1255 { | 1285 { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1311 AAAFillPath(path, clip.bwRgn(), blitter); | 1341 AAAFillPath(path, clip.bwRgn(), blitter); |
1312 } else { | 1342 } else { |
1313 SkRegion tmp; | 1343 SkRegion tmp; |
1314 SkAAClipBlitter aaBlitter; | 1344 SkAAClipBlitter aaBlitter; |
1315 | 1345 |
1316 tmp.setRect(clip.getBounds()); | 1346 tmp.setRect(clip.getBounds()); |
1317 aaBlitter.init(blitter, &clip.aaRgn()); | 1347 aaBlitter.init(blitter, &clip.aaRgn()); |
1318 AAAFillPath(path, tmp, &aaBlitter, true); | 1348 AAAFillPath(path, tmp, &aaBlitter, true); |
1319 } | 1349 } |
1320 } | 1350 } |
OLD | NEW |