[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