blob: f9e122d9e8560067b3259aff49bcd253bb14e63c [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. */
Brian Salomon34169692017-08-28 15:32:01 -0400158 GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) {}
159 GrTGpuResourceRef(sk_sp<T> resource, GrIOType ioType) : INHERITED(resource, ioType) {}
bsalomonc4923342014-09-16 13:54:53 -0700160
161 T* get() const { return static_cast<T*>(this->getResource()); }
162
163 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
164 pending on the resource when markPendingIO is called. */
bsalomonbcf0a522014-10-08 08:40:09 -0700165 void set(T* resource, GrIOType ioType) { this->setResource(resource, ioType); }
bsalomonf96ba022014-09-17 08:05:40 -0700166
167private:
168 typedef GrGpuResourceRef INHERITED;
bsalomonc4923342014-09-16 13:54:53 -0700169};
170
bsalomonb3e3a952014-09-19 11:10:40 -0700171/**
172 * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
173 * ref.
174 */
bsalomonbcf0a522014-10-08 08:40:09 -0700175template <typename T, GrIOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
bsalomonb3e3a952014-09-19 11:10:40 -0700176public:
Ben Wagnera93a14a2017-08-28 10:34:05 -0400177 GrPendingIOResource(T* resource = nullptr) : fResource(nullptr) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800178 this->reset(resource);
179 }
180
Chris Daltonff926502017-05-03 14:36:54 -0400181 GrPendingIOResource(const GrPendingIOResource& that)
182 : GrPendingIOResource(that.get()) {
183 }
184
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400185 void reset(T* resource = nullptr) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800186 if (resource) {
bsalomon45725db2014-09-19 11:48:02 -0700187 switch (IO_TYPE) {
bsalomonbcf0a522014-10-08 08:40:09 -0700188 case kRead_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800189 resource->addPendingRead();
bsalomonb3e3a952014-09-19 11:10:40 -0700190 break;
bsalomonbcf0a522014-10-08 08:40:09 -0700191 case kWrite_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800192 resource->addPendingWrite();
bsalomonb3e3a952014-09-19 11:10:40 -0700193 break;
bsalomonbcf0a522014-10-08 08:40:09 -0700194 case kRW_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800195 resource->addPendingRead();
196 resource->addPendingWrite();
bsalomonb3e3a952014-09-19 11:10:40 -0700197 break;
198 }
199 }
joshualitt7eb8c7b2014-11-18 14:24:27 -0800200 this->release();
201 fResource = resource;
bsalomonb3e3a952014-09-19 11:10:40 -0700202 }
bsalomonc4923342014-09-16 13:54:53 -0700203
bsalomonb3e3a952014-09-19 11:10:40 -0700204 ~GrPendingIOResource() {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800205 this->release();
bsalomonb3e3a952014-09-19 11:10:40 -0700206 }
207
reedd9ffaed2015-11-10 04:55:08 -0800208 explicit operator bool() const { return SkToBool(fResource); }
209
210 bool operator==(const GrPendingIOResource& other) const {
211 return fResource == other.fResource;
212 }
bsalomonb03c4a32014-11-20 09:56:11 -0800213
bsalomonb3e3a952014-09-19 11:10:40 -0700214 T* get() const { return fResource; }
215
216private:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800217 void release() {
218 if (fResource) {
219 switch (IO_TYPE) {
220 case kRead_GrIOType:
221 fResource->completedRead();
222 break;
223 case kWrite_GrIOType:
224 fResource->completedWrite();
225 break;
226 case kRW_GrIOType:
227 fResource->completedRead();
228 fResource->completedWrite();
229 break;
230 }
231 }
232 }
233
bsalomonbcf0a522014-10-08 08:40:09 -0700234 T* fResource;
bsalomonb3e3a952014-09-19 11:10:40 -0700235};
bsalomon95740982014-09-04 13:12:37 -0700236#endif