diff options
| author | 2018-10-11 13:09:40 -0600 | |
|---|---|---|
| committer | 2018-10-17 15:09:39 -0600 | |
| commit | 4adf75bf53978dffcfc553254f4f67bf935724a0 (patch) | |
| tree | 692b95819d717bad0e788debac1adbcf40bd1fcd | |
| parent | e498a2d12cf234634809339bb7d447b13a24f0c8 (diff) | |
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
| -rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 15 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_display.cpp | 101 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_display.h | 3 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_entries.in | 1 | ||||
| -rw-r--r-- | opengl/libs/EGL/egl_platform_entries.cpp | 39 | ||||
| -rw-r--r-- | opengl/libs/platform_entries.in | 1 |
6 files changed, 115 insertions, 45 deletions
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 3a7979c771..619297feec 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -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(); diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp index 893cf0be08..476b304bc8 100644 --- a/opengl/libs/EGL/egl_display.cpp +++ b/opengl/libs/EGL/egl_display.cpp @@ -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,10 +298,24 @@ 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) { - dpy = cnx->egl.eglGetDisplay(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; @@ -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 diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h index f7640287e4..36856b79fe 100644 --- a/opengl/libs/EGL/egl_display.h +++ b/opengl/libs/EGL/egl_display.h @@ -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, diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in index 35c2ecbe69..177c15452b 100644 --- a/opengl/libs/EGL/egl_entries.in +++ b/opengl/libs/EGL/egl_entries.in @@ -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 */ diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp index 6ef0082224..e6aa24dcec 100644 --- a/opengl/libs/EGL/egl_platform_entries.cpp +++ b/opengl/libs/EGL/egl_platform_entries.cpp @@ -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 }, diff --git a/opengl/libs/platform_entries.in b/opengl/libs/platform_entries.in index 6f087fdbb7..95fa32d105 100644 --- a/opengl/libs/platform_entries.in +++ b/opengl/libs/platform_entries.in @@ -1,4 +1,5 @@ EGL_ENTRY(EGLDisplay, eglGetDisplay, EGLNativeDisplayType) +EGL_ENTRY(EGLDisplay, eglGetPlatformDisplay, EGLenum, EGLNativeDisplayType, const EGLAttrib*) EGL_ENTRY(EGLBoolean, eglInitialize, EGLDisplay, EGLint*, EGLint*) EGL_ENTRY(EGLBoolean, eglTerminate, EGLDisplay) EGL_ENTRY(EGLBoolean, eglGetConfigs, EGLDisplay, EGLConfig*, EGLint, EGLint*) |