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 "SkRefCnt.h"
12 #include "SkTDArray.h"
13 
14 //#define ENABLE_MDB 1
15 
16 class GrAuditTrail;
17 class GrOpFlushState;
18 class GrRenderTargetOpList;
19 class GrSurface;
20 class GrSurfaceProxy;
21 class GrTextureOpList;
22 
23 class GrOpList : public SkRefCnt {
24 public:
25     GrOpList(GrSurfaceProxy* surfaceProxy, GrAuditTrail* auditTrail);
26     ~GrOpList() override;
27 
28     // These two methods are invoked as flush time
29     virtual void prepareOps(GrOpFlushState* flushState) = 0;
30     virtual bool executeOps(GrOpFlushState* flushState) = 0;
31 
makeClosed()32     virtual void makeClosed() {
33         // We only close GrOpLists when MDB is enabled. When MDB is disabled there is only
34         // ever one GrOpLists and all calls will be funnelled into it.
35 #ifdef ENABLE_MDB
36         this->setFlag(kClosed_Flag);
37 #endif
38     }
39 
40     // TODO: it seems a bit odd that GrOpList has nothing to clear on reset
41     virtual void reset() = 0;
42 
43     // TODO: in an MDB world, where the OpLists don't allocate GPU resources, it seems like
44     // these could go away
45     virtual void abandonGpuResources() = 0;
46     virtual void freeGpuResources() = 0;
47 
48     // TODO: this entry point is only needed in the non-MDB world. Remove when
49     // we make the switch to MDB
clearTarget()50     void clearTarget() { fTarget = nullptr; }
51 
isClosed()52     bool isClosed() const { return this->isSetFlag(kClosed_Flag); }
53 
54     /*
55      * Notify this GrOpList that it relies on the contents of 'dependedOn'
56      */
57     void addDependency(GrSurface* dependedOn);
58 
59     /*
60      * Does this opList depend on 'dependedOn'?
61      */
dependsOn(GrOpList * dependedOn)62     bool dependsOn(GrOpList* dependedOn) const {
63         return fDependencies.find(dependedOn) >= 0;
64     }
65 
66     /*
67      * Safely cast this GrOpList to a GrTextureOpList (if possible).
68      */
asTextureOpList()69     virtual GrTextureOpList* asTextureOpList() { return nullptr; }
70 
71     /*
72      * Safely case this GrOpList to a GrRenderTargetOpList (if possible).
73      */
asRenderTargetOpList()74     virtual GrRenderTargetOpList* asRenderTargetOpList() { return nullptr; }
75 
uniqueID()76     int32_t uniqueID() const { return fUniqueID; }
77 
78     /*
79      * Dump out the GrOpList dependency DAG
80      */
81     SkDEBUGCODE(virtual void dump() const;)
82 
83 private:
84     friend class GrDrawingManager; // for resetFlag & TopoSortTraits
85 
86     static uint32_t CreateUniqueID();
87 
88     enum Flags {
89         kClosed_Flag    = 0x01,   //!< This GrOpList can't accept any more ops
90 
91         kWasOutput_Flag = 0x02,   //!< Flag for topological sorting
92         kTempMark_Flag  = 0x04,   //!< Flag for topological sorting
93     };
94 
setFlag(uint32_t flag)95     void setFlag(uint32_t flag) {
96         fFlags |= flag;
97     }
98 
resetFlag(uint32_t flag)99     void resetFlag(uint32_t flag) {
100         fFlags &= ~flag;
101     }
102 
isSetFlag(uint32_t flag)103     bool isSetFlag(uint32_t flag) const {
104         return SkToBool(fFlags & flag);
105     }
106 
107     struct TopoSortTraits {
OutputTopoSortTraits108         static void Output(GrOpList* dt, int /* index */) {
109             dt->setFlag(GrOpList::kWasOutput_Flag);
110         }
WasOutputTopoSortTraits111         static bool WasOutput(const GrOpList* dt) {
112             return dt->isSetFlag(GrOpList::kWasOutput_Flag);
113         }
SetTempMarkTopoSortTraits114         static void SetTempMark(GrOpList* dt) {
115             dt->setFlag(GrOpList::kTempMark_Flag);
116         }
ResetTempMarkTopoSortTraits117         static void ResetTempMark(GrOpList* dt) {
118             dt->resetFlag(GrOpList::kTempMark_Flag);
119         }
IsTempMarkedTopoSortTraits120         static bool IsTempMarked(const GrOpList* dt) {
121             return dt->isSetFlag(GrOpList::kTempMark_Flag);
122         }
NumDependenciesTopoSortTraits123         static int NumDependencies(const GrOpList* dt) {
124             return dt->fDependencies.count();
125         }
DependencyTopoSortTraits126         static GrOpList* Dependency(GrOpList* dt, int index) {
127             return dt->fDependencies[index];
128         }
129     };
130 
131     void addDependency(GrOpList* dependedOn);
132 
133     uint32_t             fUniqueID;
134     uint32_t             fFlags;
135     GrSurfaceProxy*      fTarget;
136 
137     // 'this' GrOpList relies on the output of the GrOpLists in 'fDependencies'
138     SkTDArray<GrOpList*> fDependencies;
139 
140 protected:
141     GrAuditTrail*        fAuditTrail;
142 
143     typedef SkRefCnt INHERITED;
144 };
145 
146 #endif
147