Skia
2DGraphicsLibrary
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GrGpuResource.h
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 GrGpuResource_DEFINED
9 #define GrGpuResource_DEFINED
10 
11 #include "GrResourceKey.h"
12 #include "GrTypesPriv.h"
13 
14 class GrContext;
15 class GrGpu;
16 class GrResourceCache;
17 class SkTraceMemoryDump;
18 
46 template <typename DERIVED> class GrIORef : public SkNoncopyable {
47 public:
48  // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
49  // templated helper classes (e.g. sk_sp). However, we have different categories of
50  // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
51  // not intended to cross thread boundaries.
52  void ref() const {
53  this->validate();
54  ++fRefCnt;
55  }
56 
57  void unref() const {
58  this->validate();
59 
60  if (!(--fRefCnt)) {
61  if (!static_cast<const DERIVED*>(this)->notifyRefCountIsZero()) {
62  return;
63  }
64  }
65 
66  this->didRemoveRefOrPendingIO(kRef_CntType);
67  }
68 
69  void validate() const {
70 #ifdef SK_DEBUG
71  SkASSERT(fRefCnt >= 0);
72  SkASSERT(fPendingReads >= 0);
73  SkASSERT(fPendingWrites >= 0);
74  SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0);
75 #endif
76  }
77 
78 protected:
79  GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { }
80 
81  enum CntType {
82  kRef_CntType,
83  kPendingRead_CntType,
84  kPendingWrite_CntType,
85  };
86 
87  bool isPurgeable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); }
88 
89  bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
90  bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
91  bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
92 
93  bool internalHasRef() const { return SkToBool(fRefCnt); }
94 
95 private:
96  friend class GrIORefProxy; // needs to forward on wrapped IO calls
97  // This is for a unit test.
98  template <typename T>
99  friend void testingOnly_getIORefCnts(const T*, int* refCnt, int* readCnt, int* writeCnt);
100 
101  void addPendingRead() const {
102  this->validate();
103  ++fPendingReads;
104  }
105 
106  void completedRead() const {
107  this->validate();
108  --fPendingReads;
109  this->didRemoveRefOrPendingIO(kPendingRead_CntType);
110  }
111 
112  void addPendingWrite() const {
113  this->validate();
114  ++fPendingWrites;
115  }
116 
117  void completedWrite() const {
118  this->validate();
119  --fPendingWrites;
120  this->didRemoveRefOrPendingIO(kPendingWrite_CntType);
121  }
122 
123 private:
124  void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const {
125  if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
126  static_cast<const DERIVED*>(this)->notifyAllCntsAreZero(cntTypeRemoved);
127  }
128  }
129 
130  mutable int32_t fRefCnt;
131  mutable int32_t fPendingReads;
132  mutable int32_t fPendingWrites;
133 
134  // This class is used to manage conversion of refs to pending reads/writes.
135  friend class GrGpuResourceRef;
136  friend class GrResourceCache; // to check IO ref counts.
137 
138  template <typename, GrIOType> friend class GrPendingIOResource;
139 };
140 
144 class SK_API GrGpuResource : public GrIORef<GrGpuResource> {
145 public:
146 
157  bool wasDestroyed() const { return NULL == fGpu; }
158 
165  const GrContext* getContext() const;
166  GrContext* getContext();
167 
175  size_t gpuMemorySize() const {
176  if (kInvalidGpuMemorySize == fGpuMemorySize) {
177  fGpuMemorySize = this->onGpuMemorySize();
178  SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
179  }
180  return fGpuMemorySize;
181  }
182 
183  class UniqueID {
184  public:
185  static UniqueID InvalidID() {
186  return UniqueID(uint32_t(SK_InvalidUniqueID));
187  }
188 
189  UniqueID() {}
190 
191  explicit UniqueID(uint32_t id) : fID(id) {}
192 
193  uint32_t asUInt() const { return fID; }
194 
195  bool operator==(const UniqueID& other) const {
196  return fID == other.fID;
197  }
198  bool operator!=(const UniqueID& other) const {
199  return !(*this == other);
200  }
201 
202  void makeInvalid() { fID = SK_InvalidUniqueID; }
203  bool isInvalid() const { return SK_InvalidUniqueID == fID; }
204 
205  protected:
206  uint32_t fID;
207  };
208 
214  UniqueID uniqueID() const { return fUniqueID; }
215 
218  const GrUniqueKey& getUniqueKey() const { return fUniqueKey; }
219 
223  class CacheAccess;
224  inline CacheAccess cacheAccess();
225  inline const CacheAccess cacheAccess() const;
226 
230  class ResourcePriv;
231  inline ResourcePriv resourcePriv();
232  inline const ResourcePriv resourcePriv() const;
233 
242  void abandon();
243 
249  virtual void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
250 
251  static uint32_t CreateUniqueID();
252 
253 protected:
254  // This must be called by every non-wrapped GrGpuObject. It should be called once the object is
255  // fully initialized (i.e. only from the constructors of the final class).
256  void registerWithCache(SkBudgeted);
257 
258  // This must be called by every GrGpuObject that references any wrapped backend objects. It
259  // should be called once the object is fully initialized (i.e. only from the constructors of the
260  // final class).
261  void registerWithCacheWrapped();
262 
263  GrGpuResource(GrGpu*);
264  virtual ~GrGpuResource();
265 
266  GrGpu* getGpu() const { return fGpu; }
267 
269  virtual void onRelease() { }
273  virtual void onAbandon() { }
274 
279  void didChangeGpuMemorySize() const;
280 
285  virtual void setMemoryBacking(SkTraceMemoryDump*, const SkString&) const {}
286 
287 private:
294  virtual void computeScratchKey(GrScratchKey*) const { }
295 
299  void release();
300 
301  virtual size_t onGpuMemorySize() const = 0;
302 
303  // See comments in CacheAccess and ResourcePriv.
304  void setUniqueKey(const GrUniqueKey&);
305  void removeUniqueKey();
306  void notifyAllCntsAreZero(CntType) const;
307  bool notifyRefCountIsZero() const;
308  void removeScratchKey();
309  void makeBudgeted();
310  void makeUnbudgeted();
311 
312 #ifdef SK_DEBUG
313  friend class GrGpu; // for assert in GrGpu to access getGpu
314 #endif
315 
316  // An index into a heap when this resource is purgeable or an array when not. This is maintained
317  // by the cache.
318  int fCacheArrayIndex;
319  // This value reflects how recently this resource was accessed in the cache. This is maintained
320  // by the cache.
321  uint32_t fTimestamp;
322  uint32_t fExternalFlushCntWhenBecamePurgeable;
323  GrStdSteadyClock::time_point fTimeWhenBecamePurgeable;
324 
325  static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
326  GrScratchKey fScratchKey;
327  GrUniqueKey fUniqueKey;
328 
329  // This is not ref'ed but abandon() or release() will be called before the GrGpu object
330  // is destroyed. Those calls set will this to NULL.
331  GrGpu* fGpu;
332  mutable size_t fGpuMemorySize;
333 
334  SkBudgeted fBudgeted;
335  bool fRefsWrappedObjects;
336  const UniqueID fUniqueID;
337 
338  typedef GrIORef<GrGpuResource> INHERITED;
339  friend class GrIORef<GrGpuResource>; // to access notifyAllCntsAreZero and notifyRefCntIsZero.
340 };
341 
342 #endif
Base class for objects that can be kept in the GrResourceCache.
Definition: GrGpuResource.h:144
Definition: GrGpuResource.h:183
virtual void onAbandon()
Overridden to abandon any internal handles, ptrs, etc to backend API resources.
Definition: GrGpuResource.h:273
#define SK_InvalidUniqueID
The unique IDs in Skia reserve 0 has an invalid marker.
Definition: SkTypes.h:323
const GrUniqueKey & getUniqueKey() const
Returns the current unique key for the resource.
Definition: GrGpuResource.h:218
A key that allows for exclusive use of a resource for a use case (AKA "domain").
Definition: GrResourceKey.h:222
virtual void onRelease()
Overridden to free GPU resources in the backend API.
Definition: GrGpuResource.h:269
bool wasDestroyed() const
Tests whether a object has been abandoned or released.
Definition: GrGpuResource.h:157
UniqueID uniqueID() const
Gets an id that is unique for this GrGpuResource object.
Definition: GrGpuResource.h:214
Base class for GrGpuResource.
Definition: GrGpuResource.h:46
#define SkToBool(cond)
Returns 0 or 1 based on the condition.
Definition: SkTypes.h:227
virtual void setMemoryBacking(SkTraceMemoryDump *, const SkString &) const
Allows subclasses to add additional backing information to the SkTraceMemoryDump. ...
Definition: GrGpuResource.h:285
size_t gpuMemorySize() const
Retrieves the amount of GPU memory used by this resource in bytes.
Definition: GrGpuResource.h:175
Definition: GrContext.h:47
A key used for scratch resources.
Definition: GrResourceKey.h:168
Interface for memory tracing.
Definition: SkTraceMemoryDump.h:20
virtual void computeScratchKey(GrScratchKey *) const
Called by the registerWithCache if the resource is available to be used as scratch.
Definition: GrGpuResource.h:294
Light weight class for managing strings.
Definition: SkString.h:121