src/video/SDL_egl.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 27 Aug 2017 19:05:57 -0700
changeset 11363 2d3d35b2c95a
parent 11347 7f254d0b7842
child 11418 7749a3b2b343
permissions -rw-r--r--
Fixed bug 3724 - Allow Angle Static Link

Carlos

We would like to add a switch (define) that allows us to compile Angle statically with SDL. That is, getting rid of the OpenGL DLL. Usually you need OpenGL to be loaded dynamically as DLL because implementation is provided by the system but no need with Angle.

Only 2 files need modification and it shouldn't affect current behaivor:
include/SDL_egl.h and src/video/SDL_egl.c, as in here

https://github.com/native-toolkit/sdl/pull/10/files

The flag name could be SDL_VIDEO_STATIC_ANGLE (instead of NATIVE_TOOLKIT_STATIC_ANGLE) as discussed here https://github.com/native-toolkit/sdl/pull/10

We have tested this with both Windows and UWP, using NME engine (https://github.com/haxenme/nme).

Releated issue: https://bugzilla.libsdl.org/show_bug.cgi?id=1820
gabomdq@7659
     1
/*
gabomdq@7659
     2
 *  Simple DirectMedia Layer
slouken@10737
     3
 *  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
gabomdq@7659
     4
 * 
gabomdq@7659
     5
 *  This software is provided 'as-is', without any express or implied
gabomdq@7659
     6
 *  warranty.  In no event will the authors be held liable for any damages
gabomdq@7659
     7
 *  arising from the use of this software.
gabomdq@7659
     8
 * 
gabomdq@7659
     9
 *  Permission is granted to anyone to use this software for any purpose,
gabomdq@7659
    10
 *  including commercial applications, and to alter it and redistribute it
gabomdq@7659
    11
 *  freely, subject to the following restrictions:
gabomdq@7659
    12
 * 
gabomdq@7659
    13
 *  1. The origin of this software must not be misrepresented; you must not
gabomdq@7659
    14
 *     claim that you wrote the original software. If you use this software
gabomdq@7659
    15
 *     in a product, an acknowledgment in the product documentation would be
gabomdq@7659
    16
 *     appreciated but is not required.
gabomdq@7659
    17
 *  2. Altered source versions must be plainly marked as such, and must not be
gabomdq@7659
    18
 *     misrepresented as being the original software.
gabomdq@7659
    19
 *  3. This notice may not be removed or altered from any source distribution.
gabomdq@7659
    20
 */
icculus@8093
    21
#include "../SDL_internal.h"
gabomdq@7659
    22
gabomdq@7659
    23
#if SDL_VIDEO_OPENGL_EGL
gabomdq@7659
    24
slouken@8734
    25
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
slouken@8734
    26
#include "../core/windows/SDL_windows.h"
slouken@8734
    27
#endif
slouken@10878
    28
#if SDL_VIDEO_DRIVER_ANDROID
slouken@10878
    29
#include <android/native_window.h>
slouken@10878
    30
#endif
slouken@8734
    31
gabomdq@7659
    32
#include "SDL_sysvideo.h"
slouken@11175
    33
#include "SDL_log.h"
gabomdq@8021
    34
#include "SDL_egl_c.h"
gabomdq@8021
    35
#include "SDL_loadso.h"
gabomdq@8021
    36
#include "SDL_hints.h"
gabomdq@7782
    37
slime73@9595
    38
#ifdef EGL_KHR_create_context
slime73@9595
    39
/* EGL_OPENGL_ES3_BIT_KHR was added in version 13 of the extension. */
slime73@9595
    40
#ifndef EGL_OPENGL_ES3_BIT_KHR
slime73@9595
    41
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
slime73@9595
    42
#endif
slime73@9595
    43
#endif /* EGL_KHR_create_context */
slime73@9595
    44
gabomdq@7753
    45
#if SDL_VIDEO_DRIVER_RPI
gabomdq@7782
    46
/* Raspbian places the OpenGL ES/EGL binaries in a non standard path */
gabomdq@7753
    47
#define DEFAULT_EGL "/opt/vc/lib/libEGL.so"
gabomdq@7753
    48
#define DEFAULT_OGL_ES2 "/opt/vc/lib/libGLESv2.so"
gabomdq@7753
    49
#define DEFAULT_OGL_ES_PVR "/opt/vc/lib/libGLES_CM.so"
gabomdq@7753
    50
#define DEFAULT_OGL_ES "/opt/vc/lib/libGLESv1_CM.so"
gabomdq@7782
    51
slouken@9164
    52
#elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_VIVANTE
gabomdq@7782
    53
/* Android */
gabomdq@7782
    54
#define DEFAULT_EGL "libEGL.so"
gabomdq@7782
    55
#define DEFAULT_OGL_ES2 "libGLESv2.so"
gabomdq@7782
    56
#define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
gabomdq@7782
    57
#define DEFAULT_OGL_ES "libGLESv1_CM.so"
gabomdq@7782
    58
dludwig@8545
    59
#elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
gabomdq@8021
    60
/* EGL AND OpenGL ES support via ANGLE */
gabomdq@8021
    61
#define DEFAULT_EGL "libEGL.dll"
gabomdq@8021
    62
#define DEFAULT_OGL_ES2 "libGLESv2.dll"
gabomdq@8021
    63
#define DEFAULT_OGL_ES_PVR "libGLES_CM.dll"
gabomdq@8021
    64
#define DEFAULT_OGL_ES "libGLESv1_CM.dll"
gabomdq@8021
    65
gabomdq@7753
    66
#else
gabomdq@7782
    67
/* Desktop Linux */
gabomdq@8062
    68
#define DEFAULT_OGL "libGL.so.1"
gabomdq@7753
    69
#define DEFAULT_EGL "libEGL.so.1"
gabomdq@7753
    70
#define DEFAULT_OGL_ES2 "libGLESv2.so.2"
gabomdq@7753
    71
#define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
gabomdq@7753
    72
#define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
gabomdq@7753
    73
#endif /* SDL_VIDEO_DRIVER_RPI */
gabomdq@7659
    74
slouken@11363
    75
#ifdef SDL_VIDEO_STATIC_ANGLE
slouken@11363
    76
#define LOAD_FUNC(NAME) \
slouken@11363
    77
_this->egl_data->NAME = (void *)NAME;
slouken@11363
    78
#else
gabomdq@7659
    79
#define LOAD_FUNC(NAME) \
slouken@9162
    80
_this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
gabomdq@7659
    81
if (!_this->egl_data->NAME) \
gabomdq@7659
    82
{ \
gabomdq@7659
    83
    return SDL_SetError("Could not retrieve EGL function " #NAME); \
gabomdq@7659
    84
}
slouken@11363
    85
#endif
dludwig@10740
    86
dludwig@10740
    87
static const char * SDL_EGL_GetErrorName(EGLint eglErrorCode)
dludwig@10740
    88
{
dludwig@10740
    89
#define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e;
dludwig@10740
    90
    switch (eglErrorCode) {
dludwig@10740
    91
        SDL_EGL_ERROR_TRANSLATE(EGL_SUCCESS);
dludwig@10740
    92
        SDL_EGL_ERROR_TRANSLATE(EGL_NOT_INITIALIZED);
dludwig@10740
    93
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ACCESS);
dludwig@10740
    94
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ALLOC);
dludwig@10740
    95
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_ATTRIBUTE);
dludwig@10740
    96
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CONTEXT);
dludwig@10740
    97
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CONFIG);
dludwig@10740
    98
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_CURRENT_SURFACE);
dludwig@10740
    99
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_DISPLAY);
dludwig@10740
   100
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_SURFACE);
dludwig@10740
   101
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_MATCH);
dludwig@10740
   102
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_PARAMETER);
dludwig@10740
   103
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_NATIVE_PIXMAP);
dludwig@10740
   104
        SDL_EGL_ERROR_TRANSLATE(EGL_BAD_NATIVE_WINDOW);
