• 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 "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