summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/SDL2/src/video/windows/SDL_windowsopengl.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/SDL2/src/video/windows/SDL_windowsopengl.c')
-rw-r--r--3rdparty/SDL2/src/video/windows/SDL_windowsopengl.c810
1 files changed, 810 insertions, 0 deletions
diff --git a/3rdparty/SDL2/src/video/windows/SDL_windowsopengl.c b/3rdparty/SDL2/src/video/windows/SDL_windowsopengl.c
new file mode 100644
index 00000000000..d30d838fdcc
--- /dev/null
+++ b/3rdparty/SDL2/src/video/windows/SDL_windowsopengl.c
@@ -0,0 +1,810 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_WINDOWS
+
+#include "SDL_assert.h"
+#include "SDL_loadso.h"
+#include "SDL_windowsvideo.h"
+#include "SDL_windowsopengles.h"
+
+/* WGL implementation of SDL OpenGL support */
+
+#if SDL_VIDEO_OPENGL_WGL
+#include "SDL_opengl.h"
+
+#define DEFAULT_OPENGL "OPENGL32.DLL"
+
+#ifndef WGL_ARB_create_context
+#define WGL_ARB_create_context
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#endif
+
+#ifndef WGL_ARB_create_context_robustness
+#define WGL_ARB_create_context_robustness
+#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
+#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
+#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
+#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
+#endif
+#endif
+
+#ifndef WGL_EXT_create_context_es2_profile
+#define WGL_EXT_create_context_es2_profile
+#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_EXT_create_context_es_profile
+#define WGL_EXT_create_context_es_profile
+#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
+#endif
+
+#ifndef WGL_ARB_framebuffer_sRGB
+#define WGL_ARB_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+#endif
+
+#ifndef WGL_ARB_context_flush_control
+#define WGL_ARB_context_flush_control
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000
+#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
+#endif
+
+typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
+ HGLRC
+ hShareContext,
+ const int
+ *attribList);
+
+int
+WIN_GL_LoadLibrary(_THIS, const char *path)
+{
+ void *handle;
+
+ if (path == NULL) {
+ path = SDL_getenv("SDL_OPENGL_LIBRARY");
+ }
+ if (path == NULL) {
+ path = DEFAULT_OPENGL;
+ }
+ _this->gl_config.dll_handle = SDL_LoadObject(path);
+ if (!_this->gl_config.dll_handle) {
+ return -1;
+ }
+ SDL_strlcpy(_this->gl_config.driver_path, path,
+ SDL_arraysize(_this->gl_config.driver_path));
+
+ /* Allocate OpenGL memory */
+ _this->gl_data = (struct SDL_GLDriverData *) SDL_calloc(1, sizeof(struct SDL_GLDriverData));
+ if (!_this->gl_data) {
+ return SDL_OutOfMemory();
+ }
+
+ /* Load function pointers */
+ handle = _this->gl_config.dll_handle;
+ _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
+ SDL_LoadFunction(handle, "wglGetProcAddress");
+ _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
+ SDL_LoadFunction(handle, "wglCreateContext");
+ _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
+ SDL_LoadFunction(handle, "wglDeleteContext");
+ _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
+ SDL_LoadFunction(handle, "wglMakeCurrent");
+ _this->gl_data->wglShareLists = (BOOL(WINAPI *) (HGLRC, HGLRC))
+ SDL_LoadFunction(handle, "wglShareLists");
+
+ if (!_this->gl_data->wglGetProcAddress ||
+ !_this->gl_data->wglCreateContext ||
+ !_this->gl_data->wglDeleteContext ||
+ !_this->gl_data->wglMakeCurrent) {
+ return SDL_SetError("Could not retrieve OpenGL functions");
+ }
+
+ return 0;
+}
+
+void *
+WIN_GL_GetProcAddress(_THIS, const char *proc)
+{
+ void *func;
+
+ /* This is to pick up extensions */
+ func = _this->gl_data->wglGetProcAddress(proc);
+ if (!func) {
+ /* This is probably a normal GL function */
+ func = GetProcAddress(_this->gl_config.dll_handle, proc);
+ }
+ return func;
+}
+
+void
+WIN_GL_UnloadLibrary(_THIS)
+{
+ SDL_UnloadObject(_this->gl_config.dll_handle);
+ _this->gl_config.dll_handle = NULL;
+
+ /* Free OpenGL memory */
+ SDL_free(_this->gl_data);
+ _this->gl_data = NULL;
+}
+
+static void
+WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
+{
+ SDL_zerop(pfd);
+ pfd->nSize = sizeof(*pfd);
+ pfd->nVersion = 1;
+ pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
+ if (_this->gl_config.double_buffer) {
+ pfd->dwFlags |= PFD_DOUBLEBUFFER;
+ }
+ if (_this->gl_config.stereo) {
+ pfd->dwFlags |= PFD_STEREO;
+ }
+ pfd->iLayerType = PFD_MAIN_PLANE;
+ pfd->iPixelType = PFD_TYPE_RGBA;
+ pfd->cRedBits = _this->gl_config.red_size;
+ pfd->cGreenBits = _this->gl_config.green_size;
+ pfd->cBlueBits = _this->gl_config.blue_size;
+ pfd->cAlphaBits = _this->gl_config.alpha_size;
+ if (_this->gl_config.buffer_size) {
+ pfd->cColorBits =
+ _this->gl_config.buffer_size - _this->gl_config.alpha_size;
+ } else {
+ pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
+ }
+ pfd->cAccumRedBits = _this->gl_config.accum_red_size;
+ pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
+ pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
+ pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
+ pfd->cAccumBits =
+ (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
+ pfd->cAccumAlphaBits);
+ pfd->cDepthBits = _this->gl_config.depth_size;
+ pfd->cStencilBits = _this->gl_config.stencil_size;
+}
+
+/* Choose the closest pixel format that meets or exceeds the target.
+ FIXME: Should we weight any particular attribute over any other?
+*/
+static int
+WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ int count, index, best = 0;
+ unsigned int dist, best_dist = ~0U;
+
+ count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
+
+ for (index = 1; index <= count; index++) {
+
+ if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
+ continue;
+ }
+
+ if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
+ continue;
+ }
+
+ if (pfd.iLayerType != target->iLayerType) {
+ continue;
+ }
+ if (pfd.iPixelType != target->iPixelType) {
+ continue;
+ }
+
+ dist = 0;
+
+ if (pfd.cColorBits < target->cColorBits) {
+ continue;
+ } else {
+ dist += (pfd.cColorBits - target->cColorBits);
+ }
+ if (pfd.cRedBits < target->cRedBits) {
+ continue;
+ } else {
+ dist += (pfd.cRedBits - target->cRedBits);
+ }
+ if (pfd.cGreenBits < target->cGreenBits) {
+ continue;
+ } else {
+ dist += (pfd.cGreenBits - target->cGreenBits);
+ }
+ if (pfd.cBlueBits < target->cBlueBits) {
+ continue;
+ } else {
+ dist += (pfd.cBlueBits - target->cBlueBits);
+ }
+ if (pfd.cAlphaBits < target->cAlphaBits) {
+ continue;
+ } else {
+ dist += (pfd.cAlphaBits - target->cAlphaBits);
+ }
+ if (pfd.cAccumBits < target->cAccumBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumBits - target->cAccumBits);
+ }
+ if (pfd.cAccumRedBits < target->cAccumRedBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumRedBits - target->cAccumRedBits);
+ }
+ if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
+ }
+ if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
+ }
+ if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
+ continue;
+ } else {
+ dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
+ }
+ if (pfd.cDepthBits < target->cDepthBits) {
+ continue;
+ } else {
+ dist += (pfd.cDepthBits - target->cDepthBits);
+ }
+ if (pfd.cStencilBits < target->cStencilBits) {
+ continue;
+ } else {
+ dist += (pfd.cStencilBits - target->cStencilBits);
+ }
+
+ if (dist < best_dist) {
+ best = index;
+ best_dist = dist;
+ }
+ }
+
+ return best;
+}
+
+static SDL_bool
+HasExtension(const char *extension, const char *extensions)
+{
+ const char *start;
+ const char *where, *terminator;
+
+ /* Extension names should not have spaces. */
+ where = SDL_strchr(extension, ' ');
+ if (where || *extension == '\0')
+ return SDL_FALSE;
+
+ if (!extensions)
+ return SDL_FALSE;
+
+ /* It takes a bit of care to be fool-proof about parsing the
+ * OpenGL extensions string. Don't be fooled by sub-strings,
+ * etc. */
+
+ start = extensions;
+
+ for (;;) {
+ where = SDL_strstr(start, extension);
+ if (!where)
+ break;
+
+ terminator = where + SDL_strlen(extension);
+ if (where == start || *(where - 1) == ' ')
+ if (*terminator == ' ' || *terminator == '\0')
+ return SDL_TRUE;
+
+ start = terminator;
+ }
+ return SDL_FALSE;
+}
+
+void
+WIN_GL_InitExtensions(_THIS)
+{
+ const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
+ const char *extensions;
+ HWND hwnd;
+ HDC hdc;
+ HGLRC hglrc;
+ PIXELFORMATDESCRIPTOR pfd;
+
+ if (!_this->gl_data) {
+ return;
+ }
+
+ hwnd =
+ CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
+ 10, 10, NULL, NULL, SDL_Instance, NULL);
+ if (!hwnd) {
+ return;
+ }
+ WIN_PumpEvents(_this);
+
+ hdc = GetDC(hwnd);
+
+ WIN_GL_SetupPixelFormat(_this, &pfd);
+
+ SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
+
+ hglrc = _this->gl_data->wglCreateContext(hdc);
+ if (!hglrc) {
+ return;
+ }
+ _this->gl_data->wglMakeCurrent(hdc, hglrc);
+
+ wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
+ _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
+ if (wglGetExtensionsStringARB) {
+ extensions = wglGetExtensionsStringARB(hdc);
+ } else {
+ extensions = NULL;
+ }
+
+ /* Check for WGL_ARB_pixel_format */
+ _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
+ if (HasExtension("WGL_ARB_pixel_format", extensions)) {
+ _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
+ (HDC, const int *,
+ const FLOAT *, UINT,
+ int *, UINT *))
+ WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
+ _this->gl_data->wglGetPixelFormatAttribivARB =
+ (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
+ WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
+
+ if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
+ (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
+ _this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
+ }
+ }
+
+ /* Check for WGL_EXT_swap_control */
+ _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
+ if (HasExtension("WGL_EXT_swap_control", extensions)) {
+ _this->gl_data->wglSwapIntervalEXT =
+ WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
+ _this->gl_data->wglGetSwapIntervalEXT =
+ WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
+ if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
+ _this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
+ }
+ } else {
+ _this->gl_data->wglSwapIntervalEXT = NULL;
+ _this->gl_data->wglGetSwapIntervalEXT = NULL;
+ }
+
+ /* Check for WGL_EXT_create_context_es2_profile */
+ _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_FALSE;
+ if (HasExtension("WGL_EXT_create_context_es2_profile", extensions)) {
+ _this->gl_data->HAS_WGL_EXT_create_context_es2_profile = SDL_TRUE;
+ }
+
+ /* Check for GLX_ARB_context_flush_control */
+ if (HasExtension("WGL_ARB_context_flush_control", extensions)) {
+ _this->gl_data->HAS_WGL_ARB_context_flush_control = SDL_TRUE;
+ }
+
+ _this->gl_data->wglMakeCurrent(hdc, NULL);
+ _this->gl_data->wglDeleteContext(hglrc);
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ WIN_PumpEvents(_this);
+}
+
+static int
+WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
+{
+ HWND hwnd;
+ HDC hdc;
+ PIXELFORMATDESCRIPTOR pfd;
+ HGLRC hglrc;
+ int pixel_format = 0;
+ unsigned int matching;
+
+ hwnd =
+ CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
+ 10, 10, NULL, NULL, SDL_Instance, NULL);
+ WIN_PumpEvents(_this);
+
+ hdc = GetDC(hwnd);
+
+ WIN_GL_SetupPixelFormat(_this, &pfd);
+
+ SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
+
+ hglrc = _this->gl_data->wglCreateContext(hdc);
+ if (hglrc) {
+ _this->gl_data->wglMakeCurrent(hdc, hglrc);
+
+ if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
+ _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
+ 1, &pixel_format,
+ &matching);
+ }
+
+ _this->gl_data->wglMakeCurrent(hdc, NULL);
+ _this->gl_data->wglDeleteContext(hglrc);
+ }
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+ WIN_PumpEvents(_this);
+
+ return pixel_format;
+}
+
+/* actual work of WIN_GL_SetupWindow() happens here. */
+static int
+WIN_GL_SetupWindowInternal(_THIS, SDL_Window * window)
+{
+ HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+ PIXELFORMATDESCRIPTOR pfd;
+ int pixel_format = 0;
+ int iAttribs[64];
+ int *iAttr;
+ int *iAccelAttr;
+ float fAttribs[1] = { 0 };
+
+ WIN_GL_SetupPixelFormat(_this, &pfd);
+
+ /* setup WGL_ARB_pixel_format attribs */
+ iAttr = &iAttribs[0];
+
+ *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
+ *iAttr++ = GL_TRUE;
+ *iAttr++ = WGL_RED_BITS_ARB;
+ *iAttr++ = _this->gl_config.red_size;
+ *iAttr++ = WGL_GREEN_BITS_ARB;
+ *iAttr++ = _this->gl_config.green_size;
+ *iAttr++ = WGL_BLUE_BITS_ARB;
+ *iAttr++ = _this->gl_config.blue_size;
+
+ if (_this->gl_config.alpha_size) {
+ *iAttr++ = WGL_ALPHA_BITS_ARB;
+ *iAttr++ = _this->gl_config.alpha_size;
+ }
+
+ *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
+ *iAttr++ = _this->gl_config.double_buffer;
+
+ *iAttr++ = WGL_DEPTH_BITS_ARB;
+ *iAttr++ = _this->gl_config.depth_size;
+
+ if (_this->gl_config.stencil_size) {
+ *iAttr++ = WGL_STENCIL_BITS_ARB;
+ *iAttr++ = _this->gl_config.stencil_size;
+ }
+
+ if (_this->gl_config.accum_red_size) {
+ *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_red_size;
+ }
+
+ if (_this->gl_config.accum_green_size) {
+ *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_green_size;
+ }
+
+ if (_this->gl_config.accum_blue_size) {
+ *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_blue_size;
+ }
+
+ if (_this->gl_config.accum_alpha_size) {
+ *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
+ *iAttr++ = _this->gl_config.accum_alpha_size;
+ }
+
+ if (_this->gl_config.stereo) {
+ *iAttr++ = WGL_STEREO_ARB;
+ *iAttr++ = GL_TRUE;
+ }
+
+ if (_this->gl_config.multisamplebuffers) {
+ *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
+ *iAttr++ = _this->gl_config.multisamplebuffers;
+ }
+
+ if (_this->gl_config.multisamplesamples) {
+ *iAttr++ = WGL_SAMPLES_ARB;
+ *iAttr++ = _this->gl_config.multisamplesamples;
+ }
+
+ if (_this->gl_config.framebuffer_srgb_capable) {
+ *iAttr++ = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
+ *iAttr++ = _this->gl_config.framebuffer_srgb_capable;
+ }
+
+ /* We always choose either FULL or NO accel on Windows, because of flaky
+ drivers. If the app didn't specify, we use FULL, because that's
+ probably what they wanted (and if you didn't care and got FULL, that's
+ a perfectly valid result in any case). */
+ *iAttr++ = WGL_ACCELERATION_ARB;
+ iAccelAttr = iAttr;
+ if (_this->gl_config.accelerated) {
+ *iAttr++ = WGL_FULL_ACCELERATION_ARB;
+ } else {
+ *iAttr++ = WGL_NO_ACCELERATION_ARB;
+ }
+
+ *iAttr = 0;
+
+ /* Choose and set the closest available pixel format */
+ pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
+
+ /* App said "don't care about accel" and FULL accel failed. Try NO. */
+ if ( ( !pixel_format ) && ( _this->gl_config.accelerated < 0 ) ) {
+ *iAccelAttr = WGL_NO_ACCELERATION_ARB;
+ pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
+ *iAccelAttr = WGL_FULL_ACCELERATION_ARB; /* if we try again. */
+ }
+ if (!pixel_format) {
+ pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
+ }
+ if (!pixel_format) {
+ return SDL_SetError("No matching GL pixel format available");
+ }
+ if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
+ return WIN_SetError("SetPixelFormat()");
+ }
+ return 0;
+}
+
+int
+WIN_GL_SetupWindow(_THIS, SDL_Window * window)
+{
+ /* The current context is lost in here; save it and reset it. */
+ SDL_Window *current_win = SDL_GL_GetCurrentWindow();
+ SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();
+ const int retval = WIN_GL_SetupWindowInternal(_this, window);
+ WIN_GL_MakeCurrent(_this, current_win, current_ctx);
+ return retval;
+}
+
+SDL_GLContext
+WIN_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+ HGLRC context, share_context;
+
+ if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES &&
+ !_this->gl_data->HAS_WGL_EXT_create_context_es2_profile) {
+#if SDL_VIDEO_OPENGL_EGL
+ /* Switch to EGL based functions */
+ WIN_GL_UnloadLibrary(_this);
+ _this->GL_LoadLibrary = WIN_GLES_LoadLibrary;
+ _this->GL_GetProcAddress = WIN_GLES_GetProcAddress;
+ _this->GL_UnloadLibrary = WIN_GLES_UnloadLibrary;
+ _this->GL_CreateContext = WIN_GLES_CreateContext;
+ _this->GL_MakeCurrent = WIN_GLES_MakeCurrent;
+ _this->GL_SetSwapInterval = WIN_GLES_SetSwapInterval;
+ _this->GL_GetSwapInterval = WIN_GLES_GetSwapInterval;
+ _this->GL_SwapWindow = WIN_GLES_SwapWindow;
+ _this->GL_DeleteContext = WIN_GLES_DeleteContext;
+
+ if (WIN_GLES_LoadLibrary(_this, NULL) != 0) {
+ return NULL;
+ }
+
+ return WIN_GLES_CreateContext(_this, window);
+#else
+ SDL_SetError("SDL not configured with EGL support");
+ return NULL;
+#endif
+ }
+
+ if (_this->gl_config.share_with_current_context) {
+ share_context = (HGLRC)SDL_GL_GetCurrentContext();
+ } else {
+ share_context = 0;
+ }
+
+ if (_this->gl_config.major_version < 3 &&
+ _this->gl_config.profile_mask == 0 &&
+ _this->gl_config.flags == 0) {
+ /* Create legacy context */
+ context = _this->gl_data->wglCreateContext(hdc);
+ if( share_context != 0 ) {
+ _this->gl_data->wglShareLists(share_context, context);
+ }
+ } else {
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
+ HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
+ if (!temp_context) {
+ SDL_SetError("Could not create GL context");
+ return NULL;
+ }
+
+ /* Make the context current */
+ if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
+ WIN_GL_DeleteContext(_this, temp_context);
+ return NULL;
+ }
+
+ wglCreateContextAttribsARB =
+ (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
+ wglGetProcAddress("wglCreateContextAttribsARB");
+ if (!wglCreateContextAttribsARB) {
+ SDL_SetError("GL 3.x is not supported");
+ context = temp_context;
+ } else {
+ /* max 10 attributes plus terminator */
+ int attribs[11] = {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
+ WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
+ 0
+ };
+ int iattr = 4;
+
+ /* SDL profile bits match WGL profile bits */
+ if (_this->gl_config.profile_mask != 0) {
+ attribs[iattr++] = WGL_CONTEXT_PROFILE_MASK_ARB;
+ attribs[iattr++] = _this->gl_config.profile_mask;
+ }
+
+ /* SDL flags match WGL flags */
+ if (_this->gl_config.flags != 0) {
+ attribs[iattr++] = WGL_CONTEXT_FLAGS_ARB;
+ attribs[iattr++] = _this->gl_config.flags;
+ }
+
+ /* only set if wgl extension is available */
+ if (_this->gl_data->HAS_WGL_ARB_context_flush_control) {
+ attribs[iattr++] = WGL_CONTEXT_RELEASE_BEHAVIOR_ARB;
+ attribs[iattr++] = _this->gl_config.release_behavior ?
+ WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB :
+ WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB;
+ }
+
+ attribs[iattr++] = 0;
+
+ /* Create the GL 3.x context */
+ context = wglCreateContextAttribsARB(hdc, share_context, attribs);
+ /* Delete the GL 2.x context */
+ _this->gl_data->wglDeleteContext(temp_context);
+ }
+ }
+
+ if (!context) {
+ WIN_SetError("Could not create GL context");
+ return NULL;
+ }
+
+ if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
+ WIN_GL_DeleteContext(_this, context);
+ return NULL;
+ }
+
+ return context;
+}
+
+int
+WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ HDC hdc;
+
+ if (!_this->gl_data) {
+ return SDL_SetError("OpenGL not initialized");
+ }
+
+ /* sanity check that higher level handled this. */
+ SDL_assert(window || (!window && !context));
+
+ /* Some Windows drivers freak out if hdc is NULL, even when context is
+ NULL, against spec. Since hdc is _supposed_ to be ignored if context
+ is NULL, we either use the current GL window, or do nothing if we
+ already have no current context. */
+ if (!window) {
+ window = SDL_GL_GetCurrentWindow();
+ if (!window) {
+ SDL_assert(SDL_GL_GetCurrentContext() == NULL);
+ return 0; /* already done. */
+ }
+ }
+
+ hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+ if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
+ return WIN_SetError("wglMakeCurrent()");
+ }
+ return 0;
+}
+
+int
+WIN_GL_SetSwapInterval(_THIS, int interval)
+{
+ if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
+ return SDL_SetError("Negative swap interval unsupported in this GL");
+ } else if (_this->gl_data->wglSwapIntervalEXT) {
+ if (_this->gl_data->wglSwapIntervalEXT(interval) != TRUE) {
+ return WIN_SetError("wglSwapIntervalEXT()");
+ }
+ } else {
+ return SDL_Unsupported();
+ }
+ return 0;
+}
+
+int
+WIN_GL_GetSwapInterval(_THIS)
+{
+ int retval = 0;
+ if (_this->gl_data->wglGetSwapIntervalEXT) {
+ retval = _this->gl_data->wglGetSwapIntervalEXT();
+ }
+ return retval;
+}
+
+void
+WIN_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
+
+ SwapBuffers(hdc);
+}
+
+void
+WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ if (!_this->gl_data) {
+ return;
+ }
+ _this->gl_data->wglDeleteContext((HGLRC) context);
+}
+
+
+SDL_bool
+WIN_GL_SetPixelFormatFrom(_THIS, SDL_Window * fromWindow, SDL_Window * toWindow)
+{
+ HDC hfromdc = ((SDL_WindowData *) fromWindow->driverdata)->hdc;
+ HDC htodc = ((SDL_WindowData *) toWindow->driverdata)->hdc;
+ BOOL result;
+
+ /* get the pixel format of the fromWindow */
+ int pixel_format = GetPixelFormat(hfromdc);
+ PIXELFORMATDESCRIPTOR pfd;
+ SDL_memset(&pfd, 0, sizeof(pfd));
+ DescribePixelFormat(hfromdc, pixel_format, sizeof(pfd), &pfd);
+
+ /* set the pixel format of the toWindow */
+ result = SetPixelFormat(htodc, pixel_format, &pfd);
+
+ return result ? SDL_TRUE : SDL_FALSE;
+}
+
+#endif /* SDL_VIDEO_OPENGL_WGL */
+
+#endif /* SDL_VIDEO_DRIVER_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */