[Replicant] [PATCH 1/7] EGL Loader patch to use both LLVMpipe and libagl at once
Andrés Domínguez
andresdju at gmail.com
Thu Aug 15 19:04:27 UTC 2019
From: JeremyRand <biolizard89 at gmail.com>
Verbatim copy of Jookia's patch.
---
opengl/libs/EGL/Loader.cpp | 132 +++++++++++++++++++++++++++++--------
1 file changed, 106 insertions(+), 26 deletions(-)
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 19cc1a747..6dce586de 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -121,6 +121,62 @@ static char const * getProcessCmdline() {
// ----------------------------------------------------------------------------
+/* Gets a system-defined per-application path to a GLES implementation.
+ * Used when running multiple (usually software) renderers on a single device.
+ * Requires ro.zygote.disable_gl_preload to be enabled!
+ *
+ * It looks for these properties in this preferred order:
+ * persist.egl._uid_<application UID>
+ * persist.egl.<application name> (limited to 31 characters in length)
+ *
+ * The UID is prefered since it works with multiple users or long names.
+ * Using the application name is useful for shipping pre-configured setups.
+ *
+ * The property value can either be a search path or a single GLES library.
+ *
+ * MatchFile::find() does the heavy lifting of using the value.
+ * As of writing it searches for the value '/system/lib/libGLES_mesa.so'
+ * in this order:
+ *
+ * /system/lib/libGLES_mesa.so/lib%s.so
+ * /system/lib/libGLES_mesa.so/lib%s_*.so
+ * /system/lib/libGLES_mesa.so
+ *
+ * where %s is determined at runtime to be GLES, EGL, GLESv1_CM, or GLESv2.
+ */
+static char* getOverridePath(void) {
+ // only really useful if ro.zygote.disable_gl_preload is enabled
+ // otherwise overrides only happen once, to zygote
+ if (!property_get_bool("ro.zygote.disable_gl_preload", 0)) {
+ ALOGD("ro.zygote.disable_gl_preload not set,"
+ " persist.egl.* overrides disabled");
+ return 0;
+ }
+
+ static char prop[PROPERTY_VALUE_MAX];
+ String8 prop_prefix("persist.egl.");
+ String8 prop_uid(prop_prefix);
+ String8 prop_name(prop_prefix);
+ prop_uid.appendFormat("_uid_%i", getuid());
+ prop_name.appendFormat("%s", getProcessCmdline());
+ char* prop_name_trunc = prop_name.lockBuffer(PROPERTY_KEY_MAX);
+ prop_name_trunc[PROPERTY_KEY_MAX - 1] = '\0';
+
+ ALOGD("checking %s then %s for overrides...",
+ prop_uid.string(), prop_name_trunc);
+
+ if (property_get(prop_uid.string(),prop,NULL) ||
+ property_get(prop_name_trunc,prop,NULL)) {
+ ALOGD("override found: %s", prop);
+ return prop;
+ }
+
+ ALOGD("no override found");
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
Loader::driver_t::driver_t(void* gles)
{
dso[0] = gles;
@@ -280,8 +336,36 @@ void *Loader::load_driver(const char* kind,
public:
static String8 find(const char* kind) {
String8 result;
- String8 pattern;
- pattern.appendFormat("lib%s", kind);
+
+ // check for overrides first
+ char* overridePath = getOverridePath();
+ if (overridePath) {
+ // search the path in case its a directory
+ // this ignores the software renderer
+ if (search_path(kind, overridePath, result)) {
+ return result;
+ } else if (!access(overridePath, R_OK)) {
+ // not a directory but accessible so probably a file?
+ result.setTo(overridePath);
+ return result;
+ } else {
+ ALOGD("override not a file or search path, ignoring...");
+ }
+ }
+
+ // in the emulator case, we just return the hardcoded name
+ // of the software renderer.
+ if (checkGlesEmulationStatus() == 0) {
+ ALOGD("Emulator without GPU support detected. "
+ "Fallback to software renderer.");
+#if defined(__LP64__)
+ result.setTo("/system/lib64/egl/libGLES_android.so");
+#else
+ result.setTo("/system/lib/egl/libGLES_android.so");
+#endif
+ return result;
+ }
+
const char* const searchPaths[] = {
#if defined(__LP64__)
"/vendor/lib64/egl",
@@ -292,16 +376,29 @@ void *Loader::load_driver(const char* kind,
#endif
};
+ for (size_t i=0 ; i<NELEM(searchPaths) ; i++) {
+ if (search_path(kind, searchPaths[i], result)) {
+ return result;
+ }
+ }
+
+ // we didn't find the driver. gah.
+ result.clear();
+ return result;
+ }
+
+ static bool search_path(const char* kind, const char* path, String8& result) {
+ String8 pattern;
+
// 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;
- }
+ pattern.appendFormat("lib%s", kind);
+ if (find(result, pattern, path, true)) {
+ return true;
}
// for compatibility with the old "egl.cfg" naming convention
@@ -310,34 +407,17 @@ void *Loader::load_driver(const char* kind,
// 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;
- }
+ if (find(result, pattern, path, false)) {
+ return true;
}
- // we didn't find the driver. gah.
- result.clear();
- return result;
+ return false;
}
private:
static bool find(String8& result,
const String8& pattern, const char* const search, bool exact) {
- // in the emulator case, we just return the hardcoded name
- // of the software renderer.
- if (checkGlesEmulationStatus() == 0) {
- ALOGD("Emulator without GPU support detected. "
- "Fallback to software renderer.");
-#if defined(__LP64__)
- result.setTo("/system/lib64/egl/libGLES_android.so");
-#else
- result.setTo("/system/lib/egl/libGLES_android.so");
-#endif
- return true;
- }
-
if (exact) {
String8 absolutePath;
absolutePath.appendFormat("%s/%s.so", search, pattern.string());
--
2.23.0.rc1
More information about the Replicant
mailing list