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