@@ -31,6 +31,13 @@
#include " SDL_loadso.h"
#include " SDL_hints.h"
#ifdef EGL_KHR_create_context
/* EGL_OPENGL_ES3_BIT_KHR was added in version 13 of the extension. */
#ifndef EGL_OPENGL_ES3_BIT_KHR
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
#endif
#endif /* EGL_KHR_create_context */
#if SDL_VIDEO_DRIVER_RPI
/* Raspbian places the OpenGL ES/EGL binaries in a non standard path */
#define DEFAULT_EGL " /opt/vc/lib/libEGL.so"
@@ -81,19 +88,18 @@ static int SDL_EGL_HasExtension(_THIS, const char *ext)
ext_len = SDL_strlen (ext);
exts = _this->egl_data ->eglQueryString (_this->egl_data ->egl_display , EGL_EXTENSIONS);
if (exts) {
if (exts) {
ext_word = exts;
for (i = 0 ; exts[i] != 0 ; i++) {
if (exts[i] == ' ' ) {
if (ext_len == len && !SDL_strncmp (ext_word, ext, len)) {
for (i = 0 ; exts[i] != 0 ; i++) {
if (exts[i] == ' ' ) {
if (ext_len == len && !SDL_strncmp (ext_word, ext, len)) {
return 1 ;
}
len = 0 ;
ext_word = &exts[i + 1 ];
}
else {
} else {
len++;
}
}
@@ -190,12 +196,11 @@ SDL_EGL_LoadLibrary(_THIS, const char *egl_path, NativeDisplayType native_displa
}
if (egl_dll_handle == NULL ) {
if (_this->gl_config .profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
if (_this->gl_config .profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
if (_this->gl_config .major_version > 1 ) {
path = DEFAULT_OGL_ES2;
egl_dll_handle = SDL_LoadObject (path);
}
else {
} else {
path = DEFAULT_OGL_ES;
egl_dll_handle = SDL_LoadObject (path);
if (egl_dll_handle == NULL ) {
@@ -334,17 +339,22 @@ SDL_EGL_ChooseConfig(_THIS)
attribs[i++] = EGL_SAMPLES;
attribs[i++] = _this->gl_config .multisamplesamples ;
}
attribs[i++] = EGL_RENDERABLE_TYPE;
if (_this->gl_config .profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
if (_this->gl_config .major_version == 2 ) {
if (_this->gl_config .profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
#ifdef EGL_KHR_create_context
if (_this->gl_config .major_version >= 3 &&
SDL_EGL_HasExtension (_this, " EGL_KHR_create_context" )) {
attribs[i++] = EGL_OPENGL_ES3_BIT_KHR;
} else
#endif
if (_this->gl_config .major_version >= 2 ) {
attribs[i++] = EGL_OPENGL_ES2_BIT;
} else {
attribs[i++] = EGL_OPENGL_ES_BIT;
}
_this->egl_data ->eglBindAPI (EGL_OPENGL_ES_API);
}
else {
} else {
attribs[i++] = EGL_OPENGL_BIT;
_this->egl_data ->eglBindAPI (EGL_OPENGL_API);
}
@@ -362,7 +372,7 @@ SDL_EGL_ChooseConfig(_THIS)
/* eglChooseConfig returns a number of configurations that match or exceed the requested attribs. */
/* From those, we select the one that matches our requirements more closely via a makeshift algorithm */
for ( i= 0 ; i< found_configs; i++ ) {
for (i = 0 ; i < found_configs; i++ ) {
bitdiff = 0 ;
for (j = 0 ; j < SDL_arraysize (attribs) - 1 ; j += 2 ) {
if (attribs[j] == EGL_NONE) {
@@ -386,8 +396,10 @@ SDL_EGL_ChooseConfig(_THIS)
best_bitdiff = bitdiff;
}
if (bitdiff == 0 ) break ; /* we found an exact match! */
if (bitdiff == 0 ) {
break ; /* we found an exact match! */
}
}
return 0 ;
@@ -396,82 +408,86 @@ SDL_EGL_ChooseConfig(_THIS)
SDL_GLContext
SDL_EGL_CreateContext (_THIS, EGLSurface egl_surface)
{
EGLint context_attrib_list[] = {
EGL_CONTEXT_CLIENT_VERSION,
1 ,
EGL_NONE,
EGL_NONE,
EGL_NONE,
EGL_NONE,
EGL_NONE
};
/* max 14 values plus terminator. */
EGLint attribs[15 ];
int attr = 0 ;
EGLContext egl_context, share_context = EGL_NO_CONTEXT;
EGLint profile_mask = _this->gl_config .profile_mask ;
if (!_this->egl_data ) {
/* The EGL library wasn't loaded, SDL_GetError() should have info */
return NULL ;
}
if (_this->gl_config .share_with_current_context ) {
share_context = (EGLContext)SDL_GL_GetCurrentContext ();
}
/* Bind the API */
if (_this->gl_config .profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
_this->egl_data ->eglBindAPI (EGL_OPENGL_ES_API);
if (_this->gl_config .major_version ) {
context_attrib_list[1 ] = _this->gl_config .major_version ;
/* Set the context version and other attributes. */
if (_this->gl_config .major_version < 3 && _this->gl_config .flags == 0 &&
(profile_mask == 0 || profile_mask == SDL_GL_CONTEXT_PROFILE_ES)) {
/* Create a context without using EGL_KHR_create_context attribs. */
if (profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
attribs[attr++] = EGL_CONTEXT_CLIENT_VERSION;
attribs[attr++] = SDL_max (_this->gl_config .major_version , 1 );
}
} else {
#ifdef EGL_KHR_create_context
/* The Major/minor version, context profiles, and context flags can
* only be specified when this extension is available.
*/
if (SDL_EGL_HasExtension (_this, " EGL_KHR_create_context" )) {
attribs[attr++] = EGL_CONTEXT_MAJOR_VERSION_KHR;
attribs[attr++] = _this->gl_config .major_version ;
attribs[attr++] = EGL_CONTEXT_MINOR_VERSION_KHR;
attribs[attr++] = _this->gl_config .minor_version ;
/* SDL profile bits match EGL profile bits. */
if (profile_mask != 0 && profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
attribs[attr++] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
attribs[attr++] = profile_mask;
}
egl_context = _this->egl_data ->eglCreateContext (_this->egl_data ->egl_display ,
_this->egl_data ->egl_config ,
share_context, context_attrib_list);
}
else {
_this->egl_data ->eglBindAPI (EGL_OPENGL_API);
#ifdef EGL_KHR_create_context
if (SDL_EGL_HasExtension (_this, " EGL_KHR_create_context" )) {
context_attrib_list[0 ] = EGL_CONTEXT_MAJOR_VERSION_KHR;
context_attrib_list[1 ] = _this->gl_config .major_version ;
context_attrib_list[2 ] = EGL_CONTEXT_MINOR_VERSION_KHR;
context_attrib_list[3 ] = _this->gl_config .minor_version ;
context_attrib_list[4 ] = EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR;
switch (_this->gl_config .profile_mask ) {
case SDL_GL_CONTEXT_PROFILE_COMPATIBILITY:
context_attrib_list[5 ] = EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
break ;
case SDL_GL_CONTEXT_PROFILE_CORE:
default :
context_attrib_list[5 ] = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
break ;
/* SDL flags match EGL flags. */
if (_this->gl_config .flags != 0 ) {
attribs[attr++] = EGL_CONTEXT_FLAGS_KHR;
attribs[attr++] = _this->gl_config .flags ;
}
}
else {
context_attrib_list[0 ] = EGL_NONE;
}
#else /* EGL_KHR_create_context */
context_attrib_list[0 ] = EGL_NONE;
} else
#endif /* EGL_KHR_create_context */
egl_context = _this->egl_data ->eglCreateContext (_this->egl_data ->egl_display ,
_this->egl_data ->egl_config ,
share_context, context_attrib_list);
{
SDL_SetError (" Could not create EGL context (context attributes are not supported)" );
return NULL ;
}
}
attribs[attr++] = EGL_NONE;
/* Bind the API */
if (_this->gl_config .profile_mask == SDL_GL_CONTEXT_PROFILE_ES) {
_this->egl_data ->eglBindAPI (EGL_OPENGL_ES_API);
} else {
_this->egl_data ->eglBindAPI (EGL_OPENGL_API);
}
egl_context = _this->egl_data ->eglCreateContext (_this->egl_data ->egl_display ,
_this->egl_data ->egl_config ,
share_context, attribs);
if (egl_context == EGL_NO_CONTEXT) {
SDL_SetError (" Could not create EGL context" );
return NULL ;
}
_this->egl_data ->egl_swapinterval = 0 ;
if (SDL_EGL_MakeCurrent (_this, egl_surface, egl_context) < 0 ) {
SDL_EGL_DeleteContext (_this, egl_context);
SDL_SetError (" Could not make EGL context current" );
return NULL ;
}
return (SDL_GLContext) egl_context;
}
@@ -489,8 +505,7 @@ SDL_EGL_MakeCurrent(_THIS, EGLSurface egl_surface, SDL_GLContext context)
*/
if (!egl_context || !egl_surface) {
_this->egl_data ->eglMakeCurrent (_this->egl_data ->egl_display , EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
else {
} else {
if (!_this->egl_data ->eglMakeCurrent (_this->egl_data ->egl_display ,
egl_surface, egl_surface, egl_context)) {
return SDL_SetError (" Unable to make EGL context current" );