| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
| 10 | 10 |
| 11 #include "GrAAConvexTessellator.h" |
| 11 #include "GrBatch.h" | 12 #include "GrBatch.h" |
| 12 #include "GrBatchTarget.h" | 13 #include "GrBatchTarget.h" |
| 13 #include "GrBufferAllocPool.h" | 14 #include "GrBufferAllocPool.h" |
| 14 #include "GrContext.h" | 15 #include "GrContext.h" |
| 16 #include "GrDefaultGeoProcFactory.h" |
| 15 #include "GrDrawTargetCaps.h" | 17 #include "GrDrawTargetCaps.h" |
| 16 #include "GrGeometryProcessor.h" | 18 #include "GrGeometryProcessor.h" |
| 17 #include "GrInvariantOutput.h" | 19 #include "GrInvariantOutput.h" |
| 18 #include "GrPathUtils.h" | 20 #include "GrPathUtils.h" |
| 19 #include "GrProcessor.h" | 21 #include "GrProcessor.h" |
| 20 #include "GrPipelineBuilder.h" | 22 #include "GrPipelineBuilder.h" |
| 21 #include "GrStrokeInfo.h" | 23 #include "GrStrokeInfo.h" |
| 22 #include "SkGeometry.h" | 24 #include "SkGeometry.h" |
| 23 #include "SkString.h" | 25 #include "SkString.h" |
| 24 #include "SkTraceEvent.h" | 26 #include "SkTraceEvent.h" |
| (...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, | 699 bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, |
| 698 const GrPipelineBuilder*, | 700 const GrPipelineBuilder*, |
| 699 const SkMatrix& viewMatrix, | 701 const SkMatrix& viewMatrix, |
| 700 const SkPath& path, | 702 const SkPath& path, |
| 701 const GrStrokeInfo& stroke, | 703 const GrStrokeInfo& stroke, |
| 702 bool antiAlias) const { | 704 bool antiAlias) const { |
| 703 return (target->caps()->shaderCaps()->shaderDerivativeSupport() && antiAlias
&& | 705 return (target->caps()->shaderCaps()->shaderDerivativeSupport() && antiAlias
&& |
| 704 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()
); | 706 stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()
); |
| 705 } | 707 } |
| 706 | 708 |
| 709 static void extract_verts(const GrAAConvexTessellator& tess, |
| 710 void* vertices, |
| 711 size_t vertexStride, |
| 712 GrColor color, |
| 713 uint16_t* idxs, |
| 714 bool tweakAlphaForCoverage) { |
| 715 intptr_t verts = reinterpret_cast<intptr_t>(vertices); |
| 716 |
| 717 for (int i = 0; i < tess.numPts(); ++i) { |
| 718 *((SkPoint*)((intptr_t)verts + i * vertexStride)) = tess.point(i); |
| 719 } |
| 720 |
| 721 // Make 'verts' point to the colors |
| 722 verts += sizeof(SkPoint); |
| 723 for (int i = 0; i < tess.numPts(); ++i) { |
| 724 if (tweakAlphaForCoverage) { |
| 725 SkASSERT(tess.depth(i) >= -0.5f); |
| 726 SkASSERT(SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f)) <= 255)
; |
| 727 unsigned scale = SkScalarRoundToInt(255.0f * (tess.depth(i) + 0.5f))
; |
| 728 GrColor scaledColor = (0xff == scale) ? color : SkAlphaMulQ(color, s
cale); |
| 729 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = scaledColor; |
| 730 } else { |
| 731 *reinterpret_cast<GrColor*>(verts + i * vertexStride) = color; |
| 732 *reinterpret_cast<float*>(verts + i * vertexStride + sizeof(GrColor)
) = |
| 733 tess.depth(i
) + 0.5f; |
| 734 } |
| 735 } |
| 736 |
| 737 for (int i = 0; i < tess.numIndices(); ++i) { |
| 738 idxs[i] = tess.index(i); |
| 739 } |
| 740 } |
| 741 |
| 742 static const GrGeometryProcessor* create_fill_gp(bool tweakAlphaForCoverage, |
| 743 const SkMatrix& localMatrix) { |
| 744 uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; |
| 745 if (!tweakAlphaForCoverage) { |
| 746 flags |= GrDefaultGeoProcFactory::kCoverage_GPType; |
| 747 } |
| 748 |
| 749 return GrDefaultGeoProcFactory::Create(flags, GrColor_WHITE, SkMatrix::I(),
localMatrix, |
| 750 false, 0xff); |
| 751 } |
| 752 |
| 707 class AAConvexPathBatch : public GrBatch { | 753 class AAConvexPathBatch : public GrBatch { |
| 708 public: | 754 public: |
| 709 struct Geometry { | 755 struct Geometry { |
| 710 GrColor fColor; | 756 GrColor fColor; |
| 711 SkMatrix fViewMatrix; | 757 SkMatrix fViewMatrix; |
| 712 SkPath fPath; | 758 SkPath fPath; |
| 713 }; | 759 }; |
| 714 | 760 |
| 715 static GrBatch* Create(const Geometry& geometry) { | 761 static GrBatch* Create(const Geometry& geometry) { |
| 716 return SkNEW_ARGS(AAConvexPathBatch, (geometry)); | 762 return SkNEW_ARGS(AAConvexPathBatch, (geometry)); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 732 fGeoData[0].fColor = GrColor_ILLEGAL; | 778 fGeoData[0].fColor = GrColor_ILLEGAL; |
| 733 } else if (GrColor_ILLEGAL != init.fOverrideColor) { | 779 } else if (GrColor_ILLEGAL != init.fOverrideColor) { |
| 734 fGeoData[0].fColor = init.fOverrideColor; | 780 fGeoData[0].fColor = init.fOverrideColor; |
| 735 } | 781 } |
| 736 | 782 |
| 737 // setup batch properties | 783 // setup batch properties |
| 738 fBatch.fColorIgnored = init.fColorIgnored; | 784 fBatch.fColorIgnored = init.fColorIgnored; |
| 739 fBatch.fColor = fGeoData[0].fColor; | 785 fBatch.fColor = fGeoData[0].fColor; |
| 740 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; | 786 fBatch.fUsesLocalCoords = init.fUsesLocalCoords; |
| 741 fBatch.fCoverageIgnored = init.fCoverageIgnored; | 787 fBatch.fCoverageIgnored = init.fCoverageIgnored; |
| 788 fBatch.fLinesOnly = SkPath::kLine_SegmentMask == fGeoData[0].fPath.getSe
gmentMasks(); |
| 789 fBatch.fCanTweakAlphaForCoverage = init.fCanTweakAlphaForCoverage; |
| 790 } |
| 791 |
| 792 void generateGeometryLinesOnly(GrBatchTarget* batchTarget, const GrPipeline*
pipeline) { |
| 793 bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage(); |
| 794 |
| 795 SkMatrix invert; |
| 796 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { |
| 797 SkDebugf("Could not invert viewmatrix\n"); |
| 798 return; |
| 799 } |
| 800 |
| 801 // Setup GrGeometryProcessor |
| 802 SkAutoTUnref<const GrGeometryProcessor> gp(create_fill_gp(canTweakAlphaF
orCoverage, invert)); |
| 803 |
| 804 batchTarget->initDraw(gp, pipeline); |
| 805 |
| 806 // TODO remove this when batch is everywhere |
| 807 GrPipelineInfo init; |
| 808 init.fColorIgnored = fBatch.fColorIgnored; |
| 809 init.fOverrideColor = GrColor_ILLEGAL; |
| 810 init.fCoverageIgnored = fBatch.fCoverageIgnored; |
| 811 init.fUsesLocalCoords = this->usesLocalCoords(); |
| 812 gp->initBatchTracker(batchTarget->currentBatchTracker(), init); |
| 813 |
| 814 size_t vertexStride = gp->getVertexStride(); |
| 815 |
| 816 SkASSERT(canTweakAlphaForCoverage ? |
| 817 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAt
tr) : |
| 818 vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCo
verageAttr)); |
| 819 |
| 820 GrAAConvexTessellator tess; |
| 821 |
| 822 int instanceCount = fGeoData.count(); |
| 823 |
| 824 for (int i = 0; i < instanceCount; i++) { |
| 825 tess.rewind(); |
| 826 |
| 827 Geometry& args = fGeoData[i]; |
| 828 |
| 829 // We use the fact that SkPath::transform path does subdivision base
d on |
| 830 // perspective. Otherwise, we apply the view matrix when copying to
the |
| 831 // segment representation. |
| 832 const SkMatrix* viewMatrix = &args.fViewMatrix; |
| 833 if (viewMatrix->hasPerspective()) { |
| 834 args.fPath.transform(*viewMatrix); |
| 835 viewMatrix = &SkMatrix::I(); |
| 836 } |
| 837 |
| 838 if (!tess.tessellate(*viewMatrix, args.fPath)) { |
| 839 continue; |
| 840 } |
| 841 |
| 842 const GrVertexBuffer* vertexBuffer; |
| 843 int firstVertex; |
| 844 |
| 845 void* verts = batchTarget->vertexPool()->makeSpace(vertexStride, |
| 846 tess.numPts(), |
| 847 &vertexBuffer, |
| 848 &firstVertex); |
| 849 if (!verts) { |
| 850 SkDebugf("Could not allocate vertices\n"); |
| 851 return; |
| 852 } |
| 853 |
| 854 const GrIndexBuffer* indexBuffer; |
| 855 int firstIndex; |
| 856 |
| 857 void* indices = batchTarget->indexPool()->makeSpace(tess.numIndices(
), |
| 858 &indexBuffer, |
| 859 &firstIndex); |
| 860 if (!indices) { |
| 861 SkDebugf("Could not allocate indices\n"); |
| 862 return; |
| 863 } |
| 864 |
| 865 uint16_t* idxs = reinterpret_cast<uint16_t*>(indices); |
| 866 |
| 867 extract_verts(tess, verts, vertexStride, args.fColor, idxs, canTweak
AlphaForCoverage); |
| 868 |
| 869 GrDrawTarget::DrawInfo info; |
| 870 info.setPrimitiveType(kTriangles_GrPrimitiveType); |
| 871 info.setStartVertex(firstVertex); |
| 872 info.setStartIndex(firstIndex); |
| 873 info.setVertexBuffer(vertexBuffer); |
| 874 info.setIndexBuffer(indexBuffer); |
| 875 info.setVertexCount(tess.numPts()); |
| 876 info.setIndexCount(tess.numIndices()); |
| 877 batchTarget->draw(info); |
| 878 } |
| 742 } | 879 } |
| 743 | 880 |
| 744 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { | 881 void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline
) override { |
| 882 if (this->linesOnly()) { |
| 883 this->generateGeometryLinesOnly(batchTarget, pipeline); |
| 884 return; |
| 885 } |
| 886 |
| 745 int instanceCount = fGeoData.count(); | 887 int instanceCount = fGeoData.count(); |
| 746 | 888 |
| 747 SkMatrix invert; | 889 SkMatrix invert; |
| 748 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { | 890 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { |
| 749 SkDebugf("Could not invert viewmatrix\n"); | 891 SkDebugf("Could not invert viewmatrix\n"); |
| 750 return; | 892 return; |
| 751 } | 893 } |
| 752 | 894 |
| 753 // Setup GrGeometryProcessor | 895 // Setup GrGeometryProcessor |
| 754 SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(t
his->color(), | 896 SkAutoTUnref<GrGeometryProcessor> quadProcessor(QuadEdgeEffect::Create(t
his->color(), |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 | 996 |
| 855 if (this->color() != that->color()) { | 997 if (this->color() != that->color()) { |
| 856 return false; | 998 return false; |
| 857 } | 999 } |
| 858 | 1000 |
| 859 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); | 1001 SkASSERT(this->usesLocalCoords() == that->usesLocalCoords()); |
| 860 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { | 1002 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { |
| 861 return false; | 1003 return false; |
| 862 } | 1004 } |
| 863 | 1005 |
| 1006 if (this->linesOnly() != that->linesOnly()) { |
| 1007 return false; |
| 1008 } |
| 1009 |
| 1010 // In the event of two batches, one who can tweak, one who cannot, we ju
st fall back to |
| 1011 // not tweaking |
| 1012 if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()
) { |
| 1013 fBatch.fCanTweakAlphaForCoverage = false; |
| 1014 } |
| 1015 |
| 864 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; | 1016 fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin())
; |
| 865 return true; | 1017 return true; |
| 866 } | 1018 } |
| 867 | 1019 |
| 868 GrColor color() const { return fBatch.fColor; } | 1020 GrColor color() const { return fBatch.fColor; } |
| 1021 bool linesOnly() const { return fBatch.fLinesOnly; } |
| 869 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 1022 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| 1023 bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCover
age; } |
| 870 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } | 1024 const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; } |
| 871 | 1025 |
| 872 struct BatchTracker { | 1026 struct BatchTracker { |
| 873 GrColor fColor; | 1027 GrColor fColor; |
| 874 bool fUsesLocalCoords; | 1028 bool fUsesLocalCoords; |
| 875 bool fColorIgnored; | 1029 bool fColorIgnored; |
| 876 bool fCoverageIgnored; | 1030 bool fCoverageIgnored; |
| 1031 bool fLinesOnly; |
| 1032 bool fCanTweakAlphaForCoverage; |
| 877 }; | 1033 }; |
| 878 | 1034 |
| 879 BatchTracker fBatch; | 1035 BatchTracker fBatch; |
| 880 SkSTArray<1, Geometry, true> fGeoData; | 1036 SkSTArray<1, Geometry, true> fGeoData; |
| 881 }; | 1037 }; |
| 882 | 1038 |
| 883 bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, | 1039 bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, |
| 884 GrPipelineBuilder* pipelineBuilder, | 1040 GrPipelineBuilder* pipelineBuilder, |
| 885 GrColor color, | 1041 GrColor color, |
| 886 const SkMatrix& vm, | 1042 const SkMatrix& vm, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 901 geometry.fColor = color; | 1057 geometry.fColor = color; |
| 902 geometry.fViewMatrix = vm; | 1058 geometry.fViewMatrix = vm; |
| 903 geometry.fPath = path; | 1059 geometry.fPath = path; |
| 904 | 1060 |
| 905 SkAutoTUnref<GrBatch> batch(AAConvexPathBatch::Create(geometry)); | 1061 SkAutoTUnref<GrBatch> batch(AAConvexPathBatch::Create(geometry)); |
| 906 target->drawBatch(pipelineBuilder, batch, &devRect); | 1062 target->drawBatch(pipelineBuilder, batch, &devRect); |
| 907 | 1063 |
| 908 return true; | 1064 return true; |
| 909 | 1065 |
| 910 } | 1066 } |
| OLD | NEW |