• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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