summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yiwei Zhang <zzyiwei@google.com> 2019-08-27 00:27:29 -0700
committer Yiwei Zhang <zzyiwei@google.com> 2019-08-27 00:27:29 -0700
commit86f9f749cc5bc1dc75ee26c3a9618d882eabe096 (patch)
treeb1ba885db759f38c05769ca4079df8678b8c0c74
parentad294ee69c56a29e518cbb23a00811c42af262ab (diff)
opengl: fix a race condition when unloading gl driver
Previously, EGL apis call clearError() at the first place including those core apis which initialize the driver. Calling clearError() before the driver has been loaded is basically a no-op. Later the driver unloading mechanism was added to support Angle and updatable driver with EGL/GL driver still preloaded in Zygote. However, calling clearError() on another thread races with the driver unloading process. So this change moves the clearError() calls after the driver has been successfully unloaded and reloaded, so that the initial core apis will be protected by the driver loading lock in the loader. For those non-core apis, they could still be incorrectly called before calling any of those core apis on another thread when the driver unloading and reloading is still on going. Since this scenario is supposed to error out anyway, so the apps need to use EGL apis correctly by themselves. Bug: 140072978 Test: CtsAngleDeveloperOptionHostTest Change-Id: Ica5b19edc0dfb0a0910f56c1442eaff63f76b35a
-rw-r--r--opengl/libs/EGL/eglApi.cpp19
1 files changed, 7 insertions, 12 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 29a966d348..c51a1295e7 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -40,7 +40,6 @@ static inline void clearError() {
EGLDisplay eglGetDisplay(EGLNativeDisplayType display) {
ATRACE_CALL();
- clearError();
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
@@ -48,6 +47,7 @@ EGLDisplay eglGetDisplay(EGLNativeDisplayType display) {
// Call down the chain, which usually points directly to the impl
// but may also be routed through layers
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglGetDisplay(display);
}
@@ -55,7 +55,6 @@ EGLDisplay eglGetDisplay(EGLNativeDisplayType display) {
EGLDisplay eglGetPlatformDisplay(EGLenum platform, EGLNativeDisplayType display,
const EGLAttrib* attrib_list) {
ATRACE_CALL();
- clearError();
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
@@ -63,6 +62,7 @@ EGLDisplay eglGetPlatformDisplay(EGLenum platform, EGLNativeDisplayType display,
// Call down the chain, which usually points directly to the impl
// but may also be routed through layers
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglGetPlatformDisplay(platform, display, attrib_list);
}
@@ -239,13 +239,12 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char* procname)
// in which case we must make sure we've initialized ourselves, this
// happens the first time egl_get_display() is called.
- clearError();
-
if (egl_init_drivers() == EGL_FALSE) {
setError(EGL_BAD_PARAMETER, NULL);
return nullptr;
}
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglGetProcAddress(procname);
}
@@ -324,23 +323,21 @@ EGLBoolean eglWaitClient(void) {
}
EGLBoolean eglBindAPI(EGLenum api) {
- clearError();
-
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
}
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglBindAPI(api);
}
EGLenum eglQueryAPI(void) {
- clearError();
-
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, (EGLBoolean)EGL_FALSE);
}
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglQueryAPI();
}
@@ -595,23 +592,21 @@ EGLClientBuffer eglGetNativeClientBufferANDROID(const AHardwareBuffer* buffer) {
}
EGLuint64NV eglGetSystemTimeFrequencyNV() {
- clearError();
-
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
}
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglGetSystemTimeFrequencyNV();
}
EGLuint64NV eglGetSystemTimeNV() {
- clearError();
-
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, (EGLuint64NV)EGL_FALSE);
}
+ clearError();
egl_connection_t* const cnx = &gEGLImpl;
return cnx->platform.eglGetSystemTimeNV();
}