1 /*
2  * Copyright 2018 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 GrCCDrawPathsOp_DEFINED
9 #define GrCCDrawPathsOp_DEFINED
10 
11 #include "GrShape.h"
12 #include "SkTInternalLList.h"
13 #include "ccpr/GrCCSTLList.h"
14 #include "ccpr/GrCCPathCache.h"
15 #include "ops/GrDrawOp.h"
16 
17 class GrCCAtlas;
18 class GrCCPerFlushResources;
19 struct GrCCPerFlushResourceSpecs;
20 struct GrCCPerOpListPaths;
21 class GrOnFlushResourceProvider;
22 class GrRecordingContext;
23 
24 /**
25  * This is the Op that draws paths to the actual canvas, using atlases generated by CCPR.
26  */
27 class GrCCDrawPathsOp : public GrDrawOp {
28 public:
29     DEFINE_OP_CLASS_ID
30     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrCCDrawPathsOp);
31 
32     static std::unique_ptr<GrCCDrawPathsOp> Make(GrRecordingContext*, const SkIRect& clipIBounds,
33                                                  const SkMatrix&, const GrShape&, GrPaint&&);
34     ~GrCCDrawPathsOp() override;
35 
name()36     const char* name() const override { return "GrCCDrawPathsOp"; }
fixedFunctionFlags()37     FixedFunctionFlags fixedFunctionFlags() const override { return FixedFunctionFlags::kNone; }
38     GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrFSAAType,
39                                       GrClampType) override;
40     CombineResult onCombineIfPossible(GrOp*, const GrCaps&) override;
visitProxies(const VisitProxyFunc & fn,VisitorType)41     void visitProxies(const VisitProxyFunc& fn, VisitorType) const override {
42         fProcessors.visitProxies(fn);
43     }
onPrepare(GrOpFlushState *)44     void onPrepare(GrOpFlushState*) override {}
45 
46     void addToOwningPerOpListPaths(sk_sp<GrCCPerOpListPaths> owningPerOpListPaths);
47 
48     // Makes decisions about how to draw each path (cached, copied, rendered, etc.), and
49     // increments/fills out the corresponding GrCCPerFlushResourceSpecs.
50     void accountForOwnPaths(GrCCPathCache*, GrOnFlushResourceProvider*, GrCCPerFlushResourceSpecs*);
51 
52     // Allows the caller to decide whether to actually do the suggested copies from cached 16-bit
53     // coverage count atlases, and into 8-bit literal coverage atlases. Purely to save space.
54     enum class DoCopiesToA8Coverage : bool {
55         kNo = false,
56         kYes = true
57     };
58 
59     // Allocates the GPU resources indicated by accountForOwnPaths(), in preparation for drawing. If
60     // DoCopiesToA8Coverage is kNo, the paths slated for copy will instead be left in their 16-bit
61     // coverage count atlases.
62     //
63     // NOTE: If using DoCopiesToA8Coverage::kNo, it is the caller's responsibility to have called
64     // cancelCopies() on the GrCCPerFlushResourceSpecs, prior to making this call.
65     void setupResources(GrCCPathCache*, GrOnFlushResourceProvider*, GrCCPerFlushResources*,
66                         DoCopiesToA8Coverage);
67 
68     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
69 
70 private:
71     friend class GrOpMemoryPool;
72 
73     static std::unique_ptr<GrCCDrawPathsOp> InternalMake(GrRecordingContext*,
74                                                          const SkIRect& clipIBounds,
75                                                          const SkMatrix&, const GrShape&,
76                                                          float strokeDevWidth,
77                                                          const SkRect& conservativeDevBounds,
78                                                          GrPaint&&);
79 
80     GrCCDrawPathsOp(const SkMatrix&, const GrShape&, float strokeDevWidth,
81                     const SkIRect& shapeConservativeIBounds, const SkIRect& maskDevIBounds,
82                     const SkRect& conservativeDevBounds, GrPaint&&);
83 
84     void recordInstance(GrTextureProxy* atlasProxy, int instanceIdx);
85 
86     const SkMatrix fViewMatrixIfUsingLocalCoords;
87 
88     class SingleDraw {
89     public:
90         SingleDraw(const SkMatrix&, const GrShape&, float strokeDevWidth,
91                    const SkIRect& shapeConservativeIBounds, const SkIRect& maskDevIBounds,
92                    const SkPMColor4f&);
93 
94         // See the corresponding methods in GrCCDrawPathsOp.
95         GrProcessorSet::Analysis finalize(
96                 const GrCaps&, const GrAppliedClip*, GrFSAAType, GrClampType, GrProcessorSet*);
97         void accountForOwnPath(GrCCPathCache*, GrOnFlushResourceProvider*,
98                                GrCCPerFlushResourceSpecs*);
99         void setupResources(GrCCPathCache*, GrOnFlushResourceProvider*, GrCCPerFlushResources*,
100                             DoCopiesToA8Coverage, GrCCDrawPathsOp*);
101 
102     private:
103         bool shouldCachePathMask(int maxRenderTargetSize) const;
104 
105         SkMatrix fMatrix;
106         GrShape fShape;
107         float fStrokeDevWidth;
108         const SkIRect fShapeConservativeIBounds;
109         SkIRect fMaskDevIBounds;
110         SkPMColor4f fColor;
111 
112         GrCCPathCache::OnFlushEntryRef fCacheEntry;
113         SkIVector fCachedMaskShift;
114         bool fDoCopyToA8Coverage = false;
115         bool fDoCachePathMask = false;
116 
117         SingleDraw* fNext = nullptr;
118 
119         friend class GrCCSTLList<SingleDraw>;  // To access fNext.
120     };
121 
122     // Declare fOwningPerOpListPaths first, before fDraws. The draws use memory allocated by
123     // fOwningPerOpListPaths, so it must not be unreffed until after fDraws is destroyed.
124     sk_sp<GrCCPerOpListPaths> fOwningPerOpListPaths;
125 
126     GrCCSTLList<SingleDraw> fDraws;
127     SkDEBUGCODE(int fNumDraws = 1);
128 
129     GrProcessorSet fProcessors;
130 
131     struct InstanceRange {
132         GrTextureProxy* fAtlasProxy;
133         int fEndInstanceIdx;
134     };
135 
136     SkSTArray<2, InstanceRange, true> fInstanceRanges;
137     int fBaseInstance SkDEBUGCODE(= -1);
138 };
139 
140 #endif
141