1*8975f5c5SAndroid Build Coastguard Worker // 2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved. 3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file. 5*8975f5c5SAndroid Build Coastguard Worker // 6*8975f5c5SAndroid Build Coastguard Worker 7*8975f5c5SAndroid Build Coastguard Worker // RefCountObject.h: Defines the gl::RefCountObject base class that provides 8*8975f5c5SAndroid Build Coastguard Worker // lifecycle support for GL objects using the traditional BindObject scheme, but 9*8975f5c5SAndroid Build Coastguard Worker // that need to be reference counted for correct cross-context deletion. 10*8975f5c5SAndroid Build Coastguard Worker // (Concretely, textures, buffers and renderbuffers.) 11*8975f5c5SAndroid Build Coastguard Worker 12*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBANGLE_REFCOUNTOBJECT_H_ 13*8975f5c5SAndroid Build Coastguard Worker #define LIBANGLE_REFCOUNTOBJECT_H_ 14*8975f5c5SAndroid Build Coastguard Worker 15*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h" 16*8975f5c5SAndroid Build Coastguard Worker #include "common/PackedEnums.h" 17*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h" 18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Error.h" 19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Observer.h" 20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/serial_utils.h" 21*8975f5c5SAndroid Build Coastguard Worker 22*8975f5c5SAndroid Build Coastguard Worker #include <cstddef> 23*8975f5c5SAndroid Build Coastguard Worker 24*8975f5c5SAndroid Build Coastguard Worker namespace angle 25*8975f5c5SAndroid Build Coastguard Worker { 26*8975f5c5SAndroid Build Coastguard Worker 27*8975f5c5SAndroid Build Coastguard Worker template <typename ContextT, typename ErrorT> 28*8975f5c5SAndroid Build Coastguard Worker class RefCountObject : angle::NonCopyable 29*8975f5c5SAndroid Build Coastguard Worker { 30*8975f5c5SAndroid Build Coastguard Worker public: 31*8975f5c5SAndroid Build Coastguard Worker using ContextType = ContextT; 32*8975f5c5SAndroid Build Coastguard Worker using ErrorType = ErrorT; 33*8975f5c5SAndroid Build Coastguard Worker RefCountObject()34*8975f5c5SAndroid Build Coastguard Worker RefCountObject() : mRefCount(0) {} 35*8975f5c5SAndroid Build Coastguard Worker onDestroy(const ContextType * context)36*8975f5c5SAndroid Build Coastguard Worker virtual void onDestroy(const ContextType *context) {} 37*8975f5c5SAndroid Build Coastguard Worker addRef()38*8975f5c5SAndroid Build Coastguard Worker void addRef() const { ++mRefCount; } 39*8975f5c5SAndroid Build Coastguard Worker release(const ContextType * context)40*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void release(const ContextType *context) 41*8975f5c5SAndroid Build Coastguard Worker { 42*8975f5c5SAndroid Build Coastguard Worker ASSERT(mRefCount > 0); 43*8975f5c5SAndroid Build Coastguard Worker if (--mRefCount == 0) 44*8975f5c5SAndroid Build Coastguard Worker { 45*8975f5c5SAndroid Build Coastguard Worker onDestroy(context); 46*8975f5c5SAndroid Build Coastguard Worker delete this; 47*8975f5c5SAndroid Build Coastguard Worker } 48*8975f5c5SAndroid Build Coastguard Worker } 49*8975f5c5SAndroid Build Coastguard Worker getRefCount()50*8975f5c5SAndroid Build Coastguard Worker size_t getRefCount() const { return mRefCount; } 51*8975f5c5SAndroid Build Coastguard Worker 52*8975f5c5SAndroid Build Coastguard Worker protected: ~RefCountObject()53*8975f5c5SAndroid Build Coastguard Worker virtual ~RefCountObject() { ASSERT(mRefCount == 0); } 54*8975f5c5SAndroid Build Coastguard Worker 55*8975f5c5SAndroid Build Coastguard Worker mutable size_t mRefCount; 56*8975f5c5SAndroid Build Coastguard Worker }; 57*8975f5c5SAndroid Build Coastguard Worker 58*8975f5c5SAndroid Build Coastguard Worker // Alternative base class to RefCountObject using atomics to track the reference count. 59*8975f5c5SAndroid Build Coastguard Worker // Interchangable with RefCountObject for usage with BindingPointer and other wrappers. 60*8975f5c5SAndroid Build Coastguard Worker template <typename ContextT, typename ErrorT> 61*8975f5c5SAndroid Build Coastguard Worker class ThreadSafeRefCountObject : angle::NonCopyable 62*8975f5c5SAndroid Build Coastguard Worker { 63*8975f5c5SAndroid Build Coastguard Worker public: 64*8975f5c5SAndroid Build Coastguard Worker using ContextType = ContextT; 65*8975f5c5SAndroid Build Coastguard Worker using ErrorType = ErrorT; 66*8975f5c5SAndroid Build Coastguard Worker ThreadSafeRefCountObject()67*8975f5c5SAndroid Build Coastguard Worker ThreadSafeRefCountObject() : mRefCount(0) {} 68*8975f5c5SAndroid Build Coastguard Worker onDestroy(const ContextType * context)69*8975f5c5SAndroid Build Coastguard Worker virtual void onDestroy(const ContextType *context) {} 70*8975f5c5SAndroid Build Coastguard Worker addRef()71*8975f5c5SAndroid Build Coastguard Worker void addRef() const { mRefCount.fetch_add(1, std::memory_order_relaxed); } 72*8975f5c5SAndroid Build Coastguard Worker release(const ContextType * context)73*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void release(const ContextType *context) 74*8975f5c5SAndroid Build Coastguard Worker { 75*8975f5c5SAndroid Build Coastguard Worker ASSERT(mRefCount > 0); 76*8975f5c5SAndroid Build Coastguard Worker if (mRefCount.fetch_sub(1, std::memory_order_acq_rel) == 1) 77*8975f5c5SAndroid Build Coastguard Worker { 78*8975f5c5SAndroid Build Coastguard Worker onDestroy(context); 79*8975f5c5SAndroid Build Coastguard Worker delete this; 80*8975f5c5SAndroid Build Coastguard Worker } 81*8975f5c5SAndroid Build Coastguard Worker } 82*8975f5c5SAndroid Build Coastguard Worker getRefCount()83*8975f5c5SAndroid Build Coastguard Worker size_t getRefCount() const { return mRefCount; } 84*8975f5c5SAndroid Build Coastguard Worker 85*8975f5c5SAndroid Build Coastguard Worker protected: ~ThreadSafeRefCountObject()86*8975f5c5SAndroid Build Coastguard Worker virtual ~ThreadSafeRefCountObject() { ASSERT(mRefCount == 0); } 87*8975f5c5SAndroid Build Coastguard Worker 88*8975f5c5SAndroid Build Coastguard Worker mutable std::atomic<size_t> mRefCount; 89*8975f5c5SAndroid Build Coastguard Worker }; 90*8975f5c5SAndroid Build Coastguard Worker 91*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType, typename ContextT, typename ErrorT = angle::Result> 92*8975f5c5SAndroid Build Coastguard Worker class RefCountObjectReleaser : angle::NonCopyable 93*8975f5c5SAndroid Build Coastguard Worker { 94*8975f5c5SAndroid Build Coastguard Worker public: 95*8975f5c5SAndroid Build Coastguard Worker using ContextType = ContextT; 96*8975f5c5SAndroid Build Coastguard Worker using ErrorType = ErrorT; 97*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser()98*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser() {} RefCountObjectReleaser(const ContextType * context,ObjectType * object)99*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser(const ContextType *context, ObjectType *object) 100*8975f5c5SAndroid Build Coastguard Worker : mContext(context), mObject(object) 101*8975f5c5SAndroid Build Coastguard Worker {} 102*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser(RefCountObjectReleaser && other)103*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser(RefCountObjectReleaser &&other) 104*8975f5c5SAndroid Build Coastguard Worker : mContext(other.mContext), mObject(other.mObject) 105*8975f5c5SAndroid Build Coastguard Worker { 106*8975f5c5SAndroid Build Coastguard Worker other.mContext = nullptr; 107*8975f5c5SAndroid Build Coastguard Worker other.mObject = nullptr; 108*8975f5c5SAndroid Build Coastguard Worker } 109*8975f5c5SAndroid Build Coastguard Worker 110*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser &operator=(RefCountObjectReleaser &&other) 111*8975f5c5SAndroid Build Coastguard Worker { 112*8975f5c5SAndroid Build Coastguard Worker std::swap(mContext, other.mContext); 113*8975f5c5SAndroid Build Coastguard Worker std::swap(mObject, other.mObject); 114*8975f5c5SAndroid Build Coastguard Worker return *this; 115*8975f5c5SAndroid Build Coastguard Worker } 116*8975f5c5SAndroid Build Coastguard Worker ~RefCountObjectReleaser()117*8975f5c5SAndroid Build Coastguard Worker ~RefCountObjectReleaser() 118*8975f5c5SAndroid Build Coastguard Worker { 119*8975f5c5SAndroid Build Coastguard Worker if (mObject) 120*8975f5c5SAndroid Build Coastguard Worker { 121*8975f5c5SAndroid Build Coastguard Worker mObject->release(mContext); 122*8975f5c5SAndroid Build Coastguard Worker mObject = nullptr; 123*8975f5c5SAndroid Build Coastguard Worker } 124*8975f5c5SAndroid Build Coastguard Worker } 125*8975f5c5SAndroid Build Coastguard Worker 126*8975f5c5SAndroid Build Coastguard Worker private: 127*8975f5c5SAndroid Build Coastguard Worker const ContextType *mContext = nullptr; 128*8975f5c5SAndroid Build Coastguard Worker ObjectType *mObject = nullptr; 129*8975f5c5SAndroid Build Coastguard Worker }; 130*8975f5c5SAndroid Build Coastguard Worker 131*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType, typename ContextT, typename ErrorT = angle::Result> 132*8975f5c5SAndroid Build Coastguard Worker class BindingPointer 133*8975f5c5SAndroid Build Coastguard Worker { 134*8975f5c5SAndroid Build Coastguard Worker public: 135*8975f5c5SAndroid Build Coastguard Worker using ContextType = ContextT; 136*8975f5c5SAndroid Build Coastguard Worker using ErrorType = ErrorT; 137*8975f5c5SAndroid Build Coastguard Worker BindingPointer()138*8975f5c5SAndroid Build Coastguard Worker BindingPointer() : mObject(nullptr) {} 139*8975f5c5SAndroid Build Coastguard Worker BindingPointer(ObjectType * object)140*8975f5c5SAndroid Build Coastguard Worker BindingPointer(ObjectType *object) : mObject(object) 141*8975f5c5SAndroid Build Coastguard Worker { 142*8975f5c5SAndroid Build Coastguard Worker if (mObject) 143*8975f5c5SAndroid Build Coastguard Worker { 144*8975f5c5SAndroid Build Coastguard Worker mObject->addRef(); 145*8975f5c5SAndroid Build Coastguard Worker } 146*8975f5c5SAndroid Build Coastguard Worker } 147*8975f5c5SAndroid Build Coastguard Worker BindingPointer(const BindingPointer & other)148*8975f5c5SAndroid Build Coastguard Worker BindingPointer(const BindingPointer &other) : mObject(other.mObject) 149*8975f5c5SAndroid Build Coastguard Worker { 150*8975f5c5SAndroid Build Coastguard Worker if (mObject) 151*8975f5c5SAndroid Build Coastguard Worker { 152*8975f5c5SAndroid Build Coastguard Worker mObject->addRef(); 153*8975f5c5SAndroid Build Coastguard Worker } 154*8975f5c5SAndroid Build Coastguard Worker } 155*8975f5c5SAndroid Build Coastguard Worker 156*8975f5c5SAndroid Build Coastguard Worker BindingPointer &operator=(BindingPointer &&other) 157*8975f5c5SAndroid Build Coastguard Worker { 158*8975f5c5SAndroid Build Coastguard Worker std::swap(mObject, other.mObject); 159*8975f5c5SAndroid Build Coastguard Worker return *this; 160*8975f5c5SAndroid Build Coastguard Worker } 161*8975f5c5SAndroid Build Coastguard Worker ~BindingPointer()162*8975f5c5SAndroid Build Coastguard Worker virtual ~BindingPointer() 163*8975f5c5SAndroid Build Coastguard Worker { 164*8975f5c5SAndroid Build Coastguard Worker // Objects have to be released before the resource manager is destroyed, so they must be 165*8975f5c5SAndroid Build Coastguard Worker // explicitly cleaned up. 166*8975f5c5SAndroid Build Coastguard Worker ASSERT(mObject == nullptr); 167*8975f5c5SAndroid Build Coastguard Worker } 168*8975f5c5SAndroid Build Coastguard Worker set(const ContextType * context,ObjectType * newObject)169*8975f5c5SAndroid Build Coastguard Worker RefCountObjectReleaser<ObjectType, ContextType, ErrorT> set(const ContextType *context, 170*8975f5c5SAndroid Build Coastguard Worker ObjectType *newObject) 171*8975f5c5SAndroid Build Coastguard Worker { 172*8975f5c5SAndroid Build Coastguard Worker // addRef first in case newObject == mObject and this is the last reference to it. 173*8975f5c5SAndroid Build Coastguard Worker if (newObject != nullptr) 174*8975f5c5SAndroid Build Coastguard Worker { 175*8975f5c5SAndroid Build Coastguard Worker newObject->addRef(); 176*8975f5c5SAndroid Build Coastguard Worker } 177*8975f5c5SAndroid Build Coastguard Worker 178*8975f5c5SAndroid Build Coastguard Worker // Store the old pointer in a temporary so we can set the pointer before calling release. 179*8975f5c5SAndroid Build Coastguard Worker // Otherwise the object could still be referenced when its destructor is called. 180*8975f5c5SAndroid Build Coastguard Worker ObjectType *oldObject = mObject; 181*8975f5c5SAndroid Build Coastguard Worker mObject = newObject; 182*8975f5c5SAndroid Build Coastguard Worker return RefCountObjectReleaser<ObjectType, ContextType, ErrorT>(context, oldObject); 183*8975f5c5SAndroid Build Coastguard Worker } 184*8975f5c5SAndroid Build Coastguard Worker assign(ObjectType * object)185*8975f5c5SAndroid Build Coastguard Worker void assign(ObjectType *object) { mObject = object; } 186*8975f5c5SAndroid Build Coastguard Worker get()187*8975f5c5SAndroid Build Coastguard Worker ObjectType *get() const { return mObject; } 188*8975f5c5SAndroid Build Coastguard Worker ObjectType *operator->() const { return mObject; } 189*8975f5c5SAndroid Build Coastguard Worker 190*8975f5c5SAndroid Build Coastguard Worker bool operator==(const BindingPointer &other) const { return mObject == other.mObject; } 191*8975f5c5SAndroid Build Coastguard Worker 192*8975f5c5SAndroid Build Coastguard Worker bool operator!=(const BindingPointer &other) const { return !(*this == other); } 193*8975f5c5SAndroid Build Coastguard Worker 194*8975f5c5SAndroid Build Coastguard Worker protected: setImpl(ObjectType * obj)195*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void setImpl(ObjectType *obj) { mObject = obj; } 196*8975f5c5SAndroid Build Coastguard Worker 197*8975f5c5SAndroid Build Coastguard Worker private: 198*8975f5c5SAndroid Build Coastguard Worker ObjectType *mObject; 199*8975f5c5SAndroid Build Coastguard Worker }; 200*8975f5c5SAndroid Build Coastguard Worker } // namespace angle 201*8975f5c5SAndroid Build Coastguard Worker 202*8975f5c5SAndroid Build Coastguard Worker namespace gl 203*8975f5c5SAndroid Build Coastguard Worker { 204*8975f5c5SAndroid Build Coastguard Worker class Context; 205*8975f5c5SAndroid Build Coastguard Worker 206*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType> 207*8975f5c5SAndroid Build Coastguard Worker class BindingPointer; 208*8975f5c5SAndroid Build Coastguard Worker 209*8975f5c5SAndroid Build Coastguard Worker using RefCountObjectNoID = angle::RefCountObject<Context, angle::Result>; 210*8975f5c5SAndroid Build Coastguard Worker using ThreadSafeRefCountObjectNoID = angle::ThreadSafeRefCountObject<Context, angle::Result>; 211*8975f5c5SAndroid Build Coastguard Worker 212*8975f5c5SAndroid Build Coastguard Worker template <typename IDType, typename RC = RefCountObjectNoID> 213*8975f5c5SAndroid Build Coastguard Worker class RefCountObject : public RC 214*8975f5c5SAndroid Build Coastguard Worker { 215*8975f5c5SAndroid Build Coastguard Worker public: RefCountObject(rx::UniqueSerial serial,IDType id)216*8975f5c5SAndroid Build Coastguard Worker explicit RefCountObject(rx::UniqueSerial serial, IDType id) : mSerial(serial), mId(id) {} 217*8975f5c5SAndroid Build Coastguard Worker serial()218*8975f5c5SAndroid Build Coastguard Worker rx::UniqueSerial serial() const { return mSerial; } id()219*8975f5c5SAndroid Build Coastguard Worker IDType id() const { return mId; } 220*8975f5c5SAndroid Build Coastguard Worker 221*8975f5c5SAndroid Build Coastguard Worker protected: ~RefCountObject()222*8975f5c5SAndroid Build Coastguard Worker ~RefCountObject() override {} 223*8975f5c5SAndroid Build Coastguard Worker 224*8975f5c5SAndroid Build Coastguard Worker private: 225*8975f5c5SAndroid Build Coastguard Worker // Unique serials are used to identify resources for frame capture. 226*8975f5c5SAndroid Build Coastguard Worker rx::UniqueSerial mSerial; 227*8975f5c5SAndroid Build Coastguard Worker IDType mId; 228*8975f5c5SAndroid Build Coastguard Worker }; 229*8975f5c5SAndroid Build Coastguard Worker template <typename IDType> 230*8975f5c5SAndroid Build Coastguard Worker using ThreadSafeRefCountObject = RefCountObject<IDType, ThreadSafeRefCountObjectNoID>; 231*8975f5c5SAndroid Build Coastguard Worker 232*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType> 233*8975f5c5SAndroid Build Coastguard Worker class BindingPointer : public angle::BindingPointer<ObjectType, Context> 234*8975f5c5SAndroid Build Coastguard Worker { 235*8975f5c5SAndroid Build Coastguard Worker public: 236*8975f5c5SAndroid Build Coastguard Worker using ContextType = typename angle::BindingPointer<ObjectType, Context>::ContextType; 237*8975f5c5SAndroid Build Coastguard Worker using ErrorType = typename angle::BindingPointer<ObjectType, Context>::ErrorType; 238*8975f5c5SAndroid Build Coastguard Worker BindingPointer()239*8975f5c5SAndroid Build Coastguard Worker BindingPointer() {} 240*8975f5c5SAndroid Build Coastguard Worker BindingPointer(ObjectType * object)241*8975f5c5SAndroid Build Coastguard Worker BindingPointer(ObjectType *object) : angle::BindingPointer<ObjectType, Context>(object) {} 242*8975f5c5SAndroid Build Coastguard Worker id()243*8975f5c5SAndroid Build Coastguard Worker typename ResourceTypeToID<ObjectType>::IDType id() const 244*8975f5c5SAndroid Build Coastguard Worker { 245*8975f5c5SAndroid Build Coastguard Worker ObjectType *obj = this->get(); 246*8975f5c5SAndroid Build Coastguard Worker if (obj) 247*8975f5c5SAndroid Build Coastguard Worker return obj->id(); 248*8975f5c5SAndroid Build Coastguard Worker return {0}; 249*8975f5c5SAndroid Build Coastguard Worker } 250*8975f5c5SAndroid Build Coastguard Worker }; 251*8975f5c5SAndroid Build Coastguard Worker 252*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType> 253*8975f5c5SAndroid Build Coastguard Worker class OffsetBindingPointer : public BindingPointer<ObjectType> 254*8975f5c5SAndroid Build Coastguard Worker { 255*8975f5c5SAndroid Build Coastguard Worker public: 256*8975f5c5SAndroid Build Coastguard Worker using ContextType = typename BindingPointer<ObjectType>::ContextType; 257*8975f5c5SAndroid Build Coastguard Worker using ErrorType = typename BindingPointer<ObjectType>::ErrorType; 258*8975f5c5SAndroid Build Coastguard Worker OffsetBindingPointer()259*8975f5c5SAndroid Build Coastguard Worker OffsetBindingPointer() : mOffset(0), mSize(0) {} 260*8975f5c5SAndroid Build Coastguard Worker set(const ContextType * context,ObjectType * newObject,GLintptr offset,GLsizeiptr size)261*8975f5c5SAndroid Build Coastguard Worker void set(const ContextType *context, ObjectType *newObject, GLintptr offset, GLsizeiptr size) 262*8975f5c5SAndroid Build Coastguard Worker { 263*8975f5c5SAndroid Build Coastguard Worker set(context, newObject); 264*8975f5c5SAndroid Build Coastguard Worker updateOffsetAndSize(newObject, offset, size); 265*8975f5c5SAndroid Build Coastguard Worker } 266*8975f5c5SAndroid Build Coastguard Worker getOffset()267*8975f5c5SAndroid Build Coastguard Worker GLintptr getOffset() const { return mOffset; } getSize()268*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr getSize() const { return mSize; } 269*8975f5c5SAndroid Build Coastguard Worker 270*8975f5c5SAndroid Build Coastguard Worker bool operator==(const OffsetBindingPointer<ObjectType> &other) const 271*8975f5c5SAndroid Build Coastguard Worker { 272*8975f5c5SAndroid Build Coastguard Worker return this->get() == other.get() && mOffset == other.mOffset && mSize == other.mSize; 273*8975f5c5SAndroid Build Coastguard Worker } 274*8975f5c5SAndroid Build Coastguard Worker 275*8975f5c5SAndroid Build Coastguard Worker bool operator!=(const OffsetBindingPointer<ObjectType> &other) const 276*8975f5c5SAndroid Build Coastguard Worker { 277*8975f5c5SAndroid Build Coastguard Worker return !(*this == other); 278*8975f5c5SAndroid Build Coastguard Worker } 279*8975f5c5SAndroid Build Coastguard Worker assign(ObjectType * newObject,GLintptr offset,GLsizeiptr size)280*8975f5c5SAndroid Build Coastguard Worker void assign(ObjectType *newObject, GLintptr offset, GLsizeiptr size) 281*8975f5c5SAndroid Build Coastguard Worker { 282*8975f5c5SAndroid Build Coastguard Worker assign(newObject); 283*8975f5c5SAndroid Build Coastguard Worker updateOffsetAndSize(newObject, offset, size); 284*8975f5c5SAndroid Build Coastguard Worker } 285*8975f5c5SAndroid Build Coastguard Worker 286*8975f5c5SAndroid Build Coastguard Worker private: updateOffsetAndSize(ObjectType * newObject,GLintptr offset,GLsizeiptr size)287*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE void updateOffsetAndSize(ObjectType *newObject, GLintptr offset, GLsizeiptr size) 288*8975f5c5SAndroid Build Coastguard Worker { 289*8975f5c5SAndroid Build Coastguard Worker if (newObject) 290*8975f5c5SAndroid Build Coastguard Worker { 291*8975f5c5SAndroid Build Coastguard Worker mOffset = offset; 292*8975f5c5SAndroid Build Coastguard Worker mSize = size; 293*8975f5c5SAndroid Build Coastguard Worker } 294*8975f5c5SAndroid Build Coastguard Worker else 295*8975f5c5SAndroid Build Coastguard Worker { 296*8975f5c5SAndroid Build Coastguard Worker mOffset = 0; 297*8975f5c5SAndroid Build Coastguard Worker mSize = 0; 298*8975f5c5SAndroid Build Coastguard Worker } 299*8975f5c5SAndroid Build Coastguard Worker } 300*8975f5c5SAndroid Build Coastguard Worker 301*8975f5c5SAndroid Build Coastguard Worker // Delete the unparameterized functions. This forces an explicit offset and size. 302*8975f5c5SAndroid Build Coastguard Worker using BindingPointer<ObjectType>::set; 303*8975f5c5SAndroid Build Coastguard Worker using BindingPointer<ObjectType>::assign; 304*8975f5c5SAndroid Build Coastguard Worker 305*8975f5c5SAndroid Build Coastguard Worker GLintptr mOffset; 306*8975f5c5SAndroid Build Coastguard Worker GLsizeiptr mSize; 307*8975f5c5SAndroid Build Coastguard Worker }; 308*8975f5c5SAndroid Build Coastguard Worker 309*8975f5c5SAndroid Build Coastguard Worker template <typename SubjectT> 310*8975f5c5SAndroid Build Coastguard Worker class SubjectBindingPointer : protected BindingPointer<SubjectT>, public angle::ObserverBindingBase 311*8975f5c5SAndroid Build Coastguard Worker { 312*8975f5c5SAndroid Build Coastguard Worker public: SubjectBindingPointer(angle::ObserverInterface * observer,angle::SubjectIndex index)313*8975f5c5SAndroid Build Coastguard Worker SubjectBindingPointer(angle::ObserverInterface *observer, angle::SubjectIndex index) 314*8975f5c5SAndroid Build Coastguard Worker : ObserverBindingBase(observer, index) 315*8975f5c5SAndroid Build Coastguard Worker {} ~SubjectBindingPointer()316*8975f5c5SAndroid Build Coastguard Worker ~SubjectBindingPointer() override {} 317*8975f5c5SAndroid Build Coastguard Worker SubjectBindingPointer(const SubjectBindingPointer &other) = default; 318*8975f5c5SAndroid Build Coastguard Worker SubjectBindingPointer &operator=(const SubjectBindingPointer &other) = default; 319*8975f5c5SAndroid Build Coastguard Worker bind(const Context * context,SubjectT * subject)320*8975f5c5SAndroid Build Coastguard Worker void bind(const Context *context, SubjectT *subject) 321*8975f5c5SAndroid Build Coastguard Worker { 322*8975f5c5SAndroid Build Coastguard Worker // AddRef first in case subject == get() 323*8975f5c5SAndroid Build Coastguard Worker if (subject) 324*8975f5c5SAndroid Build Coastguard Worker { 325*8975f5c5SAndroid Build Coastguard Worker subject->addObserver(this); 326*8975f5c5SAndroid Build Coastguard Worker subject->addRef(); 327*8975f5c5SAndroid Build Coastguard Worker } 328*8975f5c5SAndroid Build Coastguard Worker 329*8975f5c5SAndroid Build Coastguard Worker if (get()) 330*8975f5c5SAndroid Build Coastguard Worker { 331*8975f5c5SAndroid Build Coastguard Worker get()->removeObserver(this); 332*8975f5c5SAndroid Build Coastguard Worker get()->release(context); 333*8975f5c5SAndroid Build Coastguard Worker } 334*8975f5c5SAndroid Build Coastguard Worker 335*8975f5c5SAndroid Build Coastguard Worker this->setImpl(subject); 336*8975f5c5SAndroid Build Coastguard Worker } 337*8975f5c5SAndroid Build Coastguard Worker 338*8975f5c5SAndroid Build Coastguard Worker using BindingPointer<SubjectT>::get; 339*8975f5c5SAndroid Build Coastguard Worker using BindingPointer<SubjectT>::operator->; 340*8975f5c5SAndroid Build Coastguard Worker 341*8975f5c5SAndroid Build Coastguard Worker friend class State; 342*8975f5c5SAndroid Build Coastguard Worker }; 343*8975f5c5SAndroid Build Coastguard Worker } // namespace gl 344*8975f5c5SAndroid Build Coastguard Worker 345*8975f5c5SAndroid Build Coastguard Worker namespace egl 346*8975f5c5SAndroid Build Coastguard Worker { 347*8975f5c5SAndroid Build Coastguard Worker class Display; 348*8975f5c5SAndroid Build Coastguard Worker 349*8975f5c5SAndroid Build Coastguard Worker using RefCountObject = angle::RefCountObject<Display, Error>; 350*8975f5c5SAndroid Build Coastguard Worker using ThreadSafeRefCountObject = angle::ThreadSafeRefCountObject<Display, Error>; 351*8975f5c5SAndroid Build Coastguard Worker 352*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType> 353*8975f5c5SAndroid Build Coastguard Worker using RefCountObjectReleaser = angle::RefCountObjectReleaser<ObjectType, Display, Error>; 354*8975f5c5SAndroid Build Coastguard Worker 355*8975f5c5SAndroid Build Coastguard Worker template <class ObjectType> 356*8975f5c5SAndroid Build Coastguard Worker using BindingPointer = angle::BindingPointer<ObjectType, Display, Error>; 357*8975f5c5SAndroid Build Coastguard Worker 358*8975f5c5SAndroid Build Coastguard Worker } // namespace egl 359*8975f5c5SAndroid Build Coastguard Worker 360*8975f5c5SAndroid Build Coastguard Worker #endif // LIBANGLE_REFCOUNTOBJECT_H_ 361