From 36b960e2244912e34a5b8a5c97e5df0a6c0b2da1 Mon Sep 17 00:00:00 2001 From: George Wright Date: Thu, 12 Nov 2020 10:54:02 -0800 Subject: [PATCH] Add D3D9 fallback path for ANGLE and ensure fallbacks are actually attempted (#22412) --- .../platform/windows/angle_surface_manager.cc | 108 +++++++++--------- .../platform/windows/angle_surface_manager.h | 3 + 2 files changed, 58 insertions(+), 53 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index eda082c7c..32c2bc3de 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -5,6 +5,7 @@ #include "flutter/shell/platform/windows/angle_surface_manager.h" #include +#include namespace flutter { @@ -19,6 +20,31 @@ AngleSurfaceManager::~AngleSurfaceManager() { CleanUp(); } +bool AngleSurfaceManager::InitializeEGL(const EGLint* attributes) { + PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = + reinterpret_cast( + eglGetProcAddress("eglGetPlatformDisplayEXT")); + if (!eglGetPlatformDisplayEXT) { + std::cerr << "EGL: eglGetPlatformDisplayEXT not available" << std::endl; + return false; + } + + egl_display_ = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, + EGL_DEFAULT_DISPLAY, attributes); + + if (egl_display_ == EGL_NO_DISPLAY) { + std::cerr << "EGL: Failed to get a compatible EGLdisplay" << std::endl; + return false; + } + + if (eglInitialize(egl_display_, nullptr, nullptr) == EGL_FALSE) { + std::cerr << "EGL: Failed to initialize"; + return false; + } + + return true; +} + bool AngleSurfaceManager::Initialize() { const EGLint configAttributes[] = {EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, @@ -28,10 +54,10 @@ bool AngleSurfaceManager::Initialize() { const EGLint display_context_attributes[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; - const EGLint default_display_attributes[] = { - // These are prefered display attributes and request ANGLE's D3D11 - // renderer. eglInitialize will only succeed with these attributes if the - // hardware supports D3D11 Feature Level 10_0+. + // These are prefered display attributes and request ANGLE's D3D11 + // renderer. eglInitialize will only succeed with these attributes if the + // hardware supports D3D11 Feature Level 10_0+. + const EGLint d3d11_display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, @@ -43,9 +69,9 @@ bool AngleSurfaceManager::Initialize() { EGL_NONE, }; - const EGLint fl9_3_display_attributes[] = { - // These are used to request ANGLE's D3D11 renderer, with D3D11 Feature - // Level 9_3. + // These are used to request ANGLE's D3D11 renderer, with D3D11 Feature + // Level 9_3. + const EGLint d3d11_fl_9_3_display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, @@ -57,9 +83,9 @@ bool AngleSurfaceManager::Initialize() { EGL_NONE, }; - const EGLint warp_display_attributes[] = { - // These attributes request D3D11 WARP (software rendering fallback) as a - // last resort. + // These attributes request D3D11 WARP (software rendering fallback) in case + // hardware-backed D3D11 is unavailable. + const EGLint d3d11_warp_display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE, @@ -67,51 +93,27 @@ bool AngleSurfaceManager::Initialize() { EGL_NONE, }; - PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = - reinterpret_cast( - eglGetProcAddress("eglGetPlatformDisplayEXT")); - if (!eglGetPlatformDisplayEXT) { - std::cerr << "EGL: eglGetPlatformDisplayEXT not available" << std::endl; - return false; - } - - // Try to initialize EGL to D3D11 Feature Level 10_0+. - egl_display_ = - eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, - default_display_attributes); - if (egl_display_ == EGL_NO_DISPLAY) { - std::cerr << "EGL: Failed to get a compatible EGLdisplay" << std::endl; - return false; - } + // These are used to request ANGLE's D3D9 renderer as a fallback if D3D11 + // is not available. + const EGLint d3d9_display_attributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, + EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, + EGL_TRUE, + EGL_NONE, + }; - if (eglInitialize(egl_display_, nullptr, nullptr) == EGL_FALSE) { - // If above failed, try to initialize EGL to D3D11 Feature Level 9_3, if - // 10_0+ is unavailable. - egl_display_ = - eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, - fl9_3_display_attributes); - if (egl_display_ == EGL_NO_DISPLAY) { - std::cerr << "EGL: Failed to get a compatible 9.3 EGLdisplay" - << std::endl; - return false; - } + std::vector display_attributes_configs = { + d3d11_display_attributes, + d3d11_fl_9_3_display_attributes, + d3d11_warp_display_attributes, + d3d9_display_attributes, + }; - if (eglInitialize(egl_display_, nullptr, nullptr) == EGL_FALSE) { - // If all else fails, attempt D3D11 Feature Level 11_0 on WARP as a last - // resort - egl_display_ = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, - EGL_DEFAULT_DISPLAY, - warp_display_attributes); - if (egl_display_ == EGL_NO_DISPLAY) { - std::cerr << "EGL: Failed to get a compatible WARP EGLdisplay" - << std::endl; - return false; - } - - if (eglInitialize(egl_display_, nullptr, nullptr) == EGL_FALSE) { - std::cerr << "EGL: Failed to initialize EGL" << std::endl; - return false; - } + // Attempt to initialize ANGLE's renderer in order of: D3D11, D3D11 Feature + // Level 9_3, D3D11 WARP and finally D3D9. + for (auto config : display_attributes_configs) { + if (InitializeEGL(config)) { + break; } } diff --git a/shell/platform/windows/angle_surface_manager.h b/shell/platform/windows/angle_surface_manager.h index 60754c37c..d5e92b9d4 100644 --- a/shell/platform/windows/angle_surface_manager.h +++ b/shell/platform/windows/angle_surface_manager.h @@ -75,6 +75,9 @@ class AngleSurfaceManager { void CleanUp(); private: + // Attempts to initialize EGL with a particular ANGLE configuration. + bool InitializeEGL(const EGLint* attributes); + // EGL representation of native display. EGLDisplay egl_display_; -- GitLab