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..af32f5297c742e24051dc8724839aae5cd872cd2 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), |