1.1 --- a/src/video/winrt/SDL_winrtopengles.cpp Sat Nov 01 11:41:18 2014 -0400
1.2 +++ b/src/video/winrt/SDL_winrtopengles.cpp Sun Nov 02 08:47:05 2014 -0500
1.3 @@ -36,7 +36,10 @@
1.4
1.5 /* ANGLE/WinRT constants */
1.6 static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0;
1.7 -
1.8 +#define EGL_PLATFORM_ANGLE_ANGLE 0x3201
1.9 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202
1.10 +#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3203
1.11 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3205
1.12
1.13 /*
1.14 * SDL/EGL top-level implementation
1.15 @@ -52,32 +55,56 @@
1.16 }
1.17
1.18 /* Load ANGLE/WinRT-specific functions */
1.19 - CreateWinrtEglWindow_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Function) SDL_LoadFunction(_this->egl_data->egl_dll_handle, "CreateWinrtEglWindow");
1.20 - if (!CreateWinrtEglWindow) {
1.21 - return SDL_SetError("Could not retrieve ANGLE/WinRT function CreateWinrtEglWindow");
1.22 + CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function) SDL_LoadFunction(_this->egl_data->egl_dll_handle, "CreateWinrtEglWindow");
1.23 + if (CreateWinrtEglWindow) {
1.24 + /* 'CreateWinrtEglWindow' was found, which means that an an older
1.25 + * version of ANGLE/WinRT is being used. Continue setting up EGL,
1.26 + * as appropriate to this version of ANGLE.
1.27 + */
1.28 +
1.29 + /* Create an ANGLE/WinRT EGL-window */
1.30 + /* TODO, WinRT: check for XAML usage before accessing the CoreWindow, as not doing so could lead to a crash */
1.31 + CoreWindow ^ native_win = CoreWindow::GetForCurrentThread();
1.32 + Microsoft::WRL::ComPtr<IUnknown> cpp_win = reinterpret_cast<IUnknown *>(native_win);
1.33 + HRESULT result = CreateWinrtEglWindow(cpp_win, ANGLE_D3D_FEATURE_LEVEL_ANY, &(video_data->winrtEglWindow));
1.34 + if (FAILED(result)) {
1.35 + return -1;
1.36 + }
1.37 +
1.38 + /* Call eglGetDisplay and eglInitialize as appropriate. On other
1.39 + * platforms, this would probably get done by SDL_EGL_LoadLibrary,
1.40 + * however ANGLE/WinRT's current implementation (as of Mar 22, 2014) of
1.41 + * eglGetDisplay requires that a C++ object be passed into it, so the
1.42 + * call will be made in this file, a C++ file, instead.
1.43 + */
1.44 + Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
1.45 + _this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display);
1.46 + if (!_this->egl_data->egl_display) {
1.47 + return SDL_SetError("Could not get EGL display");
1.48 + }
1.49 + } else {
1.50 + const EGLint displayAttributes[] = {
1.51 + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
1.52 + EGL_NONE,
1.53 + };
1.54 +
1.55 + /* 'CreateWinrtEglWindow' was NOT found, which either means that a
1.56 + * newer version of ANGLE/WinRT is being used, or that we don't have
1.57 + * a valid copy of ANGLE.
1.58 + *
1.59 + * Try loading ANGLE as if it were the newer version.
1.60 + */
1.61 + eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT");
1.62 + if (!eglGetPlatformDisplayEXT) {
1.63 + return SDL_SetError("Could not retrieve ANGLE/WinRT display function(s)");
1.64 + }
1.65 +
1.66 + _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
1.67 + if (!_this->egl_data->egl_display) {
1.68 + return SDL_SetError("Could not get EGL display");
1.69 + }
1.70 }
1.71
1.72 - /* Create an ANGLE/WinRT EGL-window */
1.73 - /* TODO, WinRT: check for XAML usage before accessing the CoreWindow, as not doing so could lead to a crash */
1.74 - CoreWindow ^ native_win = CoreWindow::GetForCurrentThread();
1.75 - Microsoft::WRL::ComPtr<IUnknown> cpp_win = reinterpret_cast<IUnknown *>(native_win);
1.76 - HRESULT result = CreateWinrtEglWindow(cpp_win, ANGLE_D3D_FEATURE_LEVEL_ANY, &(video_data->winrtEglWindow));
1.77 - if (FAILED(result)) {
1.78 - return -1;
1.79 - }
1.80 -
1.81 - /* Call eglGetDisplay and eglInitialize as appropriate. On other
1.82 - * platforms, this would probably get done by SDL_EGL_LoadLibrary,
1.83 - * however ANGLE/WinRT's current implementation (as of Mar 22, 2014) of
1.84 - * eglGetDisplay requires that a C++ object be passed into it, so the
1.85 - * call will be made in this file, a C++ file, instead.
1.86 - */
1.87 - Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
1.88 - _this->egl_data->egl_display = ((eglGetDisplay_Function)_this->egl_data->eglGetDisplay)(cpp_display);
1.89 - if (!_this->egl_data->egl_display) {
1.90 - return SDL_SetError("Could not get EGL display");
1.91 - }
1.92 -
1.93 if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
1.94 return SDL_SetError("Could not initialize EGL");
1.95 }
2.1 --- a/src/video/winrt/SDL_winrtopengles.h Sat Nov 01 11:41:18 2014 -0400
2.2 +++ b/src/video/winrt/SDL_winrtopengles.h Sun Nov 02 08:47:05 2014 -0500
2.3 @@ -47,18 +47,22 @@
2.4 /* Typedefs for ANGLE/WinRT's C++-based native-display and native-window types,
2.5 * which are used when calling eglGetDisplay and eglCreateWindowSurface.
2.6 */
2.7 -typedef Microsoft::WRL::ComPtr<IUnknown> WINRT_EGLNativeWindowType;
2.8 -typedef WINRT_EGLNativeWindowType WINRT_EGLNativeDisplayType;
2.9 +typedef Microsoft::WRL::ComPtr<IUnknown> WINRT_EGLNativeWindowType_Old;
2.10
2.11 -/* Function pointer typedefs for ANGLE/WinRT's functions that require
2.12 - * parameter customization [by passing in C++ objects].
2.13 +/* Function pointer typedefs for 'old' ANGLE/WinRT's functions, which may
2.14 + * require that C++ objects be passed in:
2.15 */
2.16 -typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_Function)(WINRT_EGLNativeWindowType);
2.17 -typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType, const EGLint *);
2.18 -typedef HRESULT (EGLAPIENTRY *CreateWinrtEglWindow_Function)(Microsoft::WRL::ComPtr<IUnknown>, int, IUnknown ** result);
2.19 +typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_Old_Function)(WINRT_EGLNativeWindowType_Old);
2.20 +typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_Old_Function)(EGLDisplay, EGLConfig, WINRT_EGLNativeWindowType_Old, const EGLint *);
2.21 +typedef HRESULT (EGLAPIENTRY *CreateWinrtEglWindow_Old_Function)(Microsoft::WRL::ComPtr<IUnknown>, int, IUnknown ** result);
2.22
2.23 #endif /* __cplusplus */
2.24
2.25 +/* Function pointer typedefs for 'new' ANGLE/WinRT functions, which, unlike
2.26 + * the old functions, do not require C++ support and work with plain C.
2.27 + */
2.28 +typedef EGLDisplay (EGLAPIENTRY *eglGetPlatformDisplayEXT_Function)(EGLenum, void *, const EGLint *);
2.29 +
2.30 #endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */
2.31
2.32 #endif /* _SDL_winrtopengles_h */
3.1 --- a/src/video/winrt/SDL_winrtvideo.cpp Sat Nov 01 11:41:18 2014 -0400
3.2 +++ b/src/video/winrt/SDL_winrtvideo.cpp Sun Nov 02 08:47:05 2014 -0500
3.3 @@ -328,13 +328,33 @@
3.4 return SDL_SetError(buf);
3.5 }
3.6
3.7 - Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->winrtEglWindow;
3.8 - data->egl_surface = ((eglCreateWindowSurface_Function)_this->egl_data->eglCreateWindowSurface)(
3.9 - _this->egl_data->egl_display,
3.10 - _this->egl_data->egl_config,
3.11 - cpp_winrtEglWindow, NULL);
3.12 - if (data->egl_surface == NULL) {
3.13 - return SDL_SetError("eglCreateWindowSurface failed");
3.14 + if (video_data->winrtEglWindow) { /* ... is the 'old' version of ANGLE/WinRT being used? */
3.15 + /* Attempt to create a window surface using older versions of
3.16 + * ANGLE/WinRT:
3.17 + */
3.18 + Microsoft::WRL::ComPtr<IUnknown> cpp_winrtEglWindow = video_data->winrtEglWindow;
3.19 + data->egl_surface = ((eglCreateWindowSurface_Old_Function)_this->egl_data->eglCreateWindowSurface)(
3.20 + _this->egl_data->egl_display,
3.21 + _this->egl_data->egl_config,
3.22 + cpp_winrtEglWindow, NULL);
3.23 + if (data->egl_surface == NULL) {
3.24 + return SDL_SetError("eglCreateWindowSurface failed");
3.25 + }
3.26 + } else if (data->coreWindow.Get() != nullptr) {
3.27 + /* Attempt to create a window surface using newer versions of
3.28 + * ANGLE/WinRT:
3.29 + */
3.30 + IInspectable * coreWindowAsIInspectable = reinterpret_cast<IInspectable *>(data->coreWindow.Get());
3.31 + data->egl_surface = _this->egl_data->eglCreateWindowSurface(
3.32 + _this->egl_data->egl_display,
3.33 + _this->egl_data->egl_config,
3.34 + coreWindowAsIInspectable,
3.35 + NULL);
3.36 + if (data->egl_surface == NULL) {
3.37 + return SDL_SetError("eglCreateWindowSurface failed");
3.38 + }
3.39 + } else {
3.40 + return SDL_SetError("No supported means to create an EGL window surface are available");
3.41 }
3.42 }
3.43 #endif