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 |