Fix support of different attrib_list in eglGetPlatformDisplay
Regression was introduced by ag/5161774, where different
EGLDisplay(s) with the same display type but different
attrib_list(s) would share the same egl_display_t object.
Only the first EGLDisplay associated with the egl_display_t
would be initialized.
Bug: 162381841
Test: Run android.graphics.cts.EGL15Test in CtsGraphicsTestCases
Change-Id: I4419e0f9f0d0f6491e7fae397b6c8926405ca836
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 07ec327..a288c21 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -74,7 +74,8 @@
return eglDisplay ? eglDisplay->getRefsCount() : 0;
}
-egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
+std::map<EGLDisplay, std::unique_ptr<egl_display_t>> egl_display_t::displayMap;
+std::mutex egl_display_t::displayMapLock;
egl_display_t::egl_display_t()
: magic('_dpy'),
@@ -93,11 +94,12 @@
return nullptr;
}
- uintptr_t index = uintptr_t(dpy) - 1U;
- if (index >= NUM_DISPLAYS || !sDisplay[index].isValid()) {
+ const std::lock_guard<std::mutex> lock(displayMapLock);
+ auto search = displayMap.find(dpy);
+ if (search == displayMap.end() || !search->second->isValid()) {
return nullptr;
}
- return &sDisplay[index];
+ return search->second.get();
}
void egl_display_t::addObject(egl_object_t* object) {
@@ -125,7 +127,7 @@
const EGLAttrib* attrib_list) {
if (uintptr_t(disp) >= NUM_DISPLAYS) return nullptr;
- return sDisplay[uintptr_t(disp)].getPlatformDisplay(disp, attrib_list);
+ return getPlatformDisplay(disp, attrib_list);
}
static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
@@ -170,7 +172,6 @@
EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
const EGLAttrib* attrib_list) {
- std::lock_guard<std::mutex> _l(lock);
ATRACE_CALL();
// get our driver loader
@@ -206,13 +207,20 @@
}
}
- disp.dpy = dpy;
if (dpy == EGL_NO_DISPLAY) {
loader.close(cnx);
+ } else {
+ const std::lock_guard<std::mutex> lock(displayMapLock);
+ if (displayMap.find(dpy) == displayMap.end()) {
+ auto d = std::make_unique<egl_display_t>();
+ d->disp.dpy = dpy;
+ displayMap[dpy] = std::move(d);
+ }
+ return dpy;
}
}
- return EGLDisplay(uintptr_t(display) + 1U);
+ return nullptr;
}
EGLBoolean egl_display_t::initialize(EGLint* major, EGLint* minor) {