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

Commit 4adf75bf authored by Courtney Goeltzenleuchter's avatar Courtney Goeltzenleuchter
Browse files

Implement getPlatformDisplay with ANGLE support

Apps that care can request a specific ANGLE backend.
That would allow them to choose the native GL backend if
that was preferred (if available.)
Test: TODO

Bug: 80239516
Change-Id: I7bfdf7094749f15f8436c266d12c1191994e27ac
parent e498a2d1
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -52,6 +52,21 @@ EGLDisplay eglGetDisplay(EGLNativeDisplayType display) {
    return cnx->platform.eglGetDisplay(display);
}

EGLDisplay eglGetPlatformDisplay(EGLenum platform, EGLNativeDisplayType display,
                                 const EGLAttrib* attrib_list) {
    ATRACE_CALL();
    clearError();

    if (egl_init_drivers() == EGL_FALSE) {
        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
    }

    // Call down the chain, which usually points directly to the impl
    // but may also be routed through layers
    egl_connection_t* const cnx = &gEGLImpl;
    return cnx->platform.eglGetPlatformDisplay(platform, display, attrib_list);
}

EGLBoolean eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
    clearError();

+69 −32
Original line number Diff line number Diff line
@@ -120,14 +120,15 @@ bool egl_display_t::getObject(egl_object_t* object) const {
    return false;
}

EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp,
                                               const EGLAttrib* attrib_list) {
    if (uintptr_t(disp) >= NUM_DISPLAYS)
        return nullptr;

    return sDisplay[uintptr_t(disp)].getDisplay(disp);
    return sDisplay[uintptr_t(disp)].getPlatformDisplay(disp, attrib_list);
}

static void addAnglePlatformAttributes(egl_connection_t* const cnx, const EGLAttrib* attrib_list,
static bool addAnglePlatformAttributes(egl_connection_t* const cnx, const EGLAttrib* attrib_list,
                                       std::vector<EGLAttrib>& attrs) {
    intptr_t vendorEGL = (intptr_t)cnx->vendorEGL;

@@ -154,24 +155,29 @@ static void addAnglePlatformAttributes(egl_connection_t* const cnx, const EGLAtt
        }
    }

    cnx->angleBackend = angleBackendDefault;

    // Allow debug property to override application's
    char prop[PROPERTY_VALUE_MAX];
    property_get("debug.angle.backend", prop, "0");
    switch (atoi(prop)) {
        case 1:
            ALOGV("addAnglePlatformAttributes: Requesting OpenGLES back-end");
            cnx->angleBackend = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
            angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
            break;
        case 2:
            ALOGV("addAnglePlatformAttributes: Requesting Vulkan back-end");
            cnx->angleBackend = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
            angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
            break;
        default:
            break;
    }

    if (cnx->angleBackend == 0) {
        // Haven't been initialized yet, so set it.
        cnx->angleBackend = angleBackendDefault;
    } else if (cnx->angleBackend != angleBackendDefault) {
        return false;
    }

    attrs.reserve(4 * 2);

    attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
@@ -199,6 +205,8 @@ static void addAnglePlatformAttributes(egl_connection_t* const cnx, const EGLAtt
    }
    attrs.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE);
    attrs.push_back(EGL_FALSE);

    return true;
}

// Initialize function ptrs for ANGLE PlatformMethods struct, used for systrace
@@ -238,24 +246,30 @@ bool initializeAnglePlatform(EGLDisplay dpy) {
    return true;
}

