blob: 410513944fb8e9a34db93da669c27969594eaaee [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
mtklein6f076652015-01-13 08:22:43 -080090/**
bsalomonb3e3a952014-09-19 11:10:40 -070091 * Templated version of GrGpuResourceRef to enforce type safety.
92 */
bsalomonf96ba022014-09-17 08:05:40 -070093template <typename T> class GrTGpuResourceRef : public GrGpuResourceRef {
bsalomonc4923342014-09-16 13:54:53 -070094public:
bsalomonf96ba022014-09-17 08:05:40 -070095 GrTGpuResourceRef() {}
bsalomonc4923342014-09-16 13:54:53 -070096
97 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
98 pending on the resource when markPendingIO is called. */
Brian Salomon34169692017-08-28 15:32:01 -040099 GrTGpuResourceRef(T* resource, GrIOType ioType) : INHERITED(resource, ioType) {}
100 GrTGpuResourceRef(sk_sp<T> resource, GrIOType ioType) : INHERITED(resource, ioType) {}
bsalomonc4923342014-09-16 13:54:53 -0700101
102 T* get() const { return static_cast<T*>(this->getResource()); }
103
104 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
105 pending on the resource when markPendingIO is called. */
bsalomonbcf0a522014-10-08 08:40:09 -0700106 void set(T* resource, GrIOType ioType) { this->setResource(resource, ioType); }
bsalomonf96ba022014-09-17 08:05:40 -0700107
108private:
109 typedef GrGpuResourceRef INHERITED;
bsalomonc4923342014-09-16 13:54:53 -0700110};
111
bsalomonb3e3a952014-09-19 11:10:40 -0700112/**
113 * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
114 * ref.
115 */
bsalomonbcf0a522014-10-08 08:40:09 -0700116template <typename T, GrIOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
bsalomonb3e3a952014-09-19 11:10:40 -0700117public:
Ben Wagnera93a14a2017-08-28 10:34:05 -0400118 GrPendingIOResource(T* resource = nullptr) : fResource(nullptr) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800119 this->reset(resource);
120 }
121
Chris Daltonff926502017-05-03 14:36:54 -0400122 GrPendingIOResource(const GrPendingIOResource& that)
123 : GrPendingIOResource(that.get()) {
124 }
125
Robert Phillips5efd5ea2017-05-30 13:47:32 -0400126 void reset(T* resource = nullptr) {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800127 if (resource) {
bsalomon45725db2014-09-19 11:48:02 -0700128 switch (IO_TYPE) {
bsalomonbcf0a522014-10-08 08:40:09 -0700129 case kRead_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800130 resource->addPendingRead();
bsalomonb3e3a952014-09-19 11:10:40 -0700131 break;
bsalomonbcf0a522014-10-08 08:40:09 -0700132 case kWrite_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800133 resource->addPendingWrite();
bsalomonb3e3a952014-09-19 11:10:40 -0700134 break;
bsalomonbcf0a522014-10-08 08:40:09 -0700135 case kRW_GrIOType:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800136 resource->addPendingRead();
137 resource->addPendingWrite();
bsalomonb3e3a952014-09-19 11:10:40 -0700138 break;
139 }
140 }
joshualitt7eb8c7b2014-11-18 14:24:27 -0800141 this->release();
142 fResource = resource;
bsalomonb3e3a952014-09-19 11:10:40 -0700143 }
bsalomonc4923342014-09-16 13:54:53 -0700144
bsalomonb3e3a952014-09-19 11:10:40 -0700145 ~GrPendingIOResource() {
joshualitt7eb8c7b2014-11-18 14:24:27 -0800146 this->release();
bsalomonb3e3a952014-09-19 11:10:40 -0700147 }
148
reedd9ffaed2015-11-10 04:55:08 -0800149 explicit operator bool() const { return SkToBool(fResource); }
150
151 bool operator==(const GrPendingIOResource& other) const {
152 return fResource == other.fResource;
153 }
bsalomonb03c4a32014-11-20 09:56:11 -0800154
bsalomonb3e3a952014-09-19 11:10:40 -0700155 T* get() const { return fResource; }
156
157private:
joshualitt7eb8c7b2014-11-18 14:24:27 -0800158 void release() {
159 if (fResource) {
160 switch (IO_TYPE) {
161 case kRead_GrIOType:
162 fResource->completedRead();
163 break;
164 case kWrite_GrIOType:
165 fResource->completedWrite();
166 break;
167 case kRW_GrIOType:
168 fResource->completedRead();
169 fResource->completedWrite();
170 break;
171 }
172 }
173 }
174
bsalomonbcf0a522014-10-08 08:40:09 -0700175 T* fResource;
bsalomonb3e3a952014-09-19 11:10:40 -0700176};
Robert Phillips62000362018-02-01 09:10:04 -0500177
bsalomon95740982014-09-04 13:12:37 -0700178#endif