dludwig@10740
   105
        SDL_EGL_ERROR_TRANSLATE(EGL_CONTEXT_LOST);
dludwig@10740
   106
    }
dludwig@10740
   107
    return "";
dludwig@10740
   108
}
dludwig@10740
   109
dludwig@10740
   110
int SDL_EGL_SetErrorEx(const char * message, const char * eglFunctionName, EGLint eglErrorCode)
dludwig@10740
   111
{
dludwig@10740
   112
    const char * errorText = SDL_EGL_GetErrorName(eglErrorCode);
dludwig@10740
   113
    char altErrorText[32];
dludwig@10740
   114
    if (errorText[0] == '\0') {
dludwig@10740
   115
        /* An unknown-to-SDL error code was reported.  Report its hexadecimal value, instead of its name. */
dludwig@10740
   116
        SDL_snprintf(altErrorText, SDL_arraysize(altErrorText), "0x%x", (unsigned int)eglErrorCode);
dludwig@10740
   117
        errorText = altErrorText;
dludwig@10740
   118
    }
dludwig@10740
   119
    return SDL_SetError("%s (call to %s failed, reporting an error of %s)", message, eglFunctionName, errorText);
dludwig@10740
   120
}
dludwig@10740
   121
gabomdq@7659
   122
/* EGL implementation of SDL OpenGL ES support */
slouken@11175
   123
typedef enum {
slouken@11175
   124
    SDL_EGL_DISPLAY_EXTENSION,
slouken@11175
   125
    SDL_EGL_CLIENT_EXTENSION
slouken@11175
   126
} SDL_EGL_ExtensionType;
slouken@11175
   127
slouken@11175
   128
static SDL_bool SDL_EGL_HasExtension(_THIS, SDL_EGL_ExtensionType type, const char *ext)
knut@8962
   129
{
slouken@9821
   130
    size_t ext_len;
slouken@11175
   131
    const char *ext_override;
slouken@11175
   132
    const char *egl_extstr;
slouken@11175
   133
    const char *ext_start;
slouken@11175
   134
slouken@11175
   135
    /* Invalid extensions can be rejected early */
slouken@11175
   136
    if (ext == NULL || *ext == 0 || SDL_strchr(ext, ' ') != NULL) {
slouken@11175
   137
        /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid EGL extension"); */
slouken@11175
   138
        return SDL_FALSE;
slouken@11175
   139
    }
slouken@11175
   140
slouken@11175
   141
    /* Extensions can be masked with an environment variable.
slouken@11175
   142
     * Unlike the OpenGL override, this will use the set bits of an integer
slouken@11175
   143
     * to disable the extension.
slouken@11175
   144
     *  Bit   Action
slouken@11175
   145
     *  0     If set, the display extension is masked and not present to SDL.
slouken@11175
   146
     *  1     If set, the client extension is masked and not present to SDL.
slouken@11175
   147
     */
slouken@11175
   148
    ext_override = SDL_getenv(ext);
slouken@11175
   149
    if (ext_override != NULL) {
slouken@11175
   150
        int disable_ext = SDL_atoi(ext_override);
slouken@11175
   151
        if (disable_ext & 0x01 && type == SDL_EGL_DISPLAY_EXTENSION) {
slouken@11175
   152
            return SDL_FALSE;
slouken@11175
   153
        } else if (disable_ext & 0x02 && type == SDL_EGL_CLIENT_EXTENSION) {
slouken@11175
   154
            return SDL_FALSE;
slouken@11175
   155
        }
slouken@11175
   156
    }
knut@8962
   157
knut@8962
   158
    ext_len = SDL_strlen(ext);
slouken@11175
   159
    switch (type) {
slouken@11175
   160
    case SDL_EGL_DISPLAY_EXTENSION:
slouken@11175
   161
        egl_extstr = _this->egl_data->eglQueryString(_this->egl_data->egl_display, EGL_EXTENSIONS);
slouken@11175
   162
        break;
slouken@11175
   163
    case SDL_EGL_CLIENT_EXTENSION:
slouken@11175
   164
        /* EGL_EXT_client_extensions modifies eglQueryString to return client extensions
slouken@11175
   165
         * if EGL_NO_DISPLAY is passed. Implementations without it are required to return NULL.
slouken@11175
   166
         * This behavior is included in EGL 1.5.
slouken@11175
   167
         */
slouken@11175
   168
        egl_extstr = _this->egl_data->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
slouken@11175
   169
        break;
slouken@11175
   170
    default:
slouken@11175
   171
        /* SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "SDL_EGL_HasExtension: Invalid extension type"); */
slouken@11175
   172
        return SDL_FALSE;
slouken@11175
   173
    }
knut@8962
   174
slouken@11175
   175
    if (egl_extstr != NULL) {
slouken@11175
   176
        ext_start = egl_extstr;
knut@8962
   177
slouken@11175
   178
        while (*ext_start) {
slouken@11175
   179
            ext_start = SDL_strstr(ext_start, ext);
slouken@11175
   180
            if (ext_start == NULL) {
slouken@11175
   181
                return SDL_FALSE;
slouken@11175
   182
            }
slouken@11175
   183
            /* Check if the match is not just a substring of one of the extensions */
slouken@11175
   184
            if (ext_start == egl_extstr || *(ext_start - 1) == ' ') {
slouken@11175
   185
                if (ext_start[ext_len] == ' ' || ext_start[ext_len] == 0) {
slouken@11175
   186
                    return SDL_TRUE;
knut@8962
   187
                }
slouken@11175
   188
            }
slouken@11175
   189
            /* If the search stopped in the middle of an extension, skip to the end of it */
slouken@11175
   190
            ext_start += ext_len;
slouken@11175
   191
            while (*ext_start != ' ' && *ext_start != 0) {
slouken@11175
   192
                ext_start++;
knut@8962
   193
            }
knut@8962
   194
        }
knut@8962
   195
    }
knut@8962
   196
slouken@11175
   197
    return SDL_FALSE;
knut@8962
   198
}
gabomdq@7659
   199
