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 726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
737 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 737 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
738 // everywhere we can remove this nastiness | 738 // everywhere we can remove this nastiness |
739 GrPipelineInfo init; | 739 GrPipelineInfo init; |
740 init.fColorIgnored = fBatch.fColorIgnored; | 740 init.fColorIgnored = fBatch.fColorIgnored; |
741 init.fOverrideColor = GrColor_ILLEGAL; | 741 init.fOverrideColor = GrColor_ILLEGAL; |
742 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 742 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
743 init.fUsesLocalCoords = this->usesLocalCoords(); | 743 init.fUsesLocalCoords = this->usesLocalCoords(); |
744 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 744 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
745 | 745 |
746 int instanceCount = fGeoData.count(); | 746 int instanceCount = fGeoData.count(); |
| 747 int vertexCount = kVertsPerCircle * instanceCount; |
747 size_t vertexStride = gp->getVertexStride(); | 748 size_t vertexStride = gp->getVertexStride(); |
748 SkASSERT(vertexStride == sizeof(CircleVertex)); | 749 SkASSERT(vertexStride == sizeof(CircleVertex)); |
749 QuadHelper helper; | 750 |
750 CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchT
arget, vertexStride, | 751 SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
751 instan
ceCount)); | 752 batchTarget->resourceProvider()->refQuadIndexBuffer()); |
752 if (!verts) { | 753 const GrVertexBuffer* vertexBuffer; |
| 754 int firstVertex; |
| 755 |
| 756 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
| 757 vertexCount, |
| 758 &vertexBuffer, |
| 759 &firstVertex); |
| 760 |
| 761 if (!vertices || !indexBuffer) { |
| 762 SkDebugf("Could not allocate buffers\n"); |
753 return; | 763 return; |
754 } | 764 } |
755 | 765 |
| 766 CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); |
| 767 |
756 for (int i = 0; i < instanceCount; i++) { | 768 for (int i = 0; i < instanceCount; i++) { |
757 Geometry& geom = fGeoData[i]; | 769 Geometry& args = fGeoData[i]; |
758 | 770 |
759 SkScalar innerRadius = geom.fInnerRadius; | 771 SkScalar innerRadius = args.fInnerRadius; |
760 SkScalar outerRadius = geom.fOuterRadius; | 772 SkScalar outerRadius = args.fOuterRadius; |
761 | 773 |
762 const SkRect& bounds = geom.fDevBounds; | 774 const SkRect& bounds = args.fDevBounds; |
763 | 775 |
764 // The inner radius in the vertex data must be specified in normaliz
ed space. | 776 // The inner radius in the vertex data must be specified in normaliz
ed space. |
765 innerRadius = innerRadius / outerRadius; | 777 innerRadius = innerRadius / outerRadius; |
766 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); | 778 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); |
767 verts[0].fOffset = SkPoint::Make(-1, -1); | 779 verts[0].fOffset = SkPoint::Make(-1, -1); |
768 verts[0].fOuterRadius = outerRadius; | 780 verts[0].fOuterRadius = outerRadius; |
769 verts[0].fInnerRadius = innerRadius; | 781 verts[0].fInnerRadius = innerRadius; |
770 | 782 |
771 verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); | 783 verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); |
772 verts[1].fOffset = SkPoint::Make(-1, 1); | 784 verts[1].fOffset = SkPoint::Make(-1, 1); |
773 verts[1].fOuterRadius = outerRadius; | 785 verts[1].fOuterRadius = outerRadius; |
774 verts[1].fInnerRadius = innerRadius; | 786 verts[1].fInnerRadius = innerRadius; |
775 | 787 |
776 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); | 788 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); |
777 verts[2].fOffset = SkPoint::Make(1, 1); | 789 verts[2].fOffset = SkPoint::Make(1, 1); |
778 verts[2].fOuterRadius = outerRadius; | 790 verts[2].fOuterRadius = outerRadius; |
779 verts[2].fInnerRadius = innerRadius; | 791 verts[2].fInnerRadius = innerRadius; |
780 | 792 |
781 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 793 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
782 verts[3].fOffset = SkPoint::Make(1, -1); | 794 verts[3].fOffset = SkPoint::Make(1, -1); |
783 verts[3].fOuterRadius = outerRadius; | 795 verts[3].fOuterRadius = outerRadius; |
784 verts[3].fInnerRadius = innerRadius; | 796 verts[3].fInnerRadius = innerRadius; |
785 | 797 |
786 verts += kVerticesPerQuad; | 798 verts += kVertsPerCircle; |
787 } | 799 } |
788 helper.issueDraws(batchTarget); | 800 |
| 801 GrDrawTarget::DrawInfo drawInfo; |
| 802 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 803 drawInfo.setStartVertex(0); |
| 804 drawInfo.setStartIndex(0); |
| 805 drawInfo.setVerticesPerInstance(kVertsPerCircle); |
| 806 drawInfo.setIndicesPerInstance(kIndicesPerCircle); |
| 807 drawInfo.adjustStartVertex(firstVertex); |
| 808 drawInfo.setVertexBuffer(vertexBuffer); |
| 809 drawInfo.setIndexBuffer(indexBuffer); |
| 810 |
| 811 int maxInstancesPerDraw = indexBuffer->maxQuads(); |
| 812 |
| 813 while (instanceCount) { |
| 814 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
| 815 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
| 816 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
| 817 |
| 818 batchTarget->draw(drawInfo); |
| 819 |
| 820 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
| 821 instanceCount -= drawInfo.instanceCount(); |
| 822 } |
789 } | 823 } |
790 | 824 |
791 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 825 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
792 | 826 |
793 private: | 827 private: |
794 CircleBatch(const Geometry& geometry) { | 828 CircleBatch(const Geometry& geometry) { |
795 this->initClassID<CircleBatch>(); | 829 this->initClassID<CircleBatch>(); |
796 fGeoData.push_back(geometry); | 830 fGeoData.push_back(geometry); |
797 | 831 |
798 this->setBounds(geometry.fDevBounds); | 832 this->setBounds(geometry.fDevBounds); |
(...skipping 27 matching lines...) Expand all Loading... |
826 bool stroke() const { return fBatch.fStroke; } | 860 bool stroke() const { return fBatch.fStroke; } |
827 | 861 |
828 struct BatchTracker { | 862 struct BatchTracker { |
829 GrColor fColor; | 863 GrColor fColor; |
830 bool fStroke; | 864 bool fStroke; |
831 bool fUsesLocalCoords; | 865 bool fUsesLocalCoords; |
832 bool fColorIgnored; | 866 bool fColorIgnored; |
833 bool fCoverageIgnored; | 867 bool fCoverageIgnored; |
834 }; | 868 }; |
835 | 869 |
| 870 static const int kVertsPerCircle = 4; |
| 871 static const int kIndicesPerCircle = 6; |
| 872 |
836 BatchTracker fBatch; | 873 BatchTracker fBatch; |
837 SkSTArray<1, Geometry, true> fGeoData; | 874 SkSTArray<1, Geometry, true> fGeoData; |
838 }; | 875 }; |
839 | 876 |
840 static GrBatch* create_circle_batch(GrColor color, | 877 static GrBatch* create_circle_batch(GrColor color, |
841 const SkMatrix& viewMatrix, | 878 const SkMatrix& viewMatrix, |
842 bool useCoverageAA, | 879 bool useCoverageAA, |
843 const SkRect& circle, | 880 const SkRect& circle, |
844 const SkStrokeRec& stroke, | 881 const SkStrokeRec& stroke, |
845 SkRect* bounds) { | 882 SkRect* bounds) { |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 1002 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
966 // everywhere we can remove this nastiness | 1003 // everywhere we can remove this nastiness |
967 GrPipelineInfo init; | 1004 GrPipelineInfo init; |
968 init.fColorIgnored = fBatch.fColorIgnored; | 1005 init.fColorIgnored = fBatch.fColorIgnored; |
969 init.fOverrideColor = GrColor_ILLEGAL; | 1006 init.fOverrideColor = GrColor_ILLEGAL; |
970 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1007 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
971 init.fUsesLocalCoords = this->usesLocalCoords(); | 1008 init.fUsesLocalCoords = this->usesLocalCoords(); |
972 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1009 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
973 | 1010 |
974 int instanceCount = fGeoData.count(); | 1011 int instanceCount = fGeoData.count(); |
975 QuadHelper helper; | 1012 int vertexCount = kVertsPerEllipse * instanceCount; |
976 size_t vertexStride = gp->getVertexStride(); | 1013 size_t vertexStride = gp->getVertexStride(); |
977 SkASSERT(vertexStride == sizeof(EllipseVertex)); | 1014 SkASSERT(vertexStride == sizeof(EllipseVertex)); |
978 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( | 1015 |
979 helper.init(batchTarget, vertexStride, instanceCount)); | 1016 const GrVertexBuffer* vertexBuffer; |
980 if (!verts) { | 1017 SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
| 1018 batchTarget->resourceProvider()->refQuadIndexBuffer()); |
| 1019 int firstVertex; |
| 1020 |
| 1021 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
| 1022 vertexCount, |
| 1023 &vertexBuffer, |
| 1024 &firstVertex); |
| 1025 |
| 1026 if (!vertices || !indexBuffer) { |
| 1027 SkDebugf("Could not allocate buffers\n"); |
981 return; | 1028 return; |
982 } | 1029 } |
983 | 1030 |
| 1031 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); |
| 1032 |
984 for (int i = 0; i < instanceCount; i++) { | 1033 for (int i = 0; i < instanceCount; i++) { |
985 Geometry& geom = fGeoData[i]; | 1034 Geometry& args = fGeoData[i]; |
986 | 1035 |
987 SkScalar xRadius = geom.fXRadius; | 1036 SkScalar xRadius = args.fXRadius; |
988 SkScalar yRadius = geom.fYRadius; | 1037 SkScalar yRadius = args.fYRadius; |
989 | 1038 |
990 // Compute the reciprocals of the radii here to save time in the sha
der | 1039 // Compute the reciprocals of the radii here to save time in the sha
der |
991 SkScalar xRadRecip = SkScalarInvert(xRadius); | 1040 SkScalar xRadRecip = SkScalarInvert(xRadius); |
992 SkScalar yRadRecip = SkScalarInvert(yRadius); | 1041 SkScalar yRadRecip = SkScalarInvert(yRadius); |
993 SkScalar xInnerRadRecip = SkScalarInvert(geom.fInnerXRadius); | 1042 SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius); |
994 SkScalar yInnerRadRecip = SkScalarInvert(geom.fInnerYRadius); | 1043 SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); |
995 | 1044 |
996 const SkRect& bounds = geom.fDevBounds; | 1045 const SkRect& bounds = args.fDevBounds; |
997 | 1046 |
998 // The inner radius in the vertex data must be specified in normaliz
ed space. | 1047 // The inner radius in the vertex data must be specified in normaliz
ed space. |
999 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); | 1048 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); |
1000 verts[0].fOffset = SkPoint::Make(-xRadius, -yRadius); | 1049 verts[0].fOffset = SkPoint::Make(-xRadius, -yRadius); |
1001 verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 1050 verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1002 verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; | 1051 verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; |
1003 | 1052 |
1004 verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); | 1053 verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); |
1005 verts[1].fOffset = SkPoint::Make(-xRadius, yRadius); | 1054 verts[1].fOffset = SkPoint::Make(-xRadius, yRadius); |
1006 verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 1055 verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1007 verts[1].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; | 1056 verts[1].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; |
1008 | 1057 |
1009 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); | 1058 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); |
1010 verts[2].fOffset = SkPoint::Make(xRadius, yRadius); | 1059 verts[2].fOffset = SkPoint::Make(xRadius, yRadius); |
1011 verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 1060 verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1012 verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; | 1061 verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; |
1013 | 1062 |
1014 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 1063 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
1015 verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); | 1064 verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); |
1016 verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 1065 verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1017 verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; | 1066 verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; |
1018 | 1067 |
1019 verts += kVerticesPerQuad; | 1068 verts += kVertsPerEllipse; |
1020 } | 1069 } |
1021 helper.issueDraws(batchTarget); | 1070 |
| 1071 GrDrawTarget::DrawInfo drawInfo; |
| 1072 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 1073 drawInfo.setStartVertex(0); |
| 1074 drawInfo.setStartIndex(0); |
| 1075 drawInfo.setVerticesPerInstance(kVertsPerEllipse); |
| 1076 drawInfo.setIndicesPerInstance(kIndicesPerEllipse); |
| 1077 drawInfo.adjustStartVertex(firstVertex); |
| 1078 drawInfo.setVertexBuffer(vertexBuffer); |
| 1079 drawInfo.setIndexBuffer(indexBuffer); |
| 1080 |
| 1081 int maxInstancesPerDraw = indexBuffer->maxQuads(); |
| 1082 |
| 1083 while (instanceCount) { |
| 1084 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
| 1085 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
| 1086 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
| 1087 |
| 1088 batchTarget->draw(drawInfo); |
| 1089 |
| 1090 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
| 1091 instanceCount -= drawInfo.instanceCount(); |
| 1092 } |
1022 } | 1093 } |
1023 | 1094 |
1024 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 1095 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
1025 | 1096 |
1026 private: | 1097 private: |
1027 EllipseBatch(const Geometry& geometry) { | 1098 EllipseBatch(const Geometry& geometry) { |
1028 this->initClassID<EllipseBatch>(); | 1099 this->initClassID<EllipseBatch>(); |
1029 fGeoData.push_back(geometry); | 1100 fGeoData.push_back(geometry); |
1030 | 1101 |
1031 this->setBounds(geometry.fDevBounds); | 1102 this->setBounds(geometry.fDevBounds); |
(...skipping 27 matching lines...) Expand all Loading... |
1059 bool stroke() const { return fBatch.fStroke; } | 1130 bool stroke() const { return fBatch.fStroke; } |
1060 | 1131 |
1061 struct BatchTracker { | 1132 struct BatchTracker { |
1062 GrColor fColor; | 1133 GrColor fColor; |
1063 bool fStroke; | 1134 bool fStroke; |
1064 bool fUsesLocalCoords; | 1135 bool fUsesLocalCoords; |
1065 bool fColorIgnored; | 1136 bool fColorIgnored; |
1066 bool fCoverageIgnored; | 1137 bool fCoverageIgnored; |
1067 }; | 1138 }; |
1068 | 1139 |
| 1140 static const int kVertsPerEllipse = 4; |
| 1141 static const int kIndicesPerEllipse = 6; |
| 1142 |
1069 BatchTracker fBatch; | 1143 BatchTracker fBatch; |
1070 SkSTArray<1, Geometry, true> fGeoData; | 1144 SkSTArray<1, Geometry, true> fGeoData; |
1071 }; | 1145 }; |
1072 | 1146 |
1073 static GrBatch* create_ellipse_batch(GrColor color, | 1147 static GrBatch* create_ellipse_batch(GrColor color, |
1074 const SkMatrix& viewMatrix, | 1148 const SkMatrix& viewMatrix, |
1075 bool useCoverageAA, | 1149 bool useCoverageAA, |
1076 const SkRect& ellipse, | 1150 const SkRect& ellipse, |
1077 const SkStrokeRec& stroke, | 1151 const SkStrokeRec& stroke, |
1078 SkRect* bounds) { | 1152 SkRect* bounds) { |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 // TODO this is hacky, but the only way we have to initialize the GP is
to use the | 1310 // TODO this is hacky, but the only way we have to initialize the GP is
to use the |
1237 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 1311 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
1238 // everywhere we can remove this nastiness | 1312 // everywhere we can remove this nastiness |
1239 GrPipelineInfo init; | 1313 GrPipelineInfo init; |
1240 init.fColorIgnored = fBatch.fColorIgnored; | 1314 init.fColorIgnored = fBatch.fColorIgnored; |
1241 init.fOverrideColor = GrColor_ILLEGAL; | 1315 init.fOverrideColor = GrColor_ILLEGAL; |
1242 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1316 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1243 init.fUsesLocalCoords = this->usesLocalCoords(); | 1317 init.fUsesLocalCoords = this->usesLocalCoords(); |
1244 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1318 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1245 | 1319 |
| 1320 SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
| 1321 batchTarget->resourceProvider()->refQuadIndexBuffer()); |
| 1322 |
1246 int instanceCount = fGeoData.count(); | 1323 int instanceCount = fGeoData.count(); |
| 1324 int vertexCount = kVertsPerEllipse * instanceCount; |
1247 size_t vertexStride = gp->getVertexStride(); | 1325 size_t vertexStride = gp->getVertexStride(); |
1248 SkASSERT(vertexStride == sizeof(DIEllipseVertex)); | 1326 SkASSERT(vertexStride == sizeof(DIEllipseVertex)); |
1249 QuadHelper helper; | 1327 const GrVertexBuffer* vertexBuffer; |
1250 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>( | 1328 int firstVertex; |
1251 helper.init(batchTarget, vertexStride, instanceCount)); | 1329 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1252 if (!verts) { | 1330 vertexCount, |
| 1331 &vertexBuffer, |
| 1332 &firstVertex); |
| 1333 |
| 1334 if (!vertices || !indexBuffer) { |
| 1335 SkDebugf("Could not allocate buffers\n"); |
1253 return; | 1336 return; |
1254 } | 1337 } |
1255 | 1338 |
| 1339 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices); |
| 1340 |
1256 for (int i = 0; i < instanceCount; i++) { | 1341 for (int i = 0; i < instanceCount; i++) { |
1257 Geometry& geom = fGeoData[i]; | 1342 Geometry& args = fGeoData[i]; |
1258 | 1343 |
1259 SkScalar xRadius = geom.fXRadius; | 1344 SkScalar xRadius = args.fXRadius; |
1260 SkScalar yRadius = geom.fYRadius; | 1345 SkScalar yRadius = args.fYRadius; |
1261 | 1346 |
1262 const SkRect& bounds = geom.fBounds; | 1347 const SkRect& bounds = args.fBounds; |
1263 | 1348 |
1264 // This adjusts the "radius" to include the half-pixel border | 1349 // This adjusts the "radius" to include the half-pixel border |
1265 SkScalar offsetDx = SkScalarDiv(geom.fGeoDx, xRadius); | 1350 SkScalar offsetDx = SkScalarDiv(args.fGeoDx, xRadius); |
1266 SkScalar offsetDy = SkScalarDiv(geom.fGeoDy, yRadius); | 1351 SkScalar offsetDy = SkScalarDiv(args.fGeoDy, yRadius); |
1267 | 1352 |
1268 SkScalar innerRatioX = SkScalarDiv(xRadius, geom.fInnerXRadius); | 1353 SkScalar innerRatioX = SkScalarDiv(xRadius, args.fInnerXRadius); |
1269 SkScalar innerRatioY = SkScalarDiv(yRadius, geom.fInnerYRadius); | 1354 SkScalar innerRatioY = SkScalarDiv(yRadius, args.fInnerYRadius); |
1270 | 1355 |
1271 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); | 1356 verts[0].fPos = SkPoint::Make(bounds.fLeft, bounds.fTop); |
1272 verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offs
etDy); | 1357 verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offs
etDy); |
1273 verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -inne
rRatioY - offsetDy); | 1358 verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -inne
rRatioY - offsetDy); |
1274 | 1359 |
1275 verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); | 1360 verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom); |
1276 verts[1].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offse
tDy); | 1361 verts[1].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offse
tDy); |
1277 verts[1].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, inner
RatioY + offsetDy); | 1362 verts[1].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, inner
RatioY + offsetDy); |
1278 | 1363 |
1279 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); | 1364 verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom); |
1280 verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offset
Dy); | 1365 verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offset
Dy); |
1281 verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerR
atioY + offsetDy); | 1366 verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerR
atioY + offsetDy); |
1282 | 1367 |
1283 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 1368 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
1284 verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offse
tDy); | 1369 verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offse
tDy); |
1285 verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -inner
RatioY - offsetDy); | 1370 verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -inner
RatioY - offsetDy); |
1286 | 1371 |
1287 verts += kVerticesPerQuad; | 1372 verts += kVertsPerEllipse; |
1288 } | 1373 } |
1289 helper.issueDraws(batchTarget); | 1374 |
| 1375 GrDrawTarget::DrawInfo drawInfo; |
| 1376 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 1377 drawInfo.setStartVertex(0); |
| 1378 drawInfo.setStartIndex(0); |
| 1379 drawInfo.setVerticesPerInstance(kVertsPerEllipse); |
| 1380 drawInfo.setIndicesPerInstance(kIndicesPerEllipse); |
| 1381 drawInfo.adjustStartVertex(firstVertex); |
| 1382 drawInfo.setVertexBuffer(vertexBuffer); |
| 1383 drawInfo.setIndexBuffer(indexBuffer); |
| 1384 |
| 1385 int maxInstancesPerDraw = indexBuffer->maxQuads(); |
| 1386 |
| 1387 while (instanceCount) { |
| 1388 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
| 1389 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
| 1390 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
| 1391 |
| 1392 batchTarget->draw(drawInfo); |
| 1393 |
| 1394 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
| 1395 instanceCount -= drawInfo.instanceCount(); |
| 1396 } |
1290 } | 1397 } |
1291 | 1398 |
1292 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 1399 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
1293 | 1400 |
1294 private: | 1401 private: |
1295 DIEllipseBatch(const Geometry& geometry, const SkRect& bounds) { | 1402 DIEllipseBatch(const Geometry& geometry, const SkRect& bounds) { |
1296 this->initClassID<DIEllipseBatch>(); | 1403 this->initClassID<DIEllipseBatch>(); |
1297 fGeoData.push_back(geometry); | 1404 fGeoData.push_back(geometry); |
1298 | 1405 |
1299 this->setBounds(bounds); | 1406 this->setBounds(bounds); |
(...skipping 27 matching lines...) Expand all Loading... |
1327 DIEllipseEdgeEffect::Mode mode() const { return fBatch.fMode; } | 1434 DIEllipseEdgeEffect::Mode mode() const { return fBatch.fMode; } |
1328 | 1435 |
1329 struct BatchTracker { | 1436 struct BatchTracker { |
1330 GrColor fColor; | 1437 GrColor fColor; |
1331 DIEllipseEdgeEffect::Mode fMode; | 1438 DIEllipseEdgeEffect::Mode fMode; |
1332 bool fUsesLocalCoords; | 1439 bool fUsesLocalCoords; |
1333 bool fColorIgnored; | 1440 bool fColorIgnored; |
1334 bool fCoverageIgnored; | 1441 bool fCoverageIgnored; |
1335 }; | 1442 }; |
1336 | 1443 |
| 1444 static const int kVertsPerEllipse = 4; |
| 1445 static const int kIndicesPerEllipse = 6; |
| 1446 |
1337 BatchTracker fBatch; | 1447 BatchTracker fBatch; |
1338 SkSTArray<1, Geometry, true> fGeoData; | 1448 SkSTArray<1, Geometry, true> fGeoData; |
1339 }; | 1449 }; |
1340 | 1450 |
1341 static GrBatch* create_diellipse_batch(GrColor color, | 1451 static GrBatch* create_diellipse_batch(GrColor color, |
1342 const SkMatrix& viewMatrix, | 1452 const SkMatrix& viewMatrix, |
1343 bool useCoverageAA, | 1453 bool useCoverageAA, |
1344 const SkRect& ellipse, | 1454 const SkRect& ellipse, |
1345 const SkStrokeRec& stroke, | 1455 const SkStrokeRec& stroke, |
1346 SkRect* bounds) { | 1456 SkRect* bounds) { |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 1715 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
1606 // everywhere we can remove this nastiness | 1716 // everywhere we can remove this nastiness |
1607 GrPipelineInfo init; | 1717 GrPipelineInfo init; |
1608 init.fColorIgnored = fBatch.fColorIgnored; | 1718 init.fColorIgnored = fBatch.fColorIgnored; |
1609 init.fOverrideColor = GrColor_ILLEGAL; | 1719 init.fOverrideColor = GrColor_ILLEGAL; |
1610 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1720 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1611 init.fUsesLocalCoords = this->usesLocalCoords(); | 1721 init.fUsesLocalCoords = this->usesLocalCoords(); |
1612 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1722 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1613 | 1723 |
1614 int instanceCount = fGeoData.count(); | 1724 int instanceCount = fGeoData.count(); |
| 1725 int vertexCount = kVertsPerRRect * instanceCount; |
1615 size_t vertexStride = gp->getVertexStride(); | 1726 size_t vertexStride = gp->getVertexStride(); |
1616 SkASSERT(vertexStride == sizeof(CircleVertex)); | 1727 SkASSERT(vertexStride == sizeof(CircleVertex)); |
1617 | 1728 |
1618 // drop out the middle quad if we're stroked | 1729 const GrVertexBuffer* vertexBuffer; |
1619 int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndi
cesPerRRect; | |
1620 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | 1730 SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
1621 ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider
())); | 1731 ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider
())); |
| 1732 int firstVertex; |
1622 | 1733 |
1623 InstancedHelper helper; | 1734 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1624 CircleVertex* verts = reinterpret_cast<CircleVertex*>(helper.init(batchT
arget, | 1735 vertexCount, |
1625 vertexStride, indexBuffer, kVertsPerRRect, indicesPerInstance, insta
nceCount)); | 1736 &vertexBuffer, |
1626 if (!verts || !indexBuffer) { | 1737 &firstVertex); |
| 1738 |
| 1739 if (!vertices || !indexBuffer) { |
1627 SkDebugf("Could not allocate vertices\n"); | 1740 SkDebugf("Could not allocate vertices\n"); |
1628 return; | 1741 return; |
1629 } | 1742 } |
1630 | 1743 |
| 1744 CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); |
| 1745 |
1631 for (int i = 0; i < instanceCount; i++) { | 1746 for (int i = 0; i < instanceCount; i++) { |
1632 Geometry& args = fGeoData[i]; | 1747 Geometry& args = fGeoData[i]; |
1633 | 1748 |
1634 SkScalar outerRadius = args.fOuterRadius; | 1749 SkScalar outerRadius = args.fOuterRadius; |
1635 | 1750 |
1636 const SkRect& bounds = args.fDevBounds; | 1751 const SkRect& bounds = args.fDevBounds; |
1637 | 1752 |
1638 SkScalar yCoords[4] = { | 1753 SkScalar yCoords[4] = { |
1639 bounds.fTop, | 1754 bounds.fTop, |
1640 bounds.fTop + outerRadius, | 1755 bounds.fTop + outerRadius, |
(...skipping 24 matching lines...) Expand all Loading... |
1665 verts++; | 1780 verts++; |
1666 | 1781 |
1667 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); | 1782 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); |
1668 verts->fOffset = SkPoint::Make(1, yOuterRadii[i]); | 1783 verts->fOffset = SkPoint::Make(1, yOuterRadii[i]); |
1669 verts->fOuterRadius = outerRadius; | 1784 verts->fOuterRadius = outerRadius; |
1670 verts->fInnerRadius = innerRadius; | 1785 verts->fInnerRadius = innerRadius; |
1671 verts++; | 1786 verts++; |
1672 } | 1787 } |
1673 } | 1788 } |
1674 | 1789 |
1675 helper.issueDraws(batchTarget); | 1790 // drop out the middle quad if we're stroked |
| 1791 int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
| 1792 SK_ARRAY_COUNT(gRRectIndices); |
| 1793 |
| 1794 GrDrawTarget::DrawInfo drawInfo; |
| 1795 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 1796 drawInfo.setStartVertex(0); |
| 1797 drawInfo.setStartIndex(0); |
| 1798 drawInfo.setVerticesPerInstance(kVertsPerRRect); |
| 1799 drawInfo.setIndicesPerInstance(indexCnt); |
| 1800 drawInfo.adjustStartVertex(firstVertex); |
| 1801 drawInfo.setVertexBuffer(vertexBuffer); |
| 1802 drawInfo.setIndexBuffer(indexBuffer); |
| 1803 |
| 1804 int maxInstancesPerDraw = kNumRRectsInIndexBuffer; |
| 1805 |
| 1806 while (instanceCount) { |
| 1807 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
| 1808 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
| 1809 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
| 1810 |
| 1811 batchTarget->draw(drawInfo); |
| 1812 |
| 1813 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
| 1814 instanceCount -= drawInfo.instanceCount(); |
| 1815 } |
1676 } | 1816 } |
1677 | 1817 |
1678 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 1818 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
1679 | 1819 |
1680 private: | 1820 private: |
1681 RRectCircleRendererBatch(const Geometry& geometry) { | 1821 RRectCircleRendererBatch(const Geometry& geometry) { |
1682 this->initClassID<RRectCircleRendererBatch>(); | 1822 this->initClassID<RRectCircleRendererBatch>(); |
1683 fGeoData.push_back(geometry); | 1823 fGeoData.push_back(geometry); |
1684 | 1824 |
1685 this->setBounds(geometry.fDevBounds); | 1825 this->setBounds(geometry.fDevBounds); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1786 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 1926 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
1787 // everywhere we can remove this nastiness | 1927 // everywhere we can remove this nastiness |
1788 GrPipelineInfo init; | 1928 GrPipelineInfo init; |
1789 init.fColorIgnored = fBatch.fColorIgnored; | 1929 init.fColorIgnored = fBatch.fColorIgnored; |
1790 init.fOverrideColor = GrColor_ILLEGAL; | 1930 init.fOverrideColor = GrColor_ILLEGAL; |
1791 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1931 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1792 init.fUsesLocalCoords = this->usesLocalCoords(); | 1932 init.fUsesLocalCoords = this->usesLocalCoords(); |
1793 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1933 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1794 | 1934 |
1795 int instanceCount = fGeoData.count(); | 1935 int instanceCount = fGeoData.count(); |
| 1936 int vertexCount = kVertsPerRRect * instanceCount; |
1796 size_t vertexStride = gp->getVertexStride(); | 1937 size_t vertexStride = gp->getVertexStride(); |
1797 SkASSERT(vertexStride == sizeof(EllipseVertex)); | 1938 SkASSERT(vertexStride == sizeof(EllipseVertex)); |
1798 | 1939 |
1799 // drop out the middle quad if we're stroked | 1940 const GrVertexBuffer* vertexBuffer; |
1800 int indicesPerInstance = this->stroke() ? kIndicesPerStrokeRRect : kIndi
cesPerRRect; | |
1801 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | 1941 SkAutoTUnref<const GrIndexBuffer> indexBuffer( |
1802 ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider
())); | 1942 ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider
())); |
| 1943 int firstVertex; |
1803 | 1944 |
1804 InstancedHelper helper; | 1945 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1805 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>( | 1946 vertexCount, |
1806 helper.init(batchTarget, vertexStride, indexBuffer, kVertsPerRRect,
indicesPerInstance, | 1947 &vertexBuffer, |
1807 instanceCount)); | 1948 &firstVertex); |
1808 if (!verts || !indexBuffer) { | 1949 |
| 1950 if (!vertices || !indexBuffer) { |
1809 SkDebugf("Could not allocate vertices\n"); | 1951 SkDebugf("Could not allocate vertices\n"); |
1810 return; | 1952 return; |
1811 } | 1953 } |
1812 | 1954 |
| 1955 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); |
| 1956 |
1813 for (int i = 0; i < instanceCount; i++) { | 1957 for (int i = 0; i < instanceCount; i++) { |
1814 Geometry& args = fGeoData[i]; | 1958 Geometry& args = fGeoData[i]; |
1815 | 1959 |
1816 // Compute the reciprocals of the radii here to save time in the sha
der | 1960 // Compute the reciprocals of the radii here to save time in the sha
der |
1817 SkScalar xRadRecip = SkScalarInvert(args.fXRadius); | 1961 SkScalar xRadRecip = SkScalarInvert(args.fXRadius); |
1818 SkScalar yRadRecip = SkScalarInvert(args.fYRadius); | 1962 SkScalar yRadRecip = SkScalarInvert(args.fYRadius); |
1819 SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius); | 1963 SkScalar xInnerRadRecip = SkScalarInvert(args.fInnerXRadius); |
1820 SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); | 1964 SkScalar yInnerRadRecip = SkScalarInvert(args.fInnerYRadius); |
1821 | 1965 |
1822 // Extend the radii out half a pixel to antialias. | 1966 // Extend the radii out half a pixel to antialias. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1857 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadReci
p); | 2001 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadReci
p); |
1858 verts++; | 2002 verts++; |
1859 | 2003 |
1860 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); | 2004 verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]); |
1861 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); | 2005 verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]); |
1862 verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 2006 verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1863 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadReci
p); | 2007 verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadReci
p); |
1864 verts++; | 2008 verts++; |
1865 } | 2009 } |
1866 } | 2010 } |
1867 helper.issueDraws(batchTarget); | 2011 |
| 2012 // drop out the middle quad if we're stroked |
| 2013 int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
| 2014 SK_ARRAY_COUNT(gRRectIndices); |
| 2015 |
| 2016 GrDrawTarget::DrawInfo drawInfo; |
| 2017 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 2018 drawInfo.setStartVertex(0); |
| 2019 drawInfo.setStartIndex(0); |
| 2020 drawInfo.setVerticesPerInstance(kVertsPerRRect); |
| 2021 drawInfo.setIndicesPerInstance(indexCnt); |
| 2022 drawInfo.adjustStartVertex(firstVertex); |
| 2023 drawInfo.setVertexBuffer(vertexBuffer); |
| 2024 drawInfo.setIndexBuffer(indexBuffer); |
| 2025 |
| 2026 int maxInstancesPerDraw = kNumRRectsInIndexBuffer; |
| 2027 |
| 2028 while (instanceCount) { |
| 2029 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
| 2030 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
| 2031 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
| 2032 |
| 2033 batchTarget->draw(drawInfo); |
| 2034 |
| 2035 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
| 2036 instanceCount -= drawInfo.instanceCount(); |
| 2037 } |
1868 } | 2038 } |
1869 | 2039 |
1870 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 2040 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
1871 | 2041 |
1872 private: | 2042 private: |
1873 RRectEllipseRendererBatch(const Geometry& geometry) { | 2043 RRectEllipseRendererBatch(const Geometry& geometry) { |
1874 this->initClassID<RRectEllipseRendererBatch>(); | 2044 this->initClassID<RRectEllipseRendererBatch>(); |
1875 fGeoData.push_back(geometry); | 2045 fGeoData.push_back(geometry); |
1876 | 2046 |
1877 this->setBounds(geometry.fDevBounds); | 2047 this->setBounds(geometry.fDevBounds); |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2145 BATCH_TEST_DEFINE(RRectBatch) { | 2315 BATCH_TEST_DEFINE(RRectBatch) { |
2146 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); | 2316 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
2147 GrColor color = GrRandomColor(random); | 2317 GrColor color = GrRandomColor(random); |
2148 const SkRRect& rrect = GrTest::TestRRectSimple(random); | 2318 const SkRRect& rrect = GrTest::TestRRectSimple(random); |
2149 | 2319 |
2150 SkRect bounds; | 2320 SkRect bounds; |
2151 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random)
, &bounds); | 2321 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random)
, &bounds); |
2152 } | 2322 } |
2153 | 2323 |
2154 #endif | 2324 #endif |
OLD | NEW |