diff options
Diffstat (limited to 'opengl/libs/EGL/egl_object.h')
-rw-r--r-- | opengl/libs/EGL/egl_object.h | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h index ecb2514..3459a8a 100644 --- a/opengl/libs/EGL/egl_object.h +++ b/opengl/libs/EGL/egl_object.h @@ -41,64 +41,92 @@ struct egl_display_t; class egl_object_t { egl_display_t *display; - volatile int32_t terminated; mutable volatile int32_t count; +protected: + virtual ~egl_object_t(); + public: egl_object_t(egl_display_t* display); + void destroy(); - inline bool isAlive() const { return !terminated; } inline int32_t incRef() { return android_atomic_inc(&count); } inline int32_t decRef() { return android_atomic_dec(&count); } private: + void terminate(); bool get(); - bool put(); public: template <typename N, typename T> - struct LocalRef { - N* ref; - LocalRef(T o) : ref(0) { - N* native = reinterpret_cast<N*>(o); + class LocalRef { + egl_object_t* ref; + LocalRef(); + LocalRef(const LocalRef* rhs); + public: + ~LocalRef(); + explicit LocalRef(egl_object_t* rhs); + explicit LocalRef(T o) : ref(0) { + egl_object_t* native = reinterpret_cast<N*>(o); if (o && native->get()) { ref = native; } } - ~LocalRef() { - if (ref && ref->put()) { - delete ref; - } - } inline N* get() { - return ref; - } - void acquire() const { - if (ref) { - android_atomic_inc(&ref->count); - } - } - void release() const { - if (ref) { - int32_t c = android_atomic_dec(&ref->count); - // ref->count cannot be 1 prior atomic_dec because we have - // a reference, and if we have one, it means there was - // already one before us. - LOGE_IF(c==1, "refcount is now 0 in release()"); - } - } - void terminate() { - if (ref) { - ref->terminated = 1; - release(); - } + return static_cast<N*>(ref); } + void acquire() const; + void release() const; + void terminate(); }; + template <typename N, typename T> + friend class LocalRef; }; +template<typename N, typename T> +egl_object_t::LocalRef<N, T>::LocalRef(egl_object_t* rhs) : ref(rhs) { + if (ref) { + ref->incRef(); + } +} + +template <typename N, typename T> +egl_object_t::LocalRef<N,T>::~LocalRef() { + if (ref) { + ref->destroy(); + } +} + +template <typename N, typename T> +void egl_object_t::LocalRef<N,T>::acquire() const { + if (ref) { + ref->incRef(); + } +} + +template <typename N, typename T> +void egl_object_t::LocalRef<N,T>::release() const { + if (ref) { + if (ref->decRef() == 1) { + // shouldn't happen because this is called from LocalRef + LOGE("LocalRef::release() removed the last reference!"); + } + } +} + +template <typename N, typename T> +void egl_object_t::LocalRef<N,T>::terminate() { + if (ref) { + ref->terminate(); + } +} + // ---------------------------------------------------------------------------- -struct egl_surface_t: public egl_object_t { +class egl_surface_t: public egl_object_t { +protected: + ~egl_surface_t() {} +public: typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref; egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, @@ -106,8 +134,6 @@ struct egl_surface_t: public egl_object_t { egl_object_t(get_display(dpy)), dpy(dpy), surface(surface), config(config), win(win), impl(impl), cnx(cnx) { } - ~egl_surface_t() { - } EGLDisplay dpy; EGLSurface surface; EGLConfig config; @@ -116,7 +142,10 @@ struct egl_surface_t: public egl_object_t { egl_connection_t const* cnx; }; -struct egl_context_t: public egl_object_t { +class egl_context_t: public egl_object_t { +protected: + ~egl_context_t() {} +public: typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref; egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config, @@ -125,8 +154,6 @@ struct egl_context_t: public egl_object_t { config(config), read(0), draw(0), impl(impl), cnx(cnx), version(version) { } - ~egl_context_t() { - } EGLDisplay dpy; EGLContext context; EGLConfig config; @@ -137,7 +164,10 @@ struct egl_context_t: public egl_object_t { int version; }; -struct egl_image_t: public egl_object_t { +class egl_image_t: public egl_object_t { +protected: + ~egl_image_t() {} +public: typedef egl_object_t::LocalRef<egl_image_t, EGLImageKHR> Ref; egl_image_t(EGLDisplay dpy, EGLContext context) : @@ -149,7 +179,10 @@ struct egl_image_t: public egl_object_t { EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS]; }; -struct egl_sync_t: public egl_object_t { +class egl_sync_t: public egl_object_t { +protected: + ~egl_sync_t() {} +public: typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref; egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync) : |