gabomdq@7659
   200
void *
gabomdq@7659
   201
SDL_EGL_GetProcAddress(_THIS, const char *proc)
gabomdq@7659
   202
{
gabomdq@7659
   203
    static char procname[1024];
gabomdq@7659
   204
    void *retval;
gabomdq@7659
   205
    
gabomdq@7659
   206
    /* eglGetProcAddress is busted on Android http://code.google.com/p/android/issues/detail?id=7681 */
brandon@8753
   207
#if !defined(SDL_VIDEO_DRIVER_ANDROID) && !defined(SDL_VIDEO_DRIVER_MIR) 
gabomdq@7659
   208
    if (_this->egl_data->eglGetProcAddress) {
gabomdq@7659
   209
        retval = _this->egl_data->eglGetProcAddress(proc);
gabomdq@7659
   210
        if (retval) {
gabomdq@7659
   211
            return retval;
gabomdq@7659
   212
        }
gabomdq@7659
   213
    }
gabomdq@7659
   214
#endif
gabomdq@7659
   215
    
gabomdq@8021
   216
    retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, proc);
gabomdq@8021
   217
    if (!retval && SDL_strlen(proc) <= 1022) {
gabomdq@7659
   218
        procname[0] = '_';
gabomdq@8021
   219
        SDL_strlcpy(procname + 1, proc, 1022);
gabomdq@8021
   220
        retval = SDL_LoadFunction(_this->egl_data->egl_dll_handle, procname);
gabomdq@7659
   221
    }
gabomdq@7659
   222
    return retval;
gabomdq@7659
   223
}
gabomdq@7659
   224
gabomdq@7659
   225
void
gabomdq@7659
   226
SDL_EGL_UnloadLibrary(_THIS)
gabomdq@7659
   227
{
slouken@7865
   228
    if (_this->egl_data) {
slouken@7865
   229
        if (_this->egl_data->egl_display) {
slouken@7865
   230
            _this->egl_data->eglTerminate(_this->egl_data->egl_display);
slouken@7865
   231
            _this->egl_data->egl_display = NULL;
slouken@7865
   232
        }
slouken@7865
   233
gabomdq@8021
   234
        if (_this->egl_data->dll_handle) {
gabomdq@8021
   235
            SDL_UnloadObject(_this->egl_data->dll_handle);
gabomdq@8021
   236
            _this->egl_data->dll_handle = NULL;
slouken@7865
   237
        }
slouken@7865
   238
        if (_this->egl_data->egl_dll_handle) {
gabomdq@8021
   239
            SDL_UnloadObject(_this->egl_data->egl_dll_handle);
slouken@7865
   240
            _this->egl_data->egl_dll_handle = NULL;
slouken@7865
   241
        }
gabomdq@7659
   242
        
gabomdq@7659
   243
        SDL_free(_this->egl_data);
gabomdq@7659
   244
        _this->egl_data = NULL;
gabomdq@7659
   245
    }
gabomdq@7659
   246
}
gabomdq@7659
   247
gabomdq@7659
   248
int
slouken@11175
   249
SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_display, EGLenum platform)
gabomdq@7659
   250
{
gabomdq@8021
   251
    void *dll_handle = NULL, *egl_dll_handle = NULL; /* The naming is counter intuitive, but hey, I just work here -- Gabriel */
slouken@10461
   252
    const char *path = NULL;
slouken@11175
   253
    int egl_version_major = 0, egl_version_minor = 0;
dludwig@8545
   254
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
gabomdq@8021
   255
    const char *d3dcompiler;
gabomdq@8021
   256
#endif
gabomdq@8021
   257
gabomdq@7659
   258
    if (_this->egl_data) {
gabomdq@7659
   259
        return SDL_SetError("OpenGL ES context already created");
gabomdq@7659
   260
    }
slouken@7865
   261
slouken@7865
   262
    _this->egl_data = (struct SDL_EGL_VideoData *) SDL_calloc(1, sizeof(SDL_EGL_VideoData));
slouken@7865
   263
    if (!_this->egl_data) {
slouken@7865
   264
        return SDL_OutOfMemory();
slouken@7865
   265
    }
slouken@7865
   266
dludwig@8545
   267
#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
gabomdq@8021
   268
    d3dcompiler = SDL_GetHint(SDL_HINT_VIDEO_WIN_D3DCOMPILER);
gabomdq@8021
   269
    if (!d3dcompiler) {
slouken@8733
   270
        if (WIN_IsWindowsVistaOrGreater()) {
slouken@8733
   271
            d3dcompiler = "d3dcompiler_46.dll";
slouken@8733
   272
        } else {
slouken@8740
   273
            d3dcompiler = "d3dcompiler_43.dll";
slouken@8733
   274
        }
gabomdq@8021
   275
    }
gabomdq@8021
   276
    if (SDL_strcasecmp(d3dcompiler, "none") != 0) {
slouken@11219
   277
        if (SDL_LoadObject(d3dcompiler) == NULL) {
slouken@11219
   278
            SDL_ClearError();
slouken@11219
   279
        }
gabomdq@8021
   280
    }
slouken@7865
   281
#endif
slouken@7865
   282
slouken@11363
   283
#ifndef SDL_VIDEO_STATIC_ANGLE
gabomdq@7753
   284
    /* A funny thing, loading EGL.so first does not work on the Raspberry, so we load libGL* first */
gabomdq@8021
   285
    path = SDL_getenv("SDL_VIDEO_GL_DRIVER");
gabomdq@8021
   286
    if (path != NULL) {
gabomdq@8021
   287
        egl_dll_handle = SDL_LoadObject(path);
gabomdq@8021
   288
    }
gabomdq@8021
   289
gabomdq@8021
   290
    if (egl_dll_handle == NULL) {
slime73@9595
   291
        if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
gabomdq@8062
   292
            if (_this->gl_config.major_version > 1) {
gabomdq@8062
   293
                path = DEFAULT_OGL_ES2;
gabomdq@8062
   294
                egl_dll_handle = SDL_LoadObject(path);
slime73@9595
   295
            } else {
gabomdq@8062
   296
                path = DEFAULT_OGL_ES;
gabomdq@8062
   297
                egl_dll_handle = SDL_LoadObject(path);
gabomdq@8062
   298
                if (egl_dll_handle == NULL) {
gabomdq@8062
   299
                    path = DEFAULT_OGL_ES_PVR;
gabomdq@8062
   300
                    egl_dll_handle = SDL_LoadObject(path);
gabomdq@8062
   301
                }
gabomdq@8062
   302
            }
gabomdq@8062
   303
        }
gabomdq@8062
   304
#ifdef DEFAULT_OGL         
gabomdq@8062
   305
        else {
gabomdq@8062
   306
            path = DEFAULT_OGL;
gabomdq@8021
   307
            egl_dll_handle = SDL_LoadObject(path);
gabomdq@8021
   308
        }
gabomdq@8062
   309
#endif        
gabomdq@7753
   310
    }