static EGLDisplay getDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx) {
static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
                                          const EGLAttrib* attrib_list, EGLint* error) {
    EGLDisplay dpy = EGL_NO_DISPLAY;
    *error = EGL_NONE;

    // 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) {
    if (cnx->egl.eglGetPlatformDisplay) {
        std::vector<EGLAttrib> attrs;
        addAnglePlatformAttributes(cnx, nullptr, attrs);
        if (attrib_list) {
            for (const EGLAttrib* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
                attrs.push_back(attr[0]);
                attrs.push_back(attr[1]);
            }
        }

        if (!addAnglePlatformAttributes(cnx, attrib_list, attrs)) {
            ALOGE("eglGetDisplay(%p) failed: Mismatch display request", display);
            *error = EGL_BAD_PARAMETER;
            return EGL_NO_DISPLAY;
        }
        attrs.push_back(EGL_NONE);

        dpy = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
                                    reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY), attrs.data());
        dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
                                             reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY),
                                             attrs.data());
        if (dpy == EGL_NO_DISPLAY) {
            ALOGE("eglGetPlatformDisplay failed!");
        } else {
@@ -271,8 +285,8 @@ static EGLDisplay getDisplayAngle(EGLNativeDisplayType display, egl_connection_t
    return dpy;
}

EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {

EGLDisplay egl_display_t::getPlatformDisplay(EGLNativeDisplayType display,
                                             const EGLAttrib* attrib_list) {
    std::lock_guard<std::mutex> _l(lock);
    ATRACE_CALL();

@@ -284,11 +298,25 @@ EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {
        EGLDisplay dpy = EGL_NO_DISPLAY;

        if (cnx->useAngle) {
            dpy = getDisplayAngle(display, cnx);
            EGLint error;
            dpy = getPlatformDisplayAngle(display, cnx, attrib_list, &error);
            if (error != EGL_NONE) {
                return setError(error, dpy);
            }
        }
        if (dpy == EGL_NO_DISPLAY) {
            // NOTE: eglGetPlatformDisplay with a empty attribute list
            // behaves the same as eglGetDisplay
            if (cnx->egl.eglGetPlatformDisplay) {
                dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANDROID_KHR, display,
                                                     attrib_list);
            } else {
                if (attrib_list) {
                    ALOGW("getPlatformDisplay: unexpected attribute list, attributes ignored");
                }
                dpy = cnx->egl.eglGetDisplay(display);
            }
        }

        disp.dpy = dpy;
        if (dpy == EGL_NO_DISPLAY) {
@@ -306,13 +334,20 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
        std::unique_lock<std::mutex> _l(refLock);
        refs++;
        if (refs > 1) {
            if (major != nullptr)
                *major = VERSION_MAJOR;
            if (minor != nullptr)
                *minor = VERSION_MINOR;
            // We don't know what to report until we know what the
            // driver supports. Make sure we are initialized before
            // returning the version info.
            while(!eglIsInitialized) {
                refCond.wait(_l);
            }
            egl_connection_t* const cnx = &gEGLImpl;

            // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
            // changing the behavior from the past where we always advertise
            // version 1.4. May need to check that revision is valid
            // before using cnx->major & cnx->minor
            if (major != nullptr) *major = cnx->major;
            if (minor != nullptr) *minor = cnx->minor;
            return EGL_TRUE;
        }
        while(eglIsInitialized) {
@@ -465,10 +500,12 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
            traceGpuCompletion = true;
        }

        if (major != nullptr)
            *major = VERSION_MAJOR;
        if (minor != nullptr)
            *minor = VERSION_MINOR;
        // TODO: If device doesn't provide 1.4 or 1.5 then we'll be
        // changing the behavior from the past where we always advertise
        // version 1.4. May need to check that revision is valid
        // before using cnx->major & cnx->minor
        if (major != nullptr) *major = cnx->major;
        if (minor != nullptr) *minor = cnx->minor;
    }

    { // scope for refLock
+2 −1
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ bool findExtension(const char* exts, const char* name, size_t nameLen = 0);
class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes
    static egl_display_t sDisplay[NUM_DISPLAYS];
    EGLDisplay getDisplay(EGLNativeDisplayType display);
    EGLDisplay getPlatformDisplay(EGLNativeDisplayType display, const EGLAttrib* attrib_list);
    void loseCurrentImpl(egl_context_t * cur_c);

public:
@@ -72,7 +73,7 @@ public:
    bool getObject(egl_object_t* object) const;

    static egl_display_t* get(EGLDisplay dpy);
    static EGLDisplay getFromNativeDisplay(EGLNativeDisplayType disp);
    static EGLDisplay getFromNativeDisplay(EGLNativeDisplayType disp, const EGLAttrib* attrib_list);

    EGLBoolean makeCurrent(egl_context_t* c, egl_context_t* cur_c,
            EGLSurface draw, EGLSurface read, EGLContext ctx,
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ EGL_ENTRY(EGLSurface, eglCreatePbufferFromClientBuffer, EGLDisplay, EGLenum, EGL
/* EGL 1.5 */
EGL_ENTRY(EGLImage, eglCreateImage, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLAttrib *)
EGL_ENTRY(EGLBoolean, eglDestroyImage, EGLDisplay, EGLImage)
EGL_ENTRY(EGLDisplay, eglGetPlatformDisplay, EGLenum, void *, const EGLAttrib *)

/* EGL_EGLEXT_VERSION 3 */

+27 −12
Original line number Diff line number Diff line
@@ -135,6 +135,11 @@ char const * const gExtensionString =
        "EGL_IMG_context_priority "
        "EGL_KHR_no_config_context "
        ;

char const * const gClientExtensionString =
        "EGL_EXT_client_extensions "
        "EGL_KHR_platform_android "
        "EGL_ANGLE_platform_angle";
// clang-format on

// extensions not exposed to applications but used by the ANDROID system
@@ -279,17 +284,31 @@ static inline EGLContext getContext() { return egl_tls_t::getContext(); }

// ----------------------------------------------------------------------------

EGLDisplay eglGetDisplayImpl(EGLNativeDisplayType display)
{
static EGLDisplay eglGetPlatformDisplayTmpl(EGLenum platform, EGLNativeDisplayType display,
                                            const EGLAttrib* attrib_list) {
    if (platform != EGL_PLATFORM_ANDROID_KHR) {
        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
    }

    uintptr_t index = reinterpret_cast<uintptr_t>(display);
    if (index >= NUM_DISPLAYS) {
        return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
    }

    EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display);
    EGLDisplay dpy = egl_display_t::getFromNativeDisplay(display, attrib_list);
    return dpy;
}

EGLDisplay eglGetDisplayImpl(EGLNativeDisplayType display) {
    return eglGetPlatformDisplayTmpl(EGL_PLATFORM_ANDROID_KHR, display, nullptr);
}

EGLDisplay eglGetPlatformDisplayImpl(EGLenum platform, void* native_display,
                                     const EGLAttrib* attrib_list) {
    return eglGetPlatformDisplayTmpl(platform, static_cast<EGLNativeDisplayType>(native_display),
                                     attrib_list);
}

// ----------------------------------------------------------------------------
// Initialization
// ----------------------------------------------------------------------------
@@ -1402,15 +1421,10 @@ EGLBoolean eglCopyBuffersImpl( EGLDisplay dpy, EGLSurface surface,

const char* eglQueryStringImpl(EGLDisplay dpy, EGLint name)
{
    // Generate an error quietly when client extensions (as defined by
    // EGL_EXT_client_extensions) are queried.  We do not want to rely on
    // validate_display to generate the error as validate_display would log
    // the error, which can be misleading.
    //
    // If we want to support EGL_EXT_client_extensions later, we can return
    // the client extension string here instead.
    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)
        return setErrorQuiet(EGL_BAD_DISPLAY, (const char*)nullptr);
    if (dpy == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) {
        // Return list of client extensions
        return gClientExtensionString;
    }

    const egl_display_ptr dp = validate_display(dpy);
    if (!dp) return (const char *) nullptr;
@@ -2434,6 +2448,7 @@ struct implementation_map_t {
static const implementation_map_t sPlatformImplMap[] = {
        // clang-format off
    { "eglGetDisplay", (EGLFuncPointer)&eglGetDisplayImpl },
    { "eglGetPlatformDisplay", (EGLFuncPointer)&eglGetPlatformDisplayImpl },
    { "eglInitialize", (EGLFuncPointer)&eglInitializeImpl },
    { "eglTerminate", (EGLFuncPointer)&eglTerminateImpl },
    { "eglGetConfigs", (EGLFuncPointer)&eglGetConfigsImpl },
Loading