Chromium Code Reviews| Index: ui/gl/gl_surface_egl.cc |
| diff --git a/ui/gl/gl_surface_egl.cc b/ui/gl/gl_surface_egl.cc |
| index 61c3c055bd0a573a3d541fd34c6ec054d7bf1507..12203cf6227a01e38dca5db2aed74d7edde4205b 100644 |
| --- a/ui/gl/gl_surface_egl.cc |
| +++ b/ui/gl/gl_surface_egl.cc |
| @@ -141,6 +141,99 @@ void DeinitializeEgl() { |
| } |
| } |
| +#if defined(OS_WIN) |
| +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, 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); |
| +} |
|
piman
2015/04/23 21:03:30
I like this, it's easier to follow with the logic
|
| + |
| +#endif |
| + |
| } // namespace |
| GLSurfaceEGL::GLSurfaceEGL() { |
| @@ -156,23 +249,28 @@ bool GLSurfaceEGL::InitializeOneOff() { |
| if (g_initialized) |
| return true; |
| - g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| - |
| #if defined(OS_WIN) |
| - g_display = GetPlatformDisplay(g_native_display_type); |
| + InitializeDisplay(); |
| + if (g_display == EGL_NO_DISPLAY) |
| + return false; |
| #else |
| + g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| + |
| 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)) { |
| + bool egl_init_success = |
| + (eglInitialize(g_display, nullptr, nullptr) == EGL_TRUE); |
| + |
| + if (!egl_init_success) { |
| LOG(ERROR) << "eglInitialize failed with error " << GetLastEGLErrorString(); |
| return false; |
| } |
| +#endif |
| // Choose an EGL configuration. |
| // On X this is only used for PBuffer surfaces. |
| @@ -329,40 +427,57 @@ GLSurfaceEGL::~GLSurfaceEGL() { |
| } |
| #if defined(OS_WIN) |
| -static const EGLint kDisplayAttribsWarp[] { |
| - EGL_PLATFORM_ANGLE_TYPE_ANGLE, |
| - EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, |
| - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, |
| - EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_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; |
| + } |
| - EGL_NONE |
| -}; |
| + g_native_display_type = GetPlatformDefaultEGLNativeDisplay(); |
| -// 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; |
| + // If EGL_EXT_client_extensions not supported this call to eglQueryString |
| + // will return NULL. |
| + const char* client_extensions = |
| + eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); |
| + |
| + 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"); |
| + } |
| + |
| + std::vector<DisplayType> init_displays; |
| + GetInitDisplays(supports_angle_d3d, &init_displays); |
| - return eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, native_display, |
| - kDisplayAttribsWarp); |
| + 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; |
| + |
| + 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) |