summaryrefslogtreecommitdiff
path: root/opengl/libs
diff options
context:
space:
mode:
author Michael I. Gold <gold@nvidia.com> 2010-12-23 13:51:36 -0800
committer Jamie Gennis <jgennis@google.com> 2011-03-29 13:43:54 -0700
commitc3fba3be74669d59141a25b36e3a07a8e2605144 (patch)
tree85d9ff7e9d82d11b5031f137de442ef62ca632e1 /opengl/libs
parent322891c689c845b5aa63dbca606967eb9f8f900b (diff)
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: I7f4c090a287ee1e29e4708ae10679fb9d7d8c8c5 Related-Bug: 2964479
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 ebe2193d7ea4..7e0c169439d3 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -814,7 +814,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy)
dp->refs--;
dp->numTotalConfigs = 0;
delete [] dp->configs;
- clearTLS();
+
return res;
}
@@ -1150,6 +1150,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)
{
@@ -1178,13 +1199,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
@@ -1230,30 +1247,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) {
setGlThreadSpecific(c->cnx->hooks[c->version]);
setContext(ctx);
_c.acquire();
+ _r.acquire();
+ _d.acquire();
+ c->read = read;
+ c->draw = draw;
} else {
setGlThreadSpecific(&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;
}
@@ -1637,6 +1645,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) {