slouken@7865
   311
    _this->egl_data->egl_dll_handle = egl_dll_handle;
gabomdq@7753
   312
gabomdq@7753
   313
    if (egl_dll_handle == NULL) {
gabomdq@8062
   314
        return SDL_SetError("Could not initialize OpenGL / GLES library");
gabomdq@7753
   315
    }
gabomdq@8021
   316
gabomdq@7753
   317
    /* Loading libGL* in the previous step took care of loading libEGL.so, but we future proof by double checking */
gabomdq@8021
   318
    if (egl_path != NULL) {
gabomdq@8021
   319
        dll_handle = SDL_LoadObject(egl_path);
gabomdq@8021
   320
    }   
gabomdq@8105
   321
    /* Try loading a EGL symbol, if it does not work try the default library paths */
gabomdq@8872
   322
    if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
gabomdq@8021
   323
        if (dll_handle != NULL) {
gabomdq@8021
   324
            SDL_UnloadObject(dll_handle);
gabomdq@8021
   325
        }
gabomdq@8021
   326
        path = SDL_getenv("SDL_VIDEO_EGL_DRIVER");
gabomdq@7659
   327
        if (path == NULL) {
gabomdq@7659
   328
            path = DEFAULT_EGL;
gabomdq@7659
   329
        }
gabomdq@8021
   330
        dll_handle = SDL_LoadObject(path);
gabomdq@8872
   331
        if (dll_handle == NULL || SDL_LoadFunction(dll_handle, "eglChooseConfig") == NULL) {
gabomdq@8872
   332
            if (dll_handle != NULL) {
gabomdq@8872
   333
                SDL_UnloadObject(dll_handle);
gabomdq@8872
   334
            }
gabomdq@8021
   335
            return SDL_SetError("Could not load EGL library");
gabomdq@8021
   336
        }
gabomdq@8763
   337
        SDL_ClearError();
gabomdq@7753
   338
    }
slouken@11363
   339
#endif
slouken@7865
   340
gabomdq@8021
   341
    _this->egl_data->dll_handle = dll_handle;
gabomdq@7659
   342
gabomdq@7659
   343
    /* Load new function pointers */
gabomdq@7659
   344
    LOAD_FUNC(eglGetDisplay);
gabomdq@7659
   345
    LOAD_FUNC(eglInitialize);
gabomdq@7659
   346
    LOAD_FUNC(eglTerminate);
gabomdq@7659
   347
    LOAD_FUNC(eglGetProcAddress);
gabomdq@7659
   348
    LOAD_FUNC(eglChooseConfig);
gabomdq@7659
   349
    LOAD_FUNC(eglGetConfigAttrib);
gabomdq@7659
   350
    LOAD_FUNC(eglCreateContext);
gabomdq@7659
   351
    LOAD_FUNC(eglDestroyContext);
gabomdq@7659
   352
    LOAD_FUNC(eglCreateWindowSurface);
gabomdq@7659
   353
    LOAD_FUNC(eglDestroySurface);
gabomdq@7659
   354
    LOAD_FUNC(eglMakeCurrent);
gabomdq@7659
   355
    LOAD_FUNC(eglSwapBuffers);
gabomdq@7659
   356
    LOAD_FUNC(eglSwapInterval);
gabomdq@7659
   357
    LOAD_FUNC(eglWaitNative);
gabomdq@7659
   358
    LOAD_FUNC(eglWaitGL);
gabomdq@8062
   359
    LOAD_FUNC(eglBindAPI);
knut@8962
   360
    LOAD_FUNC(eglQueryString);
dludwig@10740
   361
    LOAD_FUNC(eglGetError);
dludwig@10740
   362
slouken@11175
   363
    if (_this->egl_data->eglQueryString) {
slouken@11175
   364
        /* EGL 1.5 allows querying for client version */
slouken@11175
   365
        const char *egl_version = _this->egl_data->eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
slouken@11175
   366
        if (egl_version != NULL) {
slouken@11175
   367
            if (SDL_sscanf(egl_version, "%d.%d", &egl_version_major, &egl_version_minor) != 2) {
slouken@11175
   368
                egl_version_major = 0;
slouken@11175
   369
                egl_version_minor = 0;
slouken@11175
   370
                SDL_LogWarn(SDL_LOG_CATEGORY_VIDEO, "Could not parse EGL version string: %s", egl_version);
slouken@11175
   371
            }
slouken@11175
   372
        }
slouken@11175
   373
    }
slouken@11175
   374
slouken@11175
   375
    if (egl_version_major == 1 && egl_version_minor == 5) {
slouken@11175
   376
        LOAD_FUNC(eglGetPlatformDisplay);
slouken@11175
   377
    }
slouken@11175
   378
slouken@11175
   379
    _this->egl_data->egl_display = EGL_NO_DISPLAY;
dludwig@8663
   380
