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