summaryrefslogtreecommitdiffstats
path: root/opengl/libs/EGL/egl_object.h
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2011-05-16 18:58:55 -0700
committerMathias Agopian <mathias@google.com>2011-05-16 19:03:33 -0700
commitf1e4e06319ef461997eefe45be716ad954defcb1 (patch)
tree5e42ec880e9320312b3feae7c37867284d16cb2a /opengl/libs/EGL/egl_object.h
parent7adf4ef0fad9973d9a07f2a73b2c4238c8e6bf7c (diff)
downloadframeworks_base-f1e4e06319ef461997eefe45be716ad954defcb1.zip
frameworks_base-f1e4e06319ef461997eefe45be716ad954defcb1.tar.gz
frameworks_base-f1e4e06319ef461997eefe45be716ad954defcb1.tar.bz2
eglTerminate() now actually frees up all active egl objects
as specified by the EGL specification, terminated objects's handles become invalid, the objects themselves are destroyed when they're not current to some thread. Change-Id: Id3a4a5736a5bbc3926a9ae8385d43772edb88eeb
Diffstat (limited to 'opengl/libs/EGL/egl_object.h')
-rw-r--r--opengl/libs/EGL/egl_object.h115
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) :