Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2014 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 GrProgramElement_DEFINED
      9 #define GrProgramElement_DEFINED
     10 
     11 #include "SkRefCnt.h"
     12 #include "SkTArray.h"
     13 
     14 class GrGpuResourceRef;
     15 
     16 /**
     17  * Base class for GrProcessor. GrDrawState uses this to manage
     18  * transitioning a GrProcessor from being owned by a client to being scheduled for execution. It
     19  * converts resources owned by the effect from being ref'ed to having pending reads/writes.
     20  *
     21  * All GrGpuResource objects owned by a GrProgramElement or derived classes (either directly or
     22  * indirectly) must be wrapped in a GrGpuResourceRef and registered with the GrProgramElement using
     23  * addGpuResource(). This allows the regular refs to be converted to pending IO events
     24  * when the program element is scheduled for deferred execution.
     25  */
     26 class GrProgramElement : public SkNoncopyable {
     27 public:
     28     SK_DECLARE_INST_COUNT_ROOT(GrProgramElement)
     29 
     30     virtual ~GrProgramElement() {
     31         // fRefCnt can be one when an effect is created statically using GR_CREATE_STATIC_EFFECT
     32         SkASSERT((0 == fRefCnt || 1 == fRefCnt) && 0 == fPendingExecutions);
     33         // Set to invalid values.
     34         SkDEBUGCODE(fRefCnt = fPendingExecutions = -10;)
     35     }
     36 
     37     void ref() const {
     38         // Once the ref cnt reaches zero it should never be ref'ed again.
     39         SkASSERT(fRefCnt > 0);
     40         this->validate();
     41         ++fRefCnt;
     42     }
     43 
     44     void unref() const {
     45         this->validate();
     46         --fRefCnt;
     47         if (0 == fRefCnt && 0 == fPendingExecutions) {
     48             SkDELETE(this);
     49         }
     50     }
     51 
     52     /**
     53      * Gets an id that is unique for this GrProgramElement object. This will never return 0.
     54      */
     55     uint32_t getUniqueID() const { return fUniqueID; }
     56 
     57     void validate() const {
     58 #ifdef SK_DEBUG
     59         SkASSERT(fRefCnt >= 0);
     60         SkASSERT(fPendingExecutions >= 0);
     61         SkASSERT(fRefCnt + fPendingExecutions > 0);
     62 #endif
     63     }
     64 
     65 protected:
     66     GrProgramElement() : fRefCnt(1), fPendingExecutions(0), fUniqueID(CreateUniqueID()) {}
     67 
     68     /** Subclasses registers their resources using this function. It is assumed the GrProgramResouce
     69         is and will remain owned by the subclass and this function will retain a raw ptr. Once a
     70         GrGpuResourceRef is registered its setResource must not be called.
     71      */
     72     void addGpuResource(const GrGpuResourceRef* res) {
     73         fGpuResources.push_back(res);
     74     }
     75 
     76 private:
     77     static uint32_t CreateUniqueID();
     78 
     79     void convertRefToPendingExecution() const;
     80 
     81     void completedExecution() const;
     82 
     83     mutable int32_t fRefCnt;
     84     // Count of deferred executions not yet issued to the 3D API.
     85     mutable int32_t fPendingExecutions;
     86     uint32_t        fUniqueID;
     87 
     88     SkSTArray<4, const GrGpuResourceRef*, true> fGpuResources;
     89 
     90     // Only this class can access convertRefToPendingExecution() and completedExecution().
     91     template <typename T> friend class GrProgramElementRef;
     92 
     93     typedef SkNoncopyable INHERITED;
     94 };
     95 
     96 #endif
     97