src/video/winrt/SDL_winrtopengles.cpp
author David Ludwig <dludwig@pobox.com>
Sun, 02 Nov 2014 08:47:05 -0500
changeset 9211 04c7e1220a65
parent 8663 308e74493106
child 9347 847eb2564aa4
permissions -rw-r--r--
WinRT: expanded OpenGL ES 2 support to enable recent updates to ANGLE/WinRT

ANGLE for WinRT has at least two versions:
- an older version, which supports Windows 8.0 and 8.1. This is currently
the "winrt" branch in MSOpenTech's ANGLE repository (at
https://github.com/msopentech/angle)
- a newer version, which drops support for Windows 8.0, but is under more
active development (via MSOpenTech's "future-dev" branch), and which was
recently merged into the ANGLE project's official "master" branch
(at https://chromium.googlesource.com/angle/angle)

Both versions are setup using slightly different APIs. SDL/WinRT will now
attempt to detect which version is being used, and configure it appropriately.
slouken@8582
     1
/*
slouken@8582
     2
  Simple DirectMedia Layer
slouken@8615
     3
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@8582
     4
slouken@8582
     5
  This software is provided 'as-is', without any express or implied
slouken@8582
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@8582
     7
  arising from the use of this software.
slouken@8582
     8
slouken@8582
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@8582
    10
  including commercial applications, and to alter it and redistribute it
slouken@8582
    11
  freely, subject to the following restrictions:
slouken@8582
    12
slouken@8582
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@8582
    14
     claim that you wrote the original software. If you use this software
slouken@8582
    15
     in a product, an acknowledgment in the product documentation would be
slouken@8582
    16
     appreciated but is not required.
slouken@8582
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@8582
    18
     misrepresented as being the original software.
slouken@8582
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@8582
    20
*/
slouken@8609
    21
#include "../../SDL_internal.h"
slouken@8582
    22
slouken@8582
    23
#if SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL
slouken@8582
    24
slouken@8582
    25
/* EGL implementation of SDL OpenGL support */
slouken@8582
    26
slouken@8582
    27
#include "SDL_winrtvideo_cpp.h"
slouken@8582
    28
extern "C" {
slouken@8582
    29
#include "SDL_winrtopengles.h"
dludwig@8663
    30
#include "SDL_loadso.h"
slouken@8582
    31
}
slouken@8582
    32
dludwig@8663
    33
/* Windows includes */
dludwig@8663
    34
#include <wrl/client.h>
dludwig@8663
    35
using namespace Windows::UI::Core;
dludwig@8663
    36
dludwig@8663
    37
/* ANGLE/WinRT constants */
dludwig@8663
    38
static const int ANGLE_D3D_FEATURE_LEVEL_ANY = 0;
dludwig@9211
    39
#define EGL_PLATFORM_ANGLE_ANGLE                0x3201
dludwig@9211
    40
#define EGL_PLATFORM_ANGLE_TYPE_ANGLE           0x3202
dludwig@9211
    41
#define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE   0x3203
dludwig@9211
    42
#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE     0x3205
dludwig@8663
    43
dludwig@8663
    44
/*
dludwig@8663
    45
 * SDL/EGL top-level implementation
dludwig@8663
    46
 */
slouken@8582
    47
slouken@8582
    48
extern "C" int
dludwig@8663
    49
WINRT_GLES_LoadLibrary(_THIS, const char *path)
dludwig@8663
    50
{
dludwig@8663
    51
    SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata;
dludwig@8663
    52
dludwig@8663
    53
    if (SDL_EGL_LoadLibrary(_this, path, EGL_DEFAULT_DISPLAY) != 0) {
dludwig@8663
    54
        return -1;
dludwig@8663
    55
    }
dludwig@8663
    56
dludwig@8663
    57
    /* Load ANGLE/WinRT-specific functions */
dludwig@9211
    58
    CreateWinrtEglWindow_Old_Function CreateWinrtEglWindow = (CreateWinrtEglWindow_Old_Function) SDL_LoadFunction(_this->egl_data->egl_dll_handle, "CreateWinrtEglWindow");
dludwig@9211
    59
    if (CreateWinrtEglWindow) {
dludwig@9211
    60
        /* 'CreateWinrtEglWindow' was found, which means that an an older
dludwig@9211
    61
         * version of ANGLE/WinRT is being used.  Continue setting up EGL,
dludwig@9211
    62
         * as appropriate to this version of ANGLE.
dludwig@9211
    63
         */
dludwig@9211
    64
dludwig@9211
    65
        /* Create an ANGLE/WinRT EGL-window */
dludwig@9211
    66
        /* TODO, WinRT: check for XAML usage before accessing the CoreWindow, as not doing so could lead to a crash */
dludwig@9211
    67
        CoreWindow ^ native_win = CoreWindow::GetForCurrentThread();
dludwig@9211
    68
        Microsoft::WRL::ComPtr<IUnknown> cpp_win = reinterpret_cast<IUnknown *>(native_win);
dludwig@9211
    69
        HRESULT result = CreateWinrtEglWindow(cpp_win, ANGLE_D3D_FEATURE_LEVEL_ANY, &(video_data->winrtEglWindow));
dludwig@9211
    70
        if (FAILED(result)) {
dludwig@9211
    71
            return -1;
dludwig@9211
    72
        }
dludwig@9211
    73
dludwig@9211
    74
        /* Call eglGetDisplay and eglInitialize as appropriate.  On other
dludwig@9211
    75
         * platforms, this would probably get done by SDL_EGL_LoadLibrary,
dludwig@9211
    76
         * however ANGLE/WinRT's current implementation (as of Mar 22, 2014) of
dludwig@9211
    77
         * eglGetDisplay requires that a C++ object be passed into it, so the
dludwig@9211
    78
         * call will be made in this file, a C++ file, instead.
dludwig@9211
    79
         */
dludwig@9211
    80
        Microsoft::WRL::ComPtr<IUnknown> cpp_display = video_data->winrtEglWindow;
dludwig@9211
    81
        _this->egl_data->egl_display = ((eglGetDisplay_Old_Function)_this->egl_data->eglGetDisplay)(cpp_display);
dludwig@9211
    82
        if (!_this->egl_data->egl_display) {
dludwig@9211
    83
            return SDL_SetError("Could not get EGL display");
dludwig@9211
    84
        }
dludwig@9211
    85
    } else {
dludwig@9211
    86
        const EGLint displayAttributes[] = {
dludwig@9211
    87
            EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
dludwig@9211
    88
            EGL_NONE,
dludwig@9211
    89
        };
dludwig@9211
    90
dludwig@9211
    91
        /* 'CreateWinrtEglWindow' was NOT found, which either means that a
dludwig@9211
    92
         * newer version of ANGLE/WinRT is being used, or that we don't have
dludwig@9211
    93
         * a valid copy of ANGLE.
dludwig@9211
    94
         *
dludwig@9211
    95
         * Try loading ANGLE as if it were the newer version.
dludwig@9211
    96
         */
dludwig@9211
    97
        eglGetPlatformDisplayEXT_Function eglGetPlatformDisplayEXT = (eglGetPlatformDisplayEXT_Function)_this->egl_data->eglGetProcAddress("eglGetPlatformDisplayEXT");
dludwig@9211
    98
        if (!eglGetPlatformDisplayEXT) {
dludwig@9211
    99
            return SDL_SetError("Could not retrieve ANGLE/WinRT display function(s)");
dludwig@9211
   100
        }
dludwig@9211
   101
dludwig@9211
   102
        _this->egl_data->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, displayAttributes);
dludwig@9211
   103
        if (!_this->egl_data->egl_display) {
dludwig@9211
   104
            return SDL_SetError("Could not get EGL display");
dludwig@9211
   105
        }
dludwig@8663
   106
    }
dludwig@8663
   107
dludwig@8663
   108
    if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
dludwig@8663
   109
        return SDL_SetError("Could not initialize EGL");
dludwig@8663
   110
    }
dludwig@8663
   111
dludwig@8663
   112
    return 0;
dludwig@8663
   113
}
dludwig@8663
   114
