shiny/driver/gldriver: try multiple ANGLE platforms
On Windows mobile/gl uses ANGLE for EGL. ANGLE has multiple backends and for some graphics cards one of these may work better than other. Automatically try to choose the next platform when initialization fails: 1. Default 2. Direct3D 11 3. Direct3D 9 4. Direct3D 11 with WARP Change-Id: Ief0911574afaf4ded3f578a1cd7b9639828f3486 Reviewed-on: https://go-review.googlesource.com/30754 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
Родитель
42596718c7
Коммит
807d650904
|
@ -30,13 +30,25 @@ const (
|
|||
_EGL_CONFIG_CAVEAT = 0x3027
|
||||
_EGL_NONE = 0x3038
|
||||
|
||||
_EGL_CONTEXT_CLIENT_VERSION = 0x3098
|
||||
)
|
||||
|
||||
// ANGLE specific options found in eglext.h
|
||||
const (
|
||||
_EGL_PLATFORM_ANGLE_ANGLE = 0x3202
|
||||
_EGL_PLATFORM_ANGLE_TYPE_ANGLE = 0x3203
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE = 0x3204
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE = 0x3205
|
||||
_EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE = 0x3206
|
||||
|
||||
_EGL_CONTEXT_CLIENT_VERSION = 0x3098
|
||||
_EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE = 0x3207
|
||||
_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE = 0x3208
|
||||
_EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE = 0x3209
|
||||
_EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE = 0x320A
|
||||
_EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE = 0x320B
|
||||
|
||||
_EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE = 0x320D
|
||||
_EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE = 0x320E
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -222,28 +222,72 @@ func eglErr() error {
|
|||
}
|
||||
|
||||
func createEGLSurface(hwnd syscall.Handle, w *windowImpl) error {
|
||||
displayAttrib := [...]eglInt{
|
||||
_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_NONE,
|
||||
var displayAttribPlatforms = [][]eglInt{
|
||||
// Default
|
||||
[]eglInt{
|
||||
_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_NONE,
|
||||
},
|
||||
// Direct3D 11
|
||||
[]eglInt{
|
||||
_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_NONE,
|
||||
},
|
||||
// Direct3D 9
|
||||
[]eglInt{
|
||||
_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_NONE,
|
||||
},
|
||||
// Direct3D 11 with WARP
|
||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/gg615082.aspx
|
||||
[]eglInt{
|
||||
_EGL_PLATFORM_ANGLE_TYPE_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, _EGL_DONT_CARE,
|
||||
_EGL_NONE,
|
||||
},
|
||||
}
|
||||
|
||||
dc, err := win32.GetDC(hwnd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("win32.GetDC failed: %v", err)
|
||||
}
|
||||
display, _, _ := eglGetPlatformDisplayEXT.Call(
|
||||
_EGL_PLATFORM_ANGLE_ANGLE,
|
||||
uintptr(dc),
|
||||
uintptr(unsafe.Pointer(&displayAttrib)),
|
||||
)
|
||||
if display == _EGL_NO_DISPLAY {
|
||||
return fmt.Errorf("eglGetPlatformDisplayEXT failed: %v", eglErr())
|
||||
}
|
||||
if ret, _, _ := eglInitialize.Call(display, 0, 0); ret == 0 {
|
||||
return fmt.Errorf("eglInitialize failed: %v", eglErr())
|
||||
|
||||
var display uintptr = _EGL_NO_DISPLAY
|
||||
for i, displayAttrib := range displayAttribPlatforms {
|
||||
lastTry := i == len(displayAttribPlatforms)-1
|
||||
|
||||
display, _, _ = eglGetPlatformDisplayEXT.Call(
|
||||
_EGL_PLATFORM_ANGLE_ANGLE,
|
||||
uintptr(dc),
|
||||
uintptr(unsafe.Pointer(&displayAttrib[0])),
|
||||
)
|
||||
|
||||
if display == _EGL_NO_DISPLAY {
|
||||
if !lastTry {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("eglGetPlatformDisplayEXT failed: %v", eglErr())
|
||||
}
|
||||
|
||||
if ret, _, _ := eglInitialize.Call(display, 0, 0); ret == 0 {
|
||||
if !lastTry {
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("eglInitialize failed: %v", eglErr())
|
||||
}
|
||||
}
|
||||
|
||||
eglBindAPI.Call(_EGL_OPENGL_ES_API)
|
||||
|
|
Загрузка…
Ссылка в новой задаче