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

Commit 555f1df2 authored by Courtney Goeltzenleuchter's avatar Courtney Goeltzenleuchter
Browse files

Add ANGLE support to getDisplay

If ANGLE is enabled for this application construct the necessary
attributes to configure ANGLE and call ANGLE's eglGetPlatformDisplay
to initialize.

Test: manual - enable ANGLE for app and verify
Bug: 80239516
Change-Id: I9bbd40c660cd3bed72989fb4529e50eb608d71ea
parent 1f00e177
Loading
Loading
Loading
Loading
+34 −22
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglext_angle.h>

#include <android/hardware_buffer.h>
#include <private/android/AHardwareBufferHelpers.h>
@@ -711,6 +712,9 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
            return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
        }

        // NOTE: When using Vulkan backend, the Vulkan runtime makes all the
        // native_window_* calls, so don't do them here.
        if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
            int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
            if (result < 0) {
                ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
@@ -718,6 +722,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
                      window, result);
                return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
            }
        }

        EGLDisplay iDpy = dp->disp.dpy;
        android_pixel_format format;
@@ -733,7 +738,7 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
        }
        attrib_list = strippedAttribList.data();

        {
        if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
            int err = native_window_set_buffers_format(window, format);
            if (err != 0) {
                ALOGE("error setting native window pixel format: %s (%d)",
@@ -741,18 +746,18 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
                native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
                return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
            }
        }

            android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
            if (dataSpace != HAL_DATASPACE_UNKNOWN) {
            int err = native_window_set_buffers_data_space(window, dataSpace);
                err = native_window_set_buffers_data_space(window, dataSpace);
                if (err != 0) {
                ALOGE("error setting native window pixel dataSpace: %s (%d)",
                      strerror(-err), err);
                    ALOGE("error setting native window pixel dataSpace: %s (%d)", strerror(-err),
                          err);
                    native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
                    return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
                }
            }
        }

        // the EGL spec requires that a new EGLSurface default to swap interval
        // 1, so explicitly set that on the window here.
@@ -769,9 +774,11 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
        }

        // EGLSurface creation failed
        if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
            native_window_set_buffers_format(window, 0);
            native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
        }
    }
    return EGL_NO_SURFACE;
}

@@ -1362,10 +1369,12 @@ EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
        }
    }

    if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
        if (!sendSurfaceMetadata(s)) {
            native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
            return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
        }
    }

    if (n_rects == 0) {
        return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
@@ -1385,7 +1394,10 @@ EGLBoolean eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface draw,
        androidRect.bottom = y;
        androidRects.push_back(androidRect);
    }
    native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(), androidRects.size());
    if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
        native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(),
                                         androidRects.size());
    }

    if (s->cnx->egl.eglSwapBuffersWithDamageKHR) {
        return s->cnx->egl.eglSwapBuffersWithDamageKHR(dp->disp.dpy, s->surface,
+84 −12
Original line number Diff line number Diff line
@@ -122,7 +122,81 @@ EGLDisplay egl_display_t::getFromNativeDisplay(EGLNativeDisplayType disp) {
    return sDisplay[uintptr_t(disp)].getDisplay(disp);
}

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

    EGLint angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
    if (attrib_list) {
        while (*attrib_list != EGL_NONE) {
            EGLAttrib attr = *attrib_list++;
            EGLAttrib value = *attrib_list++;
            if (attr == EGL_PLATFORM_ANGLE_TYPE_ANGLE) {
                switch (value) {
                    case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
                        angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
                        break;
                    case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
                    case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
                        angleBackendDefault = value;
                        break;
                    default:
                        ALOGW("Invalid EGL_PLATFORM_ANGLE_TYPE_ANGLE attribute: 0x%" PRIxPTR,
                              value);
                        break;
                }
            }
        }
    }

    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;
            break;
        case 2:
            ALOGV("addAnglePlatformAttributes: Requesting Vulkan back-end");
            cnx->angleBackend = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
            break;
        default:
            break;
    }

    attrs.reserve(4 * 2);

    attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
    attrs.push_back(cnx->angleBackend);

    switch (cnx->angleBackend) {
        case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
            ALOGV("%s: Requesting Vulkan ANGLE back-end", __FUNCTION__);
            property_get("debug.angle.validation", prop, "0");
            attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
            attrs.push_back(atoi(prop));
            break;
        case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
            ALOGV("%s: Requesting Default ANGLE back-end", __FUNCTION__);
            break;
        case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
            ALOGV("%s: Requesting OpenGL ES ANGLE back-end", __FUNCTION__);
            // NOTE: This is only valid if the backend is OpenGL
            attrs.push_back(EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE);
            attrs.push_back(vendorEGL);
            break;
        default:
            ALOGV("%s: Requesting Unknown (%d) ANGLE back-end", __FUNCTION__, cnx->angleBackend);
            break;
    }
    attrs.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE);
    attrs.push_back(EGL_FALSE);
}

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

    // Locally define this until EGL 1.5 is supported
@@ -134,18 +208,15 @@ EGLDisplay getDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const
                    cnx->egl.eglGetProcAddress("eglGetPlatformDisplay"));

    if (eglGetPlatformDisplay) {
        intptr_t vendorEGL = (intptr_t)cnx->vendorEGL;
        std::vector<EGLAttrib> attrs;
        addAnglePlatformAttributes(cnx, nullptr, attrs);
        attrs.push_back(EGL_NONE);

        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);

                                    reinterpret_cast<void*>(EGL_DEFAULT_DISPLAY), attrs.data());
        if (dpy == EGL_NO_DISPLAY) {
            ALOGE("eglGetPlatformDisplay failed!");
        }
    } else {
        ALOGE("eglGetDisplay(%p) failed: Unable to look up eglGetPlatformDisplay from ANGLE",
              display);
@@ -168,7 +239,8 @@ EGLDisplay egl_display_t::getDisplay(EGLNativeDisplayType display) {

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

+1 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ struct egl_connection_t {
    void*               libGles2;

    bool                useAngle;
    EGLint              angleBackend;
    void*               vendorEGL;
};