src/video/windows/SDL_windowsopengl.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 07 Mar 2011 14:06:46 -0800
changeset 5446 6ac8b0ac645e
parent 5262 b530ef003506
child 5535 96594ac5fd1a
permissions -rw-r--r--
Fixed bug 1161 (Setting GL_ACCELERATED_VISUAL to 1 forces software rendering in Windows XP)

Jesse Anders 2011-03-05 23:30:09 PST

It seems that in Windows XP, setting SDL_GL_ACCELERATED_VISUAL to 1 actually
disables hardware acceleration and puts OpenGL in software mode.

In the source code, the corresponding WGL attribute is first set here:

*iAttr++ = WGL_ACCELERATION_ARB;
*iAttr++ = WGL_FULL_ACCELERATION_ARB;

Later, this code:

if (_this->gl_config.accelerated >= 0) {
*iAttr++ = WGL_ACCELERATION_ARB;
*iAttr++ =
(_this->gl_config.accelerated ? WGL_GENERIC_ACCELERATION_ARB :
WGL_NO_ACCELERATION_ARB);
}

Sets it again if SDL_GL_ACCELERATED_VISUAL has a value other than the default.

More importantly, the documentation I found states that
WGL_GENERIC_ACCELERATION_ARB asks for an MDC driver, which, although I don't
know much about this topic, doesn't seem like the correct choice here. As
mentioned previously, the end effect is that requesting hardware acceleration
in Windows XP actually forces the renderer into software mode (on my system at
least), which I'm guessing isn't the desired behavior.
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2011 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 #include "SDL_config.h"
    23 
    24 #include "SDL_windowsvideo.h"
    25 
    26 /* WGL implementation of SDL OpenGL support */
    27 
    28 #if SDL_VIDEO_OPENGL_WGL
    29 #include "SDL_opengl.h"
    30 
    31 #define DEFAULT_OPENGL "OPENGL32.DLL"
    32 
    33 #ifndef WGL_ARB_create_context
    34 #define WGL_ARB_create_context
    35 #define WGL_CONTEXT_MAJOR_VERSION_ARB   0x2091
    36 #define WGL_CONTEXT_MINOR_VERSION_ARB   0x2092
    37 #define WGL_CONTEXT_LAYER_PLANE_ARB     0x2093
    38 #define WGL_CONTEXT_FLAGS_ARB           0x2093
    39 #define WGL_CONTEXT_DEBUG_BIT_ARB       0x0001
    40 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB  0x0002
    41 #endif
    42 
    43 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC,
    44                                                             HGLRC
    45                                                             hShareContext,
    46                                                             const int
    47                                                             *attribList);
    48 
    49 int
    50 WIN_GL_LoadLibrary(_THIS, const char *path)
    51 {
    52     LPTSTR wpath;
    53     HANDLE handle;
    54 
    55     if (path == NULL) {
    56         path = SDL_getenv("SDL_OPENGL_LIBRARY");
    57     }
    58     if (path == NULL) {
    59         path = DEFAULT_OPENGL;
    60     }
    61     wpath = WIN_UTF8ToString(path);
    62     _this->gl_config.dll_handle = LoadLibrary(wpath);
    63     SDL_free(wpath);
    64     if (!_this->gl_config.dll_handle) {
    65         char message[1024];
    66         SDL_snprintf(message, SDL_arraysize(message), "LoadLibrary(\"%s\")",
    67                      path);
    68         WIN_SetError(message);
    69         return -1;
    70     }
    71     SDL_strlcpy(_this->gl_config.driver_path, path,
    72                 SDL_arraysize(_this->gl_config.driver_path));
    73 
    74     /* Allocate OpenGL memory */
    75     _this->gl_data =
    76         (struct SDL_GLDriverData *) SDL_calloc(1,
    77                                                sizeof(struct
    78                                                       SDL_GLDriverData));
    79     if (!_this->gl_data) {
    80         SDL_OutOfMemory();
    81         return -1;
    82     }
    83 
    84     /* Load function pointers */
    85     handle = _this->gl_config.dll_handle;
    86     _this->gl_data->wglGetProcAddress = (void *(WINAPI *) (const char *))
    87         GetProcAddress(handle, "wglGetProcAddress");
    88     _this->gl_data->wglCreateContext = (HGLRC(WINAPI *) (HDC))
    89         GetProcAddress(handle, "wglCreateContext");
    90     _this->gl_data->wglDeleteContext = (BOOL(WINAPI *) (HGLRC))
    91         GetProcAddress(handle, "wglDeleteContext");
    92     _this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
    93         GetProcAddress(handle, "wglMakeCurrent");
    94     _this->gl_data->wglSwapIntervalEXT = (void (WINAPI *) (int))
    95         GetProcAddress(handle, "wglSwapIntervalEXT");
    96     _this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *) (void))
    97         GetProcAddress(handle, "wglGetSwapIntervalEXT");
    98 
    99     if (!_this->gl_data->wglGetProcAddress ||
   100         !_this->gl_data->wglCreateContext ||
   101         !_this->gl_data->wglDeleteContext ||
   102         !_this->gl_data->wglMakeCurrent) {
   103         SDL_SetError("Could not retrieve OpenGL functions");
   104         SDL_UnloadObject(handle);
   105         return -1;
   106     }
   107 
   108     return 0;
   109 }
   110 
   111 void *
   112 WIN_GL_GetProcAddress(_THIS, const char *proc)
   113 {
   114     void *func;
   115 
   116     /* This is to pick up extensions */
   117     func = _this->gl_data->wglGetProcAddress(proc);
   118     if (!func) {
   119         /* This is probably a normal GL function */
   120         func = GetProcAddress(_this->gl_config.dll_handle, proc);
   121     }
   122     return func;
   123 }
   124 
   125 void
   126 WIN_GL_UnloadLibrary(_THIS)
   127 {
   128     FreeLibrary((HMODULE) _this->gl_config.dll_handle);
   129     _this->gl_config.dll_handle = NULL;
   130 
   131     /* Free OpenGL memory */
   132     SDL_free(_this->gl_data);
   133     _this->gl_data = NULL;
   134 }
   135 
   136 static void
   137 WIN_GL_SetupPixelFormat(_THIS, PIXELFORMATDESCRIPTOR * pfd)
   138 {
   139     SDL_zerop(pfd);
   140     pfd->nSize = sizeof(*pfd);
   141     pfd->nVersion = 1;
   142     pfd->dwFlags = (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL);
   143     if (_this->gl_config.double_buffer) {
   144         pfd->dwFlags |= PFD_DOUBLEBUFFER;
   145     }
   146     if (_this->gl_config.stereo) {
   147         pfd->dwFlags |= PFD_STEREO;
   148     }
   149     pfd->iLayerType = PFD_MAIN_PLANE;
   150     pfd->iPixelType = PFD_TYPE_RGBA;
   151     pfd->cRedBits = _this->gl_config.red_size;
   152     pfd->cGreenBits = _this->gl_config.green_size;
   153     pfd->cBlueBits = _this->gl_config.blue_size;
   154     pfd->cAlphaBits = _this->gl_config.alpha_size;
   155     if (_this->gl_config.buffer_size) {
   156         pfd->cColorBits =
   157             _this->gl_config.buffer_size - _this->gl_config.alpha_size;
   158     } else {
   159         pfd->cColorBits = (pfd->cRedBits + pfd->cGreenBits + pfd->cBlueBits);
   160     }
   161     pfd->cAccumRedBits = _this->gl_config.accum_red_size;
   162     pfd->cAccumGreenBits = _this->gl_config.accum_green_size;
   163     pfd->cAccumBlueBits = _this->gl_config.accum_blue_size;
   164     pfd->cAccumAlphaBits = _this->gl_config.accum_alpha_size;
   165     pfd->cAccumBits =
   166         (pfd->cAccumRedBits + pfd->cAccumGreenBits + pfd->cAccumBlueBits +
   167          pfd->cAccumAlphaBits);
   168     pfd->cDepthBits = _this->gl_config.depth_size;
   169     pfd->cStencilBits = _this->gl_config.stencil_size;
   170 }
   171 
   172 /* Choose the closest pixel format that meets or exceeds the target.
   173    FIXME: Should we weight any particular attribute over any other?
   174 */
   175 static int
   176 WIN_GL_ChoosePixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR * target)
   177 {
   178     PIXELFORMATDESCRIPTOR pfd;
   179     int count, index, best = 0;
   180     unsigned int dist, best_dist = ~0U;
   181 
   182     count = DescribePixelFormat(hdc, 1, sizeof(pfd), NULL);
   183 
   184     for (index = 1; index <= count; index++) {
   185 
   186         if (!DescribePixelFormat(hdc, index, sizeof(pfd), &pfd)) {
   187             continue;
   188         }
   189 
   190         if ((pfd.dwFlags & target->dwFlags) != target->dwFlags) {
   191             continue;
   192         }
   193 
   194         if (pfd.iLayerType != target->iLayerType) {
   195             continue;
   196         }
   197         if (pfd.iPixelType != target->iPixelType) {
   198             continue;
   199         }
   200 
   201         dist = 0;
   202 
   203         if (pfd.cColorBits < target->cColorBits) {
   204             continue;
   205         } else {
   206             dist += (pfd.cColorBits - target->cColorBits);
   207         }
   208         if (pfd.cRedBits < target->cRedBits) {
   209             continue;
   210         } else {
   211             dist += (pfd.cRedBits - target->cRedBits);
   212         }
   213         if (pfd.cGreenBits < target->cGreenBits) {
   214             continue;
   215         } else {
   216             dist += (pfd.cGreenBits - target->cGreenBits);
   217         }
   218         if (pfd.cBlueBits < target->cBlueBits) {
   219             continue;
   220         } else {
   221             dist += (pfd.cBlueBits - target->cBlueBits);
   222         }
   223         if (pfd.cAlphaBits < target->cAlphaBits) {
   224             continue;
   225         } else {
   226             dist += (pfd.cAlphaBits - target->cAlphaBits);
   227         }
   228         if (pfd.cAccumBits < target->cAccumBits) {
   229             continue;
   230         } else {
   231             dist += (pfd.cAccumBits - target->cAccumBits);
   232         }
   233         if (pfd.cAccumRedBits < target->cAccumRedBits) {
   234             continue;
   235         } else {
   236             dist += (pfd.cAccumRedBits - target->cAccumRedBits);
   237         }
   238         if (pfd.cAccumGreenBits < target->cAccumGreenBits) {
   239             continue;
   240         } else {
   241             dist += (pfd.cAccumGreenBits - target->cAccumGreenBits);
   242         }
   243         if (pfd.cAccumBlueBits < target->cAccumBlueBits) {
   244             continue;
   245         } else {
   246             dist += (pfd.cAccumBlueBits - target->cAccumBlueBits);
   247         }
   248         if (pfd.cAccumAlphaBits < target->cAccumAlphaBits) {
   249             continue;
   250         } else {
   251             dist += (pfd.cAccumAlphaBits - target->cAccumAlphaBits);
   252         }
   253         if (pfd.cDepthBits < target->cDepthBits) {
   254             continue;
   255         } else {
   256             dist += (pfd.cDepthBits - target->cDepthBits);
   257         }
   258         if (pfd.cStencilBits < target->cStencilBits) {
   259             continue;
   260         } else {
   261             dist += (pfd.cStencilBits - target->cStencilBits);
   262         }
   263 
   264         if (dist < best_dist) {
   265             best = index;
   266             best_dist = dist;
   267         }
   268     }
   269 
   270     return best;
   271 }
   272 
   273 static SDL_bool
   274 HasExtension(const char *extension, const char *extensions)
   275 {
   276     const char *start;
   277     const char *where, *terminator;
   278 
   279     /* Extension names should not have spaces. */
   280     where = SDL_strchr(extension, ' ');
   281     if (where || *extension == '\0')
   282         return SDL_FALSE;
   283 
   284     if (!extensions)
   285         return SDL_FALSE;
   286 
   287     /* It takes a bit of care to be fool-proof about parsing the
   288      * OpenGL extensions string. Don't be fooled by sub-strings,
   289      * etc. */
   290 
   291     start = extensions;
   292 
   293     for (;;) {
   294         where = SDL_strstr(start, extension);
   295         if (!where)
   296             break;
   297 
   298         terminator = where + SDL_strlen(extension);
   299         if (where == start || *(where - 1) == ' ')
   300             if (*terminator == ' ' || *terminator == '\0')
   301                 return SDL_TRUE;
   302 
   303         start = terminator;
   304     }
   305     return SDL_FALSE;
   306 }
   307 
   308 static void
   309 WIN_GL_InitExtensions(_THIS, HDC hdc)
   310 {
   311     const char *(WINAPI * wglGetExtensionsStringARB) (HDC) = 0;
   312     const char *extensions;
   313 
   314     wglGetExtensionsStringARB = (const char *(WINAPI *) (HDC))
   315         _this->gl_data->wglGetProcAddress("wglGetExtensionsStringARB");
   316     if (wglGetExtensionsStringARB) {
   317         extensions = wglGetExtensionsStringARB(hdc);
   318     } else {
   319         extensions = NULL;
   320     }
   321 
   322     /* Check for WGL_ARB_pixel_format */
   323     _this->gl_data->WGL_ARB_pixel_format = 0;
   324     if (HasExtension("WGL_ARB_pixel_format", extensions)) {
   325         _this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
   326                                                    (HDC, const int *,
   327                                                     const FLOAT *, UINT,
   328                                                     int *, UINT *))
   329             WIN_GL_GetProcAddress(_this, "wglChoosePixelFormatARB");
   330         _this->gl_data->wglGetPixelFormatAttribivARB =
   331             (BOOL(WINAPI *) (HDC, int, int, UINT, const int *, int *))
   332             WIN_GL_GetProcAddress(_this, "wglGetPixelFormatAttribivARB");
   333 
   334         if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
   335             (_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
   336             _this->gl_data->WGL_ARB_pixel_format = 1;
   337         }
   338     }
   339 
   340     /* Check for WGL_EXT_swap_control */
   341     if (HasExtension("WGL_EXT_swap_control", extensions)) {
   342         _this->gl_data->wglSwapIntervalEXT =
   343             WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
   344         _this->gl_data->wglGetSwapIntervalEXT =
   345             WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
   346     } else {
   347         _this->gl_data->wglSwapIntervalEXT = NULL;
   348         _this->gl_data->wglGetSwapIntervalEXT = NULL;
   349     }
   350 }
   351 
   352 static int
   353 WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
   354 {
   355     HWND hwnd;
   356     HDC hdc;
   357     PIXELFORMATDESCRIPTOR pfd;
   358     HGLRC hglrc;
   359     int pixel_format = 0;
   360     unsigned int matching;
   361 
   362     hwnd =
   363         CreateWindow(SDL_Appname, SDL_Appname, (WS_POPUP | WS_DISABLED), 0, 0,
   364                      10, 10, NULL, NULL, SDL_Instance, NULL);
   365     WIN_PumpEvents(_this);
   366 
   367     hdc = GetDC(hwnd);
   368 
   369     WIN_GL_SetupPixelFormat(_this, &pfd);
   370 
   371     SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd);
   372 
   373     hglrc = _this->gl_data->wglCreateContext(hdc);
   374     if (hglrc) {
   375         _this->gl_data->wglMakeCurrent(hdc, hglrc);
   376 
   377         WIN_GL_InitExtensions(_this, hdc);
   378 
   379         if (_this->gl_data->WGL_ARB_pixel_format) {
   380             _this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
   381                                                     1, &pixel_format,
   382                                                     &matching);
   383         }
   384 
   385         _this->gl_data->wglMakeCurrent(NULL, NULL);
   386         _this->gl_data->wglDeleteContext(hglrc);
   387     }
   388     ReleaseDC(hwnd, hdc);
   389     DestroyWindow(hwnd);
   390     WIN_PumpEvents(_this);
   391 
   392     return pixel_format;
   393 }
   394 
   395 int
   396 WIN_GL_SetupWindow(_THIS, SDL_Window * window)
   397 {
   398     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   399     PIXELFORMATDESCRIPTOR pfd;
   400     int pixel_format;
   401     int iAttribs[64];
   402     int *iAttr;
   403     float fAttribs[1] = { 0 };
   404 
   405     WIN_GL_SetupPixelFormat(_this, &pfd);
   406 
   407     /* setup WGL_ARB_pixel_format attribs */
   408     iAttr = &iAttribs[0];
   409 
   410     *iAttr++ = WGL_DRAW_TO_WINDOW_ARB;
   411     *iAttr++ = GL_TRUE;
   412     *iAttr++ = WGL_RED_BITS_ARB;
   413     *iAttr++ = _this->gl_config.red_size;
   414     *iAttr++ = WGL_GREEN_BITS_ARB;
   415     *iAttr++ = _this->gl_config.green_size;
   416     *iAttr++ = WGL_BLUE_BITS_ARB;
   417     *iAttr++ = _this->gl_config.blue_size;
   418 
   419     if (_this->gl_config.alpha_size) {
   420         *iAttr++ = WGL_ALPHA_BITS_ARB;
   421         *iAttr++ = _this->gl_config.alpha_size;
   422     }
   423 
   424     *iAttr++ = WGL_DOUBLE_BUFFER_ARB;
   425     *iAttr++ = _this->gl_config.double_buffer;
   426 
   427     *iAttr++ = WGL_DEPTH_BITS_ARB;
   428     *iAttr++ = _this->gl_config.depth_size;
   429 
   430     if (_this->gl_config.stencil_size) {
   431         *iAttr++ = WGL_STENCIL_BITS_ARB;
   432         *iAttr++ = _this->gl_config.stencil_size;
   433     }
   434 
   435     if (_this->gl_config.accum_red_size) {
   436         *iAttr++ = WGL_ACCUM_RED_BITS_ARB;
   437         *iAttr++ = _this->gl_config.accum_red_size;
   438     }
   439 
   440     if (_this->gl_config.accum_green_size) {
   441         *iAttr++ = WGL_ACCUM_GREEN_BITS_ARB;
   442         *iAttr++ = _this->gl_config.accum_green_size;
   443     }
   444 
   445     if (_this->gl_config.accum_blue_size) {
   446         *iAttr++ = WGL_ACCUM_BLUE_BITS_ARB;
   447         *iAttr++ = _this->gl_config.accum_blue_size;
   448     }
   449 
   450     if (_this->gl_config.accum_alpha_size) {
   451         *iAttr++ = WGL_ACCUM_ALPHA_BITS_ARB;
   452         *iAttr++ = _this->gl_config.accum_alpha_size;
   453     }
   454 
   455     if (_this->gl_config.stereo) {
   456         *iAttr++ = WGL_STEREO_ARB;
   457         *iAttr++ = GL_TRUE;
   458     }
   459 
   460     if (_this->gl_config.multisamplebuffers) {
   461         *iAttr++ = WGL_SAMPLE_BUFFERS_ARB;
   462         *iAttr++ = _this->gl_config.multisamplebuffers;
   463     }
   464 
   465     if (_this->gl_config.multisamplesamples) {
   466         *iAttr++ = WGL_SAMPLES_ARB;
   467         *iAttr++ = _this->gl_config.multisamplesamples;
   468     }
   469 
   470     *iAttr++ = WGL_ACCELERATION_ARB;
   471     *iAttr++ = (_this->gl_config.accelerated ? WGL_FULL_ACCELERATION_ARB :
   472                                                WGL_NO_ACCELERATION_ARB);
   473 
   474     *iAttr = 0;
   475 
   476     /* Choose and set the closest available pixel format */
   477     pixel_format = WIN_GL_ChoosePixelFormatARB(_this, iAttribs, fAttribs);
   478     if (!pixel_format) {
   479         pixel_format = WIN_GL_ChoosePixelFormat(hdc, &pfd);
   480     }
   481     if (!pixel_format) {
   482         SDL_SetError("No matching GL pixel format available");
   483         return -1;
   484     }
   485     if (!SetPixelFormat(hdc, pixel_format, &pfd)) {
   486         WIN_SetError("SetPixelFormat()");
   487         return (-1);
   488     }
   489     return 0;
   490 }
   491 
   492 SDL_GLContext
   493 WIN_GL_CreateContext(_THIS, SDL_Window * window)
   494 {
   495     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   496     HGLRC context;
   497 
   498     if (_this->gl_config.major_version < 3) {
   499         context = _this->gl_data->wglCreateContext(hdc);
   500     } else {
   501         PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
   502         HGLRC temp_context = _this->gl_data->wglCreateContext(hdc);
   503         if (!temp_context) {
   504             SDL_SetError("Could not create GL context");
   505             return NULL;
   506         }
   507 
   508         /* Make the context current */
   509         if (WIN_GL_MakeCurrent(_this, window, temp_context) < 0) {
   510             WIN_GL_DeleteContext(_this, temp_context);
   511             return NULL;
   512         }
   513 
   514         wglCreateContextAttribsARB =
   515             (PFNWGLCREATECONTEXTATTRIBSARBPROC) _this->gl_data->
   516             wglGetProcAddress("wglCreateContextAttribsARB");
   517         if (!wglCreateContextAttribsARB) {
   518             SDL_SetError("GL 3.x is not supported");
   519             context = temp_context;
   520         } else {
   521             int attribs[] = {
   522                 WGL_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version,
   523                 WGL_CONTEXT_MINOR_VERSION_ARB, _this->gl_config.minor_version,
   524                 0
   525             };
   526             /* Create the GL 3.x context */
   527             context = wglCreateContextAttribsARB(hdc, 0, attribs);
   528             /* Delete the GL 2.x context */
   529             _this->gl_data->wglDeleteContext(temp_context);
   530         }
   531     }
   532 
   533     if (!context) {
   534         WIN_SetError("Could not create GL context");
   535         return NULL;
   536     }
   537 
   538     if (WIN_GL_MakeCurrent(_this, window, context) < 0) {
   539         WIN_GL_DeleteContext(_this, context);
   540         return NULL;
   541     }
   542 
   543     WIN_GL_InitExtensions(_this, hdc);
   544 
   545     return context;
   546 }
   547 
   548 int
   549 WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
   550 {
   551     HDC hdc;
   552     int status;
   553 
   554     if (window) {
   555         hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   556     } else {
   557         hdc = NULL;
   558     }
   559     if (!_this->gl_data->wglMakeCurrent(hdc, (HGLRC) context)) {
   560         WIN_SetError("wglMakeCurrent()");
   561         status = -1;
   562     } else {
   563         status = 0;
   564     }
   565     return status;
   566 }
   567 
   568 int
   569 WIN_GL_SetSwapInterval(_THIS, int interval)
   570 {
   571     if (_this->gl_data->wglSwapIntervalEXT) {
   572         _this->gl_data->wglSwapIntervalEXT(interval);
   573         return 0;
   574     } else {
   575         SDL_Unsupported();
   576         return -1;
   577     }
   578 }
   579 
   580 int
   581 WIN_GL_GetSwapInterval(_THIS)
   582 {
   583     if (_this->gl_data->wglGetSwapIntervalEXT) {
   584         return _this->gl_data->wglGetSwapIntervalEXT();
   585     } else {
   586         SDL_Unsupported();
   587         return -1;
   588     }
   589 }
   590 
   591 void
   592 WIN_GL_SwapWindow(_THIS, SDL_Window * window)
   593 {
   594     HDC hdc = ((SDL_WindowData *) window->driverdata)->hdc;
   595 
   596     SwapBuffers(hdc);
   597 }
   598 
   599 void
   600 WIN_GL_DeleteContext(_THIS, SDL_GLContext context)
   601 {
   602     _this->gl_data->wglDeleteContext((HGLRC) context);
   603 }
   604 
   605 #endif /* SDL_VIDEO_OPENGL_WGL */
   606 
   607 /* vi: set ts=4 sw=4 expandtab: */