Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1864b93f authored by Courtney Goeltzenleuchter's avatar Courtney Goeltzenleuchter Committed by Android (Google) Code Review
Browse files

Merge "Load ANGLE from APK"

parents 3fe5ead7 1f00e177
Loading
Loading
Loading
Loading
+34 −1
Original line number Diff line number Diff line
@@ -56,6 +56,16 @@ void GraphicsEnv::setDriverPath(const std::string path) {
    mDriverPath = path;
}

void GraphicsEnv::setAnglePath(const std::string path) {
    if (!mAnglePath.empty()) {
        ALOGV("ignoring attempt to change ANGLE path from '%s' to '%s'", mAnglePath.c_str(),
              path.c_str());
        return;
    }
    ALOGV("setting ANGLE path to '%s'", path.c_str());
    mAnglePath = path;
}

void GraphicsEnv::setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths) {
    if (mLayerPaths.empty()) {
        mLayerPaths = layerPaths;
@@ -102,8 +112,31 @@ android_namespace_t* GraphicsEnv::getDriverNamespace() {
    return mDriverNamespace;
}

android_namespace_t* GraphicsEnv::getAngleNamespace() {
    static std::once_flag once;
    std::call_once(once, [this]() {
        if (mAnglePath.empty()) return;

        mAngleNamespace = android_create_namespace("ANGLE",
                                                   nullptr,            // ld_library_path
                                                   mAnglePath.c_str(), // default_library_path
                                                   ANDROID_NAMESPACE_TYPE_SHARED |
                                                           ANDROID_NAMESPACE_TYPE_ISOLATED,
                                                   nullptr, // permitted_when_isolated_path
                                                   nullptr);
        if (!mAngleNamespace) ALOGD("Could not create ANGLE namespace from default");
    });

    return mAngleNamespace;
}

} // namespace android

extern "C" android_namespace_t* android_getDriverNamespace() {
extern "C" {
android_namespace_t* android_getDriverNamespace() {
    return android::GraphicsEnv::getInstance().getDriverNamespace();
}
android_namespace_t* android_getAngleNamespace() {
    return android::GraphicsEnv::getInstance().getAngleNamespace();
}
}
+12 −0
Original line number Diff line number Diff line
@@ -37,8 +37,17 @@ public:
    void setDriverPath(const std::string path);
    android_namespace_t* getDriverNamespace();

    // Set a search path for loading ANGLE libraries. The path is a list of
    // directories separated by ':'. A directory can be contained in a zip file
    // (libraries must be stored uncompressed and page aligned); such elements
    // in the search path must have a '!' after the zip filename, e.g.
    //     /system/app/ANGLEPrebuilt/ANGLEPrebuilt.apk!/lib/arm64-v8a
    void setAnglePath(const std::string path);
    android_namespace_t* getAngleNamespace();

    void setLayerPaths(NativeLoaderNamespace* appNamespace, const std::string layerPaths);
    NativeLoaderNamespace* getAppNamespace();

    const std::string getLayerPaths();

    void setDebugLayers(const std::string layers);
@@ -47,9 +56,11 @@ public:
private:
    GraphicsEnv() = default;
    std::string mDriverPath;
    std::string mAnglePath;
    std::string mDebugLayers;
    std::string mLayerPaths;
    android_namespace_t* mDriverNamespace = nullptr;
    android_namespace_t* mAngleNamespace = nullptr;
    NativeLoaderNamespace* mAppNamespace = nullptr;
};

@@ -67,5 +78,6 @@ private:
 *    will be removed soon.
 */
extern "C" android_namespace_t* android_getDriverNamespace();
extern "C" android_namespace_t* android_getAngleNamespace();

#endif // ANDROID_UI_GRAPHICS_ENV_H
+191 −0
Original line number Diff line number Diff line
//
// Copyright (c) 2017 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// eglext_angle.h: ANGLE modifications to the eglext.h header file.
//   Currently we don't include this file directly, we patch eglext.h
//   to include it implicitly so it is visible throughout our code.

#ifndef INCLUDE_EGL_EGLEXT_ANGLE_
#define INCLUDE_EGL_EGLEXT_ANGLE_

// clang-format off

#ifndef EGL_ANGLE_robust_resource_initialization
#define EGL_ANGLE_robust_resource_initialization 1
#define EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453
#endif /* EGL_ANGLE_robust_resource_initialization */

#ifndef EGL_ANGLE_keyed_mutex
#define EGL_ANGLE_keyed_mutex 1
#define EGL_DXGI_KEYED_MUTEX_ANGLE        0x33A2
#endif /* EGL_ANGLE_keyed_mutex */

#ifndef EGL_ANGLE_d3d_texture_client_buffer
#define EGL_ANGLE_d3d_texture_client_buffer 1
#define EGL_D3D_TEXTURE_ANGLE             0x33A3
#endif /* EGL_ANGLE_d3d_texture_client_buffer */

#ifndef EGL_ANGLE_software_display
#define EGL_ANGLE_software_display 1
#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1)
#endif /* EGL_ANGLE_software_display */

#ifndef EGL_ANGLE_direct3d_display
#define EGL_ANGLE_direct3d_display 1
#define EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ((EGLNativeDisplayType)-2)
#define EGL_D3D11_ONLY_DISPLAY_ANGLE ((EGLNativeDisplayType)-3)
#endif /* EGL_ANGLE_direct3d_display */

#ifndef EGL_ANGLE_direct_composition
#define EGL_ANGLE_direct_composition 1
#define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5
#endif /* EGL_ANGLE_direct_composition */

#ifndef EGL_ANGLE_platform_angle
#define EGL_ANGLE_platform_angle 1
#define EGL_PLATFORM_ANGLE_ANGLE          0x3202
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE     0x3203
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
#define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
#define EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE 0x3451
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x345E
#endif /* EGL_ANGLE_platform_angle */

#ifndef EGL_ANGLE_platform_angle_d3d
#define EGL_ANGLE_platform_angle_d3d 1
#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE 0x320B
#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE 0x320C
#define EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE 0x320F
#endif /* EGL_ANGLE_platform_angle_d3d */

#ifndef EGL_ANGLE_platform_angle_opengl
#define EGL_ANGLE_platform_angle_opengl 1
#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
#define EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE 0x3480
#endif /* EGL_ANGLE_platform_angle_opengl */

#ifndef EGL_ANGLE_platform_angle_null
#define EGL_ANGLE_platform_angle_null 1
#define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
#endif /* EGL_ANGLE_platform_angle_null */

#ifndef EGL_ANGLE_platform_angle_vulkan
#define EGL_ANGLE_platform_angle_vulkan 1
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#endif /* EGL_ANGLE_platform_angle_vulkan */

#ifndef EGL_ANGLE_platform_angle_context_virtualization
#define EGL_ANGLE_platform_angle_context_virtualization 1
#define EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE 0x3481
#endif /* EGL_ANGLE_platform_angle_context_virtualization */

#ifndef EGL_ANGLE_x11_visual
#define EGL_ANGLE_x11_visual
#define EGL_X11_VISUAL_ID_ANGLE 0x33A3
#endif /* EGL_ANGLE_x11_visual */

#ifndef EGL_ANGLE_flexible_surface_compatibility
#define EGL_ANGLE_flexible_surface_compatibility 1
#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
#endif /* EGL_ANGLE_flexible_surface_compatibility */

#ifndef EGL_ANGLE_surface_orientation
#define EGL_ANGLE_surface_orientation
#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7
#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8
#define EGL_SURFACE_ORIENTATION_INVERT_X_ANGLE 0x0001
#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002
#endif /* EGL_ANGLE_surface_orientation */

#ifndef EGL_ANGLE_experimental_present_path
#define EGL_ANGLE_experimental_present_path
#define EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE 0x33A4
#define EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE 0x33A9
#define EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE 0x33AA
#endif /* EGL_ANGLE_experimental_present_path */

#ifndef EGL_ANGLE_stream_producer_d3d_texture
#define EGL_ANGLE_stream_producer_d3d_texture
#define EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE 0x33AB
typedef EGLBoolean(EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERD3DTEXTUREANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
typedef EGLBoolean(EGLAPIENTRYP PFNEGLSTREAMPOSTD3DTEXTUREANGLEPROC)(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglCreateStreamProducerD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglStreamPostD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream, void *texture, const EGLAttrib *attrib_list);
#endif
#endif /* EGL_ANGLE_stream_producer_d3d_texture */

#ifndef EGL_ANGLE_create_context_webgl_compatibility
#define EGL_ANGLE_create_context_webgl_compatibility 1
#define EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE 0x33AC
#endif /* EGL_ANGLE_create_context_webgl_compatibility */

#ifndef EGL_ANGLE_display_texture_share_group
#define EGL_ANGLE_display_texture_share_group 1
#define EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE 0x33AF
#endif /* EGL_ANGLE_display_texture_share_group */

#ifndef EGL_CHROMIUM_create_context_bind_generates_resource
#define EGL_CHROMIUM_create_context_bind_generates_resource 1
#define EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM 0x33AD
#endif /* EGL_CHROMIUM_create_context_bind_generates_resource */

#ifndef EGL_ANGLE_create_context_client_arrays
#define EGL_ANGLE_create_context_client_arrays 1
#define EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE 0x3452
#endif /* EGL_ANGLE_create_context_client_arrays */

#ifndef EGL_ANGLE_device_creation
#define EGL_ANGLE_device_creation 1
typedef EGLDeviceEXT(EGLAPIENTRYP PFNEGLCREATEDEVICEANGLEPROC) (EGLint device_type, void *native_device, const EGLAttrib *attrib_list);
typedef EGLBoolean(EGLAPIENTRYP PFNEGLRELEASEDEVICEANGLEPROC) (EGLDeviceEXT device);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLDeviceEXT EGLAPIENTRY eglCreateDeviceANGLE(EGLint device_type, void *native_device, const EGLAttrib *attrib_list);
EGLAPI EGLBoolean EGLAPIENTRY eglReleaseDeviceANGLE(EGLDeviceEXT device);
#endif
#endif /* EGL_ANGLE_device_creation */

#ifndef EGL_ANGLE_program_cache_control
#define EGL_ANGLE_program_cache_control 1
#define EGL_PROGRAM_CACHE_SIZE_ANGLE 0x3455
#define EGL_PROGRAM_CACHE_KEY_LENGTH_ANGLE 0x3456
#define EGL_PROGRAM_CACHE_RESIZE_ANGLE 0x3457
#define EGL_PROGRAM_CACHE_TRIM_ANGLE 0x3458
#define EGL_CONTEXT_PROGRAM_BINARY_CACHE_ENABLED_ANGLE 0x3459
typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHEGETATTRIBANGLEPROC) (EGLDisplay dpy, EGLenum attrib);
typedef void (EGLAPIENTRYP PFNEGLPROGRAMCACHEQUERYANGLEPROC) (EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
typedef void (EGLAPIENTRYP PFNEGPROGRAMCACHELPOPULATEANGLEPROC) (EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
typedef EGLint (EGLAPIENTRYP PFNEGLPROGRAMCACHERESIZEANGLEPROC) (EGLDisplay dpy, EGLint limit, EGLenum mode);
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLint EGLAPIENTRY eglProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib);
EGLAPI void EGLAPIENTRY eglProgramCacheQueryANGLE(EGLDisplay dpy, EGLint index, void *key, EGLint *keysize, void *binary, EGLint *binarysize);
EGLAPI void EGLAPIENTRY eglProgramCachePopulateANGLE(EGLDisplay dpy, const void *key, EGLint keysize, const void *binary, EGLint binarysize);
EGLAPI EGLint EGLAPIENTRY eglProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode);
#endif
#endif /* EGL_ANGLE_program_cache_control */

#ifndef EGL_ANGLE_iosurface_client_buffer
#define EGL_ANGLE_iosurface_client_buffer 1
#define EGL_IOSURFACE_ANGLE 0x3454
#define EGL_IOSURFACE_PLANE_ANGLE 0x345A
#define EGL_TEXTURE_RECTANGLE_ANGLE 0x345B
#define EGL_TEXTURE_TYPE_ANGLE 0x345C
#define EGL_TEXTURE_INTERNAL_FORMAT_ANGLE 0x345D
#endif /* EGL_ANGLE_iosurface_client_buffer */

#ifndef EGL_ANGLE_create_context_extensions_enabled
#define EGL_ANGLE_create_context_extensions_enabled 1
#define EGL_EXTENSIONS_ENABLED_ANGLE 0x345F
#endif /* EGL_ANGLE_create_context_extensions_enabled */

// clang-format on

#endif // INCLUDE_EGL_EGLEXT_ANGLE_
+51 −3
Original line number Diff line number Diff line
@@ -455,6 +455,50 @@ static void* load_system_driver(const char* kind) {
    return dso;
}

static void* load_angle_from_namespace(const char* kind, android_namespace_t* ns) {
    const android_dlextinfo dlextinfo = {
            .flags = ANDROID_DLEXT_USE_NAMESPACE,
            .library_namespace = ns,
    };

    std::string name = std::string("lib") + kind + "_angle.so";

    void* so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);

    if (so) {
        ALOGD("dlopen_ext from APK (%s) success at %p", name.c_str(), so);
        return so;
    } else {
        ALOGE("dlopen_ext(\"%s\") failed: %s", name.c_str(), dlerror());
    }

    return nullptr;
}