#if !defined(__WINRT__)
slouken@11175
   381
    if (platform) {
slouken@11175
   382
        if (egl_version_major == 1 && egl_version_minor == 5) {
philipp@11192
   383
            _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplay(platform, (void *)native_display, NULL);
slouken@11175
   384
        } else {
slouken@11175
   385
            if (SDL_EGL_HasExtension(_this, SDL_EGL_CLIENT_EXTENSION, "EGL_EXT_platform_base")) {
slouken@11175
   386
                _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(_this, "eglGetPlatformDisplayEXT");
slouken@11175
   387
                if (_this->egl_data->eglGetPlatformDisplayEXT) {
philipp@11192
   388
                    _this->egl_data->egl_display = _this->egl_data->eglGetPlatformDisplayEXT(platform, (void *)native_display, NULL);
slouken@11175
   389
                }
slouken@11175
   390
            }
slouken@11175
   391
        }
slouken@11175
   392
    }
slouken@11175
   393
    /* Try the implementation-specific eglGetDisplay even if eglGetPlatformDisplay fails */
slouken@11175
   394
    if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
slouken@11175
   395
        _this->egl_data->egl_display = _this->egl_data->eglGetDisplay(native_display);
slouken@11175
   396
    }
slouken@11175
   397
    if (_this->egl_data->egl_display == EGL_NO_DISPLAY) {
gabomdq@7659
   398
        return SDL_SetError("Could not get EGL display");
gabomdq@7659
   399
    }
gabomdq@7659
   400
    
gabomdq@7659
   401
    if (_this->egl_data->eglInitialize(_this->egl_data->egl_display, NULL, NULL) != EGL_TRUE) {
gabomdq@7659
   402
        return SDL_SetError("Could not initialize EGL");
gabomdq@7659
   403
    }
dludwig@8663
   404
#endif
gabomdq@7659
   405
gabomdq@7659
   406
    if (path) {
gabomdq@8021
   407
        SDL_strlcpy(_this->gl_config.driver_path, path, sizeof(_this->gl_config.driver_path) - 1);
gabomdq@7659
   408
    } else {
gabomdq@8021
   409
        *_this->gl_config.driver_path = '\0';
gabomdq@7659
   410
    }
gabomdq@7659
   411
    
gabomdq@8041
   412
    return 0;
gabomdq@7659
   413
}
gabomdq@7659
   414
gabomdq@7659
   415
int
gabomdq@7659
   416
SDL_EGL_ChooseConfig(_THIS) 
gabomdq@7659
   417
{
slouken@11175
   418
/* 64 seems nice. */
gabomdq@7659
   419
    EGLint attribs[64];
gabomdq@8021
   420
    EGLint found_configs = 0, value;
slouken@11175
   421
#ifdef SDL_VIDEO_DRIVER_KMSDRM
slouken@11175
   422
    /* Intel EGL on KMS/DRM (al least) returns invalid configs that confuse the bitdiff search used */
slouken@11175
   423
    /* later in this function, so we simply use the first one when using the KMSDRM driver for now. */
slouken@11175
   424
    EGLConfig configs[1];
slouken@11175
   425
#else
gabomdq@8015
   426
    /* 128 seems even nicer here */
gabomdq@8015
   427
    EGLConfig configs[128];
slouken@11175
   428
#endif
gabomdq@8021
   429
    int i, j, best_bitdiff = -1, bitdiff;
slouken@11175
   430
   
gabomdq@7659
   431
    if (!_this->egl_data) {
gabomdq@7659
   432
        /* The EGL library wasn't loaded, SDL_GetError() should have info */
gabomdq@7659
   433
        return -1;
gabomdq@7659
   434
    }
gabomdq@7659
   435
  
gabomdq@7659
   436
    /* Get a valid EGL configuration */
gabomdq@7659
   437
    i = 0;
gabomdq@7659
   438
    attribs[i++] = EGL_RED_SIZE;
gabomdq@7659
   439
    attribs[i++] = _this->gl_config.red_size;
gabomdq@7659
   440
    attribs[i++] = EGL_GREEN_SIZE;
gabomdq@7659
   441
    attribs[i++] = _this->gl_config.green_size;
gabomdq@7659
   442
    attribs[i++] = EGL_BLUE_SIZE;
gabomdq@7659
   443
    attribs[i++] = _this->gl_config.blue_size;
gabomdq@7659
   444
    
gabomdq@7659
   445
    if (_this->gl_config.alpha_size) {
gabomdq@7659
   446
        attribs[i++] = EGL_ALPHA_SIZE;
gabomdq@7659
   447
        attribs[i++] = _this->gl_config.alpha_size;
gabomdq@7659
   448
    }
gabomdq@7659
   449
    
gabomdq@7659
   450
    if (_this->gl_config.buffer_size) {
gabomdq@7659
   451
        attribs[i++] = EGL_BUFFER_SIZE;
gabomdq@7659
   452
        attribs[i++] = _this->gl_config.buffer_size;
gabomdq@7659
   453
    }
gabomdq@7659
   454
    
gabomdq@7659
   455
    attribs[i++] = EGL_DEPTH_SIZE;
gabomdq@7659
   456
    attribs[i++] = _this->gl_config.depth_size;
gabomdq@7659
   457
    
gabomdq@7659
   458
    if (_this->gl_config.stencil_size) {
gabomdq@7659
   459
        attribs[i++] = EGL_STENCIL_SIZE;
gabomdq@7659
   460
        attribs[i++] = _this->gl_config.stencil_size;
gabomdq@7659
   461
    }
gabomdq@7659
   462
    
gabomdq@7659
   463
    if (_this->gl_config.multisamplebuffers) {
gabomdq@7659
   464
        attribs[i++] = EGL_SAMPLE_BUFFERS;
gabomdq@7659
   465
        attribs[i++] = _this->gl_config.multisamplebuffers;
gabomdq@7659
   466
    }
gabomdq@7659
   467
    
gabomdq@7659
   468
    if (_this->gl_config.multisamplesamples) {
gabomdq@7659
   469
        attribs[i++] = EGL_SAMPLES;
gabomdq@7659
   470
        attribs[i++] = _this->gl_config.multisamplesamples;
gabomdq@7659
   471
    }
slime73@9595
   472
slime73@9827
   473
    if (_this->gl_config.framebuffer_srgb_capable) {
slime73@9827
   474
#ifdef EGL_KHR_gl_colorspace
slouken@11175
   475
        if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_gl_colorspace")) {
slime73@9827
   476
            attribs[i++] = EGL_GL_COLORSPACE_KHR;
slime73@9827
   477
            attribs[i++] = EGL_GL_COLORSPACE_SRGB_KHR;
slime73@9827
   478
        } else
slime73@9827
   479
#endif
slime73@9827
   480
        {
slime73@9827
   481
            return SDL_SetError("EGL implementation does not support sRGB system framebuffers");
slime73@9827
   482
        }
slime73@9827
   483
    }
