1 /*
2  * Copyright 2016 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 GrOpList_DEFINED
9 #define GrOpList_DEFINED
10 
11 #include "GrProxyRef.h"
12 #include "GrTextureProxy.h"
13 #include "SkColorData.h"
14 #include "SkRefCnt.h"
15 #include "SkTDArray.h"
16 
17 class GrAuditTrail;
18 class GrCaps;
19 class GrOpFlushState;
20 class GrOpMemoryPool;
21 class GrRenderTargetOpList;
22 class GrResourceAllocator;
23 class GrResourceProvider;
24 class GrSurfaceProxy;
25 class GrTextureOpList;
26 
27 struct SkIPoint;
28 struct SkIRect;
29 
30 class GrOpList : public SkRefCnt {
31 public:
32     GrOpList(GrResourceProvider*, sk_sp<GrOpMemoryPool>, GrSurfaceProxy*, GrAuditTrail*);
33     ~GrOpList() override;
34 
35     // These four methods are invoked at flush time
36     bool instantiate(GrResourceProvider* resourceProvider);
37     // Instantiates any "threaded" texture proxies that are being prepared elsewhere
38     void instantiateDeferredProxies(GrResourceProvider* resourceProvider);
39     void prepare(GrOpFlushState* flushState);
execute(GrOpFlushState * flushState)40     bool execute(GrOpFlushState* flushState) { return this->onExecute(flushState); }
41 
42     virtual bool copySurface(GrContext*,
43                              GrSurfaceProxy* dst,
44                              GrSurfaceProxy* src,
45                              const SkIRect& srcRect,
46                              const SkIPoint& dstPoint) = 0;
47 
makeClosed(const GrCaps &)48     virtual void makeClosed(const GrCaps&) {
49         if (!this->isClosed()) {
50             this->setFlag(kClosed_Flag);
51             fTarget.removeRef();
52         }
53     }
54 
55     // Called when this class will survive a flush and needs to truncate its ops and start over.
56     // TODO: ultimately it should be invalid for an op list to survive a flush.
57     // https://bugs.chromium.org/p/skia/issues/detail?id=7111
58     virtual void endFlush();
59 
isClosed()60     bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
61 
62     /*
63      * Notify this GrOpList that it relies on the contents of 'dependedOn'
64      */
65     void addDependency(GrSurfaceProxy* dependedOn, const GrCaps& caps);
66 
67     /*
68      * Does this opList depend on 'dependedOn'?
69      */
70     bool dependsOn(const GrOpList* dependedOn) const;
71 
72     /*
73      * Safely cast this GrOpList to a GrTextureOpList (if possible).
74      */
asTextureOpList()75     virtual GrTextureOpList* asTextureOpList() { return nullptr; }
76 
77     /*
78      * Safely case this GrOpList to a GrRenderTargetOpList (if possible).
79      */
asRenderTargetOpList()80     virtual GrRenderTargetOpList* asRenderTargetOpList() { return nullptr; }
81 
uniqueID()82     uint32_t uniqueID() const { return fUniqueID; }
83 
84     /*
85      * Dump out the GrOpList dependency DAG
86      */
87     SkDEBUGCODE(virtual void dump(bool printDependencies) const;)
88 
89     SkDEBUGCODE(virtual int numClips() const { return 0; })
90 
91 protected:
92     bool isInstantiated() const;
93 
94     // In addition to just the GrSurface being allocated, has the stencil buffer been allocated (if
95     // it is required)?
96     bool isFullyInstantiated() const;
97 
98     // This is a backpointer to the GrOpMemoryPool that holds the memory for this opLists' ops.
99     // In the DDL case, these back pointers keep the DDL's GrOpMemoryPool alive as long as its
100     // constituent opLists survive.
101     sk_sp<GrOpMemoryPool> fOpMemoryPool;
102     GrSurfaceProxyRef     fTarget;
103     GrAuditTrail*         fAuditTrail;
104 
105     GrLoadOp              fColorLoadOp    = GrLoadOp::kLoad;
106     SkPMColor4f           fLoadClearColor = SK_PMColor4fTRANSPARENT;
107     GrLoadOp              fStencilLoadOp  = GrLoadOp::kLoad;
108 
109     // List of texture proxies whose contents are being prepared on a worker thread
110     SkTArray<GrTextureProxy*, true> fDeferredProxies;
111 
112 private:
113     friend class GrDrawingManager; // for resetFlag, TopoSortTraits & gatherProxyIntervals
114 
115     void addDependency(GrOpList* dependedOn);
116     void addDependent(GrOpList* dependent);
117     SkDEBUGCODE(bool isDependedent(const GrOpList* dependent) const);
118     SkDEBUGCODE(void validate() const);
119     void closeThoseWhoDependOnMe(const GrCaps&);
120 
121     // Remove all Ops which reference proxies that are not instantiated.
122     virtual void purgeOpsWithUninstantiatedProxies() = 0;
123 
124     // Feed proxy usage intervals to the GrResourceAllocator class
125     virtual void gatherProxyIntervals(GrResourceAllocator*) const = 0;
126 
127     static uint32_t CreateUniqueID();
128 
129     enum Flags {
130         kClosed_Flag    = 0x01,   //!< This GrOpList can't accept any more ops
131 
132         kWasOutput_Flag = 0x02,   //!< Flag for topological sorting
133         kTempMark_Flag  = 0x04,   //!< Flag for topological sorting
134     };
135 
setFlag(uint32_t flag)136     void setFlag(uint32_t flag) {
137         fFlags |= flag;
138     }
139 
resetFlag(uint32_t flag)140     void resetFlag(uint32_t flag) {
141         fFlags &= ~flag;
142     }
143 
isSetFlag(uint32_t flag)144     bool isSetFlag(uint32_t flag) const {
145         return SkToBool(fFlags & flag);
146     }
147 
148     struct TopoSortTraits {
OutputTopoSortTraits149         static void Output(GrOpList* opList, int /* index */) {
150             opList->setFlag(GrOpList::kWasOutput_Flag);
151         }
WasOutputTopoSortTraits152         static bool WasOutput(const GrOpList* opList) {
153             return opList->isSetFlag(GrOpList::kWasOutput_Flag);
154         }
SetTempMarkTopoSortTraits155         static void SetTempMark(GrOpList* opList) {
156             opList->setFlag(GrOpList::kTempMark_Flag);
157         }
ResetTempMarkTopoSortTraits158         static void ResetTempMark(GrOpList* opList) {
159             opList->resetFlag(GrOpList::kTempMark_Flag);
160         }
IsTempMarkedTopoSortTraits161         static bool IsTempMarked(const GrOpList* opList) {
162             return opList->isSetFlag(GrOpList::kTempMark_Flag);
163         }
NumDependenciesTopoSortTraits164         static int NumDependencies(const GrOpList* opList) {
165             return opList->fDependencies.count();
166         }
DependencyTopoSortTraits167         static GrOpList* Dependency(GrOpList* opList, int index) {
168             return opList->fDependencies[index];
169         }
170     };
171 
172     virtual void onPrepare(GrOpFlushState* flushState) = 0;
173     virtual bool onExecute(GrOpFlushState* flushState) = 0;
174 
175     uint32_t               fUniqueID;
176     uint32_t               fFlags;
177 
178     // 'this' GrOpList relies on the output of the GrOpLists in 'fDependencies'
179     SkSTArray<1, GrOpList*, true> fDependencies;
180     // 'this' GrOpList's output is relied on by the GrOpLists in 'fDependents'
181     SkSTArray<1, GrOpList*, true> fDependents;
182 
183     typedef SkRefCnt INHERITED;
184 };
185 
186 #endif
187