summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peiyong Lin <lpy@google.com> 2019-04-22 10:14:57 -0700
committer Peiyong Lin <lpy@google.com> 2019-04-22 16:30:45 -0700
commit9f0c79d730f54f91608de58d2b30afadba4535c2 (patch)
tree6b0804825783fe17110296f8b7210c13b7fad21e
parent8cd204d6cd66f581e10ce574ba72faf1ebf6b592 (diff)
Honor the property overrides for GLES.
One of the fundamental problems of the GLES loader is that we never take ro.hardware.egl and ro.board.platform into account while we try to load the system driver. As a result, if a device specify the naming via these two properties, it will not work. Checking these two properties will allow us to remove a bunch of checks as well, eventually we want emulator and swiftshader to go through this approach instead of having a bunch of checks. Another issue, is that the final loading of the system graphics driver will load from whatever that match the wildcards of libGLES_*.so or [libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so]. This is bad, for example, on cuttlefish, there could be multiple system drivers exist at the same time and cuttlefish can set ro.hardware.egl during boot time, however, when the graphics driver fails to load, it will silently load other graphics driver via wildcards matching. We want to make sure that once the loader fails to load the graphics driver using system properties, the device can't boot. In this patch, we attempt to load the system graphics driver by appending these two properties at the end of the graphics driver library names before we start to load from the exact names of the graphics driver, and remove the wildcards matching. BUG: 127353494 Test: Boots locally, verify emulator. Test: atest CtsAngleIntegrationHostTestCases Change-Id: Ib38c797fd3ce5a6e84e2cd38e24c9d3ab3da8274
-rw-r--r--opengl/libs/EGL/Loader.cpp151
-rw-r--r--opengl/libs/EGL/Loader.h2
2 files changed, 68 insertions, 85 deletions
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 10dd8cbf52..4b73fe915b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -208,6 +208,11 @@ static void setEmulatorGlesValue(void) {
}
}
+static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
+ "ro.hardware.egl",
+ "ro.board.platform",
+};
+
void* Loader::open(egl_connection_t* cnx)
{
ATRACE_CALL();
@@ -233,8 +238,30 @@ void* Loader::open(egl_connection_t* cnx)
hnd = attempt_to_load_emulation_driver(cnx);
}
if (!hnd) {
- // Finally, load system driver.
- hnd = attempt_to_load_system_driver(cnx);
+ // Finally, try to load system driver, start by searching for the library name appended by
+ // the system properties of the GLES userspace driver in both locations.
+ // i.e.:
+ // libGLES_${prop}.so, or:
+ // libEGL_${prop}.so, libGLESv1_CM_${prop}.so, libGLESv2_${prop}.so
+ char prop[PROPERTY_VALUE_MAX + 1];
+ for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
+ if (property_get(key, prop, nullptr) <= 0) {
+ continue;
+ }
+ hnd = attempt_to_load_system_driver(cnx, prop);
+ if (hnd) {
+ break;
+ }
+ }
+ }
+
+ if (!hnd) {
+ // Can't find graphics driver by appending system properties, now search for the exact name
+ // without any suffix of the GLES userspace driver in both locations.
+ // i.e.:
+ // libGLES.so, or:
+ // libEGL.so, libGLESv1_CM.so, libGLESv2.so
+ hnd = attempt_to_load_system_driver(cnx, nullptr);
}
if (!hnd) {
@@ -408,13 +435,11 @@ static void* load_emulation_driver(const char* kind) {
return dso;
}
-static void* load_system_driver(const char* kind) {
+static void* load_system_driver(const char* kind, const char* suffix) {
ATRACE_CALL();
class MatchFile {
public:
- static std::string find(const char* kind) {
- std::string result;
- std::string pattern = std::string("lib") + kind;
+ static std::string find(const char* libraryName) {
const char* const searchPaths[] = {
#if defined(__LP64__)
"/vendor/lib64/egl",
@@ -425,74 +450,23 @@ static void* load_system_driver(const char* kind) {
#endif
};
- // first, we search for the exact name of the GLES userspace
- // driver in both locations.
- // i.e.:
- // libGLES.so, or:
- // libEGL.so, libGLESv1_CM.so, libGLESv2.so
-
- for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
- if (find(result, pattern, searchPaths[i], true)) {
- return result;
- }
- }
-
- // for compatibility with the old "egl.cfg" naming convention
- // we look for files that match:
- // libGLES_*.so, or:
- // libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so
-
- pattern.append("_");
- for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
- if (find(result, pattern, searchPaths[i], false)) {
- return result;
- }
- }
-
- // we didn't find the driver. gah.
- result.clear();
- return result;
- }
-
- private:
- static bool find(std::string& result,
- const std::string& pattern, const char* const search, bool exact) {
- if (exact) {
- std::string absolutePath = std::string(search) + "/" + pattern + ".so";
+ for (auto dir : searchPaths) {
+ std::string absolutePath = dir + std::string("/") + libraryName + ".so";
if (!access(absolutePath.c_str(), R_OK)) {
- result = absolutePath;
- return true;
+ return absolutePath;
}
- return false;
}
- DIR* d = opendir(search);
- if (d != nullptr) {
- struct dirent* e;
- while ((e = readdir(d)) != nullptr) {
- if (e->d_type == DT_DIR) {
- continue;
- }
- if (!strcmp(e->d_name, "libGLES_android.so")) {
- // always skip the software renderer
- continue;
- }
- if (strstr(e->d_name, pattern.c_str()) == e->d_name) {
- if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
- result = std::string(search) + "/" + e->d_name;
- closedir(d);
- return true;
- }
- }
- }
- closedir(d);
- }
- return false;
+ // Driver not found. gah.
+ return std::string();
}
};
-
- std::string absolutePath = MatchFile::find(kind);
+ std::string libraryName = std::string("lib") + kind;
+ if (suffix) {
+ libraryName += std::string("_") + suffix;
+ }
+ std::string absolutePath = MatchFile::find(libraryName.c_str());
if (absolutePath.empty()) {
// this happens often, we don't want to log an error
return nullptr;
@@ -574,7 +548,20 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio
cnx->angleBackend = angleBackendDefault;
if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) {
// Find and load vendor libEGL for ANGLE's GL back-end to use.
- cnx->vendorEGL = load_system_driver("EGL");
+ char prop[PROPERTY_VALUE_MAX + 1];
+ for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
+ if (property_get(key, prop, nullptr) <= 0) {
+ continue;
+ }
+ void* dso = load_system_driver("EGL", prop);
+ if (dso) {
+ cnx->vendorEGL = dso;
+ break;
+ }
+ }
+ if (!cnx->vendorEGL) {
+ cnx->vendorEGL = load_system_driver("EGL", nullptr);
+ }
}
} else {
ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind,
@@ -586,11 +573,6 @@ static void* load_angle(const char* kind, android_namespace_t* ns, egl_connectio
return so;
}
-static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
- "ro.hardware.egl",
- "ro.board.platform",
-};
-
static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
ATRACE_CALL();
const android_dlextinfo dlextinfo = {
@@ -600,12 +582,13 @@ static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
void* so = nullptr;
char prop[PROPERTY_VALUE_MAX + 1];
for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
- if (property_get(key, prop, nullptr) > 0) {
- std::string name = std::string("lib") + kind + "_" + prop + ".so";
- so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
- if (so) {
- return so;
- }
+ if (property_get(key, prop, nullptr) <= 0) {
+ continue;
+ }
+ std::string name = std::string("lib") + kind + "_" + prop + ".so";
+ so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ if (so) {
+ return so;
}
}
return nullptr;
@@ -700,26 +683,26 @@ Loader::driver_t* Loader::attempt_to_load_emulation_driver(egl_connection_t* cnx
return hnd;
}
-Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx) {
+Loader::driver_t* Loader::attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix) {
ATRACE_CALL();
android::GraphicsEnv::getInstance().setDriverToLoad(android::GraphicsEnv::Driver::GL);
driver_t* hnd = nullptr;
- void* dso = load_system_driver("GLES");
+ void* dso = load_system_driver("GLES", suffix);
if (dso) {
initialize_api(dso, cnx, EGL | GLESv1_CM | GLESv2);
hnd = new driver_t(dso);
return hnd;
}
- dso = load_system_driver("EGL");
+ dso = load_system_driver("EGL", suffix);
if (dso) {
initialize_api(dso, cnx, EGL);
hnd = new driver_t(dso);
- dso = load_system_driver("GLESv1_CM");
+ dso = load_system_driver("GLESv1_CM", suffix);
initialize_api(dso, cnx, GLESv1_CM);
hnd->set(dso, GLESv1_CM);
- dso = load_system_driver("GLESv2");
+ dso = load_system_driver("GLESv2", suffix);
initialize_api(dso, cnx, GLESv2);
hnd->set(dso, GLESv2);
}
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index c0f1b75e48..ebeaebab5f 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -58,7 +58,7 @@ private:
driver_t* attempt_to_load_angle(egl_connection_t* cnx);
driver_t* attempt_to_load_updated_driver(egl_connection_t* cnx);
driver_t* attempt_to_load_emulation_driver(egl_connection_t* cnx);
- driver_t* attempt_to_load_system_driver(egl_connection_t* cnx);
+ driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix);
void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask);
static __attribute__((noinline))