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 "GrMesh.h" 12 #include "SkPathPriv.h" 13 #include "SkRect.h" 14 #include "SkRefCnt.h" 15 #include "GrTessellator.h" 16 #include "ccpr/GrCCCoverageProcessor.h" 17 #include "ccpr/GrCCFillGeometry.h" 18 #include "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 GrCCFiller(int numPaths, int numSkPoints, int numSkVerbs, int numConicWeights); 31 32 // Parses a device-space SkPath into the current batch, using the SkPath's original verbs and 33 // 'deviceSpacePts'. Accepts an optional post-device-space translate for placement in an atlas. 34 void parseDeviceSpaceFill(const SkPath&, const SkPoint* deviceSpacePts, GrScissorTest, 35 const SkIRect& clippedDevIBounds, const SkIVector& devToAtlasOffset); 36 37 using BatchID = int; 38 39 // Compiles the outstanding parsed paths into a batch, and returns an ID that can be used to 40 // draw their fills in the future. 41 BatchID closeCurrentBatch(); 42 43 // Builds internal GPU buffers and prepares for calls to drawFills(). Caller must close the 44 // current batch before calling this method, and cannot parse new paths afer. 45 bool prepareToDraw(GrOnFlushResourceProvider*); 46 47 // Called after prepareToDraw(). Draws the given batch of path fills. 48 void drawFills(GrOpFlushState*, BatchID, const SkIRect& drawBounds) const; 49 50 private: 51 static constexpr int kNumScissorModes = 2; 52 using PrimitiveTallies = GrCCFillGeometry::PrimitiveTallies; 53 54 // Every kBeginPath verb has a corresponding PathInfo entry. 55 class PathInfo { 56 public: PathInfo(GrScissorTest scissorTest,const SkIVector & devToAtlasOffset)57 PathInfo(GrScissorTest scissorTest, const SkIVector& devToAtlasOffset) 58 : fScissorTest(scissorTest), fDevToAtlasOffset(devToAtlasOffset) {} 59 scissorTest()60 GrScissorTest scissorTest() const { return fScissorTest; } devToAtlasOffset()61 const SkIVector& devToAtlasOffset() const { return fDevToAtlasOffset; } 62 63 // An empty tessellation fan is also valid; we use negative count to denote not tessellated. hasFanTessellation()64 bool hasFanTessellation() const { return fFanTessellationCount >= 0; } fanTessellationCount()65 int fanTessellationCount() const { 66 SkASSERT(this->hasFanTessellation()); 67 return fFanTessellationCount; 68 } fanTessellation()69 const GrTessellator::WindingVertex* fanTessellation() const { 70 SkASSERT(this->hasFanTessellation()); 71 return fFanTessellation.get(); 72 } 73 void tessellateFan(const GrCCFillGeometry&, int verbsIdx, int ptsIdx, 74 const SkIRect& clippedDevIBounds, PrimitiveTallies* newTriangleCounts); 75 76 private: 77 GrScissorTest fScissorTest; 78 SkIVector fDevToAtlasOffset; // Translation from device space to location in atlas. 79 int fFanTessellationCount = -1; 80 std::unique_ptr<const GrTessellator::WindingVertex[]> fFanTessellation; 81 }; 82 83 // Defines a batch of CCPR primitives. Start indices are deduced by looking at the previous 84 // Batch in the list. 85 struct Batch { 86 PrimitiveTallies fEndNonScissorIndices; 87 int fEndScissorSubBatchIdx; 88 PrimitiveTallies fTotalPrimitiveCounts; 89 }; 90 91 // Defines a sub-batch that will be drawn with the given scissor rect. Start indices are deduced 92 // by looking at the previous ScissorSubBatch in the list. 93 struct ScissorSubBatch { 94 PrimitiveTallies fEndPrimitiveIndices; 95 SkIRect fScissor; 96 }; 97 98 void drawPrimitives(GrOpFlushState*, const GrPipeline&, BatchID, 99 GrCCCoverageProcessor::PrimitiveType, int PrimitiveTallies::*instanceType, 100 const SkIRect& drawBounds) const; 101 102 GrCCFillGeometry fGeometry; 103 SkSTArray<32, PathInfo, true> fPathInfos; 104 SkSTArray<32, Batch, true> fBatches; 105 SkSTArray<32, ScissorSubBatch, true> fScissorSubBatches; 106 PrimitiveTallies fTotalPrimitiveCounts[kNumScissorModes]; 107 int fMaxMeshesPerDraw = 0; 108 109 sk_sp<GrBuffer> fInstanceBuffer; 110 PrimitiveTallies fBaseInstances[kNumScissorModes]; 111 mutable SkSTArray<32, GrMesh> fMeshesScratchBuffer; 112 mutable SkSTArray<32, SkIRect> fScissorRectScratchBuffer; 113 }; 114 115 #endif 116