blob: a56674b494c9d36b67cab3965f088f1c3970bcbe [file] [log] [blame]
bsalomon95740982014-09-04 13:12:37 -07001/*
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
bsalomonf96ba022014-09-17 08:05:40 -07008#ifndef GrGpuResourceRef_DEFINED
9#define GrGpuResourceRef_DEFINED
bsalomon95740982014-09-04 13:12:37 -070010
bsalomon45725db2014-09-19 11:48:02 -070011#include "GrGpuResource.h"
bsalomon95740982014-09-04 13:12:37 -070012#include "SkRefCnt.h"
13
bsalomon95740982014-09-04 13:12:37 -070014/**
bsalomonb3e3a952014-09-19 11:10:40 -070015 * This class is intended only for internal use in core Gr code.
16 *
bsalomon95740982014-09-04 13:12:37 -070017 * Class that wraps a resource referenced by a GrProgramElement or GrDrawState. It manages
bsalomonb3e3a952014-09-19 11:10:40 -070018 * converting refs to pending IO operations. It allows a resource ownership to be in three
19 * states:
20 * 1. Owns a single ref
21 * 2. Owns a single ref and a pending IO operation (read, write, or read-write)
22 * 3. Owns a single pending IO operation.
23 *
24 * It is legal to destroy the GrGpuResourceRef in any of these states. It starts in state
25 * 1. Calling markPendingIO() converts it from state 1 to state 2. Calling removeRef() goes from
26 * state 2 to state 3. Calling pendingIOComplete() moves from state 2 to state 1. There is no
27 * valid way of going from state 3 back to 2 or 1.
28 *
bungeman6bd52842016-10-27 09:30:08 -070029 * Like sk_sp, its constructor and setter adopt a ref from their caller.
bsalomonb3e3a952014-09-19 11:10:40 -070030 *
31 * TODO: Once GrDODrawState no longer exists and therefore GrDrawState and GrOptDrawState no
32 * longer share an instance of this class, attempt to make the resource owned by GrGpuResourceRef
33 * only settable via the constructor.
bsalomon95740982014-09-04 13:12:37 -070034 */
bsalomonf96ba022014-09-17 08:05:40 -070035class GrGpuResourceRef : SkNoncopyable {
bsalomon95740982014-09-04 13:12:37 -070036public:
bsalomonf96ba022014-09-17 08:05:40 -070037 ~GrGpuResourceRef();
bsalomon95740982014-09-04 13:12:37 -070038
39 GrGpuResource* getResource() const { return fResource; }
40
bsalomon95740982014-09-04 13:12:37 -070041 /** Does this object own a pending read or write on the resource it is wrapping. */
42 bool ownsPendingIO() const { return fPendingIO; }
43
Brian Salomonf9f45122016-11-29 11:59:17 -050044 /** What type of IO does this represent? This is independent of whether a normal ref or a
45 pending IO is currently held. */
46 GrIOType ioType() const { return fIOType; }
47
bsalomon95740982014-09-04 13:12:37 -070048 /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
49 is called. */
50 void reset();
51
bsalomonc4923342014-09-16 13:54:53 -070052protected:
bsalomonf96ba022014-09-17 08:05:40 -070053 GrGpuResourceRef();
bsalomonc4923342014-09-16 13:54:53 -070054
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. */
bsalomonbcf0a522014-10-08 08:40:09 -070057 GrGpuResourceRef(GrGpuResource*, GrIOType);
bsalomonc4923342014-09-16 13:54:53 -070058
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. */
bsalomonbcf0a522014-10-08 08:40:09 -070061 void setResource(GrGpuResource*, GrIOType);
bsalomonc4923342014-09-16 13:54:53 -070062
bsalomon95740982014-09-04 13:12:37 -070063private:
64 /** Called by owning GrProgramElement when the program element is first scheduled for
bsalomonb3e3a952014-09-19 11:10:40 -070065 execution. It can only be called once. */
bsalomon95740982014-09-04 13:12:37 -070066 void markPendingIO() const;
67
Robert Phillipsf2361d22016-10-25 14:20:06 -040068 /** Called when the program element/draw state is no longer owned by GrOpList-client code.
bsalomon95740982014-09-04 13:12:37 -070069 This lets the cache know that the drawing code will no longer schedule additional reads or
bsalomonb3e3a952014-09-19 11:10:40 -070070 writes to the resource using the program element or draw state. It can only be called once.
71 */
bsalomon95740982014-09-04 13:12:37 -070072 void removeRef() const;
73
bsalomonac8d6192014-09-04 14:13:44 -070074 /** Called to indicate that the previous pending IO is complete. Useful when the owning object
bsalomonf96ba022014-09-17 08:05:40 -070075 still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
bsalomonb3e3a952014-09-19 11:10:40 -070076 pending executions have been complete. Can only be called if removeRef() was not previously
77 called. */
bsalomonac8d6192014-09-04 14:13:44 -070078 void pendingIOComplete() const;
79
Brian Salomonab015ef2017-04-04 10:15:51 -040080 friend class GrResourceIOProcessor;
bsalomon95740982014-09-04 13:12:37 -070081
bsalomonbcf0a522014-10-08 08:40:09 -070082 GrGpuResource* fResource;
83 mutable bool fOwnRef;
84 mutable bool fPendingIO;
85 GrIOType fIOType;
bsalomon95740982014-09-04 13:12:37 -070086
87 typedef SkNoncopyable INHERITED;
88};
89
Robert Phillipsb6deea82017-05-11 14:14:30 -040090class GrSurfaceProxy;
Robert Phillips952a2432017-05-04 08:52:22 -040091
Robert Phillipsb6deea82017-05-11 14:14:30 -040092class GrSurfaceProxyRef : SkNoncopyable {
Robert Phillips952a2432017-05-04 08:52:22 -040093public:
Robert Phillipsb6deea82017-05-11 14:14:30 -040094 virtual ~GrSurfaceProxyRef();
Robert Phillips952a2432017-05-04 08:52:22 -040095
Robert Phillips5efd5ea2017-05-30 13:47:32 -040096 GrSurfaceProxy* get() const { return fProxy; }
Robert Phillips952a2432017-05-04 08:52:22 -040097
98 /** Does this object own a pending read or write on the resource it is wrapping. */
99 bool ownsPendingIO() const { return fPendingIO; }
100
101 /** What type of IO does this represent? This is independent of whether a normal ref or a
102 pending IO is currently held. */
103 GrIOType ioType() const { return fIOType; }
104
105 /** Shortcut for calling setProxy() with NULL. It cannot be called after markingPendingIO
106 is called. */
107 void reset();
108
109protected:
Robert Phillipsb6deea82017-05-11 14:14:30 -0400110 GrSurfaceProxyRef();
Robert Phillips952a2432017-05-04 08:52:22 -0400111
112 /** ioType expresses what type of IO operations will be marked as
113 pending on the resource when markPendingIO is called. */
Robert Phillipsb6deea82017-05-11 14:14:30 -0400114 GrSurfaceProxyRef(sk_sp<GrSurfaceProxy>, GrIOType);
Robert Phillips952a2432017-05-04 08:52:22 -0400115
116 /** ioType expresses what type of IO operations will be marked as
117 pending on the resource when markPendingIO is called. */
Robert Phillipsb6deea82017-05-11 14:14:30 -0400118 void setProxy(sk_sp<GrSurfaceProxy>, GrIOType);
Robert Phillips952a2432017-05-04 08:52:22 -0400119
120private:
121 /** Called by owning GrProgramElement when the program element is first scheduled for
122 execution. It can only be called once. */
123 void markPendingIO() const;
124
125 /** Called when the program element/draw state is no longer owned by GrOpList-client code.
126 This lets the cache know that the drawing code will no longer schedule additional reads or
127 writes to the resource using the program element or draw state. It can only be called once.
128 */
129 void removeRef() const;
130
131 /** Called to indicate that the previous pending IO is complete. Useful when the owning object
132 still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
133 pending executions have been complete. Can only be called if removeRef() was not previously
134 called. */
135 void pendingIOComplete() const;
136
137 friend class GrResourceIOProcessor;
Robert Phillipsb6deea82017-05-11 14:14:30 -0400138 friend class GrOpList; // for setProxy
Robert Phillips952a2432017-05-04 08:52:22 -0400139
Robert Phillipsb6deea82017-05-11 14:14:30 -0400140 GrSurfaceProxy* fProxy;
Robert Phillips952a2432017-05-04 08:52:22 -0400141 mutable bool fOwnRef;
142 mutable bool fPendingIO;
143 GrIOType fIOType;
144
145 typedef SkNoncopyable INHERITED;
146};
147
148
mtklein6f076652015-01-13 08:22:43 -0800149/**
bsalomonb3e3a952014-09-19 11:10:40 -0700150 * Templated version of GrGpuResourceRef to enforce type safety.
151 */
bsalomonf96ba022014-09-17 08:05:40 -0700152template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
bsalomonc4923342014-09-16 13:54:53 -0700153public:
bsalomonf96ba022014-09-17 08:05:40 -0700154 GrTGpuResourceRef() {}
bsalomonc4923342014-09-16 13:54:53 -0700155
156 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
157 pending on the resource when markPendingIO is called. */
bsalomon37dd3312014-11-03 08:47:23 -0800158 GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) { }
bsalomonc4923342014-09-16 13:54:53 -0700159
160 T* get() const { return static_cast<T*>(this->getResource()); }
161
162 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
163 pending on the resource when markPendingIO is called. */
bsalomonbcf0a522014-10-08 08:40:09 -0700164 void set(T* resource, GrIOType ioType) { this->setResource(resource, ioType); }
bsalomonf96ba022014-09-17 08:05:40 -0700165
166private:
167 typedef GrGpuResourceRef INHERITED;
bsalomonc4923342014-09-16 13:54:53 -0700168};
169
bsalomonb3e3a952014-09-19 11:10:40 -0700170/**
171 * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
172 * ref.
173 */
bsalomonbcf0a522014-10-08 08:40:09 -0700174template <typename T, GrIOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
bsalomonb3e3a952014-09-19 11:10:40 -0700175public:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800176 GrPendingIOResource(T* resource = NULL) : fResource(NULL) {
177 this->reset(resource);
178 }
179
Chris Daltonff926502017-05-03 14:36:54 -0400180 GrPendingIOResource(const GrPendingIOResource& that)
181 : GrPendingIOResource(that.get()) {
182 }
183
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400184 void reset(T* resource = nullptr) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800185 if (resource) {
bsalomon45725db2014-09-19 11:48:02 -0700186 switch (IO_TYPE) {
bsalomonbcf0a522014-10-08 08:40:09 -0700187 case kRead_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800188 resource->addPendingRead();
bsalomonb3e3a952014-09-19 11:10:40 -0700189 break;
bsalomonbcf0a522014-10-08 08:40:09 -0700190 case kWrite_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800191 resource->addPendingWrite();
bsalomonb3e3a952014-09-19 11:10:40 -0700192 break;
bsalomonbcf0a522014-10-08 08:40:09 -0700193 case kRW_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800194 resource->addPendingRead();
195 resource->addPendingWrite();
bsalomonb3e3a952014-09-19 11:10:40 -0700196 break;
197 }
198 }
joshualitt7eb8c7b2014-11-18 14:24:27 -0800199 this->release();
200 fResource = resource;
bsalomonb3e3a952014-09-19 11:10:40 -0700201 }
bsalomonc4923342014-09-16 13:54:53 -0700202
bsalomonb3e3a952014-09-19 11:10:40 -0700203 ~GrPendingIOResource() {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800204 this->release();
bsalomonb3e3a952014-09-19 11:10:40 -0700205 }
206
reedd9ffaed2015-11-10 04:55:08 -0800207 explicit operator bool() const { return SkToBool(fResource); }
208
209 bool operator==(const GrPendingIOResource& other) const {
210 return fResource == other.fResource;
211 }
bsalomonb03c4a32014-11-20 09:56:11 -0800212
bsalomonb3e3a952014-09-19 11:10:40 -0700213 T* get() const { return fResource; }
214
215private:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800216 void release() {
217 if (fResource) {
218 switch (IO_TYPE) {
219 case kRead_GrIOType:
220 fResource->completedRead();
221 break;
222 case kWrite_GrIOType:
223 fResource->completedWrite();
224 break;
225 case kRW_GrIOType:
226 fResource->completedRead();
227 fResource->completedWrite();
228 break;
229 }
230 }
231 }
232
bsalomonbcf0a522014-10-08 08:40:09 -0700233 T* fResource;
bsalomonb3e3a952014-09-19 11:10:40 -0700234};
bsalomon95740982014-09-04 13:12:37 -0700235#endif