summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmadill <jmadill@chromium.org>2015-04-28 10:23:47 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-28 17:25:28 +0000
commitfefb7cfcf73c07b5f2774266bda02e839a829ef1 (patch)
tree0d01ffb3346951c3cd531d47b69cb5504020b2d6
parent215900d19ec77d27a0772f29ec1ad2c9bf812a50 (diff)
downloadchromium_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.cc12
-rw-r--r--ui/gl/gl_surface_egl.cc183
-rw-r--r--ui/gl/gl_surface_egl.h6
-rw-r--r--ui/gl/gl_surface_win.cc6
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