src/video/SDL_egl.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 15 Oct 2014 09:13:36 -0700
changeset 9162 69856cdc9da6
parent 8976 1a5d959d7b32
child 9164 494876610c49
permissions -rw-r--r--
Fixed bug where EGL function pointers wouldn't get saved in optimized gcc builds
     1 /*
     2  *  Simple DirectMedia Layer
     3  *  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     4  * 
     5  *  This software is provided 'as-is', without any express or implied
     6  *  warranty.  In no event will the authors be held liable for any damages
     7  *  arising from the use of this software.
     8  * 
     9  *  Permission is granted to anyone to use this software for any purpose,
    10  *  including commercial applications, and to alter it and redistribute it
    11  *  freely, subject to the following restrictions:
    12  * 
    13  *  1. The origin of this software must not be misrepresented; you must not
    14  *     claim that you wrote the original software. If you use this software
    15  *     in a product, an acknowledgment in the product documentation would be
    16  *     appreciated but is not required.
    17  *  2. Altered source versions must be plainly marked as such, and must not be
    18  *     misrepresented as being the original software.
    19  *  3. This notice may not be removed or altered from any source distribution.
    20  */
    21 #include "../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_OPENGL_EGL
    24 
    25 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
    26 #include "../core/windows/SDL_windows.h"
    27 #endif
    28 
    29 #include "SDL_sysvideo.h"
    30 #include "SDL_egl_c.h"
    31 #include "SDL_loadso.h"
    32 #include "SDL_hints.h"
    33 
    34 #if SDL_VIDEO_DRIVER_RPI
    35 /* Raspbian places the OpenGL ES/EGL binaries in a non standard path */
    36 #define DEFAULT_EGL "/opt/vc/lib/libEGL.so"
    37 #define DEFAULT_OGL_ES2 "/opt/vc/lib/libGLESv2.so"
    38 #define DEFAULT_OGL_ES_PVR "/opt/vc/lib/libGLES_CM.so"
    39 #define DEFAULT_OGL_ES "/opt/vc/lib/libGLESv1_CM.so"
    40 
    41 #elif SDL_VIDEO_DRIVER_ANDROID
    42 /* Android */
    43 #define DEFAULT_EGL "libEGL.so"
    44 #define DEFAULT_OGL_ES2 "libGLESv2.so"
    45 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
    46 #define DEFAULT_OGL_ES "libGLESv1_CM.so"
    47 
    48 #elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
    49 /* EGL AND OpenGL ES support via ANGLE */
    50 #define DEFAULT_EGL "libEGL.dll"
    51 #define DEFAULT_OGL_ES2 "libGLESv2.dll"
    52 #define DEFAULT_OGL_ES_PVR "libGLES_CM.dll"
    53 #define DEFAULT_OGL_ES "libGLESv1_CM.dll"
    54 
    55 #else
    56 /* Desktop Linux */
    57 #define DEFAULT_OGL "libGL.so.1"
    58 #define DEFAULT_EGL "libEGL.so.1"
    59 #define DEFAULT_OGL_ES2 "libGLESv2.so.2"
    60 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
    61 #define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
    62 #endif /* SDL_VIDEO_DRIVER_RPI */
    63 
    64 #define LOAD_FUNC(NAME) \
    65 _this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
    66 if (!_this->egl_data->NAME) \
    67 { \
    68     return SDL_SetError("Could not retrieve EGL function " #NAME); \
    69 }
    70     
    71 /* EGL implementation of SDL OpenGL ES support */
    72 #ifdef EGL_KHR_create_context        
    73 static int SDL_EGL_HasExtension(_THIS, const char *ext)
    74 {
    75     int i;
    76     int len = 0;
    77     int ext_len;
    78     const char *exts;
    79     const char *ext_word;
    80 
    81     ext_len = SDL_strlen(ext);
    82     exts = _this->egl_data->eglQueryString(_this->egl_data->egl_display, EGL_EXTENSIONS);
    83 
    84     if(exts) {
    85         ext_word = exts;
    86 
    87         for(i = 0; exts[i] != 0; i++) {
    88             if(exts[i] == ' ') {
    89                 if(ext_len == len && !SDL_strncmp(ext_word, ext, len)) {
    90                     return 1;
    91                 }
    92 
    93                 len = 0;
    94                 ext_word = &exts[i + 1];
    95             }
    96             else {
    97                 len++;
    98             }
    99         }
   100     }
   101 
   102     return 0;
   103 }
   104 #endif /* EGL_KHR_create_context */
   105 
   106 void *
   107 SDL_EGL_GetProcAddress(_THIS, const char *proc)
   108 {
   109     static char procname[1024];
   110     void *retval;
   111     
   112     /* eglGetProcAddress is busted on Android http://code.google.com/p/android/issues/detail?id=7681 */
   113 #if !defined(SDL_VIDEO_DRIVER_ANDROID) && !defined(SDL_VIDEO_DRIVER_MIR) 
   114     if (_this->egl_data->eglGetProcAddress) {
   115         retval = _this->egl_data->eglGetProcAddress(proc);
   116         if (retval) {
   117             return retval;
   118         }
   119     }
   120 #endif
   121     
   122     retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, proc);
   123     if (!retval && SDL_strlen(proc) <= 1022) {
   124         procname[0] = '_';
   125         SDL_strlcpy(procname + 1, proc, 1022);
   126         retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, procname);
   127     }
   128     return retval;
   129 }
   130 
   131 void
   132 SDL_EGL_UnloadLibrary(_THIS)
   133 {
   134     if (_this->egl_data) {
   135         if (_this->egl_data->egl_display) {
   136             _this->egl_data->eglTerminate(_this->egl_data->egl_display);
   137             _this->egl_data->egl_display = NULL;
   138         }
   139 
   140         if (_this->egl_data->dll_handle) {
   141             SDL_UnloadObject(_this->egl_data->dll_handle);
   142             _this->egl_data->dll_handle = NULL;
   143         }
   144         if (_this->egl_data->egl_dll_handle) {
   145             SDL_UnloadObject(_this->egl_data->egl_dll_handle);
   146             _this->egl_data->egl_dll_handle = NULL;
   147         }
   148         
   149         SDL_free(_this->egl_data);
   150         _this->egl_data = NULL;
   151     }
   152 }
   153 
   154 int
   155 SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display)
   156 {
   157     void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */
   158     char *path = NULL;
   159 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
   160     const char *d3dcompiler;
   161 #endif
   162 
   163     if (_this->egl_data) {
   164         return SDL_SetError("OpenGL ES context already created");
   165     }
   166 
   167     _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
   168     if (!_this->egl_data) {
   169         return SDL_OutOfMemory();
   170     }
   171 
   172 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
   173     d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER);
   174     if (!d3dcompiler) {
   175         if (WIN_IsWindowsVistaOrGreater()) {
   176             d3dcompiler = "d3dcompiler_46.dll";
   177         } else {
   178             d3dcompiler = "d3dcompiler_43.dll";
   179         }
   180     }
   181     if (SDL_strcasecmp(d3dcompiler, "none") != 0) {
   182         SDL_LoadObject(d3dcompiler);
   183     }
   184 #endif
   185 
   186     /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */
   187     path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
   188     if (path != NULL) {
   189         egl_dll_handle = SDL_LoadObject(path);
   190     }
   191 
   192     if (egl_dll_handle == NULL) {
   193         if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
   194             if (_this->gl_config.major_version > 1) {
   195                 path = DEFAULT_OGL_ES2;
   196                 egl_dll_handle = SDL_LoadObject(path);
   197             }
   198             else {
   199                 path = DEFAULT_OGL_ES;
   200                 egl_dll_handle = SDL_LoadObject(path);
   201                 if (egl_dll_handle == NULL) {
   202                     path = DEFAULT_OGL_ES_PVR;
   203                     egl_dll_handle = SDL_LoadObject(path);
   204                 }
   205             }
   206         }
   207 #ifdef DEFAULT_OGL         
   208         else {
   209             path = DEFAULT_OGL;
   210             egl_dll_handle = SDL_LoadObject(path);
   211         }
   212 #endif        
   213     }
   214     _this->egl_data->egl_dll_handle = egl_dll_handle;
   215 
   216     if (egl_dll_handle == NULL) {
   217         return SDL_SetError("Could not initialize OpenGL / GLES library");
   218     }
   219 
   220     /* Loading libGL* in the previous step took care of loading libEGL.so, but we future proof by double checking */
   221     if (egl_path != NULL) {
   222         dll_handle = SDL_LoadObject(egl_path);
   223     }   
   224     /* Try loading a EGL symbol, if it does not work try the default library paths */
   225     if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
   226         if (dll_handle != NULL) {
   227             SDL_UnloadObject(dll_handle);
   228         }
   229         path = SDL_getenv("SDL_VIDEO_EGL_DRIVER");
   230         if (path == NULL) {
   231             path = DEFAULT_EGL;
   232         }
   233         dll_handle = SDL_LoadObject(path);
   234         if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
   235             if (dll_handle != NULL) {
   236                 SDL_UnloadObject(dll_handle);
   237             }
   238             return SDL_SetError("Could not load EGL library");
   239         }
   240         SDL_ClearError();
   241     }
   242 
   243     _this->egl_data->dll_handle = dll_handle;
   244 
   245     /* Load new function pointers */
   246     LOAD_FUNC(eglGetDisplay);
   247     LOAD_FUNC(eglInitialize);
   248     LOAD_FUNC(eglTerminate);
   249     LOAD_FUNC(eglGetProcAddress);
   250     LOAD_FUNC(eglChooseConfig);
   251     LOAD_FUNC(eglGetConfigAttrib);
   252     LOAD_FUNC(eglCreateContext);
   253     LOAD_FUNC(eglDestroyContext);
   254     LOAD_FUNC(eglCreateWindowSurface);
   255     LOAD_FUNC(eglDestroySurface);
   256     LOAD_FUNC(eglMakeCurrent);
   257     LOAD_FUNC(eglSwapBuffers);
   258     LOAD_FUNC(eglSwapInterval);
   259     LOAD_FUNC(eglWaitNative);
   260     LOAD_FUNC(eglWaitGL);
   261     LOAD_FUNC(eglBindAPI);
   262     LOAD_FUNC(eglQueryString);
   263     
   264 #if !defined(__WINRT__)
   265     _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
   266     if (!_this->egl_data->egl_display) {
   267         return SDL_SetError("Could not get EGL display");
   268     }
   269     
   270     if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
   271         return SDL_SetError("Could not initialize EGL");
   272     }
   273 #endif
   274 
   275     _this->gl_config.driver_loaded = 1;
   276 
   277     if (path) {
   278         SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1);
   279     } else {
   280         *_this->gl_config.driver_path = '\0';
   281     }
   282     
   283     return 0;
   284 }
   285 
   286 int
   287 SDL_EGL_ChooseConfig(_THIS) 
   288 {
   289     /* 64 seems nice. */
   290     EGLint attribs[64];
   291     EGLint found_configs = 0, value;
   292     /* 128 seems even nicer here */
   293     EGLConfig configs[128];
   294     int i, j, best_bitdiff = -1, bitdiff;
   295     
   296     if (!_this->egl_data) {
   297         /* The EGL library wasn't loaded, SDL_GetError() should have info */
   298         return -1;
   299     }
   300   
   301     /* Get a valid EGL configuration */
   302     i = 0;
   303     attribs[i++] = EGL_RED_SIZE;
   304     attribs[i++] = _this->gl_config.red_size;
   305     attribs[i++] = EGL_GREEN_SIZE;
   306     attribs[i++] = _this->gl_config.green_size;
   307     attribs[i++] = EGL_BLUE_SIZE;
   308     attribs[i++] = _this->gl_config.blue_size;
   309     
   310     if (_this->gl_config.alpha_size) {
   311         attribs[i++] = EGL_ALPHA_SIZE;
   312         attribs[i++] = _this->gl_config.alpha_size;
   313     }
   314     
   315     if (_this->gl_config.buffer_size) {
   316         attribs[i++] = EGL_BUFFER_SIZE;
   317         attribs[i++] = _this->gl_config.buffer_size;
   318     }
   319     
   320     attribs[i++] = EGL_DEPTH_SIZE;
   321     attribs[i++] = _this->gl_config.depth_size;
   322     
   323     if (_this->gl_config.stencil_size) {
   324         attribs[i++] = EGL_STENCIL_SIZE;
   325         attribs[i++] = _this->gl_config.stencil_size;
   326     }
   327     
   328     if (_this->gl_config.multisamplebuffers) {
   329         attribs[i++] = EGL_SAMPLE_BUFFERS;
   330         attribs[i++] = _this->gl_config.multisamplebuffers;
   331     }
   332     
   333     if (_this->gl_config.multisamplesamples) {
   334         attribs[i++] = EGL_SAMPLES;
   335         attribs[i++] = _this->gl_config.multisamplesamples;
   336     }
   337     
   338     attribs[i++] = EGL_RENDERABLE_TYPE;
   339     if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
   340         if (_this->gl_config.major_version == 2) {
   341             attribs[i++] = EGL_OPENGL_ES2_BIT;
   342         } else {
   343             attribs[i++] = EGL_OPENGL_ES_BIT;
   344         }
   345         _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
   346     }
   347     else {
   348         attribs[i++] = EGL_OPENGL_BIT;
   349         _this->egl_data->eglBindAPI(EGL_OPENGL_API);
   350     }
   351     
   352     attribs[i++] = EGL_NONE;
   353    
   354     if (_this->egl_data->eglChooseConfig(_this->egl_data->egl_display,
   355         attribs,
   356         configs, SDL_arraysize(configs),
   357         &found_configs) == EGL_FALSE ||
   358         found_configs == 0) {
   359         return SDL_SetError("Couldn't find matching EGL config");
   360     }
   361     
   362     /* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */
   363     /* From those, we select the one that matches our requirements more closely via a makeshift algorithm */
   364 
   365     for ( i=0; i<found_configs; i++ ) {
   366         bitdiff = 0;
   367         for (j = 0; j < SDL_arraysize(attribs) - 1; j += 2) {
   368             if (attribs[j] == EGL_NONE) {
   369                break;
   370             }
   371             
   372             if ( attribs[j+1] != EGL_DONT_CARE && (
   373                 attribs[j] == EGL_RED_SIZE ||
   374                 attribs[j] == EGL_GREEN_SIZE ||
   375                 attribs[j] == EGL_BLUE_SIZE ||
   376                 attribs[j] == EGL_ALPHA_SIZE ||
   377                 attribs[j] == EGL_DEPTH_SIZE ||
   378                 attribs[j] == EGL_STENCIL_SIZE)) {
   379                 _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], attribs[j], &value);
   380                 bitdiff += value - attribs[j + 1]; /* value is always >= attrib */
   381             }
   382         }
   383 
   384         if (bitdiff < best_bitdiff || best_bitdiff == -1) {
   385             _this->egl_data->egl_config = configs[i];
   386             
   387             best_bitdiff = bitdiff;
   388         }
   389            
   390         if (bitdiff == 0) break; /* we found an exact match! */
   391     }
   392     
   393     return 0;
   394 }
   395 
   396 SDL_GLContext
   397 SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
   398 {
   399     EGLint context_attrib_list[] = {
   400         EGL_CONTEXT_CLIENT_VERSION,
   401         1,
   402         EGL_NONE,
   403         EGL_NONE,
   404         EGL_NONE,
   405         EGL_NONE,
   406         EGL_NONE
   407     };
   408     
   409     EGLContext egl_context, share_context = EGL_NO_CONTEXT;
   410     
   411     if (!_this->egl_data) {
   412         /* The EGL library wasn't loaded, SDL_GetError() should have info */
   413         return NULL;
   414     }
   415     
   416     if (_this->gl_config.share_with_current_context) {
   417         share_context = (EGLContext)SDL_GL_GetCurrentContext();
   418     }
   419     
   420     /* Bind the API */
   421     if(_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
   422         _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
   423         if (_this->gl_config.major_version) {
   424             context_attrib_list[1] = _this->gl_config.major_version;
   425         }
   426 
   427         egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
   428                                           _this->egl_data->egl_config,
   429                                           share_context, context_attrib_list);
   430     }
   431     else {
   432         _this->egl_data->eglBindAPI(EGL_OPENGL_API);
   433 #ifdef EGL_KHR_create_context        
   434         if(SDL_EGL_HasExtension(_this, "EGL_KHR_create_context")) {
   435             context_attrib_list[0] = EGL_CONTEXT_MAJOR_VERSION_KHR;
   436             context_attrib_list[1] = _this->gl_config.major_version;
   437             context_attrib_list[2] = EGL_CONTEXT_MINOR_VERSION_KHR;
   438             context_attrib_list[3] = _this->gl_config.minor_version;
   439             context_attrib_list[4] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
   440             switch(_this->gl_config.profile_mask) {
   441             case SDL_GL_CONTEXT_PROFILE_COMPATIBILITY:
   442                 context_attrib_list[5] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
   443                 break;
   444 
   445             case SDL_GL_CONTEXT_PROFILE_CORE:
   446             default:
   447                 context_attrib_list[5] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
   448                 break;
   449             }
   450         }
   451         else {
   452             context_attrib_list[0] = EGL_NONE;
   453         }
   454 #else /* EGL_KHR_create_context */
   455         context_attrib_list[0] = EGL_NONE;
   456 #endif /* EGL_KHR_create_context */
   457         egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
   458                                           _this->egl_data->egl_config,
   459                                           share_context, context_attrib_list);
   460     }
   461     
   462     if (egl_context == EGL_NO_CONTEXT) {
   463         SDL_SetError("Could not create EGL context");
   464         return NULL;
   465     }
   466     
   467     _this->egl_data->egl_swapinterval = 0;
   468     
   469     if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) {
   470         SDL_EGL_DeleteContext(_this, egl_context);
   471         SDL_SetError("Could not make EGL context current");
   472         return NULL;
   473     }
   474   
   475     return (SDL_GLContext) egl_context;
   476 }
   477 
   478 int
   479 SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
   480 {
   481     EGLContext egl_context = (EGLContext) context;
   482 
   483     if (!_this->egl_data) {
   484         return SDL_SetError("OpenGL not initialized");
   485     }
   486     
   487     /* The android emulator crashes badly if you try to eglMakeCurrent 
   488      * with a valid context and invalid surface, so we have to check for both here.
   489      */
   490     if (!egl_context || !egl_surface) {
   491          _this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
   492     }
   493     else {
   494         if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
   495             egl_surface, egl_surface, egl_context)) {
   496             return SDL_SetError("Unable to make EGL context current");
   497         }
   498     }
   499       
   500     return 0;
   501 }
   502 
   503 int
   504 SDL_EGL_SetSwapInterval(_THIS, int interval)
   505 {
   506     EGLBoolean status;
   507     
   508     if (!_this->egl_data) {
   509         return SDL_SetError("EGL not initialized");
   510     }
   511     
   512     status = _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, interval);
   513     if (status == EGL_TRUE) {
   514         _this->egl_data->egl_swapinterval = interval;
   515         return 0;
   516     }
   517     
   518     return SDL_SetError("Unable to set the EGL swap interval");
   519 }
   520 
   521 int
   522 SDL_EGL_GetSwapInterval(_THIS)
   523 {
   524     if (!_this->egl_data) {
   525         return SDL_SetError("EGL not initialized");
   526     }
   527     
   528     return _this->egl_data->egl_swapinterval;
   529 }
   530 
   531 void
   532 SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface)
   533 {
   534     _this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, egl_surface);
   535 }
   536 
   537 void
   538 SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
   539 {
   540     EGLContext egl_context = (EGLContext) context;
   541 
   542     /* Clean up GLES and EGL */
   543     if (!_this->egl_data) {
   544         return;
   545     }
   546     
   547     if (egl_context != NULL && egl_context != EGL_NO_CONTEXT) {
   548         SDL_EGL_MakeCurrent(_this, NULL, NULL);
   549         _this->egl_data->eglDestroyContext(_this->egl_data->egl_display, egl_context);
   550     }
   551         
   552 }
   553 
   554 EGLSurface *
   555 SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) 
   556 {
   557     if (SDL_EGL_ChooseConfig(_this) != 0) {
   558         return EGL_NO_SURFACE;
   559     }
   560     
   561 #if __ANDROID__
   562     {
   563         /* Android docs recommend doing this!
   564          * Ref: http://developer.android.com/reference/android/app/NativeActivity.html 
   565          */
   566         EGLint format;
   567         _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
   568                                             _this->egl_data->egl_config, 
   569                                             EGL_NATIVE_VISUAL_ID, &format);
   570 
   571         ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
   572     }
   573 #endif    
   574     
   575     return _this->egl_data->eglCreateWindowSurface(
   576             _this->egl_data->egl_display,
   577             _this->egl_data->egl_config,
   578             nw, NULL);
   579 }
   580 
   581 void
   582 SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface) 
   583 {
   584     if (!_this->egl_data) {
   585         return;
   586     }
   587     
   588     if (egl_surface != EGL_NO_SURFACE) {
   589         _this->egl_data->eglDestroySurface(_this->egl_data->egl_display, egl_surface);
   590     }
   591 }
   592 
   593 #endif /* SDL_VIDEO_OPENGL_EGL */
   594 
   595 /* vi: set ts=4 sw=4 expandtab: */
   596