2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrGpuResourceRef_DEFINED
9 #define GrGpuResourceRef_DEFINED
11 #include "GrGpuResource.h"
12 #include "GrRenderTarget.h"
13 #include "GrTexture.h"
17 * This class is intended only for internal use in core Gr code.
19 * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages
20 * converting refs to pending IO operations. It allows a resource ownership to be in three
22 * 1. Owns a single ref
23 * 2. Owns a single ref and a pending IO operation (read, write, or read-write)
24 * 3. Owns a single pending IO operation.
26 * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state
27 * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from
28 * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no
29 * valid way of going from state 3 back to 2 or 1.
31 * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller.
33 * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no
34 * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef
35 * only settable via the constructor.
37 class GrGpuResourceRef : SkNoncopyable {
39 SK_DECLARE_INST_COUNT_ROOT(GrGpuResourceRef);
43 GrGpuResource* getResource() const { return fResource; }
45 /** Does this object own a pending read or write on the resource it is wrapping. */
46 bool ownsPendingIO() const { return fPendingIO; }
48 /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
55 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
56 pending on the resource when markPendingIO is called. */
57 GrGpuResourceRef(GrGpuResource*, GrIOType);
59 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
60 pending on the resource when markPendingIO is called. */
61 void setResource(GrGpuResource*, GrIOType);
64 /** Called by owning GrProgramElement when the program element is first scheduled for
65 execution. It can only be called once. */
66 void markPendingIO() const;
68 /** Called when the program element/draw state is no longer owned by GrDrawTarget-client code.
69 This lets the cache know that the drawing code will no longer schedule additional reads or
70 writes to the resource using the program element or draw state. It can only be called once.
72 void removeRef() const;
74 /** Called to indicate that the previous pending IO is complete. Useful when the owning object
75 still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
76 pending executions have been complete. Can only be called if removeRef() was not previously
78 void pendingIOComplete() const;
80 friend class GrDrawState;
81 friend class GrOptDrawState;
82 friend class GrProgramElement;
84 GrGpuResource* fResource;
86 mutable bool fPendingIO;
89 typedef SkNoncopyable INHERITED;
93 * Templated version of GrGpuResourceRef to enforce type safety.
95 template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
97 GrTGpuResourceRef() {}
99 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
100 pending on the resource when markPendingIO is called. */
101 GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) { }
103 T* get() const { return static_cast<T*>(this->getResource()); }
105 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
106 pending on the resource when markPendingIO is called. */
107 void set(T* resource, GrIOType ioType) { this->setResource(resource, ioType); }
110 typedef GrGpuResourceRef INHERITED;
113 // Specializations for GrTexture and GrRenderTarget because they use virtual inheritance.
114 template<> class GrTGpuResourceRef<GrTexture> : public GrGpuResourceRef {
116 GrTGpuResourceRef() {}
118 GrTGpuResourceRef(GrTexture* texture, GrIOType ioType) : INHERITED(texture, ioType) { }
120 GrTexture* get() const {
121 GrSurface* surface = static_cast<GrSurface*>(this->getResource());
123 return surface->asTexture();
129 void set(GrTexture* texture, GrIOType ioType) { this->setResource(texture, ioType); }
132 typedef GrGpuResourceRef INHERITED;
135 template<> class GrTGpuResourceRef<GrRenderTarget> : public GrGpuResourceRef {
137 GrTGpuResourceRef() {}
139 GrTGpuResourceRef(GrRenderTarget* rt, GrIOType ioType) : INHERITED(rt, ioType) { }
141 GrRenderTarget* get() const {
142 GrSurface* surface = static_cast<GrSurface*>(this->getResource());
144 return surface->asRenderTarget();
150 void set(GrRenderTarget* rt, GrIOType ioType) { this->setResource(rt, ioType); }
153 typedef GrGpuResourceRef INHERITED;
157 * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
160 template <typename T, GrIOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
162 GrPendingIOResource(T* resource) : fResource(resource) {
163 if (NULL != fResource) {
166 fResource->addPendingRead();
168 case kWrite_GrIOType:
169 fResource->addPendingWrite();
172 fResource->addPendingRead();
173 fResource->addPendingWrite();
179 ~GrPendingIOResource() {
180 if (NULL != fResource) {
183 fResource->completedRead();
185 case kWrite_GrIOType:
186 fResource->completedWrite();
189 fResource->completedRead();
190 fResource->completedWrite();
196 T* get() const { return fResource; }