slime73@9827
   484
gabomdq@7659
   485
    attribs[i++] = EGL_RENDERABLE_TYPE;
slime73@9595
   486
    if (_this->gl_config.profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
slime73@9595
   487
#ifdef EGL_KHR_create_context
slime73@9595
   488
        if (_this->gl_config.major_version >= 3 &&
slouken@11175
   489
            SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context")) {
slime73@9595
   490
            attribs[i++] = EGL_OPENGL_ES3_BIT_KHR;
slime73@9595
   491
        } else
slime73@9595
   492
#endif
slime73@9595
   493
        if (_this->gl_config.major_version >= 2) {
gabomdq@8062
   494
            attribs[i++] = EGL_OPENGL_ES2_BIT;
gabomdq@8062
   495
        } else {
gabomdq@8062
   496
            attribs[i++] = EGL_OPENGL_ES_BIT;
gabomdq@8062
   497
        }
gabomdq@8062
   498
        _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
slime73@9595
   499
    } else {
gabomdq@8062
   500
        attribs[i++] = EGL_OPENGL_BIT;
gabomdq@8062
   501
        _this->egl_data->eglBindAPI(EGL_OPENGL_API);
gabomdq@7659
   502
    }
slime73@9827
   503
gabomdq@7659
   504
    attribs[i++] = EGL_NONE;
slime73@9827
   505
gabomdq@7659
   506
    if (_this->egl_data->eglChooseConfig(_this->egl_data->egl_display,
gabomdq@7659
   507
        attribs,
gabomdq@8015
   508
        configs, SDL_arraysize(configs),
gabomdq@7659
   509
        &found_configs) == EGL_FALSE ||
gabomdq@7659
   510
        found_configs == 0) {
dludwig@10740
   511
        return SDL_EGL_SetError("Couldn't find matching EGL config", "eglChooseConfig");
gabomdq@7659
   512
    }
slime73@9827
   513
gabomdq@8015
   514
    /* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */
gabomdq@8015
   515
    /* From those, we select the one that matches our requirements more closely via a makeshift algorithm */
gabomdq@8021
   516
slime73@9595
   517
    for (i = 0; i < found_configs; i++ ) {
gabomdq@8015
   518
        bitdiff = 0;
gabomdq@8021
   519
        for (j = 0; j < SDL_arraysize(attribs) - 1; j += 2) {
gabomdq@8015
   520
            if (attribs[j] == EGL_NONE) {
gabomdq@8015
   521
               break;
gabomdq@8015
   522
            }
gabomdq@8015
   523
            
gabomdq@8015
   524
            if ( attribs[j+1] != EGL_DONT_CARE && (
gabomdq@8015
   525
                attribs[j] == EGL_RED_SIZE ||
gabomdq@8015
   526
                attribs[j] == EGL_GREEN_SIZE ||
gabomdq@8015
   527
                attribs[j] == EGL_BLUE_SIZE ||
gabomdq@8015
   528
                attribs[j] == EGL_ALPHA_SIZE ||
gabomdq@8015
   529
                attribs[j] == EGL_DEPTH_SIZE ||
gabomdq@8015
   530
                attribs[j] == EGL_STENCIL_SIZE)) {
gabomdq@8015
   531
                _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display, configs[i], attribs[j], &value);
gabomdq@8015
   532
                bitdiff += value - attribs[j + 1]; /* value is always >= attrib */
gabomdq@8015
   533
            }
gabomdq@8015
   534
        }
gabomdq@8015
   535
gabomdq@8015
   536
        if (bitdiff < best_bitdiff || best_bitdiff == -1) {
gabomdq@8015
   537
            _this->egl_data->egl_config = configs[i];
gabomdq@8015
   538
            
gabomdq@8015
   539
            best_bitdiff = bitdiff;
gabomdq@8015
   540
        }
slime73@9595
   541
slime73@9595
   542
        if (bitdiff == 0) {
slime73@9595
   543
            break; /* we found an exact match! */
slime73@9595
   544
        }
gabomdq@8015
   545
    }
gabomdq@8015
   546
    
gabomdq@7659
   547
    return 0;
gabomdq@7659
   548
}
gabomdq@7659
   549
gabomdq@7659
   550
SDL_GLContext
gabomdq@7659
   551
