[Replicant] [PATCH 1/1] egl loader: add ability to override the opengl renderer at runtime

Kurtis Hanna kurtis at riseup.net
Mon Jan 15 18:45:00 UTC 2018


Hey Replicant peoples,

Just checking in on this. Has anyone reviewed or tested this patch?
Thanks for working on it Jookia!

In Solidarity,
kurtis

Jookia:
> Signed-off-by: Jookia <166291 at gmail.com>
> ---
>  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());
> 
> 
> 
> _______________________________________________
> Replicant mailing list
> Replicant at osuosl.org
> https://lists.osuosl.org/mailman/listinfo/replicant
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.osuosl.org/pipermail/replicant/attachments/20180115/1c52b506/attachment.asc>


More information about the Replicant mailing list