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
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index c361ab0..1ed9850 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -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,12 +712,16 @@
return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
- int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
- if (result < 0) {
- ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
- "failed (%#x) (already connected to another API?)",
- window, result);
- return setError(EGL_BAD_ALLOC, 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) "
+ "failed (%#x) (already connected to another API?)",
+ window, result);
+ return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ }
}
EGLDisplay iDpy = dp->disp.dpy;
@@ -733,7 +738,7 @@
}
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,16 +746,16 @@
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);
- if (err != 0) {
- 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);
+ android_dataspace dataSpace = dataSpaceFromEGLColorSpace(colorSpace);
+ if (dataSpace != HAL_DATASPACE_UNKNOWN) {
+ err = native_window_set_buffers_data_space(window, dataSpace);
+ if (err != 0) {
+ 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);
+ }
}
}
@@ -769,8 +774,10 @@
}
// EGLSurface creation failed
- native_window_set_buffers_format(window, 0);
- native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
+ 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,9 +1369,11 @@
}
}
- if (!sendSurfaceMetadata(s)) {
- native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
- return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
+ 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) {
@@ -1385,7 +1394,10 @@
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,
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 10a097a..d1635b7 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -122,7 +122,81 @@
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 @@
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 @@
if (cnx->useAngle) {
dpy = getDisplayAngle(display, cnx);
- } else {
+ }
+ if (dpy == EGL_NO_DISPLAY) {
dpy = cnx->egl.eglGetDisplay(display);
}
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 2600eb0..4990af6 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -49,6 +49,7 @@
void* libGles2;
bool useAngle;
+ EGLint angleBackend;
void* vendorEGL;
};