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