diff options
author | jmadill <jmadill@chromium.org> | 2015-04-28 10:23:47 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-28 17:25:28 +0000 |
commit | fefb7cfcf73c07b5f2774266bda02e839a829ef1 (patch) | |
tree | 0d01ffb3346951c3cd531d47b69cb5504020b2d6 | |
parent | 215900d19ec77d27a0772f29ec1ad2c9bf812a50 (diff) | |
download | chromium_src-fefb7cfcf73c07b5f2774266bda02e839a829ef1.zip chromium_src-fefb7cfcf73c07b5f2774266bda02e839a829ef1.tar.gz chromium_src-fefb7cfcf73c07b5f2774266bda02e839a829ef1.tar.bz2 |
gpu: Upgrade to new ANGLE Platform Display init.
This allows us to select which ANGLE back-end to use more flexibly,
and controls the selection process entirely in Chrome.
The logic for when to try a backup renderer is a bit more complex
because we query the display extensions in the static binding
init code.
BUG=457325
Review URL: https://codereview.chromium.org/1051253008
Cr-Commit-Position: refs/heads/master@{#327315}
-rw-r--r-- | ui/gl/gl_bindings.cc | 12 | ||||
-rw-r--r-- | ui/gl/gl_surface_egl.cc | 183 | ||||
-rw-r--r-- | ui/gl/gl_surface_egl.h | 6 | ||||
-rw-r--r-- | ui/gl/gl_surface_win.cc | 6 |
4 files changed, 141 insertions, 66 deletions
diff --git a/ui/gl/gl_bindings.cc b/ui/gl/gl_bindings.cc index 83b6b59..c576db8 100644 --- a/ui/gl/gl_bindings.cc +++ b/ui/gl/gl_bindings.cc @@ -41,15 +41,10 @@ std::string DriverWGL::GetPlatformExtensions() { #if defined(OS_WIN) || defined(USE_X11) || defined(OS_ANDROID) || defined(USE_OZONE) std::string DriverEGL::GetPlatformExtensions() { - EGLDisplay display = -#if defined(OS_WIN) - GLSurfaceEGL::GetPlatformDisplay(GetPlatformDefaultEGLNativeDisplay()); -#else - g_driver_egl.fn.eglGetDisplayFn(GetPlatformDefaultEGLNativeDisplay()); -#endif + EGLDisplay display = GLSurfaceEGL::InitializeDisplay(); + if (display == EGL_NO_DISPLAY) + return ""; - DCHECK(g_driver_egl.fn.eglInitializeFn); - g_driver_egl.fn.eglInitializeFn(display, NULL, NULL); DCHECK(g_driver_egl.fn.eglQueryStringFn); const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS); return str ? std::string(str) : ""; @@ -57,6 +52,7 @@ std::string DriverEGL::GetPlatformExtensions() { // static std::string DriverEGL::GetClientExtensions() { + DCHECK(g_driver_egl.fn.eglQueryStringFn); const char* str = g_driver_egl.fn.eglQueryStringFn(EGL_NO_DISPLAY, EGL_EXTENSIONS); return str ? std::string(str) : ""; diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc index 61c3c05..af32f52 100644 --- a/ui/gl/gl_surface_egl.cc +++ b/ui/gl/gl_surface_egl.cc @@ -41,7 +41,6 @@ extern "C" { #define EGL_OPENGL_ES3_BIT 0x00000040 #endif -#if defined(OS_WIN) // From ANGLE's egl/eglext.h. #ifndef EGL_ANGLE_platform_angle @@ -63,8 +62,6 @@ extern "C" { #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE 0x320C #endif /* EGL_ANGLE_platform_angle_d3d */ -#endif // defined(OS_WIN) - using ui::GetLastEGLErrorString; namespace gfx { @@ -141,6 +138,97 @@ void DeinitializeEgl() { } } +EGLDisplay GetPlatformANGLEDisplay(EGLNativeDisplayType native_display, + EGLenum platform_type, + EGLenum device_type) { + const EGLint display_attribs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, + platform_type, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, + device_type, + EGL_NONE}; + return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, + reinterpret_cast<void*>(native_display), + display_attribs); +} + +enum DisplayType { DEFAULT, SWIFT_SHADER, ANGLE_WARP, ANGLE_D3D9, ANGLE_D3D11 }; + +EGLDisplay GetDisplayFromType(DisplayType display_type, + EGLNativeDisplayType native_display) { + switch (display_type) { + case DEFAULT: + case SWIFT_SHADER: + return eglGetDisplay(native_display); + case ANGLE_WARP: + return GetPlatformANGLEDisplay(native_display, + EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE); + case ANGLE_D3D9: + return GetPlatformANGLEDisplay( + native_display, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + case ANGLE_D3D11: + return GetPlatformANGLEDisplay( + native_display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + default: + NOTREACHED(); + return EGL_NO_DISPLAY; + } +} + +const char* DisplayTypeString(DisplayType display_type) { + switch (display_type) { + case DEFAULT: + return "Default"; + case SWIFT_SHADER: + return "SwiftShader"; + case ANGLE_WARP: + return "WARP"; + case ANGLE_D3D9: + return "D3D9"; + case ANGLE_D3D11: + return "D3D11"; + default: + NOTREACHED(); + return "Err"; + } +} + +void GetInitDisplays(bool supports_angle_d3d, + std::vector<DisplayType>* init_displays) { + const base::CommandLine* command_line = + base::CommandLine::ForCurrentProcess(); + bool using_swift_shader = + command_line->GetSwitchValueASCII(switches::kUseGL) == "swiftshader"; + + // SwiftShader does not use the platform extensions + if (using_swift_shader) { + init_displays->push_back(SWIFT_SHADER); + return; + } + + // If we're missing the ANGLE extensions, fall back to default. + if (!supports_angle_d3d) { + init_displays->push_back(DEFAULT); + return; + } + + if (command_line->HasSwitch(switches::kUseWarp)) { + init_displays->push_back(ANGLE_WARP); + return; + } + + if (command_line->HasSwitch(switches::kDisableD3D11)) { + init_displays->push_back(ANGLE_D3D9); + return; + } + + // Default mode for ANGLE - try D3D11, else try D3D9 + init_displays->push_back(ANGLE_D3D11); + init_displays->push_back(ANGLE_D3D9); +} + } // namespace GLSurfaceEGL::GLSurfaceEGL() { @@ -156,23 +244,9 @@ bool GLSurfaceEGL::InitializeOneOff() { if (g_initialized) return true; - g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); - -#if defined(OS_WIN) - g_display = GetPlatformDisplay(g_native_display_type); -#else - g_display = eglGetDisplay(g_native_display_type); -#endif - - if (!g_display) { - LOG(ERROR) << "eglGetDisplay failed with error " << GetLastEGLErrorString(); - return false; - } - - if (!eglInitialize(g_display, NULL, NULL)) { - LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); + InitializeDisplay(); + if (g_display == EGL_NO_DISPLAY) return false; - } // Choose an EGL configuration. // On X this is only used for PBuffer surfaces. @@ -328,42 +402,55 @@ GLSurfaceEGL::~GLSurfaceEGL() { } } -#if defined(OS_WIN) -static const EGLint kDisplayAttribsWarp[] { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, +// InitializeDisplay is necessary because the static binding code +// needs a full Display init before it can query the Display extensions. +// static +EGLDisplay GLSurfaceEGL::InitializeDisplay() { + if (g_display != EGL_NO_DISPLAY) { + return g_display; + } + + g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, + // If EGL_EXT_client_extensions not supported this call to eglQueryString + // will return NULL. + const char* client_extensions = + eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); - EGL_NONE -}; + bool supports_angle_d3d = false; + // Check for availability of ANGLE extensions. + if (client_extensions) { + supports_angle_d3d = + ExtensionsContain(client_extensions, "ANGLE_platform_angle") && + ExtensionsContain(client_extensions, "ANGLE_platform_angle_d3d"); + } -// static -EGLDisplay GLSurfaceEGL::GetPlatformDisplay( - EGLNativeDisplayType native_display) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) { - // Check for availability of WARP via ANGLE extension. - bool supports_warp = false; - const char* no_display_extensions = eglQueryString(EGL_NO_DISPLAY, - EGL_EXTENSIONS); - // If EGL_EXT_client_extensions not supported this call to eglQueryString - // will return NULL. - if (no_display_extensions) - supports_warp = - ExtensionsContain(no_display_extensions, "ANGLE_platform_angle") && - ExtensionsContain(no_display_extensions, "ANGLE_platform_angle_d3d"); - - if (!supports_warp) - return NULL; + std::vector<DisplayType> init_displays; + GetInitDisplays(supports_angle_d3d, &init_displays); + + for (size_t disp_index = 0; disp_index < init_displays.size(); ++disp_index) { + DisplayType display_type = init_displays[disp_index]; + EGLDisplay display = + GetDisplayFromType(display_type, g_native_display_type); + if (display == EGL_NO_DISPLAY) { + LOG(ERROR) << "EGL display query failed with error " + << GetLastEGLErrorString(); + } + + if (!eglInitialize(display, nullptr, nullptr)) { + bool is_last = disp_index == init_displays.size() - 1; - return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, native_display, - kDisplayAttribsWarp); + LOG(ERROR) << "eglInitialize " << DisplayTypeString(display_type) + << " failed with error " << GetLastEGLErrorString() + << (is_last ? "" : ", trying next display type"); + } else { + g_display = display; + break; + } } - return eglGetDisplay(native_display); + return g_display; } -#endif NativeViewGLSurfaceEGL::NativeViewGLSurfaceEGL(EGLNativeWindowType window) : window_(window), diff --git a/ui/gl/gl_surface_egl.h b/ui/gl/gl_surface_egl.h index 21669d7..614a784 100644 --- a/ui/gl/gl_surface_egl.h +++ b/ui/gl/gl_surface_egl.h @@ -34,6 +34,7 @@ class GL_EXPORT GLSurfaceEGL : public GLSurface { static bool InitializeOneOff(); static EGLDisplay GetHardwareDisplay(); + static EGLDisplay InitializeDisplay(); static EGLNativeDisplayType GetNativeDisplay(); // These aren't particularly tied to surfaces, but since we already @@ -48,11 +49,6 @@ class GL_EXPORT GLSurfaceEGL : public GLSurface { ~GLSurfaceEGL() override; private: -#if defined(OS_WIN) - friend struct DriverEGL; - static EGLDisplay GetPlatformDisplay(EGLNativeDisplayType native_display); -#endif - DISALLOW_COPY_AND_ASSIGN(GLSurfaceEGL); }; diff --git a/ui/gl/gl_surface_win.cc b/ui/gl/gl_surface_win.cc index 8d55009..d919ed1 100644 --- a/ui/gl/gl_surface_win.cc +++ b/ui/gl/gl_surface_win.cc @@ -341,11 +341,7 @@ scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface( } EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableD3D11) || - base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseWarp)) - return GetDC(NULL); - return EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE; + return GetDC(NULL); } } // namespace gfx |