1 /* 2 * Copyright 2017 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrCCPathParser_DEFINED 9 #define GrCCPathParser_DEFINED 10 11 #include "include/core/SkRect.h" 12 #include "include/core/SkRefCnt.h" 13 #include "src/core/SkPathPriv.h" 14 #include "src/gpu/GrMesh.h" 15 #include "src/gpu/GrTessellator.h" 16 #include "src/gpu/ccpr/GrCCCoverageProcessor.h" 17 #include "src/gpu/ccpr/GrCCFillGeometry.h" 18 #include "src/gpu/ops/GrDrawOp.h" 19 20 class GrOnFlushResourceProvider; 21 class SkMatrix; 22 class SkPath; 23 24 /** 25 * This class parses SkPaths into CCPR primitives in GPU buffers, then issues calls to draw their 26 * coverage counts. 27 */ 28 class GrCCFiller { 29 public: 30 enum class Algorithm : bool { 31 kCoverageCount, 32 kStencilWindingCount 33 }; 34 35 GrCCFiller(Algorithm, int numPaths, int numSkPoints, int numSkVerbs, int numConicWeights); 36 37 // Parses a device-space SkPath into the current batch, using the SkPath's original verbs and 38 // 'deviceSpacePts'. Accepts an optional post-device-space translate for placement in an atlas. 39 void parseDeviceSpaceFill(const SkPath&, const SkPoint* deviceSpacePts, GrScissorTest, 40 const SkIRect& clippedDevIBounds, const SkIVector& devToAtlasOffset); 41 42 using BatchID = int; 43 44 // Compiles the outstanding parsed paths into a batch, and returns an ID that can be used to 45 // draw their fills in the future. 46 BatchID closeCurrentBatch(); 47 48 // Builds internal GPU buffers and prepares for calls to drawFills(). Caller must close the 49 // current batch before calling this method, and cannot parse new paths afer. 50 bool prepareToDraw(GrOnFlushResourceProvider*); 51 52 // Called after prepareToDraw(). Draws the given batch of path fills. 53 void drawFills(GrOpFlushState*, GrCCCoverageProcessor*, const GrPipeline&, BatchID, 54 const SkIRect& drawBounds) const; 55 56 private: 57 static constexpr int kNumScissorModes = 2; 58 using PrimitiveTallies = GrCCFillGeometry::PrimitiveTallies; 59 60 // Every kBeginPath verb has a corresponding PathInfo entry. 61 class PathInfo { 62 public: PathInfo(GrScissorTest scissorTest,const SkIVector & devToAtlasOffset)63 PathInfo(GrScissorTest scissorTest, const SkIVector& devToAtlasOffset) 64 : fScissorTest(scissorTest), fDevToAtlasOffset(devToAtlasOffset) {} 65 scissorTest()66 GrScissorTest scissorTest() const { return fScissorTest; } devToAtlasOffset()67 const SkIVector& devToAtlasOffset() const { return fDevToAtlasOffset; } 68 69 // An empty tessellation fan is also valid; we use negative count to denote not tessellated. hasFanTessellation()70 bool hasFanTessellation() const { return fFanTessellationCount >= 0; } fanTessellationCount()71 int fanTessellationCount() const { 72 SkASSERT(this->hasFanTessellation()); 73 return fFanTessellationCount; 74 } fanTessellation()75 const GrTessellator::WindingVertex* fanTessellation() const { 76 SkASSERT(this->hasFanTessellation()); 77 return fFanTessellation.get(); 78 } 79 void tessellateFan( 80 Algorithm, const SkPath& originalPath, const GrCCFillGeometry&, int verbsIdx, 81 int ptsIdx, const SkIRect& clippedDevIBounds, PrimitiveTallies* newTriangleCounts); 82 83 private: 84 GrScissorTest fScissorTest; 85 SkIVector fDevToAtlasOffset; // Translation from device space to location in atlas. 86 int fFanTessellationCount = -1; 87 std::unique_ptr<const GrTessellator::WindingVertex[]> fFanTessellation; 88 }; 89 90 // Defines a batch of CCPR primitives. Start indices are deduced by looking at the previous 91 // Batch in the list. 92 struct Batch { 93 PrimitiveTallies fEndNonScissorIndices; 94 int fEndScissorSubBatchIdx; 95 PrimitiveTallies fTotalPrimitiveCounts; 96 }; 97 98 // Defines a sub-batch that will be drawn with the given scissor rect. Start indices are deduced 99 // by looking at the previous ScissorSubBatch in the list. 100 struct ScissorSubBatch { 101 PrimitiveTallies fEndPrimitiveIndices; 102 SkIRect fScissor; 103 }; 104 105 void emitTessellatedFan( 106 const GrTessellator::WindingVertex*, int numVertices, const Sk2f& devToAtlasOffset, 107 GrCCCoverageProcessor::TriPointInstance::Ordering, 108 GrCCCoverageProcessor::TriPointInstance*, GrCCCoverageProcessor::QuadPointInstance*, 109 GrCCFillGeometry::PrimitiveTallies*); 110 void drawPrimitives(GrOpFlushState*, const GrCCCoverageProcessor&, const GrPipeline&, BatchID, 111 int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const; 112 113 const Algorithm fAlgorithm; 114 GrCCFillGeometry fGeometry; 115 SkSTArray<32, PathInfo, true> fPathInfos; 116 SkSTArray<32, Batch, true> fBatches; 117 SkSTArray<32, ScissorSubBatch, true> fScissorSubBatches; 118 PrimitiveTallies fTotalPrimitiveCounts[kNumScissorModes]; 119 int fMaxMeshesPerDraw = 0; 120 121 sk_sp<GrGpuBuffer> fInstanceBuffer; 122 PrimitiveTallies fBaseInstances[kNumScissorModes]; 123 mutable SkSTArray<32, GrMesh> fMeshesScratchBuffer; 124 mutable SkSTArray<32, SkIRect> fScissorRectScratchBuffer; 125 }; 126 127 #endif 128