Home | History | Annotate | Download | only in private
      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