| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 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 "GrOvalRenderer.h" | 8 #include "GrOvalRenderer.h" |
| 9 | 9 |
| 10 #include "GrBatch.h" | 10 #include "GrBatch.h" |
| (...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 834 }; | 834 }; |
| 835 | 835 |
| 836 BatchTracker fBatch; | 836 BatchTracker fBatch; |
| 837 SkSTArray<1, Geometry, true> fGeoData; | 837 SkSTArray<1, Geometry, true> fGeoData; |
| 838 }; | 838 }; |
| 839 | 839 |
| 840 static GrBatch* create_circle_batch(GrColor color, | 840 static GrBatch* create_circle_batch(GrColor color, |
| 841 const SkMatrix& viewMatrix, | 841 const SkMatrix& viewMatrix, |
| 842 bool useCoverageAA, | 842 bool useCoverageAA, |
| 843 const SkRect& circle, | 843 const SkRect& circle, |
| 844 const SkStrokeRec& stroke, | 844 const SkStrokeRec& stroke) { |
| 845 SkRect* bounds) { | |
| 846 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); | 845 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); |
| 847 viewMatrix.mapPoints(¢er, 1); | 846 viewMatrix.mapPoints(¢er, 1); |
| 848 SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width())); | 847 SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width())); |
| 849 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth()); | 848 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth()); |
| 850 | 849 |
| 851 SkStrokeRec::Style style = stroke.getStyle(); | 850 SkStrokeRec::Style style = stroke.getStyle(); |
| 852 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || | 851 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || |
| 853 SkStrokeRec::kHairline_Style == style; | 852 SkStrokeRec::kHairline_Style == style; |
| 854 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; | 853 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; |
| 855 | 854 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 869 } | 868 } |
| 870 } | 869 } |
| 871 | 870 |
| 872 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform simpler | 871 // The radii are outset for two reasons. First, it allows the shader to simp
ly perform simpler |
| 873 // computation because the computed alpha is zero, rather than 50%, at the r
adius. | 872 // computation because the computed alpha is zero, rather than 50%, at the r
adius. |
| 874 // Second, the outer radius is used to compute the verts of the bounding box
that is rendered | 873 // Second, the outer radius is used to compute the verts of the bounding box
that is rendered |
| 875 // and the outset ensures the box will cover all partially covered by the ci
rcle. | 874 // and the outset ensures the box will cover all partially covered by the ci
rcle. |
| 876 outerRadius += SK_ScalarHalf; | 875 outerRadius += SK_ScalarHalf; |
| 877 innerRadius -= SK_ScalarHalf; | 876 innerRadius -= SK_ScalarHalf; |
| 878 | 877 |
| 879 bounds->setLTRB(center.fX - outerRadius, center.fY - outerRadius, | |
| 880 center.fX + outerRadius, center.fY + outerRadius); | |
| 881 | |
| 882 CircleBatch::Geometry geometry; | 878 CircleBatch::Geometry geometry; |
| 883 geometry.fViewMatrix = viewMatrix; | 879 geometry.fViewMatrix = viewMatrix; |
| 884 geometry.fColor = color; | 880 geometry.fColor = color; |
| 885 geometry.fInnerRadius = innerRadius; | 881 geometry.fInnerRadius = innerRadius; |
| 886 geometry.fOuterRadius = outerRadius; | 882 geometry.fOuterRadius = outerRadius; |
| 887 geometry.fStroke = isStrokeOnly && innerRadius > 0; | 883 geometry.fStroke = isStrokeOnly && innerRadius > 0; |
| 888 geometry.fDevBounds = *bounds; | 884 geometry.fDevBounds = SkRect::MakeLTRB(center.fX - outerRadius, center.fY -
outerRadius, |
| 885 center.fX + outerRadius, center.fY +
outerRadius); |
| 889 | 886 |
| 890 return CircleBatch::Create(geometry); | 887 return CircleBatch::Create(geometry); |
| 891 } | 888 } |
| 892 | 889 |
| 893 void GrOvalRenderer::drawCircle(GrDrawTarget* target, | 890 void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| 894 GrPipelineBuilder* pipelineBuilder, | 891 GrPipelineBuilder* pipelineBuilder, |
| 895 GrColor color, | 892 GrColor color, |
| 896 const SkMatrix& viewMatrix, | 893 const SkMatrix& viewMatrix, |
| 897 bool useCoverageAA, | 894 bool useCoverageAA, |
| 898 const SkRect& circle, | 895 const SkRect& circle, |
| 899 const SkStrokeRec& stroke) { | 896 const SkStrokeRec& stroke) { |
| 900 SkRect bounds; | |
| 901 SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCovera
geAA, circle, | 897 SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCovera
geAA, circle, |
| 902 stroke, &bounds)); | 898 stroke)); |
| 903 target->drawBatch(pipelineBuilder, batch); | 899 target->drawBatch(pipelineBuilder, batch); |
| 904 } | 900 } |
| 905 | 901 |
| 906 /////////////////////////////////////////////////////////////////////////////// | 902 /////////////////////////////////////////////////////////////////////////////// |
| 907 | 903 |
| 908 class EllipseBatch : public GrBatch { | 904 class EllipseBatch : public GrBatch { |
| 909 public: | 905 public: |
| 910 struct Geometry { | 906 struct Geometry { |
| 911 GrColor fColor; | 907 GrColor fColor; |
| 912 SkMatrix fViewMatrix; | 908 SkMatrix fViewMatrix; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 }; | 1063 }; |
| 1068 | 1064 |
| 1069 BatchTracker fBatch; | 1065 BatchTracker fBatch; |
| 1070 SkSTArray<1, Geometry, true> fGeoData; | 1066 SkSTArray<1, Geometry, true> fGeoData; |
| 1071 }; | 1067 }; |
| 1072 | 1068 |
| 1073 static GrBatch* create_ellipse_batch(GrColor color, | 1069 static GrBatch* create_ellipse_batch(GrColor color, |
| 1074 const SkMatrix& viewMatrix, | 1070 const SkMatrix& viewMatrix, |
| 1075 bool useCoverageAA, | 1071 bool useCoverageAA, |
| 1076 const SkRect& ellipse, | 1072 const SkRect& ellipse, |
| 1077 const SkStrokeRec& stroke, | 1073 const SkStrokeRec& stroke) { |
| 1078 SkRect* bounds) { | |
| 1079 #ifdef SK_DEBUG | 1074 #ifdef SK_DEBUG |
| 1080 { | 1075 { |
| 1081 // we should have checked for this previously | 1076 // we should have checked for this previously |
| 1082 bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); | 1077 bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); |
| 1083 SkASSERT(useCoverageAA && isAxisAlignedEllipse); | 1078 SkASSERT(useCoverageAA && isAxisAlignedEllipse); |
| 1084 } | 1079 } |
| 1085 #endif | 1080 #endif |
| 1086 | 1081 |
| 1087 // do any matrix crunching before we reset the draw state for device coords | 1082 // do any matrix crunching before we reset the draw state for device coords |
| 1088 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); | 1083 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 xRadius += scaledStroke.fX; | 1132 xRadius += scaledStroke.fX; |
| 1138 yRadius += scaledStroke.fY; | 1133 yRadius += scaledStroke.fY; |
| 1139 } | 1134 } |
| 1140 | 1135 |
| 1141 // We've extended the outer x radius out half a pixel to antialias. | 1136 // We've extended the outer x radius out half a pixel to antialias. |
| 1142 // This will also expand the rect so all the pixels will be captured. | 1137 // This will also expand the rect so all the pixels will be captured. |
| 1143 // TODO: Consider if we should use sqrt(2)/2 instead | 1138 // TODO: Consider if we should use sqrt(2)/2 instead |
| 1144 xRadius += SK_ScalarHalf; | 1139 xRadius += SK_ScalarHalf; |
| 1145 yRadius += SK_ScalarHalf; | 1140 yRadius += SK_ScalarHalf; |
| 1146 | 1141 |
| 1147 bounds->setLTRB(center.fX - xRadius, center.fY - yRadius, | |
| 1148 center.fX + xRadius, center.fY + yRadius); | |
| 1149 | |
| 1150 EllipseBatch::Geometry geometry; | 1142 EllipseBatch::Geometry geometry; |
| 1151 geometry.fViewMatrix = viewMatrix; | 1143 geometry.fViewMatrix = viewMatrix; |
| 1152 geometry.fColor = color; | 1144 geometry.fColor = color; |
| 1153 geometry.fXRadius = xRadius; | 1145 geometry.fXRadius = xRadius; |
| 1154 geometry.fYRadius = yRadius; | 1146 geometry.fYRadius = yRadius; |
| 1155 geometry.fInnerXRadius = innerXRadius; | 1147 geometry.fInnerXRadius = innerXRadius; |
| 1156 geometry.fInnerYRadius = innerYRadius; | 1148 geometry.fInnerYRadius = innerYRadius; |
| 1157 geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; | 1149 geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; |
| 1158 geometry.fDevBounds = *bounds; | 1150 geometry.fDevBounds = SkRect::MakeLTRB(center.fX - xRadius, center.fY - yRad
ius, |
| 1151 center.fX + xRadius, center.fY + yRad
ius); |
| 1159 | 1152 |
| 1160 return EllipseBatch::Create(geometry); | 1153 return EllipseBatch::Create(geometry); |
| 1161 } | 1154 } |
| 1162 | 1155 |
| 1163 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, | 1156 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| 1164 GrPipelineBuilder* pipelineBuilder, | 1157 GrPipelineBuilder* pipelineBuilder, |
| 1165 GrColor color, | 1158 GrColor color, |
| 1166 const SkMatrix& viewMatrix, | 1159 const SkMatrix& viewMatrix, |
| 1167 bool useCoverageAA, | 1160 bool useCoverageAA, |
| 1168 const SkRect& ellipse, | 1161 const SkRect& ellipse, |
| 1169 const SkStrokeRec& stroke) { | 1162 const SkStrokeRec& stroke) { |
| 1170 SkRect bounds; | |
| 1171 SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCover
ageAA, ellipse, | 1163 SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCover
ageAA, ellipse, |
| 1172 stroke, &bounds)); | 1164 stroke)); |
| 1173 if (!batch) { | 1165 if (!batch) { |
| 1174 return false; | 1166 return false; |
| 1175 } | 1167 } |
| 1176 | 1168 |
| 1177 target->drawBatch(pipelineBuilder, batch); | 1169 target->drawBatch(pipelineBuilder, batch); |
| 1178 return true; | 1170 return true; |
| 1179 } | 1171 } |
| 1180 | 1172 |
| 1181 ////////////////////////////////////////////////////////////////////////////////
///////////////// | 1173 ////////////////////////////////////////////////////////////////////////////////
///////////////// |
| 1182 | 1174 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 | 1296 |
| 1305 // TODO use vertex color to avoid breaking batches | 1297 // TODO use vertex color to avoid breaking batches |
| 1306 if (this->color() != that->color()) { | 1298 if (this->color() != that->color()) { |
| 1307 return false; | 1299 return false; |
| 1308 } | 1300 } |
| 1309 | 1301 |
| 1310 if (this->mode() != that->mode()) { | 1302 if (this->mode() != that->mode()) { |
| 1311 return false; | 1303 return false; |
| 1312 } | 1304 } |
| 1313 | 1305 |
| 1314 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | 1306 // TODO rewrite to allow positioning on CPU |
| 1315 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { | 1307 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
| 1316 return false; | 1308 return false; |
| 1317 } | 1309 } |
| 1318 | 1310 |
| 1319 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 1311 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| 1320 this->joinBounds(that->bounds()); | 1312 this->joinBounds(that->bounds()); |
| 1321 return true; | 1313 return true; |
| 1322 } | 1314 } |
| 1323 | 1315 |
| 1324 GrColor color() const { return fBatch.fColor; } | 1316 GrColor color() const { return fBatch.fColor; } |
| 1325 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 1317 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| 1326 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 1318 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| 1327 DIEllipseEdgeEffect::Mode mode() const { return fBatch.fMode; } | 1319 DIEllipseEdgeEffect::Mode mode() const { return fBatch.fMode; } |
| 1328 | 1320 |
| 1329 struct BatchTracker { | 1321 struct BatchTracker { |
| 1330 GrColor fColor; | 1322 GrColor fColor; |
| 1331 DIEllipseEdgeEffect::Mode fMode; | 1323 DIEllipseEdgeEffect::Mode fMode; |
| 1332 bool fUsesLocalCoords; | 1324 bool fUsesLocalCoords; |
| 1333 bool fColorIgnored; | 1325 bool fColorIgnored; |
| 1334 bool fCoverageIgnored; | 1326 bool fCoverageIgnored; |
| 1335 }; | 1327 }; |
| 1336 | 1328 |
| 1337 BatchTracker fBatch; | 1329 BatchTracker fBatch; |
| 1338 SkSTArray<1, Geometry, true> fGeoData; | 1330 SkSTArray<1, Geometry, true> fGeoData; |
| 1339 }; | 1331 }; |
| 1340 | 1332 |
| 1341 static GrBatch* create_diellipse_batch(GrColor color, | 1333 static GrBatch* create_diellipse_batch(GrColor color, |
| 1342 const SkMatrix& viewMatrix, | 1334 const SkMatrix& viewMatrix, |
| 1343 bool useCoverageAA, | 1335 bool useCoverageAA, |
| 1344 const SkRect& ellipse, | 1336 const SkRect& ellipse, |
| 1345 const SkStrokeRec& stroke, | 1337 const SkStrokeRec& stroke) { |
| 1346 SkRect* bounds) { | |
| 1347 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); | 1338 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); |
| 1348 SkScalar xRadius = SkScalarHalf(ellipse.width()); | 1339 SkScalar xRadius = SkScalarHalf(ellipse.width()); |
| 1349 SkScalar yRadius = SkScalarHalf(ellipse.height()); | 1340 SkScalar yRadius = SkScalarHalf(ellipse.height()); |
| 1350 | 1341 |
| 1351 SkStrokeRec::Style style = stroke.getStyle(); | 1342 SkStrokeRec::Style style = stroke.getStyle(); |
| 1352 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? | 1343 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? |
| 1353 DIEllipseEdgeEffect::kStroke : | 1344 DIEllipseEdgeEffect::kStroke : |
| 1354 (SkStrokeRec::kHairline_Style == style) ? | 1345 (SkStrokeRec::kHairline_Style == style) ? |
| 1355 DIEllipseEdgeEffect::kHairline : DIEllipseEd
geEffect::kFill; | 1346 DIEllipseEdgeEffect::kHairline : DIEllipseEd
geEffect::kFill; |
| 1356 | 1347 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 } | 1383 } |
| 1393 | 1384 |
| 1394 // This expands the outer rect so that after CTM we end up with a half-pixel
border | 1385 // This expands the outer rect so that after CTM we end up with a half-pixel
border |
| 1395 SkScalar a = viewMatrix[SkMatrix::kMScaleX]; | 1386 SkScalar a = viewMatrix[SkMatrix::kMScaleX]; |
| 1396 SkScalar b = viewMatrix[SkMatrix::kMSkewX]; | 1387 SkScalar b = viewMatrix[SkMatrix::kMSkewX]; |
| 1397 SkScalar c = viewMatrix[SkMatrix::kMSkewY]; | 1388 SkScalar c = viewMatrix[SkMatrix::kMSkewY]; |
| 1398 SkScalar d = viewMatrix[SkMatrix::kMScaleY]; | 1389 SkScalar d = viewMatrix[SkMatrix::kMScaleY]; |
| 1399 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); | 1390 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); |
| 1400 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); | 1391 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); |
| 1401 | 1392 |
| 1402 bounds->setLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy, | |
| 1403 center.fX + xRadius + geoDx, center.fY + yRadius + geoDy); | |
| 1404 | |
| 1405 DIEllipseBatch::Geometry geometry; | 1393 DIEllipseBatch::Geometry geometry; |
| 1406 geometry.fViewMatrix = viewMatrix; | 1394 geometry.fViewMatrix = viewMatrix; |
| 1407 geometry.fColor = color; | 1395 geometry.fColor = color; |
| 1408 geometry.fXRadius = xRadius; | 1396 geometry.fXRadius = xRadius; |
| 1409 geometry.fYRadius = yRadius; | 1397 geometry.fYRadius = yRadius; |
| 1410 geometry.fInnerXRadius = innerXRadius; | 1398 geometry.fInnerXRadius = innerXRadius; |
| 1411 geometry.fInnerYRadius = innerYRadius; | 1399 geometry.fInnerYRadius = innerYRadius; |
| 1412 geometry.fGeoDx = geoDx; | 1400 geometry.fGeoDx = geoDx; |
| 1413 geometry.fGeoDy = geoDy; | 1401 geometry.fGeoDy = geoDy; |
| 1414 geometry.fMode = mode; | 1402 geometry.fMode = mode; |
| 1415 geometry.fBounds = *bounds; | 1403 geometry.fBounds = SkRect::MakeLTRB(center.fX - xRadius - geoDx, center.fY -
yRadius - geoDy, |
| 1404 center.fX + xRadius + geoDx, center.fY +
yRadius + geoDy); |
| 1416 | 1405 |
| 1417 viewMatrix.mapRect(bounds); | 1406 SkRect devBounds = geometry.fBounds; |
| 1418 return DIEllipseBatch::Create(geometry, *bounds); | 1407 viewMatrix.mapRect(&devBounds); |
| 1408 return DIEllipseBatch::Create(geometry, devBounds); |
| 1419 } | 1409 } |
| 1420 | 1410 |
| 1421 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, | 1411 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| 1422 GrPipelineBuilder* pipelineBuilder, | 1412 GrPipelineBuilder* pipelineBuilder, |
| 1423 GrColor color, | 1413 GrColor color, |
| 1424 const SkMatrix& viewMatrix, | 1414 const SkMatrix& viewMatrix, |
| 1425 bool useCoverageAA, | 1415 bool useCoverageAA, |
| 1426 const SkRect& ellipse, | 1416 const SkRect& ellipse, |
| 1427 const SkStrokeRec& stroke) { | 1417 const SkStrokeRec& stroke) { |
| 1428 SkRect bounds; | |
| 1429 SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCov
erageAA, ellipse, | 1418 SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCov
erageAA, ellipse, |
| 1430 stroke, &bounds)); | 1419 stroke)); |
| 1431 if (!batch) { | 1420 if (!batch) { |
| 1432 return false; | 1421 return false; |
| 1433 } | 1422 } |
| 1434 target->drawBatch(pipelineBuilder, batch); | 1423 target->drawBatch(pipelineBuilder, batch); |
| 1435 return true; | 1424 return true; |
| 1436 } | 1425 } |
| 1437 | 1426 |
| 1438 /////////////////////////////////////////////////////////////////////////////// | 1427 /////////////////////////////////////////////////////////////////////////////// |
| 1439 | 1428 |
| 1440 static const uint16_t gRRectIndices[] = { | 1429 static const uint16_t gRRectIndices[] = { |
| (...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1913 bool fCoverageIgnored; | 1902 bool fCoverageIgnored; |
| 1914 }; | 1903 }; |
| 1915 | 1904 |
| 1916 BatchTracker fBatch; | 1905 BatchTracker fBatch; |
| 1917 SkSTArray<1, Geometry, true> fGeoData; | 1906 SkSTArray<1, Geometry, true> fGeoData; |
| 1918 }; | 1907 }; |
| 1919 | 1908 |
| 1920 static GrBatch* create_rrect_batch(GrColor color, | 1909 static GrBatch* create_rrect_batch(GrColor color, |
| 1921 const SkMatrix& viewMatrix, | 1910 const SkMatrix& viewMatrix, |
| 1922 const SkRRect& rrect, | 1911 const SkRRect& rrect, |
| 1923 const SkStrokeRec& stroke, | 1912 const SkStrokeRec& stroke) { |
| 1924 SkRect* bounds) { | |
| 1925 SkASSERT(viewMatrix.rectStaysRect()); | 1913 SkASSERT(viewMatrix.rectStaysRect()); |
| 1926 SkASSERT(rrect.isSimple()); | 1914 SkASSERT(rrect.isSimple()); |
| 1927 SkASSERT(!rrect.isOval()); | 1915 SkASSERT(!rrect.isOval()); |
| 1928 | 1916 |
| 1929 // RRect batchs only handle simple, but not too simple, rrects | 1917 // RRect batchs only handle simple, but not too simple, rrects |
| 1930 // do any matrix crunching before we reset the draw state for device coords | 1918 // do any matrix crunching before we reset the draw state for device coords |
| 1931 const SkRect& rrectBounds = rrect.getBounds(); | 1919 const SkRect& rrectBounds = rrect.getBounds(); |
| 1932 viewMatrix.mapRect(bounds, rrectBounds); | 1920 SkRect bounds; |
| 1921 viewMatrix.mapRect(&bounds, rrectBounds); |
| 1933 | 1922 |
| 1934 SkVector radii = rrect.getSimpleRadii(); | 1923 SkVector radii = rrect.getSimpleRadii(); |
| 1935 SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX + | 1924 SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX + |
| 1936 viewMatrix[SkMatrix::kMSkewY]*radii.fY); | 1925 viewMatrix[SkMatrix::kMSkewY]*radii.fY); |
| 1937 SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX + | 1926 SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX + |
| 1938 viewMatrix[SkMatrix::kMScaleY]*radii.fY); | 1927 viewMatrix[SkMatrix::kMScaleY]*radii.fY); |
| 1939 | 1928 |
| 1940 SkStrokeRec::Style style = stroke.getStyle(); | 1929 SkStrokeRec::Style style = stroke.getStyle(); |
| 1941 | 1930 |
| 1942 // do (potentially) anisotropic mapping of stroke | 1931 // do (potentially) anisotropic mapping of stroke |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1981 if (SkScalarNearlyZero(scaledStroke.fX)) { | 1970 if (SkScalarNearlyZero(scaledStroke.fX)) { |
| 1982 halfWidth = SK_ScalarHalf; | 1971 halfWidth = SK_ScalarHalf; |
| 1983 } else { | 1972 } else { |
| 1984 halfWidth = SkScalarHalf(scaledStroke.fX); | 1973 halfWidth = SkScalarHalf(scaledStroke.fX); |
| 1985 } | 1974 } |
| 1986 | 1975 |
| 1987 if (isStrokeOnly) { | 1976 if (isStrokeOnly) { |
| 1988 innerRadius = xRadius - halfWidth; | 1977 innerRadius = xRadius - halfWidth; |
| 1989 } | 1978 } |
| 1990 outerRadius += halfWidth; | 1979 outerRadius += halfWidth; |
| 1991 bounds->outset(halfWidth, halfWidth); | 1980 bounds.outset(halfWidth, halfWidth); |
| 1992 } | 1981 } |
| 1993 | 1982 |
| 1994 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); | 1983 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
| 1995 | 1984 |
| 1996 // The radii are outset for two reasons. First, it allows the shader to
simply perform | 1985 // The radii are outset for two reasons. First, it allows the shader to
simply perform |
| 1997 // simpler computation because the computed alpha is zero, rather than 5
0%, at the radius. | 1986 // simpler computation because the computed alpha is zero, rather than 5
0%, at the radius. |
| 1998 // Second, the outer radius is used to compute the verts of the bounding
box that is | 1987 // Second, the outer radius is used to compute the verts of the bounding
box that is |
| 1999 // rendered and the outset ensures the box will cover all partially cove
red by the rrect | 1988 // rendered and the outset ensures the box will cover all partially cove
red by the rrect |
| 2000 // corners. | 1989 // corners. |
| 2001 outerRadius += SK_ScalarHalf; | 1990 outerRadius += SK_ScalarHalf; |
| 2002 innerRadius -= SK_ScalarHalf; | 1991 innerRadius -= SK_ScalarHalf; |
| 2003 | 1992 |
| 2004 // Expand the rect so all the pixels will be captured. | 1993 // Expand the rect so all the pixels will be captured. |
| 2005 bounds->outset(SK_ScalarHalf, SK_ScalarHalf); | 1994 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| 2006 | 1995 |
| 2007 RRectCircleRendererBatch::Geometry geometry; | 1996 RRectCircleRendererBatch::Geometry geometry; |
| 2008 geometry.fViewMatrix = viewMatrix; | 1997 geometry.fViewMatrix = viewMatrix; |
| 2009 geometry.fColor = color; | 1998 geometry.fColor = color; |
| 2010 geometry.fInnerRadius = innerRadius; | 1999 geometry.fInnerRadius = innerRadius; |
| 2011 geometry.fOuterRadius = outerRadius; | 2000 geometry.fOuterRadius = outerRadius; |
| 2012 geometry.fStroke = isStrokeOnly; | 2001 geometry.fStroke = isStrokeOnly; |
| 2013 geometry.fDevBounds = *bounds; | 2002 geometry.fDevBounds = bounds; |
| 2014 | 2003 |
| 2015 return RRectCircleRendererBatch::Create(geometry); | 2004 return RRectCircleRendererBatch::Create(geometry); |
| 2016 // otherwise we use the ellipse renderer | 2005 // otherwise we use the ellipse renderer |
| 2017 } else { | 2006 } else { |
| 2018 SkScalar innerXRadius = 0.0f; | 2007 SkScalar innerXRadius = 0.0f; |
| 2019 SkScalar innerYRadius = 0.0f; | 2008 SkScalar innerYRadius = 0.0f; |
| 2020 if (hasStroke) { | 2009 if (hasStroke) { |
| 2021 if (SkScalarNearlyZero(scaledStroke.length())) { | 2010 if (SkScalarNearlyZero(scaledStroke.length())) { |
| 2022 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); | 2011 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); |
| 2023 } else { | 2012 } else { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2037 } | 2026 } |
| 2038 | 2027 |
| 2039 // this is legit only if scale & translation (which should be the ca
se at the moment) | 2028 // this is legit only if scale & translation (which should be the ca
se at the moment) |
| 2040 if (isStrokeOnly) { | 2029 if (isStrokeOnly) { |
| 2041 innerXRadius = xRadius - scaledStroke.fX; | 2030 innerXRadius = xRadius - scaledStroke.fX; |
| 2042 innerYRadius = yRadius - scaledStroke.fY; | 2031 innerYRadius = yRadius - scaledStroke.fY; |
| 2043 } | 2032 } |
| 2044 | 2033 |
| 2045 xRadius += scaledStroke.fX; | 2034 xRadius += scaledStroke.fX; |
| 2046 yRadius += scaledStroke.fY; | 2035 yRadius += scaledStroke.fY; |
| 2047 bounds->outset(scaledStroke.fX, scaledStroke.fY); | 2036 bounds.outset(scaledStroke.fX, scaledStroke.fY); |
| 2048 } | 2037 } |
| 2049 | 2038 |
| 2050 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); | 2039 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
| 2051 | 2040 |
| 2052 // Expand the rect so all the pixels will be captured. | 2041 // Expand the rect so all the pixels will be captured. |
| 2053 bounds->outset(SK_ScalarHalf, SK_ScalarHalf); | 2042 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| 2054 | 2043 |
| 2055 RRectEllipseRendererBatch::Geometry geometry; | 2044 RRectEllipseRendererBatch::Geometry geometry; |
| 2056 geometry.fViewMatrix = viewMatrix; | 2045 geometry.fViewMatrix = viewMatrix; |
| 2057 geometry.fColor = color; | 2046 geometry.fColor = color; |
| 2058 geometry.fXRadius = xRadius; | 2047 geometry.fXRadius = xRadius; |
| 2059 geometry.fYRadius = yRadius; | 2048 geometry.fYRadius = yRadius; |
| 2060 geometry.fInnerXRadius = innerXRadius; | 2049 geometry.fInnerXRadius = innerXRadius; |
| 2061 geometry.fInnerYRadius = innerYRadius; | 2050 geometry.fInnerYRadius = innerYRadius; |
| 2062 geometry.fStroke = isStrokeOnly; | 2051 geometry.fStroke = isStrokeOnly; |
| 2063 geometry.fDevBounds = *bounds; | 2052 geometry.fDevBounds = bounds; |
| 2064 | 2053 |
| 2065 return RRectEllipseRendererBatch::Create(geometry); | 2054 return RRectEllipseRendererBatch::Create(geometry); |
| 2066 } | 2055 } |
| 2067 } | 2056 } |
| 2068 | 2057 |
| 2069 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, | 2058 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| 2070 GrPipelineBuilder* pipelineBuilder, | 2059 GrPipelineBuilder* pipelineBuilder, |
| 2071 GrColor color, | 2060 GrColor color, |
| 2072 const SkMatrix& viewMatrix, | 2061 const SkMatrix& viewMatrix, |
| 2073 bool useAA, | 2062 bool useAA, |
| 2074 const SkRRect& rrect, | 2063 const SkRRect& rrect, |
| 2075 const SkStrokeRec& stroke) { | 2064 const SkStrokeRec& stroke) { |
| 2076 if (rrect.isOval()) { | 2065 if (rrect.isOval()) { |
| 2077 return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA,
rrect.getBounds(), | 2066 return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA,
rrect.getBounds(), |
| 2078 stroke); | 2067 stroke); |
| 2079 } | 2068 } |
| 2080 | 2069 |
| 2081 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisa
mpled(); | 2070 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisa
mpled(); |
| 2082 | 2071 |
| 2083 // only anti-aliased rrects for now | 2072 // only anti-aliased rrects for now |
| 2084 if (!useCoverageAA) { | 2073 if (!useCoverageAA) { |
| 2085 return false; | 2074 return false; |
| 2086 } | 2075 } |
| 2087 | 2076 |
| 2088 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { | 2077 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { |
| 2089 return false; | 2078 return false; |
| 2090 } | 2079 } |
| 2091 | 2080 |
| 2092 SkRect bounds; | 2081 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str
oke)); |
| 2093 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str
oke, &bounds)); | |
| 2094 if (!batch) { | 2082 if (!batch) { |
| 2095 return false; | 2083 return false; |
| 2096 } | 2084 } |
| 2097 | 2085 |
| 2098 target->drawBatch(pipelineBuilder, batch); | 2086 target->drawBatch(pipelineBuilder, batch); |
| 2099 return true; | 2087 return true; |
| 2100 } | 2088 } |
| 2101 | 2089 |
| 2102 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 2090 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 2103 | 2091 |
| 2104 #ifdef GR_TEST_UTILS | 2092 #ifdef GR_TEST_UTILS |
| 2105 | 2093 |
| 2106 static SkStrokeRec random_strokerec(SkRandom* random) { | 2094 static SkStrokeRec random_strokerec(SkRandom* random) { |
| 2107 SkStrokeRec::InitStyle style = | 2095 SkStrokeRec::InitStyle style = |
| 2108 SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_Init
Style + 1)); | 2096 SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_Init
Style + 1)); |
| 2109 SkStrokeRec rec(style); | 2097 SkStrokeRec rec(style); |
| 2110 bool strokeAndFill = random->nextBool(); | 2098 bool strokeAndFill = random->nextBool(); |
| 2111 SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f; | 2099 SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f; |
| 2112 rec.setStrokeStyle(strokeWidth, strokeAndFill); | 2100 rec.setStrokeStyle(strokeWidth, strokeAndFill); |
| 2113 return rec; | 2101 return rec; |
| 2114 } | 2102 } |
| 2115 | 2103 |
| 2116 BATCH_TEST_DEFINE(CircleBatch) { | 2104 BATCH_TEST_DEFINE(CircleBatch) { |
| 2117 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 2105 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
| 2118 GrColor color = GrRandomColor(random); | 2106 GrColor color = GrRandomColor(random); |
| 2119 bool useCoverageAA = random->nextBool(); | 2107 bool useCoverageAA = random->nextBool(); |
| 2120 SkRect circle = GrTest::TestRect(random); | 2108 SkRect circle = GrTest::TestRect(random); |
| 2121 SkRect bounds; // unused | 2109 return create_circle_batch(color, viewMatrix, useCoverageAA, circle, random_
strokerec(random)); |
| 2122 return create_circle_batch(color, viewMatrix, useCoverageAA, circle, random_
strokerec(random), | |
| 2123 &bounds); | |
| 2124 } | 2110 } |
| 2125 | 2111 |
| 2126 BATCH_TEST_DEFINE(EllipseBatch) { | 2112 BATCH_TEST_DEFINE(EllipseBatch) { |
| 2127 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); | 2113 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
| 2128 GrColor color = GrRandomColor(random); | 2114 GrColor color = GrRandomColor(random); |
| 2129 bool useCoverageAA = random->nextBool(); | 2115 bool useCoverageAA = random->nextBool(); |
| 2130 SkRect ellipse = GrTest::TestRect(random); | 2116 SkRect ellipse = GrTest::TestRect(random); |
| 2131 SkRect bounds; // unused | |
| 2132 return create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse, | 2117 return create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
| 2133 random_strokerec(random), &bounds); | 2118 random_strokerec(random)); |
| 2134 } | 2119 } |
| 2135 | 2120 |
| 2136 BATCH_TEST_DEFINE(DIEllipseBatch) { | 2121 BATCH_TEST_DEFINE(DIEllipseBatch) { |
| 2137 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 2122 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
| 2138 GrColor color = GrRandomColor(random); | 2123 GrColor color = GrRandomColor(random); |
| 2139 bool useCoverageAA = random->nextBool(); | 2124 bool useCoverageAA = random->nextBool(); |
| 2140 SkRect ellipse = GrTest::TestRect(random); | 2125 SkRect ellipse = GrTest::TestRect(random); |
| 2141 SkRect bounds; // unused | |
| 2142 return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, | 2126 return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
| 2143 random_strokerec(random), &bounds); | 2127 random_strokerec(random)); |
| 2144 } | 2128 } |
| 2145 | 2129 |
| 2146 BATCH_TEST_DEFINE(RRectBatch) { | 2130 BATCH_TEST_DEFINE(RRectBatch) { |
| 2147 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); | 2131 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
| 2148 GrColor color = GrRandomColor(random); | 2132 GrColor color = GrRandomColor(random); |
| 2149 const SkRRect& rrect = GrTest::TestRRectSimple(random); | 2133 const SkRRect& rrect = GrTest::TestRRectSimple(random); |
| 2150 | 2134 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random)
); |
| 2151 SkRect bounds; | |
| 2152 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random)
, &bounds); | |
| 2153 } | 2135 } |
| 2154 | 2136 |
| 2155 #endif | 2137 #endif |
| OLD | NEW |