Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GpuRefCnt.h
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google LLC
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 GrRefCnt_DEFINED
9#define GrRefCnt_DEFINED
10
14
15#include <cstddef>
16#include <type_traits>
17
18// We have to use auto for the function pointers here because if the actual functions live on the
19// base class of T we need the function here to be a pointer to a function of the base class and not
20// a function on T. Thus we can't have something like void(T::*Ref)() since we may need T or we may
21// need some base class of T.
22template <typename T, auto Ref, auto Unref> class gr_sp {
23private:
24 static inline T* SafeRef(T* obj) {
25 if (obj) {
26 (obj->*Ref)();
27 }
28 return obj;
29 }
30
31 static inline void SafeUnref(T* obj) {
32 if (obj) {
33 (obj->*Unref)();
34 }
35 }
36
37public:
38 using element_type = T;
39
40 constexpr gr_sp() : fPtr(nullptr) {}
41 constexpr gr_sp(std::nullptr_t) : fPtr(nullptr) {}
42
43 /**
44 * Shares the underlying object by calling Ref(), so that both the argument and the newly
45 * created gr_sp both have a reference to it.
46 */
47 gr_sp(const gr_sp<T, Ref, Unref>& that) : fPtr(SafeRef(that.get())) {}
48 template <typename U,
49 typename = typename std::enable_if<std::is_convertible<U*, T*>::value>::type>
50 gr_sp(const gr_sp<U, Ref, Unref>& that) : fPtr(SafeRef(that.get())) {}
51
52 gr_sp(const sk_sp<T>& that) : fPtr(SafeRef(that.get())) {}
53
54
55 /**
56 * Move the underlying object from the argument to the newly created gr_sp. Afterwards only the
57 * new gr_sp will have a reference to the object, and the argument will point to null.
58 * No call to Ref() or Unref() will be made.
59 */
60 gr_sp(gr_sp<T, Ref, Unref>&& that) : fPtr(that.release()) {}
61
62 /**
63 * Copies the underlying object pointer from the argument to the gr_sp. It will then call
64 * Ref() on the new object.
65 */
66 gr_sp(sk_sp<T>&& that) : fPtr(SafeRef(that.get())) {}
67
68 /**
69 * Adopt the bare pointer into the newly created gr_sp.
70 * No call to Ref() or Unref() will be made.
71 */
72 explicit gr_sp(T* obj) : fPtr(obj) {}
73
74 /**
75 * Calls Unref() on the underlying object pointer.
76 */
78 SafeUnref(fPtr);
79 SkDEBUGCODE(fPtr = nullptr);
80 }
81
82 gr_sp& operator=(std::nullptr_t) {
83 this->reset();
84 return *this;
85 }
86
87 /**
88 * Shares the underlying object referenced by the argument by calling Ref() on it. If this gr_sp
89 * previously had a reference to an object (i.e. not null) it will call Unref() on that object.
90 */
92 if (this != &that) {
93 this->reset(SafeRef(that.get()));
94 }
95 return *this;
96 }
97
98 /**
99 * Copies the underlying object pointer from the argument to the gr_sp. If the gr_sp previously
100 * held a reference to another object, Unref() will be called on that object. It will then call
101 * Ref() on the new object.
102 */
103 gr_sp& operator=(const sk_sp<T>& that) {
104 this->reset(SafeRef(that.get()));
105 return *this;
106 }
107
108 /**
109 * Move the underlying object from the argument to the gr_sp. If the gr_sp previously held
110 * a reference to another object, Unref() will be called on that object. No call to Ref() will
111 * be made.
112 */
114 this->reset(that.release());
115 return *this;
116 }
117
118 /**
119 * Copies the underlying object pointer from the argument to the gr_sp. If the gr_sp previously
120 * held a reference to another object, Unref() will be called on that object. It will then call
121 * Ref() on the new object.
122 */
124 this->reset(SafeRef(that.get()));
125 return *this;
126 }
127
128 T& operator*() const {
129 SkASSERT(this->get() != nullptr);
130 return *this->get();
131 }
132
133 explicit operator bool() const { return this->get() != nullptr; }
134
135 T* get() const { return fPtr; }
136 T* operator->() const { return fPtr; }
137
138 /**
139 * Adopt the new bare pointer, and call Unref() on any previously held object (if not null).
140 * No call to Ref() will be made.
141 */
142 void reset(T* ptr = nullptr) {
143 T* oldPtr = fPtr;
144 fPtr = ptr;
145 SafeUnref(oldPtr);
146 }
147
148private:
149 /**
150 * Return the bare pointer, and set the internal object pointer to nullptr.
151 * The caller must assume ownership of the object, and manage its reference count directly.
152 * No call to Unref() will be made.
153 */
154 [[nodiscard]] T* release() {
155 T* ptr = fPtr;
156 fPtr = nullptr;
157 return ptr;
158 }
159
160 T* fPtr;
161};
162
163////////////////////////////////////////////////////////////////////////////////////////////////////
164
165/**
166 * Shared pointer class to wrap classes that support a refCommandBuffer() and unrefCommandBuffer()
167 * interface.
168 *
169 * This class supports copying, moving, and assigning an sk_sp into it. In general these commands do
170 * not modify the sk_sp at all but just call refCommandBuffer() on the underlying object.
171 *
172 * This class is designed to be used by GrGpuResources/graphite::Resources that need to track when
173 * they are in use on gpu (usually via a command buffer) separately from tracking if there are any
174 * current logical usages in Skia. This allows for a scratch resources to be reused for new draw
175 * calls even if it is in use on the GPU.
176 */
177template <typename T>
179
180////////////////////////////////////////////////////////////////////////////////////////////////////
181
182/**
183 * This class mimics sk_sp but instead of calling unref it calls recycle instead.
184 */
185template <typename T> using gr_rp = gr_sp<T, &T::ref, &T::recycle>;
186
187/**
188 * Returns a gr_rp wrapping the provided ptr AND calls ref on it (if not null).
189 *
190 * This is different than the semantics of the constructor for gr_rp, which just wraps the ptr,
191 * effectively "adopting" it.
192 */
193template <typename T> gr_rp<T> gr_ref_rp(T* obj) { return gr_rp<T>(SkSafeRef(obj)); }
194
195template <typename T> gr_rp<T> gr_ref_rp(const T* obj) {
196 return gr_rp<T>(const_cast<T*>(SkSafeRef(obj)));
197}
198#endif
m reset()
gr_rp< T > gr_ref_rp(T *obj)
Definition GpuRefCnt.h:193
#define SkASSERT(cond)
Definition SkAssert.h:116
#define SkDEBUGCODE(...)
Definition SkDebug.h:23
static T * SkSafeRef(T *obj)
Definition SkRefCnt.h:140
gr_sp & operator=(gr_sp< T, Ref, Unref > &&that)
Definition GpuRefCnt.h:113
gr_sp(const gr_sp< T, Ref, Unref > &that)
Definition GpuRefCnt.h:47
gr_sp & operator=(sk_sp< T > &&that)
Definition GpuRefCnt.h:123
T * get() const
Definition GpuRefCnt.h:135
void reset(T *ptr=nullptr)
Definition GpuRefCnt.h:142
T * operator->() const
Definition GpuRefCnt.h:136
gr_sp(gr_sp< T, Ref, Unref > &&that)
Definition GpuRefCnt.h:60
gr_sp & operator=(const gr_sp< T, Ref, Unref > &that)
Definition GpuRefCnt.h:91
T & operator*() const
Definition GpuRefCnt.h:128
gr_sp(const sk_sp< T > &that)
Definition GpuRefCnt.h:52
T element_type
Definition GpuRefCnt.h:38
gr_sp(const gr_sp< U, Ref, Unref > &that)
Definition GpuRefCnt.h:50
constexpr gr_sp()
Definition GpuRefCnt.h:40
gr_sp & operator=(const sk_sp< T > &that)
Definition GpuRefCnt.h:103
gr_sp(sk_sp< T > &&that)
Definition GpuRefCnt.h:66
~gr_sp()
Definition GpuRefCnt.h:77
gr_sp & operator=(std::nullptr_t)
Definition GpuRefCnt.h:82
constexpr gr_sp(std::nullptr_t)
Definition GpuRefCnt.h:41
gr_sp(T *obj)
Definition GpuRefCnt.h:72
T * get() const
Definition SkRefCnt.h:303
#define T