1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkRefCnt.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,292 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkRefCnt_DEFINED 1.14 +#define SkRefCnt_DEFINED 1.15 + 1.16 +#include "SkDynamicAnnotations.h" 1.17 +#include "SkThread.h" 1.18 +#include "SkInstCnt.h" 1.19 +#include "SkTemplates.h" 1.20 + 1.21 +/** \class SkRefCntBase 1.22 + 1.23 + SkRefCntBase is the base class for objects that may be shared by multiple 1.24 + objects. When an existing owner wants to share a reference, it calls ref(). 1.25 + When an owner wants to release its reference, it calls unref(). When the 1.26 + shared object's reference count goes to zero as the result of an unref() 1.27 + call, its (virtual) destructor is called. It is an error for the 1.28 + destructor to be called explicitly (or via the object going out of scope on 1.29 + the stack or calling delete) if getRefCnt() > 1. 1.30 +*/ 1.31 +class SK_API SkRefCntBase : public SkNoncopyable { 1.32 +public: 1.33 + SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase) 1.34 + 1.35 + /** Default construct, initializing the reference count to 1. 1.36 + */ 1.37 + SkRefCntBase() : fRefCnt(1) {} 1.38 + 1.39 + /** Destruct, asserting that the reference count is 1. 1.40 + */ 1.41 + virtual ~SkRefCntBase() { 1.42 +#ifdef SK_DEBUG 1.43 + SkASSERT(fRefCnt == 1); 1.44 + fRefCnt = 0; // illegal value, to catch us if we reuse after delete 1.45 +#endif 1.46 + } 1.47 + 1.48 + /** Return the reference count. Use only for debugging. */ 1.49 + int32_t getRefCnt() const { return fRefCnt; } 1.50 + 1.51 + /** May return true if the caller is the only owner. 1.52 + * Ensures that all previous owner's actions are complete. 1.53 + */ 1.54 + bool unique() const { 1.55 + // We believe we're reading fRefCnt in a safe way here, so we stifle the TSAN warning about 1.56 + // an unproctected read. Generally, don't read fRefCnt, and don't stifle this warning. 1.57 + bool const unique = (1 == SK_ANNOTATE_UNPROTECTED_READ(fRefCnt)); 1.58 + if (unique) { 1.59 + // Acquire barrier (L/SL), if not provided by load of fRefCnt. 1.60 + // Prevents user's 'unique' code from happening before decrements. 1.61 + //TODO: issue the barrier. 1.62 + } 1.63 + return unique; 1.64 + } 1.65 + 1.66 + /** Increment the reference count. Must be balanced by a call to unref(). 1.67 + */ 1.68 + void ref() const { 1.69 + SkASSERT(fRefCnt > 0); 1.70 + sk_atomic_inc(&fRefCnt); // No barrier required. 1.71 + } 1.72 + 1.73 + /** Decrement the reference count. If the reference count is 1 before the 1.74 + decrement, then delete the object. Note that if this is the case, then 1.75 + the object needs to have been allocated via new, and not on the stack. 1.76 + */ 1.77 + void unref() const { 1.78 + SkASSERT(fRefCnt > 0); 1.79 + // Release barrier (SL/S), if not provided below. 1.80 + if (sk_atomic_dec(&fRefCnt) == 1) { 1.81 + // Acquire barrier (L/SL), if not provided above. 1.82 + // Prevents code in dispose from happening before the decrement. 1.83 + sk_membar_acquire__after_atomic_dec(); 1.84 + internal_dispose(); 1.85 + } 1.86 + } 1.87 + 1.88 +#ifdef SK_DEBUG 1.89 + void validate() const { 1.90 + SkASSERT(fRefCnt > 0); 1.91 + } 1.92 +#endif 1.93 + 1.94 +protected: 1.95 + /** 1.96 + * Allow subclasses to call this if they've overridden internal_dispose 1.97 + * so they can reset fRefCnt before the destructor is called. Should only 1.98 + * be called right before calling through to inherited internal_dispose() 1.99 + * or before calling the destructor. 1.100 + */ 1.101 + void internal_dispose_restore_refcnt_to_1() const { 1.102 +#ifdef SK_DEBUG 1.103 + SkASSERT(0 == fRefCnt); 1.104 + fRefCnt = 1; 1.105 +#endif 1.106 + } 1.107 + 1.108 +private: 1.109 + /** 1.110 + * Called when the ref count goes to 0. 1.111 + */ 1.112 + virtual void internal_dispose() const { 1.113 + this->internal_dispose_restore_refcnt_to_1(); 1.114 + SkDELETE(this); 1.115 + } 1.116 + 1.117 + // The following friends are those which override internal_dispose() 1.118 + // and conditionally call SkRefCnt::internal_dispose(). 1.119 + friend class GrTexture; 1.120 + friend class SkWeakRefCnt; 1.121 + 1.122 + mutable int32_t fRefCnt; 1.123 + 1.124 + typedef SkNoncopyable INHERITED; 1.125 +}; 1.126 + 1.127 +#ifdef SK_REF_CNT_MIXIN_INCLUDE 1.128 +// It is the responsibility of the following include to define the type SkRefCnt. 1.129 +// This SkRefCnt should normally derive from SkRefCntBase. 1.130 +#include SK_REF_CNT_MIXIN_INCLUDE 1.131 +#else 1.132 +class SK_API SkRefCnt : public SkRefCntBase { }; 1.133 +#endif 1.134 + 1.135 +/////////////////////////////////////////////////////////////////////////////// 1.136 + 1.137 +/** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for 1.138 + null in on each side of the assignment, and ensuring that ref() is called 1.139 + before unref(), in case the two pointers point to the same object. 1.140 + */ 1.141 +#define SkRefCnt_SafeAssign(dst, src) \ 1.142 + do { \ 1.143 + if (src) src->ref(); \ 1.144 + if (dst) dst->unref(); \ 1.145 + dst = src; \ 1.146 + } while (0) 1.147 + 1.148 + 1.149 +/** Call obj->ref() and return obj. The obj must not be NULL. 1.150 + */ 1.151 +template <typename T> static inline T* SkRef(T* obj) { 1.152 + SkASSERT(obj); 1.153 + obj->ref(); 1.154 + return obj; 1.155 +} 1.156 + 1.157 +/** Check if the argument is non-null, and if so, call obj->ref() and return obj. 1.158 + */ 1.159 +template <typename T> static inline T* SkSafeRef(T* obj) { 1.160 + if (obj) { 1.161 + obj->ref(); 1.162 + } 1.163 + return obj; 1.164 +} 1.165 + 1.166 +/** Check if the argument is non-null, and if so, call obj->unref() 1.167 + */ 1.168 +template <typename T> static inline void SkSafeUnref(T* obj) { 1.169 + if (obj) { 1.170 + obj->unref(); 1.171 + } 1.172 +} 1.173 + 1.174 +template<typename T> static inline void SkSafeSetNull(T*& obj) { 1.175 + if (NULL != obj) { 1.176 + obj->unref(); 1.177 + obj = NULL; 1.178 + } 1.179 +} 1.180 + 1.181 +/////////////////////////////////////////////////////////////////////////////// 1.182 + 1.183 +/** 1.184 + * Utility class that simply unref's its argument in the destructor. 1.185 + */ 1.186 +template <typename T> class SkAutoTUnref : SkNoncopyable { 1.187 +public: 1.188 + explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {} 1.189 + ~SkAutoTUnref() { SkSafeUnref(fObj); } 1.190 + 1.191 + T* get() const { return fObj; } 1.192 + 1.193 + T* reset(T* obj) { 1.194 + SkSafeUnref(fObj); 1.195 + fObj = obj; 1.196 + return obj; 1.197 + } 1.198 + 1.199 + void swap(SkAutoTUnref* other) { 1.200 + T* tmp = fObj; 1.201 + fObj = other->fObj; 1.202 + other->fObj = tmp; 1.203 + } 1.204 + 1.205 + /** 1.206 + * Return the hosted object (which may be null), transferring ownership. 1.207 + * The reference count is not modified, and the internal ptr is set to NULL 1.208 + * so unref() will not be called in our destructor. A subsequent call to 1.209 + * detach() will do nothing and return null. 1.210 + */ 1.211 + T* detach() { 1.212 + T* obj = fObj; 1.213 + fObj = NULL; 1.214 + return obj; 1.215 + } 1.216 + 1.217 + /** 1.218 + * BlockRef<B> is a type which inherits from B, cannot be created, 1.219 + * cannot be deleted, and makes ref and unref private. 1.220 + */ 1.221 + template<typename B> class BlockRef : public B { 1.222 + private: 1.223 + BlockRef(); 1.224 + ~BlockRef(); 1.225 + void ref() const; 1.226 + void unref() const; 1.227 + }; 1.228 + 1.229 + /** If T is const, the type returned from operator-> will also be const. */ 1.230 + typedef typename SkTConstType<BlockRef<T>, SkTIsConst<T>::value>::type BlockRefType; 1.231 + 1.232 + /** 1.233 + * SkAutoTUnref assumes ownership of the ref. As a result, it is an error 1.234 + * for the user to ref or unref through SkAutoTUnref. Therefore 1.235 + * SkAutoTUnref::operator-> returns BlockRef<T>*. This prevents use of 1.236 + * skAutoTUnrefInstance->ref() and skAutoTUnrefInstance->unref(). 1.237 + */ 1.238 + BlockRefType *operator->() const { 1.239 + return static_cast<BlockRefType*>(fObj); 1.240 + } 1.241 + operator T*() { return fObj; } 1.242 + 1.243 +private: 1.244 + T* fObj; 1.245 +}; 1.246 +// Can't use the #define trick below to guard a bare SkAutoTUnref(...) because it's templated. :( 1.247 + 1.248 +class SkAutoUnref : public SkAutoTUnref<SkRefCnt> { 1.249 +public: 1.250 + SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref<SkRefCnt>(obj) {} 1.251 +}; 1.252 +#define SkAutoUnref(...) SK_REQUIRE_LOCAL_VAR(SkAutoUnref) 1.253 + 1.254 +class SkAutoRef : SkNoncopyable { 1.255 +public: 1.256 + SkAutoRef(SkRefCnt* obj) : fObj(obj) { SkSafeRef(obj); } 1.257 + ~SkAutoRef() { SkSafeUnref(fObj); } 1.258 +private: 1.259 + SkRefCnt* fObj; 1.260 +}; 1.261 +#define SkAutoRef(...) SK_REQUIRE_LOCAL_VAR(SkAutoRef) 1.262 + 1.263 +/** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to 1.264 + a SkRefCnt (or subclass) object. 1.265 + */ 1.266 +template <typename T> class SkRefPtr { 1.267 +public: 1.268 + SkRefPtr() : fObj(NULL) {} 1.269 + SkRefPtr(T* obj) : fObj(obj) { SkSafeRef(fObj); } 1.270 + SkRefPtr(const SkRefPtr& o) : fObj(o.fObj) { SkSafeRef(fObj); } 1.271 + ~SkRefPtr() { SkSafeUnref(fObj); } 1.272 + 1.273 + SkRefPtr& operator=(const SkRefPtr& rp) { 1.274 + SkRefCnt_SafeAssign(fObj, rp.fObj); 1.275 + return *this; 1.276 + } 1.277 + SkRefPtr& operator=(T* obj) { 1.278 + SkRefCnt_SafeAssign(fObj, obj); 1.279 + return *this; 1.280 + } 1.281 + 1.282 + T* get() const { return fObj; } 1.283 + T& operator*() const { return *fObj; } 1.284 + T* operator->() const { return fObj; } 1.285 + 1.286 + typedef T* SkRefPtr::*unspecified_bool_type; 1.287 + operator unspecified_bool_type() const { 1.288 + return fObj ? &SkRefPtr::fObj : NULL; 1.289 + } 1.290 + 1.291 +private: 1.292 + T* fObj; 1.293 +}; 1.294 + 1.295 +#endif