8 #ifndef SkRefCnt_DEFINED
9 #define SkRefCnt_DEFINED
11 #include "../private/SkTLogic.h"
16 #include <type_traits>
39 SkASSERTF(getRefCnt() == 1,
"fRefCnt was %d", getRefCnt());
41 fRefCnt.store(0, std::memory_order_relaxed);
48 return fRefCnt.load(std::memory_order_relaxed);
51 void validate()
const {
52 SkASSERT(getRefCnt() > 0);
60 if (1 == fRefCnt.load(std::memory_order_acquire)) {
72 SkASSERT(getRefCnt() > 0);
74 (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed);
82 SkASSERT(getRefCnt() > 0);
84 if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
87 this->internal_dispose();
98 SkASSERT(0 == getRefCnt());
99 fRefCnt.store(1, std::memory_order_relaxed);
107 this->internal_dispose_restore_refcnt_to_1();
113 friend class SkWeakRefCnt;
115 mutable std::atomic<int32_t> fRefCnt;
117 typedef SkNoncopyable INHERITED;
120 #ifdef SK_REF_CNT_MIXIN_INCLUDE
123 #include SK_REF_CNT_MIXIN_INCLUDE
129 void deref()
const { this->
unref(); }
141 #if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
146 #define SkRefCnt_SafeAssign(dst, src) \
148 typedef typename std::remove_reference<decltype(dst)>::type \
150 SkRefCntPtrT old_dst = *const_cast<SkRefCntPtrT volatile *>(&dst); \
151 if (src) src->ref(); \
152 if (old_dst) old_dst->unref(); \
153 if (old_dst != *const_cast<SkRefCntPtrT volatile *>(&dst)) { \
154 SkDebugf("Detected racing Skia calls at %s:%d\n", \
155 __FILE__, __LINE__); \
162 #define SkRefCnt_SafeAssign(dst, src) \
164 if (src) src->ref(); \
165 if (dst) dst->unref(); \
174 template <
typename T>
static inline T* SkRef(T* obj) {
182 template <
typename T>
static inline T* SkSafeRef(T* obj) {
191 template <
typename T>
static inline void SkSafeUnref(T* obj) {
197 template<
typename T>
static inline void SkSafeSetNull(T*& obj) {
208 template <
typename Derived>
212 ~
SkNVRefCnt() { SkASSERTF(1 == getRefCnt(),
"NVRefCnt was %d", getRefCnt()); }
219 bool unique()
const {
return 1 == fRefCnt.load(std::memory_order_acquire); }
220 void ref()
const { (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed); }
222 if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
224 SkDEBUGCODE(fRefCnt.store(1, std::memory_order_relaxed));
225 delete (
const Derived*)
this;
228 void deref()
const { this->unref(); }
231 mutable std::atomic<int32_t> fRefCnt;
232 int32_t getRefCnt()
const {
233 return fRefCnt.load(std::memory_order_relaxed);
252 constexpr
sk_sp() : fPtr(nullptr) {}
253 constexpr
sk_sp(std::nullptr_t) : fPtr(nullptr) {}
260 template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
269 template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
276 explicit sk_sp(T* obj) : fPtr(obj) {}
283 SkDEBUGCODE(fPtr =
nullptr);
286 sk_sp<T>& operator=(std::nullptr_t) { this->
reset();
return *
this; }
294 this->
reset(SkSafeRef(that.get()));
297 template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
299 this->
reset(SkSafeRef(that.get()));
312 template <typename U, typename = skstd::enable_if_t<std::is_convertible<U*, T*>::value>>
318 T& operator*()
const {
319 SkASSERT(this->
get() !=
nullptr);
328 bool operator!()
const {
return this->
get() ==
nullptr; }
330 T*
get()
const {
return fPtr; }
331 T* operator->()
const {
return fPtr; }
359 swap(fPtr, that.fPtr);
370 template <
typename T,
typename U>
inline bool operator==(
const sk_sp<T>& a,
const sk_sp<U>& b) {
371 return a.get() == b.get();
373 template <
typename T>
inline bool operator==(
const sk_sp<T>& a, std::nullptr_t) {
376 template <
typename T>
inline bool operator==(std::nullptr_t,
const sk_sp<T>& b) {
380 template <
typename T,
typename U>
inline bool operator!=(
const sk_sp<T>& a,
const sk_sp<U>& b) {
381 return a.get() != b.get();
383 template <
typename T>
inline bool operator!=(
const sk_sp<T>& a, std::nullptr_t) {
384 return static_cast<bool>(a);
386 template <
typename T>
inline bool operator!=(std::nullptr_t,
const sk_sp<T>& b) {
387 return static_cast<bool>(b);
390 template <
typename T,
typename U>
inline bool operator<(const sk_sp<T>& a,
const sk_sp<U>& b) {
394 return std::less<skstd::common_type_t<T*, U*>>()(a.get(), b.get());
396 template <
typename T>
inline bool operator<(const sk_sp<T>& a, std::nullptr_t) {
397 return std::less<T*>()(a.get(),
nullptr);
399 template <
typename T>
inline bool operator<(std::nullptr_t, const sk_sp<T>& b) {
400 return std::less<T*>()(
nullptr, b.get());
403 template <
typename T,
typename U>
inline bool operator<=(const sk_sp<T>& a,
const sk_sp<U>& b) {
406 template <
typename T>
inline bool operator<=(const sk_sp<T>& a, std::nullptr_t) {
407 return !(
nullptr < a);
409 template <
typename T>
inline bool operator<=(std::nullptr_t, const sk_sp<T>& b) {
410 return !(b <
nullptr);
413 template <
typename T,
typename U>
inline bool operator>(
const sk_sp<T>& a,
const sk_sp<U>& b) {
416 template <
typename T>
inline bool operator>(
const sk_sp<T>& a, std::nullptr_t) {
419 template <
typename T>
inline bool operator>(std::nullptr_t,
const sk_sp<T>& b) {
423 template <
typename T,
typename U>
inline bool operator>=(
const sk_sp<T>& a,
const sk_sp<U>& b) {
426 template <
typename T>
inline bool operator>=(
const sk_sp<T>& a, std::nullptr_t) {
427 return !(a <
nullptr);
429 template <
typename T>
inline bool operator>=(std::nullptr_t,
const sk_sp<T>& b) {
430 return !(
nullptr < b);
433 template <
typename T,
typename... Args>
434 sk_sp<T> sk_make_sp(Args&&... args) {
435 return sk_sp<T>(
new T(std::forward<Args>(args)...));
444 template <
typename T>
sk_sp<T> sk_ref_sp(T* obj) {
T *SK_WARN_UNUSED_RESULT release()
Return the bare pointer, and set the internal object pointer to nullptr.
Definition: SkRefCnt.h:351
void reset(T *ptr=nullptr)
Adopt the new bare pointer, and call unref() on any previously held object (if not null)...
Definition: SkRefCnt.h:337
sk_sp(T *obj)
Adopt the bare pointer into the newly created sk_sp.
Definition: SkRefCnt.h:276
void internal_dispose_restore_refcnt_to_1() const
Allow subclasses to call this if they've overridden internal_dispose so they can reset fRefCnt before...
Definition: SkRefCnt.h:97
int32_t getRefCnt() const
Return the reference count.
Definition: SkRefCnt.h:47
Definition: SkRefCnt.h:125
sk_sp< T > & operator=(sk_sp< T > &&that)
Move the underlying object from the argument to the sk_sp.
Definition: SkRefCnt.h:308
void unref() const
Decrement the reference count.
Definition: SkRefCnt.h:81
bool unique() const
May return true if the caller is the only owner.
Definition: SkRefCnt.h:59
void ref() const
Increment the reference count.
Definition: SkRefCnt.h:71
sk_sp(sk_sp< T > &&that)
Move the underlying object from the argument to the newly created sk_sp.
Definition: SkRefCnt.h:268
Shared pointer class to wrap classes that support a ref()/unref() interface.
Definition: SkRefCnt.h:246
Definition: GrShaderCaps.h:20
GrShaderCaps *sk_sp::* unspecified_bool_type
Supports safe bool idiom.
Definition: SkRefCnt.h:248
SkRefCntBase()
Default construct, initializing the reference count to 1.
Definition: SkRefCnt.h:33
sk_sp(const sk_sp< T > &that)
Shares the underlying object by calling ref(), so that both the argument and the newly created sk_sp ...
Definition: SkRefCnt.h:259
virtual void internal_dispose() const
Called when the ref count goes to 0.
Definition: SkRefCnt.h:106
virtual ~SkRefCntBase()
Destruct, asserting that the reference count is 1.
Definition: SkRefCnt.h:37
~sk_sp()
Calls unref() on the underlying object pointer.
Definition: SkRefCnt.h:281
SkRefCntBase is the base class for objects that may be shared by multiple objects.
Definition: SkRefCnt.h:29
Definition: SkRefCnt.h:209
sk_sp< T > & operator=(const sk_sp< T > &that)
Shares the underlying object referenced by the argument by calling ref() on it.
Definition: SkRefCnt.h:293