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