| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrOpList_DEFINED |
| #define GrOpList_DEFINED |
| |
| #include "GrColor.h" |
| #include "GrGpuResourceRef.h" |
| #include "SkRefCnt.h" |
| #include "SkTDArray.h" |
| |
| |
| // Turn on/off the explicit distribution of GPU resources at flush time |
| //#define MDB_ALLOC_RESOURCES 1 |
| |
| // Turn on/off the sorting of opLists at flush time |
| //#define ENABLE_MDB_SORT 1 |
| |
| class GrAuditTrail; |
| class GrCaps; |
| class GrOpFlushState; |
| class GrRenderTargetOpList; |
| class GrResourceAllocator; |
| class GrResourceProvider; |
| class GrSurfaceProxy; |
| class GrTextureProxy; |
| class GrTextureOpList; |
| |
| struct SkIPoint; |
| struct SkIRect; |
| |
| class GrOpList : public SkRefCnt { |
| public: |
| GrOpList(GrResourceProvider*, GrSurfaceProxy*, GrAuditTrail*); |
| ~GrOpList() override; |
| |
| // These four methods are invoked at flush time |
| bool instantiate(GrResourceProvider* resourceProvider); |
| // Instantiates any "threaded" texture proxies that are being prepared elsewhere |
| void instantiateDeferredProxies(GrResourceProvider* resourceProvider); |
| void prepare(GrOpFlushState* flushState); |
| bool execute(GrOpFlushState* flushState) { return this->onExecute(flushState); } |
| |
| virtual bool copySurface(const GrCaps& caps, |
| GrSurfaceProxy* dst, |
| GrSurfaceProxy* src, |
| const SkIRect& srcRect, |
| const SkIPoint& dstPoint) = 0; |
| |
| virtual void makeClosed(const GrCaps&) { |
| if (!this->isClosed()) { |
| this->setFlag(kClosed_Flag); |
| fTarget.removeRef(); |
| } |
| } |
| |
| virtual void reset(); |
| |
| // TODO: in an MDB world, where the OpLists don't allocate GPU resources, it seems like |
| // these could go away |
| virtual void abandonGpuResources() = 0; |
| virtual void freeGpuResources() = 0; |
| |
| bool isClosed() const { return this->isSetFlag(kClosed_Flag); } |
| |
| /* |
| * Notify this GrOpList that it relies on the contents of 'dependedOn' |
| */ |
| void addDependency(GrSurfaceProxy* dependedOn, const GrCaps& caps); |
| |
| /* |
| * Does this opList depend on 'dependedOn'? |
| */ |
| bool dependsOn(GrOpList* dependedOn) const { |
| for (int i = 0; i < fDependencies.count(); ++i) { |
| if (fDependencies[i] == dependedOn) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /* |
| * Safely cast this GrOpList to a GrTextureOpList (if possible). |
| */ |
| virtual GrTextureOpList* asTextureOpList() { return nullptr; } |
| |
| /* |
| * Safely case this GrOpList to a GrRenderTargetOpList (if possible). |
| */ |
| virtual GrRenderTargetOpList* asRenderTargetOpList() { return nullptr; } |
| |
| int32_t uniqueID() const { return fUniqueID; } |
| |
| /* |
| * Dump out the GrOpList dependency DAG |
| */ |
| SkDEBUGCODE(virtual void dump() const;) |
| |
| SkDEBUGCODE(virtual int numOps() const = 0;) |
| SkDEBUGCODE(virtual int numClips() const { return 0; }) |
| |
| // TODO: it would be nice for this to be hidden |
| void setStencilLoadOp(GrLoadOp loadOp) { fStencilLoadOp = loadOp; } |
| |
| protected: |
| SkDEBUGCODE(bool isInstantiated() const;) |
| |
| GrSurfaceProxyRef fTarget; |
| GrAuditTrail* fAuditTrail; |
| |
| GrLoadOp fColorLoadOp = GrLoadOp::kLoad; |
| GrColor fLoadClearColor = 0x0; |
| GrLoadOp fStencilLoadOp = GrLoadOp::kLoad; |
| |
| // List of texture proxies whose contents are being prepared on a worker thread |
| SkTArray<GrTextureProxy*, true> fDeferredProxies; |
| |
| private: |
| friend class GrDrawingManager; // for resetFlag, TopoSortTraits & gatherProxyIntervals |
| |
| // Feed proxy usage intervals to the GrResourceAllocator class |
| virtual void gatherProxyIntervals(GrResourceAllocator*) const = 0; |
| |
| static uint32_t CreateUniqueID(); |
| |
| enum Flags { |
| kClosed_Flag = 0x01, //!< This GrOpList can't accept any more ops |
| |
| kWasOutput_Flag = 0x02, //!< Flag for topological sorting |
| kTempMark_Flag = 0x04, //!< Flag for topological sorting |
| }; |
| |
| void setFlag(uint32_t flag) { |
| fFlags |= flag; |
| } |
| |
| void resetFlag(uint32_t flag) { |
| fFlags &= ~flag; |
| } |
| |
| bool isSetFlag(uint32_t flag) const { |
| return SkToBool(fFlags & flag); |
| } |
| |
| struct TopoSortTraits { |
| static void Output(GrOpList* dt, int /* index */) { |
| dt->setFlag(GrOpList::kWasOutput_Flag); |
| } |
| static bool WasOutput(const GrOpList* dt) { |
| return dt->isSetFlag(GrOpList::kWasOutput_Flag); |
| } |
| static void SetTempMark(GrOpList* dt) { |
| dt->setFlag(GrOpList::kTempMark_Flag); |
| } |
| static void ResetTempMark(GrOpList* dt) { |
| dt->resetFlag(GrOpList::kTempMark_Flag); |
| } |
| static bool IsTempMarked(const GrOpList* dt) { |
| return dt->isSetFlag(GrOpList::kTempMark_Flag); |
| } |
| static int NumDependencies(const GrOpList* dt) { |
| return dt->fDependencies.count(); |
| } |
| static GrOpList* Dependency(GrOpList* dt, int index) { |
| return dt->fDependencies[index]; |
| } |
| }; |
| |
| virtual void onPrepare(GrOpFlushState* flushState) = 0; |
| virtual bool onExecute(GrOpFlushState* flushState) = 0; |
| |
| void addDependency(GrOpList* dependedOn); |
| |
| uint32_t fUniqueID; |
| uint32_t fFlags; |
| |
| // 'this' GrOpList relies on the output of the GrOpLists in 'fDependencies' |
| SkSTArray<1, GrOpList*, true> fDependencies; |
| |
| typedef SkRefCnt INHERITED; |
| }; |
| |
| #endif |