summaryrefslogtreecommitdiffstats
path: root/opengl/libs
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
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')
-rw-r--r--opengl/libs/EGL/egl.cpp53
-rw-r--r--opengl/libs/EGL/eglApi.cpp108
-rw-r--r--opengl/libs/EGL/egl_display.cpp27
-rw-r--r--opengl/libs/EGL/egl_display.h6
-rw-r--r--opengl/libs/EGL/egl_object.cpp27
-rw-r--r--opengl/libs/EGL/egl_object.h115
6 files changed, 176 insertions, 160 deletions
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 1aca4c3..31fe306 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -173,21 +173,21 @@ static int sEarlyInitState = pthread_once(&once_control, &early_egl_init);
// ----------------------------------------------------------------------------
-egl_display_t* validate_display(EGLDisplay dpy)
-{
+egl_display_t* validate_display(EGLDisplay dpy) {
egl_display_t * const dp = get_display(dpy);
- if (!dp) return setError(EGL_BAD_DISPLAY, (egl_display_t*)NULL);
- if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, (egl_display_t*)NULL);
+ if (!dp)
+ return setError(EGL_BAD_DISPLAY, (egl_display_t*)NULL);
+ if (!dp->isReady())
+ return setError(EGL_NOT_INITIALIZED, (egl_display_t*)NULL);
return dp;
}
-egl_connection_t* validate_display_config(
- EGLDisplay dpy, EGLConfig config,
- egl_display_t const*& dp)
-{
+egl_connection_t* validate_display_config(EGLDisplay dpy, EGLConfig config,
+ egl_display_t const*& dp) {
dp = validate_display(dpy);
- if (!dp) return (egl_connection_t*) NULL;
+ if (!dp)
+ return (egl_connection_t*) NULL;
if (intptr_t(config) >= dp->numTotalConfigs) {
return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
@@ -199,43 +199,26 @@ egl_connection_t* validate_display_config(
return cnx;
}
-EGLBoolean validate_display_context(EGLDisplay dpy, EGLContext ctx)
-{
- egl_display_t const * const dp = validate_display(dpy);
- if (!dp) return EGL_FALSE;
- if (!dp->isAlive())
- return setError(EGL_BAD_DISPLAY, EGL_FALSE);
- if (!get_context(ctx)->isAlive())
- return setError(EGL_BAD_CONTEXT, EGL_FALSE);
- return EGL_TRUE;
-}
-
-EGLBoolean validate_display_surface(EGLDisplay dpy, EGLSurface surface)
-{
- egl_display_t const * const dp = validate_display(dpy);
- if (!dp) return EGL_FALSE;
- if (!dp->isAlive())
- return setError(EGL_BAD_DISPLAY, EGL_FALSE);
- if (!get_surface(surface)->isAlive())
- return setError(EGL_BAD_SURFACE, EGL_FALSE);
- return EGL_TRUE;
-}
-
// ----------------------------------------------------------------------------
EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
{
ImageRef _i(image);
- if (!_i.get()) return EGL_NO_IMAGE_KHR;
-
+ if (!_i.get())
+ return EGL_NO_IMAGE_KHR;
+
EGLContext context = egl_tls_t::getContext();
if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR)
return EGL_NO_IMAGE_KHR;
-
+
egl_context_t const * const c = get_context(context);
- if (!c->isAlive())
+ if (c == NULL) // this should never happen
return EGL_NO_IMAGE_KHR;
+ // here we don't validate the context because if it's been marked for
+ // termination, this call should still succeed since it's internal to
+ // EGL.
+
egl_image_t const * const i = get_image(image);
return i->images[c->impl];
}
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 210c24d..7d5d010 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -431,10 +431,8 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
-
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t * const s = get_surface(surface);
EGLBoolean result = s->cnx->egl.eglDestroySurface(
@@ -457,12 +455,10 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface,
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(surface);
-
EGLBoolean result(EGL_TRUE);
if (attribute == EGL_CONFIG_ID) {
// We need to remap EGL_CONFIG_IDs
@@ -524,13 +520,13 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
clearError();
egl_display_t const * const dp = validate_display(dpy);
- if (!dp) return EGL_FALSE;
+ if (!dp)
+ return EGL_FALSE;
ContextRef _c(ctx);
- if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+ if (!_c.get())
+ return setError(EGL_BAD_CONTEXT, EGL_FALSE);
- if (!validate_display_context(dpy, ctx))
- return EGL_FALSE;
egl_context_t * const c = get_context(ctx);
EGLBoolean result = c->cnx->egl.eglDestroyContext(
dp->disp[c->impl].dpy, c->context);
@@ -569,9 +565,9 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
egl_display_t const * const dp = get_display(dpy);
if (!dp) return setError(EGL_BAD_DISPLAY, EGL_FALSE);
- /* If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
- EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
- a valid but uninitialized display. */
+ // If ctx is not EGL_NO_CONTEXT, read is not EGL_NO_SURFACE, or draw is not
+ // EGL_NO_SURFACE, then an EGL_NOT_INITIALIZED error is generated if dpy is
+ // a valid but uninitialized display.
if ( (ctx != EGL_NO_CONTEXT) || (read != EGL_NO_SURFACE) ||
(draw != EGL_NO_SURFACE) ) {
if (!dp->isReady()) return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
@@ -583,7 +579,7 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
SurfaceRef _r(read);
// validate the context (if not EGL_NO_CONTEXT)
- if ((ctx != EGL_NO_CONTEXT) && (!validate_display_context(dpy, ctx))) {
+ if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
// EGL_NO_CONTEXT is valid
return EGL_FALSE;
}
@@ -682,9 +678,6 @@ EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
ContextRef _c(ctx);
if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
- if (!validate_display_context(dpy, ctx))
- return EGL_FALSE;
-
egl_context_t * const c = get_context(ctx);
EGLBoolean result(EGL_TRUE);
@@ -924,10 +917,9 @@ EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
if (!dp) return EGL_FALSE;
SurfaceRef _s(draw);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, draw))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(draw);
return s->cnx->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface);
}
@@ -941,10 +933,9 @@ EGLBoolean eglCopyBuffers( EGLDisplay dpy, EGLSurface surface,
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(surface);
return s->cnx->egl.eglCopyBuffers(
dp->disp[s->impl].dpy, s->surface, target);
@@ -984,10 +975,9 @@ EGLBoolean eglSurfaceAttrib(
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglSurfaceAttrib) {
return s->cnx->egl.eglSurfaceAttrib(
@@ -1005,10 +995,9 @@ EGLBoolean eglBindTexImage(
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglBindTexImage) {
return s->cnx->egl.eglBindTexImage(
@@ -1026,10 +1015,9 @@ EGLBoolean eglReleaseTexImage(
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(surface);
if (s->cnx->egl.eglReleaseTexImage) {
return s->cnx->egl.eglReleaseTexImage(
@@ -1186,13 +1174,10 @@ EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
-
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t const * const s = get_surface(surface);
-
if (s->cnx->egl.eglLockSurfaceKHR) {
return s->cnx->egl.eglLockSurfaceKHR(
dp->disp[s->impl].dpy, s->surface, attrib_list);
@@ -1208,13 +1193,10 @@ EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
if (!dp) return EGL_FALSE;
SurfaceRef _s(surface);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
-
- if (!validate_display_surface(dpy, surface))
- return EGL_FALSE;
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t const * const s = get_surface(surface);
-
if (s->cnx->egl.eglUnlockSurfaceKHR) {
return s->cnx->egl.eglUnlockSurfaceKHR(
dp->disp[s->impl].dpy, s->surface);
@@ -1232,9 +1214,8 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
if (ctx != EGL_NO_CONTEXT) {
ContextRef _c(ctx);
- if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
- if (!validate_display_context(dpy, ctx))
- return EGL_NO_IMAGE_KHR;
+ if (!_c.get())
+ return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
egl_context_t * const c = get_context(ctx);
// since we have an EGLContext, we know which implementation to use
EGLImageKHR image = c->cnx->egl.eglCreateImageKHR(
@@ -1341,9 +1322,9 @@ EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_l
EGLContext ctx = eglGetCurrentContext();
ContextRef _c(ctx);
- if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
- if (!validate_display_context(dpy, ctx))
- return EGL_NO_SYNC_KHR;
+ if (!_c.get())
+ return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
+
egl_context_t * const c = get_context(ctx);
EGLSyncKHR result = EGL_NO_SYNC_KHR;
if (c->cnx->egl.eglCreateSyncKHR) {
@@ -1369,9 +1350,8 @@ EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
EGLContext ctx = syncObject->context;
ContextRef _c(ctx);
- if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
- if (!validate_display_context(dpy, ctx))
- return EGL_FALSE;
+ if (!_c.get())
+ return setError(EGL_BAD_CONTEXT, EGL_FALSE);
EGLBoolean result = EGL_FALSE;
egl_context_t * const c = get_context(ctx);
@@ -1397,12 +1377,10 @@ EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTi
EGLContext ctx = syncObject->context;
ContextRef _c(ctx);
- if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
- if (!validate_display_context(dpy, ctx))
- return EGL_FALSE;
+ if (!_c.get())
+ return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_context_t * const c = get_context(ctx);
-
if (c->cnx->egl.eglClientWaitSyncKHR) {
return c->cnx->egl.eglClientWaitSyncKHR(
dp->disp[c->impl].dpy, syncObject->sync, flags, timeout);
@@ -1419,17 +1397,16 @@ EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute
if (!dp) return EGL_FALSE;
SyncRef _s(sync);
- if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
- egl_sync_t* syncObject = get_sync(sync);
+ if (!_s.get())
+ return setError(EGL_BAD_PARAMETER, EGL_FALSE);
+ egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
ContextRef _c(ctx);
- if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
- if (!validate_display_context(dpy, ctx))
- return EGL_FALSE;
+ if (!_c.get())
+ return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_context_t * const c = get_context(ctx);
-
if (c->cnx->egl.eglGetSyncAttribKHR) {
return c->cnx->egl.eglGetSyncAttribKHR(
dp->disp[c->impl].dpy, syncObject->sync, attribute, value);
@@ -1451,10 +1428,9 @@ EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
if (!dp) return EGL_FALSE;
SurfaceRef _s(draw);
- if (!_s.get()) return setError(EGL_BAD_SURFACE, EGL_FALSE);
+ if (!_s.get())
+ return setError(EGL_BAD_SURFACE, EGL_FALSE);
- if (!validate_display_surface(dpy, draw))
- return EGL_FALSE;
egl_surface_t const * const s = get_surface(draw);
if (s->cnx->egl.eglSetSwapRectangleANDROID) {
return s->cnx->egl.eglSetSwapRectangleANDROID(
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 272fa44..83aafa6 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -55,19 +55,15 @@ void egl_display_t::addObject(egl_object_t* object) {
objects.add(object);
}
-bool egl_display_t::getObject(egl_object_t* object) {
+void egl_display_t::removeObject(egl_object_t* object) {
Mutex::Autolock _l(lock);
- if (objects.indexOf(object) >= 0) {
- object->incRef();
- return true;
- }
- return false;
+ objects.remove(object);
}
-bool egl_display_t::removeObject(egl_object_t* object) {
+bool egl_display_t::getObject(egl_object_t* object) {
Mutex::Autolock _l(lock);
- if (object->decRef() == 1) {
- objects.remove(object);
+ if (objects.indexOf(object) >= 0) {
+ object->incRef();
return true;
}
return false;
@@ -255,7 +251,18 @@ EGLBoolean egl_display_t::terminate() {
}
}
- // TODO: all egl_object_t should be marked for termination
+ // Mark all objects remaining in the list as terminated, unless
+ // there are no reference to them, it which case, we're free to
+ // delete them.
+ size_t count = objects.size();
+ LOGW_IF(count, "eglTerminate() called w/ %d objects remaining", count);
+ for (size_t i=0 ; i<count ; i++) {
+ egl_object_t* o = objects.itemAt(i);
+ o->destroy();
+ }
+
+ // this marks all object handles are "terminated"
+ objects.clear();
refs--;
numTotalConfigs = 0;
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index c194002..8c482c3 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -77,12 +77,12 @@ public:
// add object to this display's list
void addObject(egl_object_t* object);
- // remove object from this display's list if it has no reference.
- // returns true if object was removed.
- bool removeObject(egl_object_t* object);
+ // remove object from this display's list
+ void removeObject(egl_object_t* object);
// add reference to this object. returns true if this is a valid object.
bool getObject(egl_object_t* object);
+
static egl_display_t* get(EGLDisplay dpy);
static EGLDisplay getFromNativeDisplay(EGLNativeDisplayType disp);
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index d4df341..dbf9a01 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -32,16 +32,33 @@ namespace android {
// ----------------------------------------------------------------------------
egl_object_t::egl_object_t(egl_display_t* disp) :
- display(disp), terminated(0), count(1) {
+ display(disp), count(1) {
+ // NOTE: this does an implicit incRef
display->addObject(this);
}
-bool egl_object_t::get() {
- return display->getObject(this);
+egl_object_t::~egl_object_t() {
+}
+
+void egl_object_t::terminate() {
+ // this marks the object as "terminated"
+ display->removeObject(this);
+ if (decRef() == 1) {
+ // shouldn't happen because this is called from LocalRef
+ LOGE("egl_object_t::terminate() removed the last reference!");
+ }
}
-bool egl_object_t::put() {
- return display->removeObject(this);
+void egl_object_t::destroy() {
+ if (decRef() == 1) {
+ delete this;
+ }
+}
+
+bool egl_object_t::get() {
+ // used by LocalRef, this does an incRef() atomically with
+ // checking that the object is valid.
+ return display->getObject(this);
}
// ----------------------------------------------------------------------------
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) :