src/video/SDL_egl.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 02 Aug 2017 10:22:48 -0700
changeset 11175 cbc6a8a5b701
parent 10878 7fa08228d9e3
child 11192 3c8377f1a323
permissions -rw-r--r--
Fixed bug 3690 - SDL2 KMS/DRM render context support

Manuel

The attached patch adds support for KMS/DRM context graphics.

It builds with no problem on X86_64 GNU/Linux systems, provided the needed libraries are present, and on ARM GNU/Linux systems that have KMS/DRM support and a GLES2 implementation.
Tested on Raspberry Pi: KMS/DRM is what the Raspberry Pi will use as default in the near future, once the propietary DispmanX API by Broadcom is overtaken by open graphics stack, it's possible to boot current Raspbian system in KMS mode by adding "dtoverlay=vc4-kms-v3d" to config.txt on Raspbian's boot partition.
X86 systems use KMS right away in every current GNU/Linux system.

Simple build instructions:

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