static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
    // Only attempt to load ANGLE libs
    if (strcmp(kind, "EGL") != 0 && strcmp(kind, "GLESv2") != 0 && strcmp(kind, "GLESv1_CM") != 0)
        return nullptr;

    void* so = nullptr;
    std::string name;

    if (ns) {
        so = load_angle_from_namespace(kind, ns);
    }

    if (so) {
        cnx->useAngle = true;
        // Find and load vendor libEGL for ANGLE
        if (!cnx->vendorEGL) {
            cnx->vendorEGL = load_system_driver("EGL");
        }
        return so;
    }

    return nullptr;
}

static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
    "ro.hardware.egl",
    "ro.board.platform",
@@ -486,11 +530,15 @@ void *Loader::load_driver(const char* kind,
    ATRACE_CALL();

    void* dso = nullptr;
    android_namespace_t* ns = android_getAngleNamespace();
    dso = load_angle(kind, ns, cnx);
#ifndef __ANDROID_VNDK__
    android_namespace_t* ns = android_getDriverNamespace();
    if (!dso) {
        ns = android_getDriverNamespace();
        if (ns) {
            dso = load_updated_driver(kind, ns);
        }
    }
#endif
    if (!dso) {
        dso = load_system_driver(kind);
+41 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@

#include "../egl_impl.h"

#include <EGL/eglext_angle.h>
#include <private/EGL/display.h>

#include "egl_cache.h"
@@ -121,6 +122,38 @@ EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
    return sDisplay[uintptr_t(disp)].getDisplay(disp);
}

EGLDisplay getDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx) {
    EGLDisplay dpy = EGL_NO_DISPLAY;

    // Locally define this until EGL 1.5 is supported
    typedef EGLDisplay (*PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void* native_display,
                                                       const EGLAttrib* attrib_list);

    PFNEGLGETPLATFORMDISPLAYPROC eglGetPlatformDisplay =
            reinterpret_cast<PFNEGLGETPLATFORMDISPLAYPROC>(
                    cnx->egl.eglGetProcAddress("eglGetPlatformDisplay"));

    if (eglGetPlatformDisplay) {
        intptr_t vendorEGL = (intptr_t)cnx->vendorEGL;

        EGLAttrib attrs[] = {
                EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
                EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE, vendorEGL,
                EGL_NONE // list terminator
        };

        // Initially, request the default display type
        dpy = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
                                    reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY), attrs);

    } else {
        ALOGE("eglGetDisplay(%p) failed: Unable to look up eglGetPlatformDisplay from ANGLE",
              display);
    }

    return dpy;
}

EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {

    std::lock_guard<std::mutex> _l(lock);
@@ -131,7 +164,14 @@ EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {

    egl_connection_t* const cnx = &gEGLImpl;
    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
        EGLDisplay dpy = EGL_NO_DISPLAY;

        if (cnx->useAngle) {
            dpy = getDisplayAngle(display, cnx);
        } else {
            dpy = cnx->egl.eglGetDisplay(display);
        }

        disp.dpy = dpy;
        if (dpy == EGL_NO_DISPLAY) {
            loader.close(cnx->dso);
Loading