blob: 3320dc069fe841dc467288871cd623bca84c698f [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 *
29 * Like SkAutoTUnref, its constructor and setter adopt a ref from their caller.
30 *
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 SK_DECLARE_INST_COUNT_ROOT(GrGpuResourceRef);
bsalomonc4923342014-09-16 13:54:53 -070038
bsalomonf96ba022014-09-17 08:05:40 -070039 ~GrGpuResourceRef();
bsalomon95740982014-09-04 13:12:37 -070040
41 GrGpuResource* getResource() const { return fResource; }
42
bsalomon95740982014-09-04 13:12:37 -070043 /** Does this object own a pending read or write on the resource it is wrapping. */
44 bool ownsPendingIO() const { return fPendingIO; }
45
46 /** Shortcut for calling setResource() with NULL. It cannot be called after markingPendingIO
47 is called. */
48 void reset();
49
bsalomonc4923342014-09-16 13:54:53 -070050protected:
bsalomonf96ba022014-09-17 08:05:40 -070051 GrGpuResourceRef();
bsalomonc4923342014-09-16 13:54:53 -070052
53 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
54 pending on the resource when markPendingIO is called. */
bsalomon45725db2014-09-19 11:48:02 -070055 GrGpuResourceRef(GrGpuResource*, GrIORef::IOType);
bsalomonc4923342014-09-16 13:54:53 -070056
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. */
bsalomon45725db2014-09-19 11:48:02 -070059 void setResource(GrGpuResource*, GrIORef::IOType);
bsalomonc4923342014-09-16 13:54:53 -070060
bsalomon95740982014-09-04 13:12:37 -070061private:
62 /** Called by owning GrProgramElement when the program element is first scheduled for
bsalomonb3e3a952014-09-19 11:10:40 -070063 execution. It can only be called once. */
bsalomon95740982014-09-04 13:12:37 -070064 void markPendingIO() const;
65
66 /** Called when the program element/draw state is no longer owned by GrDrawTarget-client code.
67 This lets the cache know that the drawing code will no longer schedule additional reads or
bsalomonb3e3a952014-09-19 11:10:40 -070068 writes to the resource using the program element or draw state. It can only be called once.
69 */
bsalomon95740982014-09-04 13:12:37 -070070 void removeRef() const;
71
bsalomonac8d6192014-09-04 14:13:44 -070072 /** Called to indicate that the previous pending IO is complete. Useful when the owning object
bsalomonf96ba022014-09-17 08:05:40 -070073 still has refs, so it is not about to destroy this GrGpuResourceRef, but its previously
bsalomonb3e3a952014-09-19 11:10:40 -070074 pending executions have been complete. Can only be called if removeRef() was not previously
75 called. */
bsalomonac8d6192014-09-04 14:13:44 -070076 void pendingIOComplete() const;
77
egdaniel89af44a2014-09-26 06:15:04 -070078 friend class GrDrawState;
79 friend class GrOptDrawState;
bsalomon95740982014-09-04 13:12:37 -070080 friend class GrProgramElement;
81
82 GrGpuResource* fResource;
83 mutable bool fOwnRef;
84 mutable bool fPendingIO;
bsalomon45725db2014-09-19 11:48:02 -070085 GrIORef::IOType fIOType;
bsalomon95740982014-09-04 13:12:37 -070086
87 typedef SkNoncopyable INHERITED;
88};
89
bsalomonb3e3a952014-09-19 11:10:40 -070090/**
91 * 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. */
bsalomon45725db2014-09-19 11:48:02 -070099 GrTGpuResourceRef(T* resource, GrIORef::IOType ioType) : INHERITED(resource, ioType) {}
bsalomonc4923342014-09-16 13:54:53 -0700100
101 T* get() const { return static_cast<T*>(this->getResource()); }
102
103 /** Adopts a ref from the caller. ioType expresses what type of IO operations will be marked as
104 pending on the resource when markPendingIO is called. */
bsalomon45725db2014-09-19 11:48:02 -0700105 void set(T* resource, GrIORef::IOType ioType) { this->setResource(resource, ioType); }
bsalomonf96ba022014-09-17 08:05:40 -0700106
107private:
108 typedef GrGpuResourceRef INHERITED;
bsalomonc4923342014-09-16 13:54:53 -0700109};
110
bsalomonb3e3a952014-09-19 11:10:40 -0700111/**
112 * This is similar to GrTGpuResourceRef but can only be in the pending IO state. It never owns a
113 * ref.
114 */
bsalomon45725db2014-09-19 11:48:02 -0700115template <typename T, GrIORef::IOType IO_TYPE> class GrPendingIOResource : SkNoncopyable {
bsalomonb3e3a952014-09-19 11:10:40 -0700116public:
bsalomon45725db2014-09-19 11:48:02 -0700117 GrPendingIOResource(T* resource) : fResource(resource) {
bsalomonb3e3a952014-09-19 11:10:40 -0700118 if (NULL != fResource) {
bsalomon45725db2014-09-19 11:48:02 -0700119 switch (IO_TYPE) {
120 case GrIORef::kRead_IOType:
bsalomonb3e3a952014-09-19 11:10:40 -0700121 fResource->addPendingRead();
122 break;
bsalomon45725db2014-09-19 11:48:02 -0700123 case GrIORef::kWrite_IOType:
bsalomonb3e3a952014-09-19 11:10:40 -0700124 fResource->addPendingWrite();
125 break;
bsalomon45725db2014-09-19 11:48:02 -0700126 case GrIORef::kRW_IOType:
bsalomonb3e3a952014-09-19 11:10:40 -0700127 fResource->addPendingRead();
128 fResource->addPendingWrite();
129 break;
130 }
131 }
132 }
bsalomonc4923342014-09-16 13:54:53 -0700133
bsalomonb3e3a952014-09-19 11:10:40 -0700134 ~GrPendingIOResource() {
135 if (NULL != fResource) {
bsalomon45725db2014-09-19 11:48:02 -0700136 switch (IO_TYPE) {
137 case GrIORef::kRead_IOType:
bsalomonb3e3a952014-09-19 11:10:40 -0700138 fResource->completedRead();
139 break;
bsalomon45725db2014-09-19 11:48:02 -0700140 case GrIORef::kWrite_IOType:
bsalomonb3e3a952014-09-19 11:10:40 -0700141 fResource->completedWrite();
142 break;
bsalomon45725db2014-09-19 11:48:02 -0700143 case GrIORef::kRW_IOType:
bsalomonb3e3a952014-09-19 11:10:40 -0700144 fResource->completedRead();
145 fResource->completedWrite();
146 break;
147 }
148 }
149 }
150
151 T* get() const { return fResource; }
152
153private:
154 T* fResource;
bsalomonb3e3a952014-09-19 11:10:40 -0700155};
bsalomon95740982014-09-04 13:12:37 -0700156#endif