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

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

Powered by Google App Engine
This is Rietveld 408576698