blob: 9a3b2e4d51e549038b3f99bf319ed504f494ee44 [file] [log] [blame]
Chris Daltone1639692018-08-20 14:00:30 -06001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#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"
Chris Daltone1639692018-08-20 14:00:30 -060019
20class GrOnFlushResourceProvider;
21class SkMatrix;
22class SkPath;
23
24/**
25 * This class parses SkPaths into CCPR primitives in GPU buffers, then issues calls to draw their
26 * coverage counts.
27 */
28class GrCCFiller {
29public:
Chris Daltonc3318f02019-07-19 14:20:53 -060030 enum class Algorithm : bool {
31 kCoverageCount,
32 kStencilWindingCount
33 };
34
35 GrCCFiller(Algorithm, int numPaths, int numSkPoints, int numSkVerbs, int numConicWeights);
Chris Daltone1639692018-08-20 14:00:30 -060036
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.
Chris Daltonc3318f02019-07-19 14:20:53 -060053 void drawFills(GrOpFlushState*, GrCCCoverageProcessor*, const GrPipeline&, BatchID,
54 const SkIRect& drawBounds) const;
Chris Daltone1639692018-08-20 14:00:30 -060055
56private:
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:
63 PathInfo(GrScissorTest scissorTest, const SkIVector& devToAtlasOffset)
64 : fScissorTest(scissorTest), fDevToAtlasOffset(devToAtlasOffset) {}
65
66 GrScissorTest scissorTest() const { return fScissorTest; }
67 const SkIVector& devToAtlasOffset() const { return fDevToAtlasOffset; }
68
69 // An empty tessellation fan is also valid; we use negative count to denote not tessellated.
70 bool hasFanTessellation() const { return fFanTessellationCount >= 0; }
71 int fanTessellationCount() const {
72 SkASSERT(this->hasFanTessellation());
73 return fFanTessellationCount;
74 }
75 const GrTessellator::WindingVertex* fanTessellation() const {
76 SkASSERT(this->hasFanTessellation());
77 return fFanTessellation.get();
78 }
Chris Daltonc3318f02019-07-19 14:20:53 -060079 void tessellateFan(
80 Algorithm, const SkPath& originalPath, const GrCCFillGeometry&, int verbsIdx,
81 int ptsIdx, const SkIRect& clippedDevIBounds, PrimitiveTallies* newTriangleCounts);
Chris Daltone1639692018-08-20 14:00:30 -060082
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
Chris Daltonc3318f02019-07-19 14:20:53 -0600105 void emitTessellatedFan(
106 const GrTessellator::WindingVertex*, int numVertices, const Sk2f& devToAtlasOffset,
107 GrCCCoverageProcessor::TriPointInstance::Ordering,
108 GrCCCoverageProcessor::TriPointInstance*, GrCCCoverageProcessor::QuadPointInstance*,
109 GrCCFillGeometry::PrimitiveTallies*);
Chris Dalton2c5e0112019-03-29 13:14:18 -0500110 void drawPrimitives(GrOpFlushState*, const GrCCCoverageProcessor&, const GrPipeline&, BatchID,
111 int PrimitiveTallies::*instanceType, const SkIRect& drawBounds) const;
Chris Daltone1639692018-08-20 14:00:30 -0600112
Chris Daltonc3318f02019-07-19 14:20:53 -0600113 const Algorithm fAlgorithm;
Chris Daltone1639692018-08-20 14:00:30 -0600114 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
Brian Salomondbf70722019-02-07 11:31:24 -0500121 sk_sp<GrGpuBuffer> fInstanceBuffer;
Chris Daltone1639692018-08-20 14:00:30 -0600122 PrimitiveTallies fBaseInstances[kNumScissorModes];
123 mutable SkSTArray<32, GrMesh> fMeshesScratchBuffer;
124 mutable SkSTArray<32, SkIRect> fScissorRectScratchBuffer;
125};
126
Chris Daltone1639692018-08-20 14:00:30 -0600127#endif