SDL_EGL_CreateContext(_THIS, EGLSurface egl_surface)
gabomdq@7659
   552
{
slime73@9595
   553
    /* max 14 values plus terminator. */
slime73@9595
   554
    EGLint attribs[15];
slime73@9595
   555
    int attr = 0;
slime73@9595
   556
gabomdq@8061
   557
    EGLContext egl_context, share_context = EGL_NO_CONTEXT;
slime73@9595
   558
    EGLint profile_mask = _this->gl_config.profile_mask;
slime73@9637
   559
    EGLint major_version = _this->gl_config.major_version;
slime73@9637
   560
    EGLint minor_version = _this->gl_config.minor_version;
slime73@9637
   561
    SDL_bool profile_es = (profile_mask == SDL_GL_CONTEXT_PROFILE_ES);
slime73@9595
   562
gabomdq@7659
   563
    if (!_this->egl_data) {
gabomdq@7659
   564
        /* The EGL library wasn't loaded, SDL_GetError() should have info */
gabomdq@7659
   565
        return NULL;
gabomdq@7659
   566
    }
slime73@9595
   567
gabomdq@8061
   568
    if (_this->gl_config.share_with_current_context) {
gabomdq@8061
   569
        share_context = (EGLContext)SDL_GL_GetCurrentContext();
gabomdq@7659
   570
    }
slime73@9595
   571
slime73@9595
   572
    /* Set the context version and other attributes. */
slime73@9637
   573
    if ((major_version < 3 || (minor_version == 0 && profile_es)) &&
slime73@9637
   574
        _this->gl_config.flags == 0 &&
slime73@9637
   575
        (profile_mask == 0 || profile_es)) {
slime73@9637
   576
        /* Create a context without using EGL_KHR_create_context attribs.
slime73@9637
   577
         * When creating a GLES context without EGL_KHR_create_context we can
slime73@9637
   578
         * only specify the major version. When creating a desktop GL context
slime73@9637
   579
         * we can't specify any version, so we only try in that case when the
slime73@9637
   580
         * version is less than 3.0 (matches SDL's GLX/WGL behavior.)
slime73@9637
   581
         */
slime73@9637
   582
        if (profile_es) {
slime73@9595
   583
            attribs[attr++] = EGL_CONTEXT_CLIENT_VERSION;
slime73@9637
   584
            attribs[attr++] = SDL_max(major_version, 1);
slime73@9595
   585
        }
slime73@9595
   586
    } else {
slime73@9595
   587
#ifdef EGL_KHR_create_context
slime73@9595
   588
        /* The Major/minor version, context profiles, and context flags can
slime73@9595
   589
         * only be specified when this extension is available.
slime73@9595
   590
         */
slouken@11175
   591
        if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context")) {
slime73@9595
   592
            attribs[attr++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
slime73@9637
   593
            attribs[attr++] = major_version;
slime73@9595
   594
            attribs[attr++] = EGL_CONTEXT_MINOR_VERSION_KHR;
slime73@9637
   595
            attribs[attr++] = minor_version;
slime73@9595
   596
slime73@9595
   597
            /* SDL profile bits match EGL profile bits. */
slime73@9595
   598
            if (profile_mask != 0 && profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
slime73@9595
   599
                attribs[attr++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
slime73@9595
   600
                attribs[attr++] = profile_mask;
slime73@9595
   601
            }
slime73@9595
   602
slime73@9595
   603
            /* SDL flags match EGL flags. */
slime73@9595
   604
            if (_this->gl_config.flags != 0) {
slime73@9595
   605
                attribs[attr++] = EGL_CONTEXT_FLAGS_KHR;
slime73@9595
   606
                attribs[attr++] = _this->gl_config.flags;
slime73@9595
   607
            }
slime73@9595
   608
        } else
slime73@9595
   609
#endif /* EGL_KHR_create_context */
slime73@9595
   610
        {
slime73@9595
   611
            SDL_SetError("Could not create EGL context (context attributes are not supported)");
slime73@9595
   612
            return NULL;
slime73@9595
   613
        }
slime73@9595
   614
    }
slime73@9595
   615
flibitijibibo@11347
   616
    if (_this->gl_config.no_error) {
flibitijibibo@11347
   617
#ifdef EGL_KHR_create_context_no_error
flibitijibibo@11347
   618
        if (SDL_EGL_HasExtension(_this, SDL_EGL_DISPLAY_EXTENSION, "EGL_KHR_create_context_no_error")) {
flibitijibibo@11347
   619
            attribs[attr++] = EGL_CONTEXT_OPENGL_NO_ERROR_KHR;
flibitijibibo@11347
   620
            attribs[attr++] = _this->gl_config.no_error;
flibitijibibo@11347
   621
        } else
flibitijibibo@11347
   622
#endif
flibitijibibo@11347
   623
        {
flibitijibibo@11347
   624
            SDL_SetError("EGL implementation does not support no_error contexts");
flibitijibibo@11347
   625
            return NULL;
flibitijibibo@11347
   626
        }
flibitijibibo@11347
   627
    }
flibitijibibo@11347
   628
slime73@9595
   629
    attribs[attr++] = EGL_NONE;
slime73@9595
   630
gabomdq@8062
   631
    /* Bind the API */
slime73@9637
   632
    if (profile_es) {
gabomdq@8062
   633
        _this->egl_data->eglBindAPI(EGL_OPENGL_ES_API);
slime73@9595
   634
    } else {
slime73@9595
   635
        _this->egl_data->eglBindAPI(EGL_OPENGL_API);
slime73@9595
   636
    }
gabomdq@7659
   637
slime73@9595
   638
    egl_context = _this->egl_data->eglCreateContext(_this->egl_data->egl_display,
slime73@9595
   639
                                      _this->egl_data->egl_config,
slime73@9595
   640
                                      share_context, attribs);
knut@8962
   641
gabomdq@7659
   642
    if (egl_context == EGL_NO_CONTEXT) {
dludwig@10740
   643
        SDL_EGL_SetError("Could not create EGL context", "eglCreateContext");
gabomdq@7659
   644
        return NULL;
gabomdq@7659
   645
    }
slime73@9595
   646
gabomdq@7659
   647
    _this->egl_data->egl_swapinterval = 0;
slime73@9595
   648
gabomdq@7659
   649
    if (SDL_EGL_MakeCurrent(_this, egl_surface, egl_context) < 0) {
dludwig@10740
   650
        /* Save the SDL error set by SDL_EGL_MakeCurrent */
dludwig@10740
   651
        char errorText[1024];
dludwig@10740
   652
        SDL_strlcpy(errorText, SDL_GetError(), SDL_arraysize(errorText));
dludwig@10740
   653
dludwig@10740
   654
        /* Delete the context, which may alter the value returned by SDL_GetError() */
gabomdq@7659
   655
        SDL_EGL_DeleteContext(_this, egl_context);
dludwig@10740
   656
dludwig@10740
   657
        /* Restore the SDL error */
dludwig@10740
   658
        SDL_SetError("%s", errorText);
dludwig@10740
   659
gabomdq@7659
   660
        return NULL;
gabomdq@7659
   661
    }
slime73@9595
   662
gabomdq@7659
   663
    return (SDL_GLContext) egl_context;
gabomdq@7659
   664
}
gabomdq@7659
   665
gabomdq@7659
   666
int
gabomdq@7659
   667
SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
gabomdq@7659
   668
{
gabomdq@7679
   669
    EGLContext egl_context = (EGLContext) context;
gabomdq@7679
   670
gabomdq@7659
   671
    if (!_this->egl_data) {
gabomdq@7659
   672
        return SDL_SetError("OpenGL not initialized");
gabomdq@7659
   673
    }
gabomdq@7659
   674
    
gabomdq@7659
   675
    /* The android emulator crashes badly if you try to eglMakeCurrent 
gabomdq@7659
   676
     * with a valid context and invalid surface, so we have to check for both here.
gabomdq@7659
   677
     */
gabomdq@7659
   678
    if (!egl_context || !egl_surface) {
gabomdq@7659
   679
         _this->egl_data->eglMakeCurrent(_this->egl_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
slime73@9595
   680
    } else {
gabomdq@7659
   681
        if (!_this->egl_data->eglMakeCurrent(_this->egl_data->egl_display,
gabomdq@7659
   682
            egl_surface, egl_surface, egl_context)) {
dludwig@10740
   683
            return SDL_EGL_SetError("Unable to make EGL context current", "eglMakeCurrent");
gabomdq@7659
   684
        }
gabomdq@7659
   685
    }
gabomdq@7659
   686
      
gabomdq@7659
   687
    return 0;
gabomdq@7659
   688
}
gabomdq@7659
   689
gabomdq@7659
   690
int
gabomdq@7659
   691
SDL_EGL_SetSwapInterval(_THIS, int interval)
gabomdq@7659
   692
{
gabomdq@7679
   693
    EGLBoolean status;
gabomdq@7679
   694
    
gabomdq@7702
   695
    if (!_this->egl_data) {
gabomdq@7702
   696
        return SDL_SetError("EGL not initialized");
gabomdq@7659
   697
    }
gabomdq@7659
   698
    
gabomdq@7659
   699
    status = _this->egl_data->eglSwapInterval(_this->egl_data->egl_display, interval);
gabomdq@7659
   700
    if (status == EGL_TRUE) {
gabomdq@7659
   701
        _this->egl_data->egl_swapinterval = interval;
gabomdq@7659
   702
        return 0;
gabomdq@7659
   703
    }
gabomdq@7659
   704
    
dludwig@10740
   705
    return SDL_EGL_SetError("Unable to set the EGL swap interval", "eglSwapInterval");
gabomdq@7659
   706
}
gabomdq@7659
   707
gabomdq@7659
   708
int
gabomdq@7659
   709
SDL_EGL_GetSwapInterval(_THIS)
gabomdq@7659
   710
{
gabomdq@7702
   711
    if (!_this->egl_data) {
philipp@10169
   712
        SDL_SetError("EGL not initialized");
philipp@10169
   713
        return 0;
gabomdq@7659
   714
    }
gabomdq@7659
   715
    
gabomdq@7659
   716
    return _this->egl_data->egl_swapinterval;
gabomdq@7659
   717
}
gabomdq@7659
   718
slouken@10693
   719
int
gabomdq@7659
   720
SDL_EGL_SwapBuffers(_THIS, EGLSurface egl_surface)
gabomdq@7659
   721
{
slouken@10693
   722
    if (!_this->egl_data->eglSwapBuffers(_this->egl_data->egl_display, egl_surface)) {
dludwig@10740
   723
        return SDL_EGL_SetError("unable to show color buffer in an OS-native window", "eglSwapBuffers");
slouken@10693
   724
    }
slouken@10693
   725
    return 0;
gabomdq@7659
   726
}
gabomdq@7659
   727
gabomdq@7659
   728
void
gabomdq@7659
   729
SDL_EGL_DeleteContext(_THIS, SDL_GLContext context)
gabomdq@7659
   730
{
gabomdq@7679
   731
    EGLContext egl_context = (EGLContext) context;
gabomdq@7679
   732
gabomdq@7659
   733
    /* Clean up GLES and EGL */
gabomdq@7659
   734
    if (!_this->egl_data) {
gabomdq@7659
   735
        return;
gabomdq@7659
   736
    }
gabomdq@7659
   737
    
gabomdq@7896
   738
    if (egl_context != NULL && egl_context != EGL_NO_CONTEXT) {
gabomdq@7659
   739
        SDL_EGL_MakeCurrent(_this, NULL, NULL);
gabomdq@7659
   740
        _this->egl_data->eglDestroyContext(_this->egl_data->egl_display, egl_context);
gabomdq@7659
   741
    }
gabomdq@7659
   742
        
gabomdq@7659
   743
}
gabomdq@7659
   744
gabomdq@7659
   745
EGLSurface *
gabomdq@7659
   746
SDL_EGL_CreateSurface(_THIS, NativeWindowType nw) 
gabomdq@7659
   747
{
dludwig@10740
   748
    EGLSurface * surface;
dludwig@10740
   749
gabomdq@8041
   750
    if (SDL_EGL_ChooseConfig(_this) != 0) {
slouken@8045
   751
        return EGL_NO_SURFACE;
gabomdq@8041
   752
    }
gabomdq@8041
   753
    
slouken@10878
   754
#if SDL_VIDEO_DRIVER_ANDROID
slouken@8976
   755
    {
slouken@8976
   756
        /* Android docs recommend doing this!
slouken@8976
   757
         * Ref: http://developer.android.com/reference/android/app/NativeActivity.html 
slouken@8976
   758
         */
slouken@8976
   759
        EGLint format;
slouken@8976
   760
        _this->egl_data->eglGetConfigAttrib(_this->egl_data->egl_display,
slouken@8976
   761
                                            _this->egl_data->egl_config, 
slouken@8976
   762
                                            EGL_NATIVE_VISUAL_ID, &format);
gabomdq@8971
   763
slouken@8976
   764
        ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
slouken@8976
   765
    }
gabomdq@8971
   766
#endif    
gabomdq@8971
   767
    
dludwig@10740
   768
    surface = _this->egl_data->eglCreateWindowSurface(
gabomdq@7659
   769
            _this->egl_data->egl_display,
gabomdq@7659
   770
            _this->egl_data->egl_config,
gabomdq@7659
   771
            nw, NULL);
dludwig@10740
   772
    if (surface == EGL_NO_SURFACE) {
dludwig@10740
   773
        SDL_EGL_SetError("unable to create an EGL window surface", "eglCreateWindowSurface");
dludwig@10740
   774
    }
dludwig@10740
   775
    return surface;
gabomdq@7659
   776
}
gabomdq@7659
   777
gabomdq@7659
   778
void
gabomdq@7659
   779
SDL_EGL_DestroySurface(_THIS, EGLSurface egl_surface) 
gabomdq@7659
   780
{
gabomdq@7659
   781
    if (!_this->egl_data) {
gabomdq@7659
   782
        return;
gabomdq@7659
   783
    }
gabomdq@7659
   784
    
gabomdq@7659
   785
    if (egl_surface != EGL_NO_SURFACE) {
gabomdq@7659
   786
        _this->egl_data->eglDestroySurface(_this->egl_data->egl_display, egl_surface);
gabomdq@7659
   787
    }
gabomdq@7659
   788
}
gabomdq@7659
   789
gabomdq@7659
   790
#endif /* SDL_VIDEO_OPENGL_EGL */
gabomdq@7659
   791
gabomdq@7659
   792
/* vi: set ts=4 sw=4 expandtab: */
philipp@11192
   793