summaryrefslogtreecommitdiffstats
path: root/opengl/libs/EGL/egl_display.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-01-30 18:20:52 -0800
committerMathias Agopian <mathias@google.com>2012-01-30 18:20:52 -0800
commit9eb95992ea34e40e83d78f5c211933246c491f0f (patch)
tree143b53dda12df1581b22961db813aefb5149788c /opengl/libs/EGL/egl_display.cpp
parent11c5db5e29f9e4ac4cdb0bb49197b48deb657e36 (diff)
downloadframeworks_base-9eb95992ea34e40e83d78f5c211933246c491f0f.zip
frameworks_base-9eb95992ea34e40e83d78f5c211933246c491f0f.tar.gz
frameworks_base-9eb95992ea34e40e83d78f5c211933246c491f0f.tar.bz2
fix a race condition in eglMakeCurrent()
it would happen when a context was made non-current, in this case we would call the implementation's eglMakeCurrent() which would succeed, if we're rescheduled at that point, another eglMakeCurrent() could make that context current to another thread, however, when we came back to the original call we would overwrite egl_context_t internal state. this is fixed by moving the critical section under egl_display_t's lock. Change-Id: I743c85696e13263d3a9570824940263df0caacdc
Diffstat (limited to 'opengl/libs/EGL/egl_display.cpp')
-rw-r--r--opengl/libs/EGL/egl_display.cpp41
1 files changed, 41 insertions, 0 deletions
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 53eaf9a..5cf5236 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -342,6 +342,47 @@ EGLBoolean egl_display_t::terminate() {
return res;
}
+void egl_display_t::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->onLooseCurrent();
+
+ _cur_c.release();
+ _cur_r.release();
+ _cur_d.release();
+ }
+}
+
+EGLBoolean egl_display_t::makeCurrent(egl_context_t* c, egl_context_t* cur_c,
+ EGLSurface draw, EGLSurface read, EGLContext ctx,
+ EGLSurface impl_draw, EGLSurface impl_read, EGLContext impl_ctx)
+{
+ Mutex::Autolock _l(lock);
+ EGLBoolean result;
+ if (c) {
+ result = c->cnx->egl.eglMakeCurrent(
+ disp[c->impl].dpy, impl_draw, impl_read, impl_ctx);
+ } else {
+ result = cur_c->cnx->egl.eglMakeCurrent(
+ disp[cur_c->impl].dpy, impl_draw, impl_read, impl_ctx);
+ }
+ if (result == EGL_TRUE) {
+ loseCurrent(cur_c);
+ if (c) {
+ c->onMakeCurrent(draw, read);
+ }
+ }
+ return result;
+}
// ----------------------------------------------------------------------------
}; // namespace android