Line data Source code
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 GrGpuResourceRef_DEFINED
9 : #define GrGpuResourceRef_DEFINED
10 :
11 : #include "GrGpuResource.h"
12 : #include "GrRenderTarget.h"
13 : #include "GrTexture.h"
14 : #include "SkRefCnt.h"
15 :
16 : /**
17 : * This class is intended only for internal use in core Gr code.
18 : *
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
21 : * states:
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.
25 : *
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.
30 : *
31 : * Like sk_sp, its constructor and setter adopt a ref from their caller.
32 : *
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.
36 : */
37 : class GrGpuResourceRef : SkNoncopyable {
38 : public:
39 : ~GrGpuResourceRef();
40 :
41 0 : GrGpuResource* getResource() const { return fResource; }
42 :
43 : /** Does this object own a pending read or write on the resource it is wrapping. */
44 : bool ownsPendingIO() const { return fPendingIO; }
45 :
46 : /** What type of IO does this represent? This is independent of whether a normal ref or a
47 : pending IO is currently held. */
48 0 : GrIOType ioType() const { return fIOType; }
49 :
50 : /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
51 : is called. */
52 : void reset();
53 :
54 : protected:
55 : GrGpuResourceRef();
56 :
57 : /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
58 : pending on the resource when markPendingIO is called. */
59 : GrGpuResourceRef(GrGpuResource*, GrIOType);
60 :
61 : /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
62 : pending on the resource when markPendingIO is called. */
63 : void setResource(GrGpuResource*, GrIOType);
64 :
65 : private:
66 : /** Called by owning GrProgramElement when the program element is first scheduled for
67 : execution. It can only be called once. */
68 : void markPendingIO() const;
69 :
70 : /** Called when the program element/draw state is no longer owned by GrOpList-client code.
71 : This lets the cache know that the drawing code will no longer schedule additional reads or
72 : writes to the resource using the program element or draw state. It can only be called once.
73 : */
74 : void removeRef() const;
75 :
76 : /** Called to indicate that the previous pending IO is complete. Useful when the owning object
77 : still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
78 : pending executions have been complete. Can only be called if removeRef() was not previously
79 : called. */
80 : void pendingIOComplete() const;
81 :
82 : friend class GrResourceIOProcessor;
83 :
84 : GrGpuResource* fResource;
85 : mutable bool fOwnRef;
86 : mutable bool fPendingIO;
87 : GrIOType fIOType;
88 :
89 : typedef SkNoncopyable INHERITED;
90 : };
91 :
92 : /**
93 : * Templated version of GrGpuResourceRef to enforce type safety.
94 : */
95 0 : template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
96 : public:
97 0 : GrTGpuResourceRef() {}
98 :
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) { }
102 :
103 0 : T* get() const { return static_cast<T*>(this->getResource()); }
104 :
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 0 : void set(T* resource, GrIOType ioType) { this->setResource(resource, ioType); }
108 :
109 : private:
110 : typedef GrGpuResourceRef INHERITED;
111 : };
112 :
113 : // Specializations for GrTexture and GrRenderTarget because they use virtual inheritance.
114 0 : template<> class GrTGpuResourceRef<GrTexture> : public GrGpuResourceRef {
115 : public:
116 0 : GrTGpuResourceRef() {}
117 :
118 : GrTGpuResourceRef(GrTexture* texture, GrIOType ioType) : INHERITED(texture, ioType) { }
119 :
120 0 : GrTexture* get() const {
121 0 : GrSurface* surface = static_cast<GrSurface*>(this->getResource());
122 0 : if (surface) {
123 0 : return surface->asTexture();
124 : } else {
125 0 : return NULL;
126 : }
127 : }
128 :
129 0 : void set(GrTexture* texture, GrIOType ioType) { this->setResource(texture, ioType); }
130 :
131 : private:
132 : typedef GrGpuResourceRef INHERITED;
133 : };
134 :
135 : template<> class GrTGpuResourceRef<GrRenderTarget> : public GrGpuResourceRef {
136 : public:
137 : GrTGpuResourceRef() {}
138 :
139 : GrTGpuResourceRef(GrRenderTarget* rt, GrIOType ioType) : INHERITED(rt, ioType) { }
140 :
141 : GrRenderTarget* get() const {
142 : GrSurface* surface = static_cast<GrSurface*>(this->getResource());
143 : if (surface) {
144 : return surface->asRenderTarget();
145 : } else {
146 : return NULL;
147 : }
148 : }
149 :
150 : void set(GrRenderTarget* rt, GrIOType ioType) { this->setResource(rt, ioType); }
151 :
152 : private:
153 : typedef GrGpuResourceRef INHERITED;
154 : };
155 :
156 : /**
157 : * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
158 : * ref.
159 : */
160 : template <typename T, GrIOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
161 : public:
162 0 : GrPendingIOResource(T* resource = NULL) : fResource(NULL) {
163 0 : this->reset(resource);
164 0 : }
165 :
166 0 : void reset(T* resource) {
167 0 : if (resource) {
168 : switch (IO_TYPE) {
169 : case kRead_GrIOType:
170 0 : resource->addPendingRead();
171 0 : break;
172 : case kWrite_GrIOType:
173 0 : resource->addPendingWrite();
174 0 : break;
175 : case kRW_GrIOType:
176 : resource->addPendingRead();
177 : resource->addPendingWrite();
178 : break;
179 : }
180 : }
181 0 : this->release();
182 0 : fResource = resource;
183 0 : }
184 :
185 0 : ~GrPendingIOResource() {
186 0 : this->release();
187 0 : }
188 :
189 0 : explicit operator bool() const { return SkToBool(fResource); }
190 :
191 0 : bool operator==(const GrPendingIOResource& other) const {
192 0 : return fResource == other.fResource;
193 : }
194 :
195 0 : T* get() const { return fResource; }
196 :
197 : private:
198 0 : void release() {
199 0 : if (fResource) {
200 : switch (IO_TYPE) {
201 : case kRead_GrIOType:
202 0 : fResource->completedRead();
203 0 : break;
204 : case kWrite_GrIOType:
205 0 : fResource->completedWrite();
206 0 : break;
207 : case kRW_GrIOType:
208 : fResource->completedRead();
209 : fResource->completedWrite();
210 : break;
211 : }
212 : }
213 0 : }
214 :
215 : T* fResource;
216 : };
217 : #endif
|