Skip to content

Commit c0775a2

Browse files
mig1964Jamie Gennis
authored andcommitted
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
1 parent 58c9d47 commit c0775a2

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

opengl/libs/EGL/egl.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -814,7 +814,7 @@ EGLBoolean eglTerminate(EGLDisplay dpy)
814814
dp->refs--;
815815
dp->numTotalConfigs = 0;
816816
delete [] dp->configs;
817-
clearTLS();
817+
818818
return res;
819819
}
820820

@@ -1150,6 +1150,27 @@ EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
11501150
return result;
11511151
}
11521152

1153+
static void loseCurrent(egl_context_t * cur_c)
1154+
{
1155+
if (cur_c) {
1156+
egl_surface_t * cur_r = get_surface(cur_c->read);
1157+
egl_surface_t * cur_d = get_surface(cur_c->draw);
1158+
1159+
// by construction, these are either 0 or valid (possibly terminated)
1160+
// it should be impossible for these to be invalid
1161+
ContextRef _cur_c(cur_c);
1162+
SurfaceRef _cur_r(cur_r);
1163+
SurfaceRef _cur_d(cur_d);
1164+
1165+
cur_c->read = NULL;
1166+
cur_c->draw = NULL;
1167+
1168+
_cur_c.release();
1169+
_cur_r.release();
1170+
_cur_d.release();
1171+
}
1172+
}
1173+
11531174
EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
11541175
EGLSurface read, EGLContext ctx)
11551176
{
@@ -1178,13 +1199,9 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
11781199

11791200
// these are the current objects structs
11801201
egl_context_t * cur_c = get_context(getContext());
1181-
egl_surface_t * cur_r = NULL;
1182-
egl_surface_t * cur_d = NULL;
11831202

11841203
if (ctx != EGL_NO_CONTEXT) {
11851204
c = get_context(ctx);
1186-
cur_r = get_surface(c->read);
1187-
cur_d = get_surface(c->draw);
11881205
impl_ctx = c->context;
11891206
} else {
11901207
// no context given, use the implementation of the current context
@@ -1230,30 +1247,21 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,
12301247
}
12311248

12321249
if (result == EGL_TRUE) {
1233-
// by construction, these are either 0 or valid (possibly terminated)
1234-
// it should be impossible for these to be invalid
1235-
ContextRef _cur_c(cur_c);
1236-
SurfaceRef _cur_r(cur_r);
1237-
SurfaceRef _cur_d(cur_d);
12381250

1239-
// cur_c has to be valid here (but could be terminated)
1251+
loseCurrent(cur_c);
1252+
12401253
if (ctx != EGL_NO_CONTEXT) {
12411254
setGlThreadSpecific(c->cnx->hooks[c->version]);
12421255
setContext(ctx);
12431256
_c.acquire();
1257+
_r.acquire();
1258+
_d.acquire();
1259+
c->read = read;
1260+
c->draw = draw;
12441261
} else {
12451262
setGlThreadSpecific(&gHooksNoContext);
12461263
setContext(EGL_NO_CONTEXT);
12471264
}
1248-
_cur_c.release();
1249-
1250-
_r.acquire();
1251-
_cur_r.release();
1252-
if (c) c->read = read;
1253-
1254-
_d.acquire();
1255-
_cur_d.release();
1256-
if (c) c->draw = draw;
12571265
}
12581266
return result;
12591267
}
@@ -1637,6 +1645,9 @@ EGLenum eglQueryAPI(void)
16371645

16381646
EGLBoolean eglReleaseThread(void)
16391647
{
1648+
// If there is context bound to the thread, release it
1649+
loseCurrent(get_context(getContext()));
1650+
16401651
for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
16411652
egl_connection_t* const cnx = &gEGLImpl[i];
16421653
if (cnx->dso) {

0 commit comments

Comments
 (0)