dludwig@8663
   115
extern "C" void
dludwig@8663
   116
WINRT_GLES_UnloadLibrary(_THIS)
dludwig@8663
   117
{
dludwig@8663
   118
    SDL_VideoData *video_data = (SDL_VideoData *)_this->driverdata;
dludwig@8663
   119
dludwig@8663
   120
    /* Release SDL's own COM reference to the ANGLE/WinRT IWinrtEglWindow */
dludwig@8663
   121
    if (video_data->winrtEglWindow) {
dludwig@8663
   122
        video_data->winrtEglWindow->Release();
dludwig@8663
   123
        video_data->winrtEglWindow = nullptr;
dludwig@8663
   124
    }
dludwig@8663
   125
dludwig@8663
   126
    /* Perform the bulk of the unloading */
dludwig@8663
   127
    SDL_EGL_UnloadLibrary(_this);
slouken@8582
   128
}
slouken@8582
   129
slouken@8582
   130
extern "C" {
slouken@8582
   131
SDL_EGL_CreateContext_impl(WINRT)
slouken@8582
   132
SDL_EGL_SwapWindow_impl(WINRT)
slouken@8582
   133
SDL_EGL_MakeCurrent_impl(WINRT)
slouken@8582
   134
}
slouken@8582
   135
slouken@8582
   136
#endif /* SDL_VIDEO_DRIVER_WINRT && SDL_VIDEO_OPENGL_EGL */
slouken@8582
   137
slouken@8582
   138
/* vi: set ts=4 sw=4 expandtab: */
slouken@8582
   139