summaryrefslogtreecommitdiffstats
path: root/opengl/libs
diff options
context:
space:
mode:
authorMichael I. Gold <gold@nvidia.com>2010-12-23 13:51:36 -0800
committerJamie Gennis <jgennis@google.com>2010-12-23 16:12:19 -0800
commit0c3ce2a3650e5a8a005179162c87af639eef60cf (patch)
tree0a2cce03c3f743cf92cc2275ee68ca7c25d09f3c /opengl/libs
parent94b6282c2d4f999fa9986b9d063398c1847a9a3e (diff)
downloadframeworks_native-0c3ce2a3650e5a8a005179162c87af639eef60cf.zip
frameworks_native-0c3ce2a3650e5a8a005179162c87af639eef60cf.tar.gz
frameworks_native-0c3ce2a3650e5a8a005179162c87af639eef60cf.tar.bz2
egl: fixes for object refcounts
eglMakeCurrent() would only deref the previous surfaces if the old and new contexts were the same. eglTerminate() should not touch TLS. eglReleaseThread() needs to unbind the current context. Change-Id: I213b8be77b1a23b5a8a6afaac60643662c8aa010
Diffstat (limited to 'opengl/libs')
-rw-r--r--opengl/libs/EGL/egl.cpp51
1 files changed, 31 insertions, 20 deletions
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 7acce02..386cc5d 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -895,7 +895,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy)
dp->refs--;
dp->numTotalConfigs = 0;
delete [] dp->configs;
- clearTLS();
+
return res;
}
@@ -1231,6 +1231,27 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
return result;
}
+static void loseCurrent(egl_context_t * cur_c)
+{
+ if (cur_c) {
+ egl_surface_t * cur_r = get_surface(cur_c->read);
+ egl_surface_t * cur_d = get_surface(cur_c->draw);
+
+ // by construction, these are either 0 or valid (possibly terminated)
+ // it should be impossible for these to be invalid
+ ContextRef _cur_c(cur_c);
+ SurfaceRef _cur_r(cur_r);
+ SurfaceRef _cur_d(cur_d);
+
+ cur_c->read = NULL;
+ cur_c->draw = NULL;
+
+ _cur_c.release();
+ _cur_r.release();
+ _cur_d.release();
+ }
+}
+
EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
EGLSurface read, EGLContext ctx)
{
@@ -1259,13 +1280,9 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
// these are the current objects structs
egl_context_t * cur_c = get_context(getContext());
- egl_surface_t * cur_r = NULL;
- egl_surface_t * cur_d = NULL;
if (ctx != EGL_NO_CONTEXT) {
c = get_context(ctx);
- cur_r = get_surface(c->read);
- cur_d = get_surface(c->draw);
impl_ctx = c->context;
} else {
// no context given, use the implementation of the current context
@@ -1311,30 +1328,21 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
}
if (result == EGL_TRUE) {
- // by construction, these are either 0 or valid (possibly terminated)
- // it should be impossible for these to be invalid
- ContextRef _cur_c(cur_c);
- SurfaceRef _cur_r(cur_r);
- SurfaceRef _cur_d(cur_d);
- // cur_c has to be valid here (but could be terminated)
+ loseCurrent(cur_c);
+
if (ctx != EGL_NO_CONTEXT) {
setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
setContext(ctx);
_c.acquire();
+ _r.acquire();
+ _d.acquire();
+ c->read = read;
+ c->draw = draw;
} else {
setGLHooksThreadSpecific(&gHooksNoContext);
setContext(EGL_NO_CONTEXT);
}
- _cur_c.release();
-
- _r.acquire();
- _cur_r.release();
- if (c) c->read = read;
-
- _d.acquire();
- _cur_d.release();
- if (c) c->draw = draw;
}
return result;
}
@@ -1721,6 +1729,9 @@ EGLenum eglQueryAPI(void)
EGLBoolean eglReleaseThread(void)
{
+ // If there is context bound to the thread, release it
+ loseCurrent(get_context(getContext()));
+
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
egl_connection_t* const cnx = &gEGLImpl[i];
if (cnx->dso) {