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" |
11 #include "GrBatchTarget.h" | 11 #include "GrBatchTarget.h" |
12 #include "GrBatchTest.h" | 12 #include "GrBatchTest.h" |
13 #include "GrBufferAllocPool.h" | 13 #include "GrBufferAllocPool.h" |
14 #include "GrDrawTarget.h" | 14 #include "GrDrawTarget.h" |
15 #include "GrGeometryProcessor.h" | 15 #include "GrGeometryProcessor.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 "GrResourceProvider.h" | |
20 #include "GrVertexBuffer.h" | 20 #include "GrVertexBuffer.h" |
21 #include "SkRRect.h" | 21 #include "SkRRect.h" |
22 #include "SkStrokeRec.h" | 22 #include "SkStrokeRec.h" |
23 #include "SkTLazy.h" | 23 #include "SkTLazy.h" |
24 #include "effects/GrRRectEffect.h" | 24 #include "effects/GrRRectEffect.h" |
25 #include "gl/GrGLProcessor.h" | 25 #include "gl/GrGLProcessor.h" |
26 #include "gl/GrGLSL.h" | 26 #include "gl/GrGLSL.h" |
27 #include "gl/GrGLGeometryProcessor.h" | 27 #include "gl/GrGLGeometryProcessor.h" |
28 #include "gl/builders/GrGLProgramBuilder.h" | 28 #include "gl/builders/GrGLProgramBuilder.h" |
29 | 29 |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 GrContext* context, | 639 GrContext* context, |
640 const GrDrawTargetCaps&, | 640 const GrDrawTargetCaps&, |
641 GrTexture* textures[]) { | 641 GrTexture* textures[]) { |
642 return DIEllipseEdgeEffect::Create(GrRandomColor(random), | 642 return DIEllipseEdgeEffect::Create(GrRandomColor(random), |
643 GrTest::TestMatrix(random), | 643 GrTest::TestMatrix(random), |
644 (Mode)(random->nextRangeU(0,2))); | 644 (Mode)(random->nextRangeU(0,2))); |
645 } | 645 } |
646 | 646 |
647 /////////////////////////////////////////////////////////////////////////////// | 647 /////////////////////////////////////////////////////////////////////////////// |
648 | 648 |
| 649 void GrOvalRenderer::reset() { |
| 650 SkSafeSetNull(fRRectIndexBuffer); |
| 651 SkSafeSetNull(fStrokeRRectIndexBuffer); |
| 652 } |
| 653 |
649 bool GrOvalRenderer::drawOval(GrDrawTarget* target, | 654 bool GrOvalRenderer::drawOval(GrDrawTarget* target, |
650 GrPipelineBuilder* pipelineBuilder, | 655 GrPipelineBuilder* pipelineBuilder, |
651 GrColor color, | 656 GrColor color, |
652 const SkMatrix& viewMatrix, | 657 const SkMatrix& viewMatrix, |
653 bool useAA, | 658 bool useAA, |
654 const SkRect& oval, | 659 const SkRect& oval, |
655 const SkStrokeRec& stroke) | 660 const SkStrokeRec& stroke) |
656 { | 661 { |
657 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisa
mpled(); | 662 bool useCoverageAA = useAA && |
| 663 !pipelineBuilder->getRenderTarget()->isMultisampled(); |
658 | 664 |
659 if (!useCoverageAA) { | 665 if (!useCoverageAA) { |
660 return false; | 666 return false; |
661 } | 667 } |
662 | 668 |
663 // we can draw circles | 669 // we can draw circles |
664 if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(
viewMatrix)) { | 670 if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(
viewMatrix)) { |
665 this->drawCircle(target, pipelineBuilder, color, viewMatrix, useCoverage
AA, oval, stroke); | 671 this->drawCircle(target, pipelineBuilder, color, viewMatrix, useCoverage
AA, oval, stroke); |
666 // if we have shader derivative support, render as device-independent | 672 // if we have shader derivative support, render as device-independent |
667 } else if (target->caps()->shaderCaps()->shaderDerivativeSupport()) { | 673 } else if (target->caps()->shaderCaps()->shaderDerivativeSupport()) { |
(...skipping 16 matching lines...) Expand all Loading... |
684 public: | 690 public: |
685 struct Geometry { | 691 struct Geometry { |
686 GrColor fColor; | 692 GrColor fColor; |
687 SkMatrix fViewMatrix; | 693 SkMatrix fViewMatrix; |
688 SkScalar fInnerRadius; | 694 SkScalar fInnerRadius; |
689 SkScalar fOuterRadius; | 695 SkScalar fOuterRadius; |
690 bool fStroke; | 696 bool fStroke; |
691 SkRect fDevBounds; | 697 SkRect fDevBounds; |
692 }; | 698 }; |
693 | 699 |
694 static GrBatch* Create(const Geometry& geometry) { return SkNEW_ARGS(CircleB
atch, (geometry)); } | 700 static GrBatch* Create(const Geometry& geometry) { |
| 701 return SkNEW_ARGS(CircleBatch, (geometry)); |
| 702 } |
695 | 703 |
696 const char* name() const override { return "CircleBatch"; } | 704 const char* name() const override { return "CircleBatch"; } |
697 | 705 |
698 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 706 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
699 // When this is called on a batch, there is only one geometry bundle | 707 // When this is called on a batch, there is only one geometry bundle |
700 out->setKnownFourComponents(fGeoData[0].fColor); | 708 out->setKnownFourComponents(fGeoData[0].fColor); |
701 } | 709 } |
702 | 710 |
703 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 711 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
704 out->setUnknownSingleComponent(); | 712 out->setUnknownSingleComponent(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 init.fOverrideColor = GrColor_ILLEGAL; | 749 init.fOverrideColor = GrColor_ILLEGAL; |
742 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 750 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
743 init.fUsesLocalCoords = this->usesLocalCoords(); | 751 init.fUsesLocalCoords = this->usesLocalCoords(); |
744 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 752 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
745 | 753 |
746 int instanceCount = fGeoData.count(); | 754 int instanceCount = fGeoData.count(); |
747 int vertexCount = kVertsPerCircle * instanceCount; | 755 int vertexCount = kVertsPerCircle * instanceCount; |
748 size_t vertexStride = gp->getVertexStride(); | 756 size_t vertexStride = gp->getVertexStride(); |
749 SkASSERT(vertexStride == sizeof(CircleVertex)); | 757 SkASSERT(vertexStride == sizeof(CircleVertex)); |
750 | 758 |
751 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | |
752 batchTarget->resourceProvider()->refQuadIndexBuffer()); | |
753 const GrVertexBuffer* vertexBuffer; | 759 const GrVertexBuffer* vertexBuffer; |
754 int firstVertex; | 760 int firstVertex; |
755 | 761 |
756 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 762 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
757 vertexCount, | 763 vertexCount, |
758 &vertexBuffer, | 764 &vertexBuffer, |
759 &firstVertex); | 765 &firstVertex); |
760 | 766 |
761 if (!vertices || !indexBuffer) { | 767 if (!vertices || !batchTarget->quadIndexBuffer()) { |
762 SkDebugf("Could not allocate buffers\n"); | 768 SkDebugf("Could not allocate buffers\n"); |
763 return; | 769 return; |
764 } | 770 } |
765 | 771 |
766 CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); | 772 CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); |
767 | 773 |
768 for (int i = 0; i < instanceCount; i++) { | 774 for (int i = 0; i < instanceCount; i++) { |
769 Geometry& args = fGeoData[i]; | 775 Geometry& args = fGeoData[i]; |
770 | 776 |
771 SkScalar innerRadius = args.fInnerRadius; | 777 SkScalar innerRadius = args.fInnerRadius; |
(...skipping 19 matching lines...) Expand all Loading... |
791 verts[2].fInnerRadius = innerRadius; | 797 verts[2].fInnerRadius = innerRadius; |
792 | 798 |
793 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 799 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
794 verts[3].fOffset = SkPoint::Make(1, -1); | 800 verts[3].fOffset = SkPoint::Make(1, -1); |
795 verts[3].fOuterRadius = outerRadius; | 801 verts[3].fOuterRadius = outerRadius; |
796 verts[3].fInnerRadius = innerRadius; | 802 verts[3].fInnerRadius = innerRadius; |
797 | 803 |
798 verts += kVertsPerCircle; | 804 verts += kVertsPerCircle; |
799 } | 805 } |
800 | 806 |
| 807 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); |
| 808 |
801 GrDrawTarget::DrawInfo drawInfo; | 809 GrDrawTarget::DrawInfo drawInfo; |
802 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 810 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
803 drawInfo.setStartVertex(0); | 811 drawInfo.setStartVertex(0); |
804 drawInfo.setStartIndex(0); | 812 drawInfo.setStartIndex(0); |
805 drawInfo.setVerticesPerInstance(kVertsPerCircle); | 813 drawInfo.setVerticesPerInstance(kVertsPerCircle); |
806 drawInfo.setIndicesPerInstance(kIndicesPerCircle); | 814 drawInfo.setIndicesPerInstance(kIndicesPerCircle); |
807 drawInfo.adjustStartVertex(firstVertex); | 815 drawInfo.adjustStartVertex(firstVertex); |
808 drawInfo.setVertexBuffer(vertexBuffer); | 816 drawInfo.setVertexBuffer(vertexBuffer); |
809 drawInfo.setIndexBuffer(indexBuffer); | 817 drawInfo.setIndexBuffer(quadIndexBuffer); |
810 | 818 |
811 int maxInstancesPerDraw = indexBuffer->maxQuads(); | 819 int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); |
812 | 820 |
813 while (instanceCount) { | 821 while (instanceCount) { |
814 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 822 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
815 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 823 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
816 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 824 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
817 | 825 |
818 batchTarget->draw(drawInfo); | 826 batchTarget->draw(drawInfo); |
819 | 827 |
820 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 828 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
821 instanceCount -= drawInfo.instanceCount(); | 829 instanceCount -= drawInfo.instanceCount(); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1007 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1015 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1008 init.fUsesLocalCoords = this->usesLocalCoords(); | 1016 init.fUsesLocalCoords = this->usesLocalCoords(); |
1009 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1017 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1010 | 1018 |
1011 int instanceCount = fGeoData.count(); | 1019 int instanceCount = fGeoData.count(); |
1012 int vertexCount = kVertsPerEllipse * instanceCount; | 1020 int vertexCount = kVertsPerEllipse * instanceCount; |
1013 size_t vertexStride = gp->getVertexStride(); | 1021 size_t vertexStride = gp->getVertexStride(); |
1014 SkASSERT(vertexStride == sizeof(EllipseVertex)); | 1022 SkASSERT(vertexStride == sizeof(EllipseVertex)); |
1015 | 1023 |
1016 const GrVertexBuffer* vertexBuffer; | 1024 const GrVertexBuffer* vertexBuffer; |
1017 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | |
1018 batchTarget->resourceProvider()->refQuadIndexBuffer()); | |
1019 int firstVertex; | 1025 int firstVertex; |
1020 | 1026 |
1021 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 1027 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1022 vertexCount, | 1028 vertexCount, |
1023 &vertexBuffer, | 1029 &vertexBuffer, |
1024 &firstVertex); | 1030 &firstVertex); |
1025 | 1031 |
1026 if (!vertices || !indexBuffer) { | 1032 if (!vertices || !batchTarget->quadIndexBuffer()) { |
1027 SkDebugf("Could not allocate buffers\n"); | 1033 SkDebugf("Could not allocate buffers\n"); |
1028 return; | 1034 return; |
1029 } | 1035 } |
1030 | 1036 |
1031 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); | 1037 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); |
1032 | 1038 |
1033 for (int i = 0; i < instanceCount; i++) { | 1039 for (int i = 0; i < instanceCount; i++) { |
1034 Geometry& args = fGeoData[i]; | 1040 Geometry& args = fGeoData[i]; |
1035 | 1041 |
1036 SkScalar xRadius = args.fXRadius; | 1042 SkScalar xRadius = args.fXRadius; |
(...skipping 24 matching lines...) Expand all Loading... |
1061 verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; | 1067 verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; |
1062 | 1068 |
1063 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 1069 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
1064 verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); | 1070 verts[3].fOffset = SkPoint::Make(xRadius, -yRadius); |
1065 verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); | 1071 verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip); |
1066 verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; | 1072 verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip)
; |
1067 | 1073 |
1068 verts += kVertsPerEllipse; | 1074 verts += kVertsPerEllipse; |
1069 } | 1075 } |
1070 | 1076 |
| 1077 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); |
| 1078 |
1071 GrDrawTarget::DrawInfo drawInfo; | 1079 GrDrawTarget::DrawInfo drawInfo; |
1072 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 1080 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
1073 drawInfo.setStartVertex(0); | 1081 drawInfo.setStartVertex(0); |
1074 drawInfo.setStartIndex(0); | 1082 drawInfo.setStartIndex(0); |
1075 drawInfo.setVerticesPerInstance(kVertsPerEllipse); | 1083 drawInfo.setVerticesPerInstance(kVertsPerEllipse); |
1076 drawInfo.setIndicesPerInstance(kIndicesPerEllipse); | 1084 drawInfo.setIndicesPerInstance(kIndicesPerEllipse); |
1077 drawInfo.adjustStartVertex(firstVertex); | 1085 drawInfo.adjustStartVertex(firstVertex); |
1078 drawInfo.setVertexBuffer(vertexBuffer); | 1086 drawInfo.setVertexBuffer(vertexBuffer); |
1079 drawInfo.setIndexBuffer(indexBuffer); | 1087 drawInfo.setIndexBuffer(quadIndexBuffer); |
1080 | 1088 |
1081 int maxInstancesPerDraw = indexBuffer->maxQuads(); | 1089 int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); |
1082 | 1090 |
1083 while (instanceCount) { | 1091 while (instanceCount) { |
1084 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 1092 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
1085 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 1093 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
1086 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 1094 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
1087 | 1095 |
1088 batchTarget->draw(drawInfo); | 1096 batchTarget->draw(drawInfo); |
1089 | 1097 |
1090 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 1098 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
1091 instanceCount -= drawInfo.instanceCount(); | 1099 instanceCount -= drawInfo.instanceCount(); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1310 // TODO this is hacky, but the only way we have to initialize the GP is
to use the | 1318 // TODO this is hacky, but the only way we have to initialize the GP is
to use the |
1311 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch | 1319 // GrPipelineInfo struct so we can generate the correct shader. Once we
have GrBatch |
1312 // everywhere we can remove this nastiness | 1320 // everywhere we can remove this nastiness |
1313 GrPipelineInfo init; | 1321 GrPipelineInfo init; |
1314 init.fColorIgnored = fBatch.fColorIgnored; | 1322 init.fColorIgnored = fBatch.fColorIgnored; |
1315 init.fOverrideColor = GrColor_ILLEGAL; | 1323 init.fOverrideColor = GrColor_ILLEGAL; |
1316 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1324 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1317 init.fUsesLocalCoords = this->usesLocalCoords(); | 1325 init.fUsesLocalCoords = this->usesLocalCoords(); |
1318 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1326 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1319 | 1327 |
1320 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | |
1321 batchTarget->resourceProvider()->refQuadIndexBuffer()); | |
1322 | |
1323 int instanceCount = fGeoData.count(); | 1328 int instanceCount = fGeoData.count(); |
1324 int vertexCount = kVertsPerEllipse * instanceCount; | 1329 int vertexCount = kVertsPerEllipse * instanceCount; |
1325 size_t vertexStride = gp->getVertexStride(); | 1330 size_t vertexStride = gp->getVertexStride(); |
1326 SkASSERT(vertexStride == sizeof(DIEllipseVertex)); | 1331 SkASSERT(vertexStride == sizeof(DIEllipseVertex)); |
| 1332 |
1327 const GrVertexBuffer* vertexBuffer; | 1333 const GrVertexBuffer* vertexBuffer; |
1328 int firstVertex; | 1334 int firstVertex; |
| 1335 |
1329 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 1336 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1330 vertexCount, | 1337 vertexCount, |
1331 &vertexBuffer, | 1338 &vertexBuffer, |
1332 &firstVertex); | 1339 &firstVertex); |
1333 | 1340 |
1334 if (!vertices || !indexBuffer) { | 1341 if (!vertices || !batchTarget->quadIndexBuffer()) { |
1335 SkDebugf("Could not allocate buffers\n"); | 1342 SkDebugf("Could not allocate buffers\n"); |
1336 return; | 1343 return; |
1337 } | 1344 } |
1338 | 1345 |
1339 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices); | 1346 DIEllipseVertex* verts = reinterpret_cast<DIEllipseVertex*>(vertices); |
1340 | 1347 |
1341 for (int i = 0; i < instanceCount; i++) { | 1348 for (int i = 0; i < instanceCount; i++) { |
1342 Geometry& args = fGeoData[i]; | 1349 Geometry& args = fGeoData[i]; |
1343 | 1350 |
1344 SkScalar xRadius = args.fXRadius; | 1351 SkScalar xRadius = args.fXRadius; |
(...skipping 20 matching lines...) Expand all Loading... |
1365 verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offset
Dy); | 1372 verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offset
Dy); |
1366 verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerR
atioY + offsetDy); | 1373 verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerR
atioY + offsetDy); |
1367 | 1374 |
1368 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); | 1375 verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop); |
1369 verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offse
tDy); | 1376 verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offse
tDy); |
1370 verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -inner
RatioY - offsetDy); | 1377 verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -inner
RatioY - offsetDy); |
1371 | 1378 |
1372 verts += kVertsPerEllipse; | 1379 verts += kVertsPerEllipse; |
1373 } | 1380 } |
1374 | 1381 |
| 1382 const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); |
| 1383 |
1375 GrDrawTarget::DrawInfo drawInfo; | 1384 GrDrawTarget::DrawInfo drawInfo; |
1376 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 1385 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
1377 drawInfo.setStartVertex(0); | 1386 drawInfo.setStartVertex(0); |
1378 drawInfo.setStartIndex(0); | 1387 drawInfo.setStartIndex(0); |
1379 drawInfo.setVerticesPerInstance(kVertsPerEllipse); | 1388 drawInfo.setVerticesPerInstance(kVertsPerEllipse); |
1380 drawInfo.setIndicesPerInstance(kIndicesPerEllipse); | 1389 drawInfo.setIndicesPerInstance(kIndicesPerEllipse); |
1381 drawInfo.adjustStartVertex(firstVertex); | 1390 drawInfo.adjustStartVertex(firstVertex); |
1382 drawInfo.setVertexBuffer(vertexBuffer); | 1391 drawInfo.setVertexBuffer(vertexBuffer); |
1383 drawInfo.setIndexBuffer(indexBuffer); | 1392 drawInfo.setIndexBuffer(quadIndexBuffer); |
1384 | 1393 |
1385 int maxInstancesPerDraw = indexBuffer->maxQuads(); | 1394 int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); |
1386 | 1395 |
1387 while (instanceCount) { | 1396 while (instanceCount) { |
1388 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 1397 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
1389 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 1398 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
1390 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 1399 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
1391 | 1400 |
1392 batchTarget->draw(drawInfo); | 1401 batchTarget->draw(drawInfo); |
1393 | 1402 |
1394 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 1403 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
1395 instanceCount -= drawInfo.instanceCount(); | 1404 instanceCount -= drawInfo.instanceCount(); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1563 // center | 1572 // center |
1564 // we place this at the end so that we can ignore these indices when renderi
ng stroke-only | 1573 // we place this at the end so that we can ignore these indices when renderi
ng stroke-only |
1565 5, 6, 10, 5, 10, 9 | 1574 5, 6, 10, 5, 10, 9 |
1566 }; | 1575 }; |
1567 | 1576 |
1568 static const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6; | 1577 static const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6; |
1569 static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices); | 1578 static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices); |
1570 static const int kVertsPerRRect = 16; | 1579 static const int kVertsPerRRect = 16; |
1571 static const int kNumRRectsInIndexBuffer = 256; | 1580 static const int kNumRRectsInIndexBuffer = 256; |
1572 | 1581 |
1573 GR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); | |
1574 GR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); | |
1575 static const GrIndexBuffer* ref_rrect_index_buffer(bool strokeOnly, | |
1576 GrResourceProvider* resourceP
rovider) { | |
1577 GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey); | |
1578 GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey); | |
1579 if (strokeOnly) { | |
1580 return resourceProvider->refOrCreateInstancedIndexBuffer( | |
1581 gRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer, kVer
tsPerRRect, | |
1582 gStrokeRRectOnlyIndexBufferKey); | |
1583 } else { | |
1584 return resourceProvider->refOrCreateInstancedIndexBuffer( | |
1585 gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerR
Rect, | |
1586 gRRectOnlyIndexBufferKey); | |
1587 | |
1588 } | |
1589 } | |
1590 | |
1591 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, | 1582 bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, |
1592 GrPipelineBuilder* pipelineBuilder, | 1583 GrPipelineBuilder* pipelineBuilder, |
1593 GrColor color, | 1584 GrColor color, |
1594 const SkMatrix& viewMatrix, | 1585 const SkMatrix& viewMatrix, |
1595 bool useAA, | 1586 bool useAA, |
1596 const SkRRect& origOuter, | 1587 const SkRRect& origOuter, |
1597 const SkRRect& origInner) { | 1588 const SkRRect& origInner) { |
1598 bool applyAA = useAA && | 1589 bool applyAA = useAA && |
1599 !pipelineBuilder->getRenderTarget()->isMultisampled(); | 1590 !pipelineBuilder->getRenderTarget()->isMultisampled(); |
1600 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; | 1591 GrPipelineBuilder::AutoRestoreFragmentProcessors arfp; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 public: | 1650 public: |
1660 struct Geometry { | 1651 struct Geometry { |
1661 GrColor fColor; | 1652 GrColor fColor; |
1662 SkMatrix fViewMatrix; | 1653 SkMatrix fViewMatrix; |
1663 SkScalar fInnerRadius; | 1654 SkScalar fInnerRadius; |
1664 SkScalar fOuterRadius; | 1655 SkScalar fOuterRadius; |
1665 bool fStroke; | 1656 bool fStroke; |
1666 SkRect fDevBounds; | 1657 SkRect fDevBounds; |
1667 }; | 1658 }; |
1668 | 1659 |
1669 static GrBatch* Create(const Geometry& geometry) { | 1660 static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexB
uffer) { |
1670 return SkNEW_ARGS(RRectCircleRendererBatch, (geometry)); | 1661 return SkNEW_ARGS(RRectCircleRendererBatch, (geometry, indexBuffer)); |
1671 } | 1662 } |
1672 | 1663 |
1673 const char* name() const override { return "RRectCircleBatch"; } | 1664 const char* name() const override { return "RRectCircleBatch"; } |
1674 | 1665 |
1675 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 1666 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
1676 // When this is called on a batch, there is only one geometry bundle | 1667 // When this is called on a batch, there is only one geometry bundle |
1677 out->setKnownFourComponents(fGeoData[0].fColor); | 1668 out->setKnownFourComponents(fGeoData[0].fColor); |
1678 } | 1669 } |
1679 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 1670 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
1680 out->setUnknownSingleComponent(); | 1671 out->setUnknownSingleComponent(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1711 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1721 init.fUsesLocalCoords = this->usesLocalCoords(); | 1712 init.fUsesLocalCoords = this->usesLocalCoords(); |
1722 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1713 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1723 | 1714 |
1724 int instanceCount = fGeoData.count(); | 1715 int instanceCount = fGeoData.count(); |
1725 int vertexCount = kVertsPerRRect * instanceCount; | 1716 int vertexCount = kVertsPerRRect * instanceCount; |
1726 size_t vertexStride = gp->getVertexStride(); | 1717 size_t vertexStride = gp->getVertexStride(); |
1727 SkASSERT(vertexStride == sizeof(CircleVertex)); | 1718 SkASSERT(vertexStride == sizeof(CircleVertex)); |
1728 | 1719 |
1729 const GrVertexBuffer* vertexBuffer; | 1720 const GrVertexBuffer* vertexBuffer; |
1730 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | |
1731 ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider
())); | |
1732 int firstVertex; | 1721 int firstVertex; |
1733 | 1722 |
1734 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 1723 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1735 vertexCount, | 1724 vertexCount, |
1736 &vertexBuffer, | 1725 &vertexBuffer, |
1737 &firstVertex); | 1726 &firstVertex); |
1738 | 1727 |
1739 if (!vertices || !indexBuffer) { | 1728 if (!vertices) { |
1740 SkDebugf("Could not allocate vertices\n"); | 1729 SkDebugf("Could not allocate vertices\n"); |
1741 return; | 1730 return; |
1742 } | 1731 } |
1743 | 1732 |
1744 CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); | 1733 CircleVertex* verts = reinterpret_cast<CircleVertex*>(vertices); |
1745 | 1734 |
1746 for (int i = 0; i < instanceCount; i++) { | 1735 for (int i = 0; i < instanceCount; i++) { |
1747 Geometry& args = fGeoData[i]; | 1736 Geometry& args = fGeoData[i]; |
1748 | 1737 |
1749 SkScalar outerRadius = args.fOuterRadius; | 1738 SkScalar outerRadius = args.fOuterRadius; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1784 verts->fOuterRadius = outerRadius; | 1773 verts->fOuterRadius = outerRadius; |
1785 verts->fInnerRadius = innerRadius; | 1774 verts->fInnerRadius = innerRadius; |
1786 verts++; | 1775 verts++; |
1787 } | 1776 } |
1788 } | 1777 } |
1789 | 1778 |
1790 // drop out the middle quad if we're stroked | 1779 // drop out the middle quad if we're stroked |
1791 int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 : | 1780 int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 : |
1792 SK_ARRAY_COUNT(gRRectIndices); | 1781 SK_ARRAY_COUNT(gRRectIndices); |
1793 | 1782 |
| 1783 |
1794 GrDrawTarget::DrawInfo drawInfo; | 1784 GrDrawTarget::DrawInfo drawInfo; |
1795 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 1785 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
1796 drawInfo.setStartVertex(0); | 1786 drawInfo.setStartVertex(0); |
1797 drawInfo.setStartIndex(0); | 1787 drawInfo.setStartIndex(0); |
1798 drawInfo.setVerticesPerInstance(kVertsPerRRect); | 1788 drawInfo.setVerticesPerInstance(kVertsPerRRect); |
1799 drawInfo.setIndicesPerInstance(indexCnt); | 1789 drawInfo.setIndicesPerInstance(indexCnt); |
1800 drawInfo.adjustStartVertex(firstVertex); | 1790 drawInfo.adjustStartVertex(firstVertex); |
1801 drawInfo.setVertexBuffer(vertexBuffer); | 1791 drawInfo.setVertexBuffer(vertexBuffer); |
1802 drawInfo.setIndexBuffer(indexBuffer); | 1792 drawInfo.setIndexBuffer(fIndexBuffer); |
1803 | 1793 |
1804 int maxInstancesPerDraw = kNumRRectsInIndexBuffer; | 1794 int maxInstancesPerDraw = kNumRRectsInIndexBuffer; |
1805 | 1795 |
1806 while (instanceCount) { | 1796 while (instanceCount) { |
1807 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 1797 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
1808 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 1798 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
1809 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 1799 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
1810 | 1800 |
1811 batchTarget->draw(drawInfo); | 1801 batchTarget->draw(drawInfo); |
1812 | 1802 |
1813 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 1803 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
1814 instanceCount -= drawInfo.instanceCount(); | 1804 instanceCount -= drawInfo.instanceCount(); |
1815 } | 1805 } |
1816 } | 1806 } |
1817 | 1807 |
1818 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 1808 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
1819 | 1809 |
1820 private: | 1810 private: |
1821 RRectCircleRendererBatch(const Geometry& geometry) { | 1811 RRectCircleRendererBatch(const Geometry& geometry, const GrIndexBuffer* inde
xBuffer) |
| 1812 : fIndexBuffer(indexBuffer) { |
1822 this->initClassID<RRectCircleRendererBatch>(); | 1813 this->initClassID<RRectCircleRendererBatch>(); |
1823 fGeoData.push_back(geometry); | 1814 fGeoData.push_back(geometry); |
1824 | 1815 |
1825 this->setBounds(geometry.fDevBounds); | 1816 this->setBounds(geometry.fDevBounds); |
1826 } | 1817 } |
1827 | 1818 |
1828 bool onCombineIfPossible(GrBatch* t) override { | 1819 bool onCombineIfPossible(GrBatch* t) override { |
1829 RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); | 1820 RRectCircleRendererBatch* that = t->cast<RRectCircleRendererBatch>(); |
1830 | 1821 |
1831 // TODO use vertex color to avoid breaking batches | 1822 // TODO use vertex color to avoid breaking batches |
(...skipping 23 matching lines...) Expand all Loading... |
1855 struct BatchTracker { | 1846 struct BatchTracker { |
1856 GrColor fColor; | 1847 GrColor fColor; |
1857 bool fStroke; | 1848 bool fStroke; |
1858 bool fUsesLocalCoords; | 1849 bool fUsesLocalCoords; |
1859 bool fColorIgnored; | 1850 bool fColorIgnored; |
1860 bool fCoverageIgnored; | 1851 bool fCoverageIgnored; |
1861 }; | 1852 }; |
1862 | 1853 |
1863 BatchTracker fBatch; | 1854 BatchTracker fBatch; |
1864 SkSTArray<1, Geometry, true> fGeoData; | 1855 SkSTArray<1, Geometry, true> fGeoData; |
| 1856 const GrIndexBuffer* fIndexBuffer; |
1865 }; | 1857 }; |
1866 | 1858 |
1867 class RRectEllipseRendererBatch : public GrBatch { | 1859 class RRectEllipseRendererBatch : public GrBatch { |
1868 public: | 1860 public: |
1869 struct Geometry { | 1861 struct Geometry { |
1870 GrColor fColor; | 1862 GrColor fColor; |
1871 SkMatrix fViewMatrix; | 1863 SkMatrix fViewMatrix; |
1872 SkScalar fXRadius; | 1864 SkScalar fXRadius; |
1873 SkScalar fYRadius; | 1865 SkScalar fYRadius; |
1874 SkScalar fInnerXRadius; | 1866 SkScalar fInnerXRadius; |
1875 SkScalar fInnerYRadius; | 1867 SkScalar fInnerYRadius; |
1876 bool fStroke; | 1868 bool fStroke; |
1877 SkRect fDevBounds; | 1869 SkRect fDevBounds; |
1878 }; | 1870 }; |
1879 | 1871 |
1880 static GrBatch* Create(const Geometry& geometry) { | 1872 static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexB
uffer) { |
1881 return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry)); | 1873 return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry, indexBuffer)); |
1882 } | 1874 } |
1883 | 1875 |
1884 const char* name() const override { return "RRectEllipseRendererBatch"; } | 1876 const char* name() const override { return "RRectEllipseRendererBatch"; } |
1885 | 1877 |
1886 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { | 1878 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { |
1887 // When this is called on a batch, there is only one geometry bundle | 1879 // When this is called on a batch, there is only one geometry bundle |
1888 out->setKnownFourComponents(fGeoData[0].fColor); | 1880 out->setKnownFourComponents(fGeoData[0].fColor); |
1889 } | 1881 } |
1890 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { | 1882 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override { |
1891 out->setUnknownSingleComponent(); | 1883 out->setUnknownSingleComponent(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1931 init.fCoverageIgnored = fBatch.fCoverageIgnored; | 1923 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
1932 init.fUsesLocalCoords = this->usesLocalCoords(); | 1924 init.fUsesLocalCoords = this->usesLocalCoords(); |
1933 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); | 1925 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
1934 | 1926 |
1935 int instanceCount = fGeoData.count(); | 1927 int instanceCount = fGeoData.count(); |
1936 int vertexCount = kVertsPerRRect * instanceCount; | 1928 int vertexCount = kVertsPerRRect * instanceCount; |
1937 size_t vertexStride = gp->getVertexStride(); | 1929 size_t vertexStride = gp->getVertexStride(); |
1938 SkASSERT(vertexStride == sizeof(EllipseVertex)); | 1930 SkASSERT(vertexStride == sizeof(EllipseVertex)); |
1939 | 1931 |
1940 const GrVertexBuffer* vertexBuffer; | 1932 const GrVertexBuffer* vertexBuffer; |
1941 SkAutoTUnref<const GrIndexBuffer> indexBuffer( | |
1942 ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider
())); | |
1943 int firstVertex; | 1933 int firstVertex; |
1944 | 1934 |
1945 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, | 1935 void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, |
1946 vertexCount, | 1936 vertexCount, |
1947 &vertexBuffer, | 1937 &vertexBuffer, |
1948 &firstVertex); | 1938 &firstVertex); |
1949 | 1939 |
1950 if (!vertices || !indexBuffer) { | 1940 if (!vertices) { |
1951 SkDebugf("Could not allocate vertices\n"); | 1941 SkDebugf("Could not allocate vertices\n"); |
1952 return; | 1942 return; |
1953 } | 1943 } |
1954 | 1944 |
1955 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); | 1945 EllipseVertex* verts = reinterpret_cast<EllipseVertex*>(vertices); |
1956 | 1946 |
1957 for (int i = 0; i < instanceCount; i++) { | 1947 for (int i = 0; i < instanceCount; i++) { |
1958 Geometry& args = fGeoData[i]; | 1948 Geometry& args = fGeoData[i]; |
1959 | 1949 |
1960 // Compute the reciprocals of the radii here to save time in the sha
der | 1950 // Compute the reciprocals of the radii here to save time in the sha
der |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2014 SK_ARRAY_COUNT(gRRectIndices); | 2004 SK_ARRAY_COUNT(gRRectIndices); |
2015 | 2005 |
2016 GrDrawTarget::DrawInfo drawInfo; | 2006 GrDrawTarget::DrawInfo drawInfo; |
2017 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); | 2007 drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); |
2018 drawInfo.setStartVertex(0); | 2008 drawInfo.setStartVertex(0); |
2019 drawInfo.setStartIndex(0); | 2009 drawInfo.setStartIndex(0); |
2020 drawInfo.setVerticesPerInstance(kVertsPerRRect); | 2010 drawInfo.setVerticesPerInstance(kVertsPerRRect); |
2021 drawInfo.setIndicesPerInstance(indexCnt); | 2011 drawInfo.setIndicesPerInstance(indexCnt); |
2022 drawInfo.adjustStartVertex(firstVertex); | 2012 drawInfo.adjustStartVertex(firstVertex); |
2023 drawInfo.setVertexBuffer(vertexBuffer); | 2013 drawInfo.setVertexBuffer(vertexBuffer); |
2024 drawInfo.setIndexBuffer(indexBuffer); | 2014 drawInfo.setIndexBuffer(fIndexBuffer); |
2025 | 2015 |
2026 int maxInstancesPerDraw = kNumRRectsInIndexBuffer; | 2016 int maxInstancesPerDraw = kNumRRectsInIndexBuffer; |
2027 | 2017 |
2028 while (instanceCount) { | 2018 while (instanceCount) { |
2029 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); | 2019 drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)
); |
2030 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); | 2020 drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.vertices
PerInstance()); |
2031 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); | 2021 drawInfo.setIndexCount(drawInfo.instanceCount() * drawInfo.indicesPe
rInstance()); |
2032 | 2022 |
2033 batchTarget->draw(drawInfo); | 2023 batchTarget->draw(drawInfo); |
2034 | 2024 |
2035 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); | 2025 drawInfo.setStartVertex(drawInfo.startVertex() + drawInfo.vertexCoun
t()); |
2036 instanceCount -= drawInfo.instanceCount(); | 2026 instanceCount -= drawInfo.instanceCount(); |
2037 } | 2027 } |
2038 } | 2028 } |
2039 | 2029 |
2040 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } | 2030 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } |
2041 | 2031 |
2042 private: | 2032 private: |
2043 RRectEllipseRendererBatch(const Geometry& geometry) { | 2033 RRectEllipseRendererBatch(const Geometry& geometry, const GrIndexBuffer* ind
exBuffer) |
| 2034 : fIndexBuffer(indexBuffer) { |
2044 this->initClassID<RRectEllipseRendererBatch>(); | 2035 this->initClassID<RRectEllipseRendererBatch>(); |
2045 fGeoData.push_back(geometry); | 2036 fGeoData.push_back(geometry); |
2046 | 2037 |
2047 this->setBounds(geometry.fDevBounds); | 2038 this->setBounds(geometry.fDevBounds); |
2048 } | 2039 } |
2049 | 2040 |
2050 bool onCombineIfPossible(GrBatch* t) override { | 2041 bool onCombineIfPossible(GrBatch* t) override { |
2051 RRectEllipseRendererBatch* that = t->cast<RRectEllipseRendererBatch>(); | 2042 RRectEllipseRendererBatch* that = t->cast<RRectEllipseRendererBatch>(); |
2052 | 2043 |
2053 // TODO use vertex color to avoid breaking batches | 2044 // TODO use vertex color to avoid breaking batches |
(...skipping 23 matching lines...) Expand all Loading... |
2077 struct BatchTracker { | 2068 struct BatchTracker { |
2078 GrColor fColor; | 2069 GrColor fColor; |
2079 bool fStroke; | 2070 bool fStroke; |
2080 bool fUsesLocalCoords; | 2071 bool fUsesLocalCoords; |
2081 bool fColorIgnored; | 2072 bool fColorIgnored; |
2082 bool fCoverageIgnored; | 2073 bool fCoverageIgnored; |
2083 }; | 2074 }; |
2084 | 2075 |
2085 BatchTracker fBatch; | 2076 BatchTracker fBatch; |
2086 SkSTArray<1, Geometry, true> fGeoData; | 2077 SkSTArray<1, Geometry, true> fGeoData; |
| 2078 const GrIndexBuffer* fIndexBuffer; |
2087 }; | 2079 }; |
2088 | 2080 |
| 2081 static GrIndexBuffer* create_rrect_indexbuffer(GrIndexBuffer** strokeRRectIndexB
uffer, |
| 2082 GrIndexBuffer** rrectIndexBuffer, |
| 2083 bool isStrokeOnly, |
| 2084 GrGpu* gpu) { |
| 2085 if (isStrokeOnly) { |
| 2086 if (NULL == *strokeRRectIndexBuffer) { |
| 2087 *strokeRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndi
ces, |
| 2088 kIndicesPe
rStrokeRRect, |
| 2089 kNumRRects
InIndexBuffer, |
| 2090 kVertsPerR
Rect); |
| 2091 } |
| 2092 return *strokeRRectIndexBuffer; |
| 2093 } else { |
| 2094 if (NULL == *rrectIndexBuffer) { |
| 2095 *rrectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices, |
| 2096 kIndicesPerRRect
, |
| 2097 kNumRRectsInInde
xBuffer, |
| 2098 kVertsPerRRect); |
| 2099 } |
| 2100 return *rrectIndexBuffer; |
| 2101 } |
| 2102 } |
| 2103 |
2089 static GrBatch* create_rrect_batch(GrColor color, | 2104 static GrBatch* create_rrect_batch(GrColor color, |
2090 const SkMatrix& viewMatrix, | 2105 const SkMatrix& viewMatrix, |
2091 const SkRRect& rrect, | 2106 const SkRRect& rrect, |
2092 const SkStrokeRec& stroke, | 2107 const SkStrokeRec& stroke, |
2093 SkRect* bounds) { | 2108 SkRect* bounds, |
| 2109 GrIndexBuffer** strokeRRectIndexBuffer, |
| 2110 GrIndexBuffer** rrectIndexBuffer, |
| 2111 GrGpu* gpu) { |
2094 SkASSERT(viewMatrix.rectStaysRect()); | 2112 SkASSERT(viewMatrix.rectStaysRect()); |
2095 SkASSERT(rrect.isSimple()); | 2113 SkASSERT(rrect.isSimple()); |
2096 SkASSERT(!rrect.isOval()); | 2114 SkASSERT(!rrect.isOval()); |
2097 | 2115 |
2098 // RRect batchs only handle simple, but not too simple, rrects | 2116 // RRect batchs only handle simple, but not too simple, rrects |
2099 // do any matrix crunching before we reset the draw state for device coords | 2117 // do any matrix crunching before we reset the draw state for device coords |
2100 const SkRect& rrectBounds = rrect.getBounds(); | 2118 const SkRect& rrectBounds = rrect.getBounds(); |
2101 viewMatrix.mapRect(bounds, rrectBounds); | 2119 viewMatrix.mapRect(bounds, rrectBounds); |
2102 | 2120 |
2103 SkVector radii = rrect.getSimpleRadii(); | 2121 SkVector radii = rrect.getSimpleRadii(); |
(...skipping 30 matching lines...) Expand all Loading... |
2134 | 2152 |
2135 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on | 2153 // The way the effect interpolates the offset-to-ellipse/circle-center attri
bute only works on |
2136 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- | 2154 // the interior of the rrect if the radii are >= 0.5. Otherwise, the inner r
ect of the nine- |
2137 // patch will have fractional coverage. This only matters when the interior
is actually filled. | 2155 // patch will have fractional coverage. This only matters when the interior
is actually filled. |
2138 // We could consider falling back to rect rendering here, since a tiny radiu
s is | 2156 // We could consider falling back to rect rendering here, since a tiny radiu
s is |
2139 // indistinguishable from a square corner. | 2157 // indistinguishable from a square corner. |
2140 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { | 2158 if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) { |
2141 return NULL; | 2159 return NULL; |
2142 } | 2160 } |
2143 | 2161 |
| 2162 GrIndexBuffer* indexBuffer = create_rrect_indexbuffer(strokeRRectIndexBuffer
, |
| 2163 rrectIndexBuffer, |
| 2164 isStrokeOnly, |
| 2165 gpu); |
| 2166 if (NULL == indexBuffer) { |
| 2167 SkDebugf("Failed to create index buffer!\n"); |
| 2168 return NULL; |
| 2169 } |
| 2170 |
2144 // if the corners are circles, use the circle renderer | 2171 // if the corners are circles, use the circle renderer |
2145 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { | 2172 if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius
) { |
2146 SkScalar innerRadius = 0.0f; | 2173 SkScalar innerRadius = 0.0f; |
2147 SkScalar outerRadius = xRadius; | 2174 SkScalar outerRadius = xRadius; |
2148 SkScalar halfWidth = 0; | 2175 SkScalar halfWidth = 0; |
2149 if (hasStroke) { | 2176 if (hasStroke) { |
2150 if (SkScalarNearlyZero(scaledStroke.fX)) { | 2177 if (SkScalarNearlyZero(scaledStroke.fX)) { |
2151 halfWidth = SK_ScalarHalf; | 2178 halfWidth = SK_ScalarHalf; |
2152 } else { | 2179 } else { |
2153 halfWidth = SkScalarHalf(scaledStroke.fX); | 2180 halfWidth = SkScalarHalf(scaledStroke.fX); |
(...skipping 20 matching lines...) Expand all Loading... |
2174 bounds->outset(SK_ScalarHalf, SK_ScalarHalf); | 2201 bounds->outset(SK_ScalarHalf, SK_ScalarHalf); |
2175 | 2202 |
2176 RRectCircleRendererBatch::Geometry geometry; | 2203 RRectCircleRendererBatch::Geometry geometry; |
2177 geometry.fViewMatrix = viewMatrix; | 2204 geometry.fViewMatrix = viewMatrix; |
2178 geometry.fColor = color; | 2205 geometry.fColor = color; |
2179 geometry.fInnerRadius = innerRadius; | 2206 geometry.fInnerRadius = innerRadius; |
2180 geometry.fOuterRadius = outerRadius; | 2207 geometry.fOuterRadius = outerRadius; |
2181 geometry.fStroke = isStrokeOnly; | 2208 geometry.fStroke = isStrokeOnly; |
2182 geometry.fDevBounds = *bounds; | 2209 geometry.fDevBounds = *bounds; |
2183 | 2210 |
2184 return RRectCircleRendererBatch::Create(geometry); | 2211 return RRectCircleRendererBatch::Create(geometry, indexBuffer); |
| 2212 |
2185 // otherwise we use the ellipse renderer | 2213 // otherwise we use the ellipse renderer |
2186 } else { | 2214 } else { |
2187 SkScalar innerXRadius = 0.0f; | 2215 SkScalar innerXRadius = 0.0f; |
2188 SkScalar innerYRadius = 0.0f; | 2216 SkScalar innerYRadius = 0.0f; |
2189 if (hasStroke) { | 2217 if (hasStroke) { |
2190 if (SkScalarNearlyZero(scaledStroke.length())) { | 2218 if (SkScalarNearlyZero(scaledStroke.length())) { |
2191 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); | 2219 scaledStroke.set(SK_ScalarHalf, SK_ScalarHalf); |
2192 } else { | 2220 } else { |
2193 scaledStroke.scale(SK_ScalarHalf); | 2221 scaledStroke.scale(SK_ScalarHalf); |
2194 } | 2222 } |
(...skipping 29 matching lines...) Expand all Loading... |
2224 RRectEllipseRendererBatch::Geometry geometry; | 2252 RRectEllipseRendererBatch::Geometry geometry; |
2225 geometry.fViewMatrix = viewMatrix; | 2253 geometry.fViewMatrix = viewMatrix; |
2226 geometry.fColor = color; | 2254 geometry.fColor = color; |
2227 geometry.fXRadius = xRadius; | 2255 geometry.fXRadius = xRadius; |
2228 geometry.fYRadius = yRadius; | 2256 geometry.fYRadius = yRadius; |
2229 geometry.fInnerXRadius = innerXRadius; | 2257 geometry.fInnerXRadius = innerXRadius; |
2230 geometry.fInnerYRadius = innerYRadius; | 2258 geometry.fInnerYRadius = innerYRadius; |
2231 geometry.fStroke = isStrokeOnly; | 2259 geometry.fStroke = isStrokeOnly; |
2232 geometry.fDevBounds = *bounds; | 2260 geometry.fDevBounds = *bounds; |
2233 | 2261 |
2234 return RRectEllipseRendererBatch::Create(geometry); | 2262 return RRectEllipseRendererBatch::Create(geometry, indexBuffer); |
2235 } | 2263 } |
2236 } | 2264 } |
2237 | 2265 |
2238 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, | 2266 bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
2239 GrPipelineBuilder* pipelineBuilder, | 2267 GrPipelineBuilder* pipelineBuilder, |
2240 GrColor color, | 2268 GrColor color, |
2241 const SkMatrix& viewMatrix, | 2269 const SkMatrix& viewMatrix, |
2242 bool useAA, | 2270 bool useAA, |
2243 const SkRRect& rrect, | 2271 const SkRRect& rrect, |
2244 const SkStrokeRec& stroke) { | 2272 const SkStrokeRec& stroke) { |
2245 if (rrect.isOval()) { | 2273 if (rrect.isOval()) { |
2246 return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA,
rrect.getBounds(), | 2274 return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA,
rrect.getBounds(), |
2247 stroke); | 2275 stroke); |
2248 } | 2276 } |
2249 | 2277 |
2250 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisa
mpled(); | 2278 bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisa
mpled(); |
2251 | 2279 |
2252 // only anti-aliased rrects for now | 2280 // only anti-aliased rrects for now |
2253 if (!useCoverageAA) { | 2281 if (!useCoverageAA) { |
2254 return false; | 2282 return false; |
2255 } | 2283 } |
2256 | 2284 |
2257 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { | 2285 if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { |
2258 return false; | 2286 return false; |
2259 } | 2287 } |
2260 | 2288 |
2261 SkRect bounds; | 2289 SkRect bounds; |
2262 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str
oke, &bounds)); | 2290 SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, str
oke, &bounds, |
| 2291 &fStrokeRRectIndexBuffer, &fR
RectIndexBuffer, |
| 2292 fGpu)); |
2263 if (!batch) { | 2293 if (!batch) { |
2264 return false; | 2294 return false; |
2265 } | 2295 } |
2266 | 2296 |
2267 target->drawBatch(pipelineBuilder, batch); | 2297 target->drawBatch(pipelineBuilder, batch); |
2268 return true; | 2298 return true; |
2269 } | 2299 } |
2270 | 2300 |
2271 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 2301 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
2272 | 2302 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2310 SkRect bounds; // unused | 2340 SkRect bounds; // unused |
2311 return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, | 2341 return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
2312 random_strokerec(random), &bounds); | 2342 random_strokerec(random), &bounds); |
2313 } | 2343 } |
2314 | 2344 |
2315 BATCH_TEST_DEFINE(RRectBatch) { | 2345 BATCH_TEST_DEFINE(RRectBatch) { |
2316 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); | 2346 SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
2317 GrColor color = GrRandomColor(random); | 2347 GrColor color = GrRandomColor(random); |
2318 const SkRRect& rrect = GrTest::TestRRectSimple(random); | 2348 const SkRRect& rrect = GrTest::TestRRectSimple(random); |
2319 | 2349 |
| 2350 static GrIndexBuffer* gStrokeRRectIndexBuffer; |
| 2351 static GrIndexBuffer* gRRectIndexBuffer; |
2320 SkRect bounds; | 2352 SkRect bounds; |
2321 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random)
, &bounds); | 2353 return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random)
, &bounds, |
| 2354 &gStrokeRRectIndexBuffer, &gRRectIndexBuffer, cont
ext->getGpu()); |
2322 } | 2355 } |
2323 | 2356 |
2324 #endif | 2357 #endif |
OLD | NEW |