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

Side by Side Diff: src/gpu/GrOvalRenderer.cpp

Issue 1108403005: Add batch unit tests for ovals (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 7 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
« no previous file with comments | « src/gpu/GrOvalRenderer.h ('k') | src/gpu/GrTestUtils.cpp » ('j') | 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 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"
11 #include "GrBatchTarget.h" 11 #include "GrBatchTarget.h"
12 #include "GrBatchTest.h"
12 #include "GrBufferAllocPool.h" 13 #include "GrBufferAllocPool.h"
13 #include "GrDrawTarget.h" 14 #include "GrDrawTarget.h"
14 #include "GrGeometryProcessor.h" 15 #include "GrGeometryProcessor.h"
15 #include "GrGpu.h" 16 #include "GrGpu.h"
16 #include "GrInvariantOutput.h" 17 #include "GrInvariantOutput.h"
17 #include "GrPipelineBuilder.h" 18 #include "GrPipelineBuilder.h"
18 #include "GrProcessor.h" 19 #include "GrProcessor.h"
19 #include "GrVertexBuffer.h" 20 #include "GrVertexBuffer.h"
20 #include "SkRRect.h" 21 #include "SkRRect.h"
21 #include "SkStrokeRec.h" 22 #include "SkStrokeRec.h"
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 bool fCoverageIgnored; 872 bool fCoverageIgnored;
872 }; 873 };
873 874
874 static const int kVertsPerCircle = 4; 875 static const int kVertsPerCircle = 4;
875 static const int kIndicesPerCircle = 6; 876 static const int kIndicesPerCircle = 6;
876 877
877 BatchTracker fBatch; 878 BatchTracker fBatch;
878 SkSTArray<1, Geometry, true> fGeoData; 879 SkSTArray<1, Geometry, true> fGeoData;
879 }; 880 };
880 881
881 void GrOvalRenderer::drawCircle(GrDrawTarget* target, 882 static GrBatch* create_circle_batch(GrColor color,
882 GrPipelineBuilder* pipelineBuilder, 883 const SkMatrix& viewMatrix,
883 GrColor color, 884 bool useCoverageAA,
884 const SkMatrix& viewMatrix, 885 const SkRect& circle,
885 bool useCoverageAA, 886 const SkStrokeRec& stroke,
886 const SkRect& circle, 887 SkRect* bounds) {
887 const SkStrokeRec& stroke) {
888 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); 888 SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY());
889 viewMatrix.mapPoints(&center, 1); 889 viewMatrix.mapPoints(&center, 1);
890 SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width())); 890 SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width()));
891 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth()); 891 SkScalar strokeWidth = viewMatrix.mapRadius(stroke.getWidth());
892 892
893 SkStrokeRec::Style style = stroke.getStyle(); 893 SkStrokeRec::Style style = stroke.getStyle();
894 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 894 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
895 SkStrokeRec::kHairline_Style == style; 895 SkStrokeRec::kHairline_Style == style;
896 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 896 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
897 897
(...skipping 13 matching lines...) Expand all
911 } 911 }
912 } 912 }
913 913
914 // The radii are outset for two reasons. First, it allows the shader to simp ly perform simpler 914 // The radii are outset for two reasons. First, it allows the shader to simp ly perform simpler
915 // computation because the computed alpha is zero, rather than 50%, at the r adius. 915 // computation because the computed alpha is zero, rather than 50%, at the r adius.
916 // Second, the outer radius is used to compute the verts of the bounding box that is rendered 916 // Second, the outer radius is used to compute the verts of the bounding box that is rendered
917 // and the outset ensures the box will cover all partially covered by the ci rcle. 917 // and the outset ensures the box will cover all partially covered by the ci rcle.
918 outerRadius += SK_ScalarHalf; 918 outerRadius += SK_ScalarHalf;
919 innerRadius -= SK_ScalarHalf; 919 innerRadius -= SK_ScalarHalf;
920 920
921 SkRect bounds = SkRect::MakeLTRB( 921 bounds->setLTRB(center.fX - outerRadius, center.fY - outerRadius,
922 center.fX - outerRadius, 922 center.fX + outerRadius, center.fY + outerRadius);
923 center.fY - outerRadius,
924 center.fX + outerRadius,
925 center.fY + outerRadius
926 );
927 923
928 CircleBatch::Geometry geometry; 924 CircleBatch::Geometry geometry;
929 geometry.fViewMatrix = viewMatrix; 925 geometry.fViewMatrix = viewMatrix;
930 geometry.fColor = color; 926 geometry.fColor = color;
931 geometry.fInnerRadius = innerRadius; 927 geometry.fInnerRadius = innerRadius;
932 geometry.fOuterRadius = outerRadius; 928 geometry.fOuterRadius = outerRadius;
933 geometry.fStroke = isStrokeOnly && innerRadius > 0; 929 geometry.fStroke = isStrokeOnly && innerRadius > 0;
934 geometry.fDevBounds = bounds; 930 geometry.fDevBounds = *bounds;
935 931
936 SkAutoTUnref<GrBatch> batch(CircleBatch::Create(geometry)); 932 return CircleBatch::Create(geometry);
933 }
934
935 void GrOvalRenderer::drawCircle(GrDrawTarget* target,
936 GrPipelineBuilder* pipelineBuilder,
937 GrColor color,
938 const SkMatrix& viewMatrix,
939 bool useCoverageAA,
940 const SkRect& circle,
941 const SkStrokeRec& stroke) {
942 SkRect bounds;
943 SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCovera geAA, circle,
944 stroke, &bounds));
937 target->drawBatch(pipelineBuilder, batch, &bounds); 945 target->drawBatch(pipelineBuilder, batch, &bounds);
938 } 946 }
939 947
940 /////////////////////////////////////////////////////////////////////////////// 948 ///////////////////////////////////////////////////////////////////////////////
941 949
942 class EllipseBatch : public GrBatch { 950 class EllipseBatch : public GrBatch {
943 public: 951 public:
944 struct Geometry { 952 struct Geometry {
945 GrColor fColor; 953 GrColor fColor;
946 SkMatrix fViewMatrix; 954 SkMatrix fViewMatrix;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1131 bool fCoverageIgnored; 1139 bool fCoverageIgnored;
1132 }; 1140 };
1133 1141
1134 static const int kVertsPerEllipse = 4; 1142 static const int kVertsPerEllipse = 4;
1135 static const int kIndicesPerEllipse = 6; 1143 static const int kIndicesPerEllipse = 6;
1136 1144
1137 BatchTracker fBatch; 1145 BatchTracker fBatch;
1138 SkSTArray<1, Geometry, true> fGeoData; 1146 SkSTArray<1, Geometry, true> fGeoData;
1139 }; 1147 };
1140 1148
1141 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, 1149 static GrBatch* create_ellipse_batch(GrColor color,
1142 GrPipelineBuilder* pipelineBuilder, 1150 const SkMatrix& viewMatrix,
1143 GrColor color, 1151 bool useCoverageAA,
1144 const SkMatrix& viewMatrix, 1152 const SkRect& ellipse,
1145 bool useCoverageAA, 1153 const SkStrokeRec& stroke,
1146 const SkRect& ellipse, 1154 SkRect* bounds) {
1147 const SkStrokeRec& stroke) {
1148 #ifdef SK_DEBUG 1155 #ifdef SK_DEBUG
1149 { 1156 {
1150 // we should have checked for this previously 1157 // we should have checked for this previously
1151 bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); 1158 bool isAxisAlignedEllipse = viewMatrix.rectStaysRect();
1152 SkASSERT(useCoverageAA && isAxisAlignedEllipse); 1159 SkASSERT(useCoverageAA && isAxisAlignedEllipse);
1153 } 1160 }
1154 #endif 1161 #endif
1155 1162
1156 // do any matrix crunching before we reset the draw state for device coords 1163 // do any matrix crunching before we reset the draw state for device coords
1157 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 1164 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
(...skipping 23 matching lines...) Expand all
1181 if (hasStroke) { 1188 if (hasStroke) {
1182 if (SkScalarNearlyZero(scaledStroke.length())) { 1189 if (SkScalarNearlyZero(scaledStroke.length())) {
1183 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 1190 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
1184 } else { 1191 } else {
1185 scaledStroke.scale(SK_ScalarHalf); 1192 scaledStroke.scale(SK_ScalarHalf);
1186 } 1193 }
1187 1194
1188 // we only handle thick strokes for near-circular ellipses 1195 // we only handle thick strokes for near-circular ellipses
1189 if (scaledStroke.length() > SK_ScalarHalf && 1196 if (scaledStroke.length() > SK_ScalarHalf &&
1190 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius) ) { 1197 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius) ) {
1191 return false; 1198 return NULL;
1192 } 1199 }
1193 1200
1194 // we don't handle it if curvature of the stroke is less than curvature of the ellipse 1201 // we don't handle it if curvature of the stroke is less than curvature of the ellipse
1195 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY )*xRadius || 1202 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY )*xRadius ||
1196 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX )*yRadius) { 1203 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX )*yRadius) {
1197 return false; 1204 return NULL;
1198 } 1205 }
1199 1206
1200 // this is legit only if scale & translation (which should be the case a t the moment) 1207 // this is legit only if scale & translation (which should be the case a t the moment)
1201 if (isStrokeOnly) { 1208 if (isStrokeOnly) {
1202 innerXRadius = xRadius - scaledStroke.fX; 1209 innerXRadius = xRadius - scaledStroke.fX;
1203 innerYRadius = yRadius - scaledStroke.fY; 1210 innerYRadius = yRadius - scaledStroke.fY;
1204 } 1211 }
1205 1212
1206 xRadius += scaledStroke.fX; 1213 xRadius += scaledStroke.fX;
1207 yRadius += scaledStroke.fY; 1214 yRadius += scaledStroke.fY;
1208 } 1215 }
1209 1216
1210 // We've extended the outer x radius out half a pixel to antialias. 1217 // We've extended the outer x radius out half a pixel to antialias.
1211 // This will also expand the rect so all the pixels will be captured. 1218 // This will also expand the rect so all the pixels will be captured.
1212 // TODO: Consider if we should use sqrt(2)/2 instead 1219 // TODO: Consider if we should use sqrt(2)/2 instead
1213 xRadius += SK_ScalarHalf; 1220 xRadius += SK_ScalarHalf;
1214 yRadius += SK_ScalarHalf; 1221 yRadius += SK_ScalarHalf;
1215 1222
1216 SkRect bounds = SkRect::MakeLTRB( 1223 bounds->setLTRB(center.fX - xRadius, center.fY - yRadius,
1217 center.fX - xRadius, 1224 center.fX + xRadius, center.fY + yRadius);
1218 center.fY - yRadius,
1219 center.fX + xRadius,
1220 center.fY + yRadius
1221 );
1222 1225
1223 EllipseBatch::Geometry geometry; 1226 EllipseBatch::Geometry geometry;
1224 geometry.fViewMatrix = viewMatrix; 1227 geometry.fViewMatrix = viewMatrix;
1225 geometry.fColor = color; 1228 geometry.fColor = color;
1226 geometry.fXRadius = xRadius; 1229 geometry.fXRadius = xRadius;
1227 geometry.fYRadius = yRadius; 1230 geometry.fYRadius = yRadius;
1228 geometry.fInnerXRadius = innerXRadius; 1231 geometry.fInnerXRadius = innerXRadius;
1229 geometry.fInnerYRadius = innerYRadius; 1232 geometry.fInnerYRadius = innerYRadius;
1230 geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; 1233 geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0;
1231 geometry.fDevBounds = bounds; 1234 geometry.fDevBounds = *bounds;
1232 1235
1233 SkAutoTUnref<GrBatch> batch(EllipseBatch::Create(geometry)); 1236 return EllipseBatch::Create(geometry);
1237 }
1238
1239 bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
1240 GrPipelineBuilder* pipelineBuilder,
1241 GrColor color,
1242 const SkMatrix& viewMatrix,
1243 bool useCoverageAA,
1244 const SkRect& ellipse,
1245 const SkStrokeRec& stroke) {
1246 SkRect bounds;
1247 SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCover ageAA, ellipse,
1248 stroke, &bounds));
1249 if (!batch) {
1250 return false;
1251 }
1252
1234 target->drawBatch(pipelineBuilder, batch, &bounds); 1253 target->drawBatch(pipelineBuilder, batch, &bounds);
1235
1236 return true; 1254 return true;
1237 } 1255 }
1238 1256
1239 //////////////////////////////////////////////////////////////////////////////// ///////////////// 1257 //////////////////////////////////////////////////////////////////////////////// /////////////////
1240 1258
1241 class DIEllipseBatch : public GrBatch { 1259 class DIEllipseBatch : public GrBatch {
1242 public: 1260 public:
1243 struct Geometry { 1261 struct Geometry {
1244 GrColor fColor; 1262 GrColor fColor;
1245 SkMatrix fViewMatrix; 1263 SkMatrix fViewMatrix;
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 bool fCoverageIgnored; 1441 bool fCoverageIgnored;
1424 }; 1442 };
1425 1443
1426 static const int kVertsPerEllipse = 4; 1444 static const int kVertsPerEllipse = 4;
1427 static const int kIndicesPerEllipse = 6; 1445 static const int kIndicesPerEllipse = 6;
1428 1446
1429 BatchTracker fBatch; 1447 BatchTracker fBatch;
1430 SkSTArray<1, Geometry, true> fGeoData; 1448 SkSTArray<1, Geometry, true> fGeoData;
1431 }; 1449 };
1432 1450
1433 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, 1451 static GrBatch* create_diellipse_batch(GrColor color,
1434 GrPipelineBuilder* pipelineBuilder, 1452 const SkMatrix& viewMatrix,
1435 GrColor color, 1453 bool useCoverageAA,
1436 const SkMatrix& viewMatrix, 1454 const SkRect& ellipse,
1437 bool useCoverageAA, 1455 const SkStrokeRec& stroke,
1438 const SkRect& ellipse, 1456 SkRect* bounds) {
1439 const SkStrokeRec& stroke) {
1440 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); 1457 SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
1441 SkScalar xRadius = SkScalarHalf(ellipse.width()); 1458 SkScalar xRadius = SkScalarHalf(ellipse.width());
1442 SkScalar yRadius = SkScalarHalf(ellipse.height()); 1459 SkScalar yRadius = SkScalarHalf(ellipse.height());
1443 1460
1444 SkStrokeRec::Style style = stroke.getStyle(); 1461 SkStrokeRec::Style style = stroke.getStyle();
1445 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ? 1462 DIEllipseEdgeEffect::Mode mode = (SkStrokeRec::kStroke_Style == style) ?
1446 DIEllipseEdgeEffect::kStroke : 1463 DIEllipseEdgeEffect::kStroke :
1447 (SkStrokeRec::kHairline_Style == style) ? 1464 (SkStrokeRec::kHairline_Style == style) ?
1448 DIEllipseEdgeEffect::kHairline : DIEllipseEd geEffect::kFill; 1465 DIEllipseEdgeEffect::kHairline : DIEllipseEd geEffect::kFill;
1449 1466
1450 SkScalar innerXRadius = 0; 1467 SkScalar innerXRadius = 0;
1451 SkScalar innerYRadius = 0; 1468 SkScalar innerYRadius = 0;
1452 if (SkStrokeRec::kFill_Style != style && SkStrokeRec::kHairline_Style != sty le) { 1469 if (SkStrokeRec::kFill_Style != style && SkStrokeRec::kHairline_Style != sty le) {
1453 SkScalar strokeWidth = stroke.getWidth(); 1470 SkScalar strokeWidth = stroke.getWidth();
1454 1471
1455 if (SkScalarNearlyZero(strokeWidth)) { 1472 if (SkScalarNearlyZero(strokeWidth)) {
1456 strokeWidth = SK_ScalarHalf; 1473 strokeWidth = SK_ScalarHalf;
1457 } else { 1474 } else {
1458 strokeWidth *= SK_ScalarHalf; 1475 strokeWidth *= SK_ScalarHalf;
1459 } 1476 }
1460 1477
1461 // we only handle thick strokes for near-circular ellipses 1478 // we only handle thick strokes for near-circular ellipses
1462 if (strokeWidth > SK_ScalarHalf && 1479 if (strokeWidth > SK_ScalarHalf &&
1463 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius) ) { 1480 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius) ) {
1464 return false; 1481 return NULL;
1465 } 1482 }
1466 1483
1467 // we don't handle it if curvature of the stroke is less than curvature of the ellipse 1484 // we don't handle it if curvature of the stroke is less than curvature of the ellipse
1468 if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius || 1485 if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius ||
1469 strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) { 1486 strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) {
1470 return false; 1487 return NULL;
1471 } 1488 }
1472 1489
1473 // set inner radius (if needed) 1490 // set inner radius (if needed)
1474 if (SkStrokeRec::kStroke_Style == style) { 1491 if (SkStrokeRec::kStroke_Style == style) {
1475 innerXRadius = xRadius - strokeWidth; 1492 innerXRadius = xRadius - strokeWidth;
1476 innerYRadius = yRadius - strokeWidth; 1493 innerYRadius = yRadius - strokeWidth;
1477 } 1494 }
1478 1495
1479 xRadius += strokeWidth; 1496 xRadius += strokeWidth;
1480 yRadius += strokeWidth; 1497 yRadius += strokeWidth;
1481 } 1498 }
1482 if (DIEllipseEdgeEffect::kStroke == mode) { 1499 if (DIEllipseEdgeEffect::kStroke == mode) {
1483 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke : 1500 mode = (innerXRadius > 0 && innerYRadius > 0) ? DIEllipseEdgeEffect::kSt roke :
1484 DIEllipseEdgeEffect::kFi ll; 1501 DIEllipseEdgeEffect::kFi ll;
1485 } 1502 }
1486 1503
1487 // This expands the outer rect so that after CTM we end up with a half-pixel border 1504 // This expands the outer rect so that after CTM we end up with a half-pixel border
1488 SkScalar a = viewMatrix[SkMatrix::kMScaleX]; 1505 SkScalar a = viewMatrix[SkMatrix::kMScaleX];
1489 SkScalar b = viewMatrix[SkMatrix::kMSkewX]; 1506 SkScalar b = viewMatrix[SkMatrix::kMSkewX];
1490 SkScalar c = viewMatrix[SkMatrix::kMSkewY]; 1507 SkScalar c = viewMatrix[SkMatrix::kMSkewY];
1491 SkScalar d = viewMatrix[SkMatrix::kMScaleY]; 1508 SkScalar d = viewMatrix[SkMatrix::kMScaleY];
1492 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); 1509 SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c));
1493 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); 1510 SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d));
1494 1511
1495 SkRect bounds = SkRect::MakeLTRB( 1512 bounds->setLTRB(center.fX - xRadius - geoDx, center.fY - yRadius - geoDy,
1496 center.fX - xRadius - geoDx, 1513 center.fX + xRadius + geoDx, center.fY + yRadius + geoDy);
1497 center.fY - yRadius - geoDy,
1498 center.fX + xRadius + geoDx,
1499 center.fY + yRadius + geoDy
1500 );
1501 1514
1502 DIEllipseBatch::Geometry geometry; 1515 DIEllipseBatch::Geometry geometry;
1503 geometry.fViewMatrix = viewMatrix; 1516 geometry.fViewMatrix = viewMatrix;
1504 geometry.fColor = color; 1517 geometry.fColor = color;
1505 geometry.fXRadius = xRadius; 1518 geometry.fXRadius = xRadius;
1506 geometry.fYRadius = yRadius; 1519 geometry.fYRadius = yRadius;
1507 geometry.fInnerXRadius = innerXRadius; 1520 geometry.fInnerXRadius = innerXRadius;
1508 geometry.fInnerYRadius = innerYRadius; 1521 geometry.fInnerYRadius = innerYRadius;
1509 geometry.fGeoDx = geoDx; 1522 geometry.fGeoDx = geoDx;
1510 geometry.fGeoDy = geoDy; 1523 geometry.fGeoDy = geoDy;
1511 geometry.fMode = mode; 1524 geometry.fMode = mode;
1512 geometry.fBounds = bounds; 1525 geometry.fBounds = *bounds;
1513 1526
1514 viewMatrix.mapRect(&bounds); 1527 viewMatrix.mapRect(bounds);
1528 return DIEllipseBatch::Create(geometry);
1529 }
1515 1530
1516 SkAutoTUnref<GrBatch> batch(DIEllipseBatch::Create(geometry)); 1531 bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
1532 GrPipelineBuilder* pipelineBuilder,
1533 GrColor color,
1534 const SkMatrix& viewMatrix,
1535 bool useCoverageAA,
1536 const SkRect& ellipse,
1537 const SkStrokeRec& stroke) {
1538 SkRect bounds;
1539 SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCov erageAA, ellipse,
1540 stroke, &bounds));
1541 if (!batch) {
1542 return false;
1543 }
1517 target->drawBatch(pipelineBuilder, batch, &bounds); 1544 target->drawBatch(pipelineBuilder, batch, &bounds);
1518
1519 return true; 1545 return true;
1520 } 1546 }
1521 1547
1522 /////////////////////////////////////////////////////////////////////////////// 1548 ///////////////////////////////////////////////////////////////////////////////
1523 1549
1524 static const uint16_t gRRectIndices[] = { 1550 static const uint16_t gRRectIndices[] = {
1525 // corners 1551 // corners
1526 0, 1, 5, 0, 5, 4, 1552 0, 1, 5, 0, 5, 4,
1527 2, 3, 7, 2, 7, 6, 1553 2, 3, 7, 2, 7, 6,
1528 8, 9, 13, 8, 13, 12, 1554 8, 9, 13, 8, 13, 12,
1529 10, 11, 15, 10, 15, 14, 1555 10, 11, 15, 10, 15, 14,
1530 1556
1531 // edges 1557 // edges
1532 1, 2, 6, 1, 6, 5, 1558 1, 2, 6, 1, 6, 5,
1533 4, 5, 9, 4, 9, 8, 1559 4, 5, 9, 4, 9, 8,
1534 6, 7, 11, 6, 11, 10, 1560 6, 7, 11, 6, 11, 10,
1535 9, 10, 14, 9, 14, 13, 1561 9, 10, 14, 9, 14, 13,
1536 1562
1537 // center 1563 // center
1538 // we place this at the end so that we can ignore these indices when renderi ng stroke-only 1564 // we place this at the end so that we can ignore these indices when renderi ng stroke-only
1539 5, 6, 10, 5, 10, 9 1565 5, 6, 10, 5, 10, 9
1540 }; 1566 };
1541 1567
1542 static const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6; 1568 static const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6;
1543 static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices); 1569 static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices);
1544 static const int kVertsPerRRect = 16; 1570 static const int kVertsPerRRect = 16;
1545 static const int kNumRRectsInIndexBuffer = 256; 1571 static const int kNumRRectsInIndexBuffer = 256;
1546 1572
1547 GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(bool isStrokeOnly) {
1548 if (isStrokeOnly) {
1549 if (NULL == fStrokeRRectIndexBuffer) {
1550 fStrokeRRectIndexBuffer = fGpu->createInstancedIndexBuffer(gRRectInd ices,
1551 kIndicesP erStrokeRRect,
1552 kNumRRect sInIndexBuffer,
1553 kVertsPer RRect);
1554 }
1555 return fStrokeRRectIndexBuffer;
1556 } else {
1557 if (NULL == fRRectIndexBuffer) {
1558 fRRectIndexBuffer = fGpu->createInstancedIndexBuffer(gRRectIndices,
1559 kIndicesPerRRec t,
1560 kNumRRectsInInd exBuffer,
1561 kVertsPerRRect) ;
1562 }
1563 return fRRectIndexBuffer;
1564 }
1565 }
1566
1567 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, 1573 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
1568 GrPipelineBuilder* pipelineBuilder, 1574 GrPipelineBuilder* pipelineBuilder,
1569 GrColor color, 1575 GrColor color,
1570 const SkMatrix& viewMatrix, 1576 const SkMatrix& viewMatrix,
1571 bool useAA, 1577 bool useAA,
1572 const SkRRect& origOuter, 1578 const SkRRect& origOuter,
1573 const SkRRect& origInner) { 1579 const SkRRect& origInner) {
1574 bool applyAA = useAA && 1580 bool applyAA = useAA &&
1575 !pipelineBuilder->getRenderTarget()->isMultisampled(); 1581 !pipelineBuilder->getRenderTarget()->isMultisampled();
1576 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; 1582 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp;
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
2050 bool fUsesLocalCoords; 2056 bool fUsesLocalCoords;
2051 bool fColorIgnored; 2057 bool fColorIgnored;
2052 bool fCoverageIgnored; 2058 bool fCoverageIgnored;
2053 }; 2059 };
2054 2060
2055 BatchTracker fBatch; 2061 BatchTracker fBatch;
2056 SkSTArray<1, Geometry, true> fGeoData; 2062 SkSTArray<1, Geometry, true> fGeoData;
2057 const GrIndexBuffer* fIndexBuffer; 2063 const GrIndexBuffer* fIndexBuffer;
2058 }; 2064 };
2059 2065
2060 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, 2066 static GrIndexBuffer* create_rrect_indexbuffer(GrIndexBuffer** strokeRRectIndexB uffer,
2061 GrPipelineBuilder* pipelineBuilder, 2067 GrIndexBuffer** rrectIndexBuffer,
2062 GrColor color, 2068 bool isStrokeOnly,
2063 const SkMatrix& viewMatrix, 2069 GrGpu* gpu) {
2064 bool useAA, 2070 if (isStrokeOnly) {
2065 const SkRRect& rrect, 2071 if (NULL == *strokeRRectIndexBuffer) {
2066 const SkStrokeRec& stroke) { 2072 *strokeRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndi ces,
2067 if (rrect.isOval()) { 2073 kIndicesPe rStrokeRRect,
2068 return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect.getBounds(), 2074 kNumRRects InIndexBuffer,
2069 stroke); 2075 kVertsPerR Rect);
2076 }
2077 return *strokeRRectIndexBuffer;
2078 } else {
2079 if (NULL == *rrectIndexBuffer) {
2080 *rrectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
2081 kIndicesPerRRect ,
2082 kNumRRectsInInde xBuffer,
2083 kVertsPerRRect);
2084 }
2085 return *rrectIndexBuffer;
2070 } 2086 }
2087 }
2071 2088
2072 bool useCoverageAA = useAA && 2089 static GrBatch* create_rrect_batch(GrColor color,
2073 !pipelineBuilder->getRenderTarget()->isMultisampled(); 2090 const SkMatrix& viewMatrix,
2091 const SkRRect& rrect,
2092 const SkStrokeRec& stroke,
2093 SkRect* bounds,
2094 GrIndexBuffer** strokeRRectIndexBuffer,
2095 GrIndexBuffer** rrectIndexBuffer,
2096 GrGpu* gpu) {
2097 SkASSERT(viewMatrix.rectStaysRect());
2098 SkASSERT(rrect.isSimple());
2099 SkASSERT(!rrect.isOval());
2074 2100
2075 // only anti-aliased rrects for now 2101 // RRect batchs only handle simple, but not too simple, rrects
2076 if (!useCoverageAA) {
2077 return false;
2078 }
2079
2080 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) {
2081 return false;
2082 }
2083
2084 // do any matrix crunching before we reset the draw state for device coords 2102 // do any matrix crunching before we reset the draw state for device coords
2085 const SkRect& rrectBounds = rrect.getBounds(); 2103 const SkRect& rrectBounds = rrect.getBounds();
2086 SkRect bounds; 2104 viewMatrix.mapRect(bounds, rrectBounds);
2087 viewMatrix.mapRect(&bounds, rrectBounds);
2088 2105
2089 SkVector radii = rrect.getSimpleRadii(); 2106 SkVector radii = rrect.getSimpleRadii();
2090 SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX + 2107 SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX +
2091 viewMatrix[SkMatrix::kMSkewY]*radii.fY); 2108 viewMatrix[SkMatrix::kMSkewY]*radii.fY);
2092 SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX + 2109 SkScalar yRadius = SkScalarAbs(viewMatrix[SkMatrix::kMSkewX]*radii.fX +
2093 viewMatrix[SkMatrix::kMScaleY]*radii.fY); 2110 viewMatrix[SkMatrix::kMScaleY]*radii.fY);
2094 2111
2095 SkStrokeRec::Style style = stroke.getStyle(); 2112 SkStrokeRec::Style style = stroke.getStyle();
2096 2113
2097 // do (potentially) anisotropic mapping of stroke 2114 // do (potentially) anisotropic mapping of stroke
2098 SkVector scaledStroke; 2115 SkVector scaledStroke;
2099 SkScalar strokeWidth = stroke.getWidth(); 2116 SkScalar strokeWidth = stroke.getWidth();
2100 2117
2101 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style || 2118 bool isStrokeOnly = SkStrokeRec::kStroke_Style == style ||
2102 SkStrokeRec::kHairline_Style == style; 2119 SkStrokeRec::kHairline_Style == style;
2103 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style; 2120 bool hasStroke = isStrokeOnly || SkStrokeRec::kStrokeAndFill_Style == style;
2104 2121
2105 if (hasStroke) { 2122 if (hasStroke) {
2106 if (SkStrokeRec::kHairline_Style == style) { 2123 if (SkStrokeRec::kHairline_Style == style) {
2107 scaledStroke.set(1, 1); 2124 scaledStroke.set(1, 1);
2108 } else { 2125 } else {
2109 scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSc aleX] + 2126 scaledStroke.fX = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSc aleX] +
2110 viewMatrix[SkMatrix::kMSk ewY])); 2127 viewMatrix[SkMatrix::kMSk ewY]));
2111 scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSk ewX] + 2128 scaledStroke.fY = SkScalarAbs(strokeWidth*(viewMatrix[SkMatrix::kMSk ewX] +
2112 viewMatrix[SkMatrix::kMSc aleY])); 2129 viewMatrix[SkMatrix::kMSc aleY]));
2113 } 2130 }
2114 2131
2115 // if half of strokewidth is greater than radius, we don't handle that r ight now 2132 // if half of strokewidth is greater than radius, we don't handle that r ight now
2116 if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStrok e.fY > yRadius) { 2133 if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStrok e.fY > yRadius) {
2117 return false; 2134 return NULL;
2118 } 2135 }
2119 } 2136 }
2120 2137
2121 // The way the effect interpolates the offset-to-ellipse/circle-center attri bute only works on 2138 // The way the effect interpolates the offset-to-ellipse/circle-center attri bute only works on
2122 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r ect of the nine- 2139 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r ect of the nine-
2123 // patch will have fractional coverage. This only matters when the interior is actually filled. 2140 // patch will have fractional coverage. This only matters when the interior is actually filled.
2124 // We could consider falling back to rect rendering here, since a tiny radiu s is 2141 // We could consider falling back to rect rendering here, since a tiny radiu s is
2125 // indistinguishable from a square corner. 2142 // indistinguishable from a square corner.
2126 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { 2143 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) {
2127 return false; 2144 return NULL;
2128 } 2145 }
2129 2146
2130 GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly); 2147 GrIndexBuffer* indexBuffer = create_rrect_indexbuffer(strokeRRectIndexBuffer ,
2148 rrectIndexBuffer,
2149 isStrokeOnly,
2150 gpu);
2131 if (NULL == indexBuffer) { 2151 if (NULL == indexBuffer) {
2132 SkDebugf("Failed to create index buffer!\n"); 2152 SkDebugf("Failed to create index buffer!\n");
2133 return false; 2153 return NULL;
2134 } 2154 }
2135 2155
2136 // if the corners are circles, use the circle renderer 2156 // if the corners are circles, use the circle renderer
2137 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) { 2157 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius ) {
2138 SkScalar innerRadius = 0.0f; 2158 SkScalar innerRadius = 0.0f;
2139 SkScalar outerRadius = xRadius; 2159 SkScalar outerRadius = xRadius;
2140 SkScalar halfWidth = 0; 2160 SkScalar halfWidth = 0;
2141 if (hasStroke) { 2161 if (hasStroke) {
2142 if (SkScalarNearlyZero(scaledStroke.fX)) { 2162 if (SkScalarNearlyZero(scaledStroke.fX)) {
2143 halfWidth = SK_ScalarHalf; 2163 halfWidth = SK_ScalarHalf;
2144 } else { 2164 } else {
2145 halfWidth = SkScalarHalf(scaledStroke.fX); 2165 halfWidth = SkScalarHalf(scaledStroke.fX);
2146 } 2166 }
2147 2167
2148 if (isStrokeOnly) { 2168 if (isStrokeOnly) {
2149 innerRadius = xRadius - halfWidth; 2169 innerRadius = xRadius - halfWidth;
2150 } 2170 }
2151 outerRadius += halfWidth; 2171 outerRadius += halfWidth;
2152 bounds.outset(halfWidth, halfWidth); 2172 bounds->outset(halfWidth, halfWidth);
2153 } 2173 }
2154 2174
2155 isStrokeOnly = (isStrokeOnly && innerRadius >= 0); 2175 isStrokeOnly = (isStrokeOnly && innerRadius >= 0);
2156 2176
2157 // The radii are outset for two reasons. First, it allows the shader to simply perform 2177 // The radii are outset for two reasons. First, it allows the shader to simply perform
2158 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius. 2178 // simpler computation because the computed alpha is zero, rather than 5 0%, at the radius.
2159 // Second, the outer radius is used to compute the verts of the bounding box that is 2179 // Second, the outer radius is used to compute the verts of the bounding box that is
2160 // rendered and the outset ensures the box will cover all partially cove red by the rrect 2180 // rendered and the outset ensures the box will cover all partially cove red by the rrect
2161 // corners. 2181 // corners.
2162 outerRadius += SK_ScalarHalf; 2182 outerRadius += SK_ScalarHalf;
2163 innerRadius -= SK_ScalarHalf; 2183 innerRadius -= SK_ScalarHalf;
2164 2184
2165 // Expand the rect so all the pixels will be captured. 2185 // Expand the rect so all the pixels will be captured.
2166 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 2186 bounds->outset(SK_ScalarHalf, SK_ScalarHalf);
2167 2187
2168 RRectCircleRendererBatch::Geometry geometry; 2188 RRectCircleRendererBatch::Geometry geometry;
2169 geometry.fViewMatrix = viewMatrix; 2189 geometry.fViewMatrix = viewMatrix;
2170 geometry.fColor = color; 2190 geometry.fColor = color;
2171 geometry.fInnerRadius = innerRadius; 2191 geometry.fInnerRadius = innerRadius;
2172 geometry.fOuterRadius = outerRadius; 2192 geometry.fOuterRadius = outerRadius;
2173 geometry.fStroke = isStrokeOnly; 2193 geometry.fStroke = isStrokeOnly;
2174 geometry.fDevBounds = bounds; 2194 geometry.fDevBounds = *bounds;
2175 2195
2176 SkAutoTUnref<GrBatch> batch(RRectCircleRendererBatch::Create(geometry, i ndexBuffer)); 2196 return RRectCircleRendererBatch::Create(geometry, indexBuffer);
2177 target->drawBatch(pipelineBuilder, batch, &bounds);
2178 2197
2179 // otherwise we use the ellipse renderer 2198 // otherwise we use the ellipse renderer
2180 } else { 2199 } else {
2181 SkScalar innerXRadius = 0.0f; 2200 SkScalar innerXRadius = 0.0f;
2182 SkScalar innerYRadius = 0.0f; 2201 SkScalar innerYRadius = 0.0f;
2183 if (hasStroke) { 2202 if (hasStroke) {
2184 if (SkScalarNearlyZero(scaledStroke.length())) { 2203 if (SkScalarNearlyZero(scaledStroke.length())) {
2185 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); 2204 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf);
2186 } else { 2205 } else {
2187 scaledStroke.scale(SK_ScalarHalf); 2206 scaledStroke.scale(SK_ScalarHalf);
2188 } 2207 }
2189 2208
2190 // we only handle thick strokes for near-circular ellipses 2209 // we only handle thick strokes for near-circular ellipses
2191 if (scaledStroke.length() > SK_ScalarHalf && 2210 if (scaledStroke.length() > SK_ScalarHalf &&
2192 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRad ius)) { 2211 (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRad ius)) {
2193 return false; 2212 return NULL;
2194 } 2213 }
2195 2214
2196 // we don't handle it if curvature of the stroke is less than curvat ure of the ellipse 2215 // we don't handle it if curvature of the stroke is less than curvat ure of the ellipse
2197 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok e.fY)*xRadius || 2216 if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStrok e.fY)*xRadius ||
2198 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok e.fX)*yRadius) { 2217 scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStrok e.fX)*yRadius) {
2199 return false; 2218 return NULL;
2200 } 2219 }
2201 2220
2202 // this is legit only if scale & translation (which should be the ca se at the moment) 2221 // this is legit only if scale & translation (which should be the ca se at the moment)
2203 if (isStrokeOnly) { 2222 if (isStrokeOnly) {
2204 innerXRadius = xRadius - scaledStroke.fX; 2223 innerXRadius = xRadius - scaledStroke.fX;
2205 innerYRadius = yRadius - scaledStroke.fY; 2224 innerYRadius = yRadius - scaledStroke.fY;
2206 } 2225 }
2207 2226
2208 xRadius += scaledStroke.fX; 2227 xRadius += scaledStroke.fX;
2209 yRadius += scaledStroke.fY; 2228 yRadius += scaledStroke.fY;
2210 bounds.outset(scaledStroke.fX, scaledStroke.fY); 2229 bounds->outset(scaledStroke.fX, scaledStroke.fY);
2211 } 2230 }
2212 2231
2213 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); 2232 isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
2214 2233
2215 // Expand the rect so all the pixels will be captured. 2234 // Expand the rect so all the pixels will be captured.
2216 bounds.outset(SK_ScalarHalf, SK_ScalarHalf); 2235 bounds->outset(SK_ScalarHalf, SK_ScalarHalf);
2217 2236
2218 RRectEllipseRendererBatch::Geometry geometry; 2237 RRectEllipseRendererBatch::Geometry geometry;
2219 geometry.fViewMatrix = viewMatrix; 2238 geometry.fViewMatrix = viewMatrix;
2220 geometry.fColor = color; 2239 geometry.fColor = color;
2221 geometry.fXRadius = xRadius; 2240 geometry.fXRadius = xRadius;
2222 geometry.fYRadius = yRadius; 2241 geometry.fYRadius = yRadius;
2223 geometry.fInnerXRadius = innerXRadius; 2242 geometry.fInnerXRadius = innerXRadius;
2224 geometry.fInnerYRadius = innerYRadius; 2243 geometry.fInnerYRadius = innerYRadius;
2225 geometry.fStroke = isStrokeOnly; 2244 geometry.fStroke = isStrokeOnly;
2226 geometry.fDevBounds = bounds; 2245 geometry.fDevBounds = *bounds;
2227 2246
2228 SkAutoTUnref<GrBatch> batch(RRectEllipseRendererBatch::Create(geometry, indexBuffer)); 2247 return RRectEllipseRendererBatch::Create(geometry, indexBuffer);
2229 target->drawBatch(pipelineBuilder, batch, &bounds);
2230 } 2248 }
2249 }
2250
2251 bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
2252 GrPipelineBuilder* pipelineBuilder,
2253 GrColor color,
2254 const SkMatrix& viewMatrix,
2255 bool useAA,
2256 const SkRRect& rrect,
2257 const SkStrokeRec& stroke) {
2258 if (rrect.isOval()) {
2259 return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect.getBounds(),
2260 stroke);
2261 }
2262
2263 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisa mpled();
2264
2265 // only anti-aliased rrects for now
2266 if (!useCoverageAA) {
2267 return false;
2268 }
2269
2270 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) {
2271 return false;
2272 }
2273
2274 SkRect bounds;
2275 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str oke, &bounds,
2276 &fStrokeRRectIndexBuffer, &fR RectIndexBuffer,
2277 fGpu));
2278 if (!batch) {
2279 return false;
2280 }
2281
2282 target->drawBatch(pipelineBuilder, batch, &bounds);
2231 return true; 2283 return true;
2232 } 2284 }
2285
2286 //////////////////////////////////////////////////////////////////////////////// ///////////////////
2287
2288 #ifdef GR_TEST_UTILS
2289
2290 static SkStrokeRec random_strokerec(SkRandom* random) {
2291 SkStrokeRec::InitStyle style =
2292 SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_Init Style + 1));
2293 SkStrokeRec rec(style);
2294 bool strokeAndFill = random->nextBool();
2295 SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f;
2296 rec.setStrokeStyle(strokeWidth, strokeAndFill);
2297 return rec;
2298 }
2299
2300 BATCH_TEST_DEFINE(CircleBatch) {
2301 SkMatrix viewMatrix = GrTest::TestMatrix(random);
2302 GrColor color = GrRandomColor(random);
2303 bool useCoverageAA = random->nextBool();
2304 SkRect circle = GrTest::TestRect(random);
2305 SkRect bounds; // unused
2306 return create_circle_batch(color, viewMatrix, useCoverageAA, circle, random_ strokerec(random),
2307 &bounds);
2308 }
2309
2310 BATCH_TEST_DEFINE(EllipseBatch) {
2311 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
2312 GrColor color = GrRandomColor(random);
2313 bool useCoverageAA = random->nextBool();
2314 SkRect ellipse = GrTest::TestRect(random);
2315 SkRect bounds; // unused
2316 return create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse,
2317 random_strokerec(random), &bounds);
2318 }
2319
2320 BATCH_TEST_DEFINE(DIEllipseBatch) {
2321 SkMatrix viewMatrix = GrTest::TestMatrix(random);
2322 GrColor color = GrRandomColor(random);
2323 bool useCoverageAA = random->nextBool();
2324 SkRect ellipse = GrTest::TestRect(random);
2325 SkRect bounds; // unused
2326 return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse,
2327 random_strokerec(random), &bounds);
2328 }
2329
2330 BATCH_TEST_DEFINE(RRectBatch) {
2331 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random);
2332 GrColor color = GrRandomColor(random);
2333 const SkRRect& rrect = GrTest::TestRRectSimple(random);
2334
2335 static GrIndexBuffer* gStrokeRRectIndexBuffer;
2336 static GrIndexBuffer* gRRectIndexBuffer;
2337 SkRect bounds;
2338 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random) , &bounds,
2339 &gStrokeRRectIndexBuffer, &gRRectIndexBuffer, cont ext->getGpu());
2340 }
2341
2342 #endif
OLDNEW
« no previous file with comments | « src/gpu/GrOvalRenderer.h ('k') | src/gpu/GrTestUtils.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698