21 #include "../SDL_internal.h"
23 #if SDL_VIDEO_OPENGL_EGL
25 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
26 #include "../core/windows/SDL_windows.h"
28 #if SDL_VIDEO_DRIVER_ANDROID
29 #include <android/native_window.h>
30 #include "../core/android/SDL_android.h"
39 #ifdef EGL_KHR_create_context
41 #ifndef EGL_OPENGL_ES3_BIT_KHR
42 #define EGL_OPENGL_ES3_BIT_KHR 0x00000040
46 #if SDL_VIDEO_DRIVER_RPI
48 #define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" )
49 #define DEFAULT_OGL_ES2 ( vc4 ? "libGLESv2.so.2" : "libbrcmGLESv2.so" )
50 #define ALT_EGL "libEGL.so"
51 #define ALT_OGL_ES2 "libGLESv2.so"
52 #define DEFAULT_OGL_ES_PVR ( vc4 ? "libGLES_CM.so.1" : "libbrcmGLESv2.so" )
53 #define DEFAULT_OGL_ES ( vc4 ? "libGLESv1_CM.so.1" : "libbrcmGLESv2.so" )
55 #elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_VIVANTE
57 #define DEFAULT_EGL "libEGL.so"
58 #define DEFAULT_OGL_ES2 "libGLESv2.so"
59 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
60 #define DEFAULT_OGL_ES "libGLESv1_CM.so"
62 #elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
64 #define DEFAULT_EGL "libEGL.dll"
65 #define DEFAULT_OGL_ES2 "libGLESv2.dll"
66 #define DEFAULT_OGL_ES_PVR "libGLES_CM.dll"
67 #define DEFAULT_OGL_ES "libGLESv1_CM.dll"
69 #elif SDL_VIDEO_DRIVER_COCOA
71 #define DEFAULT_EGL "libEGL.dylib"
72 #define DEFAULT_OGL_ES2 "libGLESv2.dylib"
73 #define DEFAULT_OGL_ES_PVR "libGLES_CM.dylib" //???
74 #define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //???
78 #define DEFAULT_OGL "libGL.so.1"
79 #define DEFAULT_EGL "libEGL.so.1"
80 #define DEFAULT_OGL_ES2 "libGLESv2.so.2"
81 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
82 #define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
85 #ifdef SDL_VIDEO_STATIC_ANGLE
86 #define LOAD_FUNC(NAME) \
87 _this->egl_data->NAME = (void *)NAME;
89 #define LOAD_FUNC(NAME) \
90 _this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
91 if (!_this->egl_data->NAME) \
93 return SDL_SetError("Could not retrieve EGL function " #NAME); \
97 static const char * SDL_EGL_GetErrorName(
EGLint eglErrorCode)
99 #define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e;
100 switch (eglErrorCode) {
120 int SDL_EGL_SetErrorEx(
const char *
message,
const char * eglFunctionName,
EGLint eglErrorCode)
122 const char * errorText = SDL_EGL_GetErrorName(eglErrorCode);
123 char altErrorText[32];
124 if (errorText[0] ==
'\0') {
127 errorText = altErrorText;
129 return SDL_SetError(
"%s (call to %s failed, reporting an error of %s)",
message, eglFunctionName, errorText);
134 SDL_EGL_DISPLAY_EXTENSION,
135 SDL_EGL_CLIENT_EXTENSION
136 } SDL_EGL_ExtensionType;
138 static SDL_bool SDL_EGL_HasExtension(
_THIS, SDL_EGL_ExtensionType
type,
const char *ext)
141 const char *ext_override;
142 const char *egl_extstr;
143 const char *ext_start;
159 if (ext_override !=
NULL) {
160 int disable_ext =
SDL_atoi(ext_override);
161 if (disable_ext & 0x01 &&
type == SDL_EGL_DISPLAY_EXTENSION) {
163 }
else if (disable_ext & 0x02 &&
type == SDL_EGL_CLIENT_EXTENSION) {
170 case SDL_EGL_DISPLAY_EXTENSION:
173 case SDL_EGL_CLIENT_EXTENSION:
185 if (egl_extstr !=
NULL) {
186 ext_start = egl_extstr;
190 if (ext_start ==
NULL) {
194 if (ext_start == egl_extstr || *(ext_start - 1) ==
' ') {
195 if (ext_start[ext_len] ==
' ' || ext_start[ext_len] == 0) {
200 ext_start += ext_len;
201 while (*ext_start !=
' ' && *ext_start != 0) {
211 SDL_EGL_GetProcAddress(
_THIS,
const char *proc)
213 static char procname[1024];
217 #if !defined(SDL_VIDEO_DRIVER_ANDROID)
218 if (
_this->egl_data->eglGetProcAddress) {
236 SDL_EGL_UnloadLibrary(
_THIS)
238 if (
_this->egl_data) {
239 if (
_this->egl_data->egl_display) {
240 _this->egl_data->eglTerminate(
_this->egl_data->egl_display);
248 if (
_this->egl_data->egl_dll_handle) {
261 void *dll_handle =
NULL, *egl_dll_handle =
NULL;
263 int egl_version_major = 0, egl_version_minor = 0;
264 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
265 const char *d3dcompiler;
267 #if SDL_VIDEO_DRIVER_RPI
271 if (
_this->egl_data) {
275 _this->egl_data = (
struct SDL_EGL_VideoData *)
SDL_calloc(1,
sizeof(SDL_EGL_VideoData));
276 if (!
_this->egl_data) {
280 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
291 const char *d3dcompiler_list[] = {
292 "d3dcompiler_47.dll",
"d3dcompiler_46.dll",
310 #ifndef SDL_VIDEO_STATIC_ANGLE
317 if (egl_dll_handle ==
NULL) {
320 path = DEFAULT_OGL_ES2;
323 if (egl_dll_handle ==
NULL && !vc4) {
330 path = DEFAULT_OGL_ES;
332 if (egl_dll_handle ==
NULL) {
333 path = DEFAULT_OGL_ES_PVR;
337 if (egl_dll_handle ==
NULL && !vc4) {
351 _this->egl_data->egl_dll_handle = egl_dll_handle;
353 if (egl_dll_handle ==
NULL) {
354 return SDL_SetError(
"Could not initialize OpenGL / GLES library");
358 if (egl_path !=
NULL) {
363 if (dll_handle !=
NULL) {
373 if (dll_handle ==
NULL && !vc4) {
380 if (dll_handle !=
NULL) {
412 if (
_this->egl_data->eglQueryString) {
415 if (egl_version !=
NULL) {
416 if (
SDL_sscanf(egl_version,
"%d.%d", &egl_version_major, &egl_version_minor) != 2) {
417 egl_version_major = 0;
418 egl_version_minor = 0;
424 _this->egl_data->egl_version_major = egl_version_major;
425 _this->egl_data->egl_version_minor = egl_version_minor;
427 if (egl_version_major == 1 && egl_version_minor == 5) {
432 #if !defined(__WINRT__)
434 if (egl_version_major == 1 && egl_version_minor == 5) {
437 if (SDL_EGL_HasExtension(
_this, SDL_EGL_CLIENT_EXTENSION,
"EGL_EXT_platform_base")) {
438 _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(
_this,
"eglGetPlatformDisplayEXT");
439 if (
_this->egl_data->eglGetPlatformDisplayEXT) {
468 SDL_EGL_SetRequiredVisualId(
_THIS,
int visual_id)
470 _this->egl_data->egl_required_visual_id=visual_id;
473 #ifdef DUMP_EGL_CONFIG
475 #define ATTRIBUTE(_attr) { _attr, #_attr }
482 Attribute attributes[] = {
522 for (attr = 0 ; attr<
sizeof(attributes)/
sizeof(Attribute) ; attr++) {
524 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display,
config, attributes[attr].attribute, &
value);
532 SDL_EGL_ChooseConfig(
_THIS)
539 int i,
j, best_bitdiff = -1, bitdiff;
541 if (!
_this->egl_data) {
585 #ifdef EGL_KHR_create_context
587 SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context")) {
602 if (
_this->egl_data->egl_surfacetype) {
609 if (
_this->egl_data->eglChooseConfig(
_this->egl_data->egl_display,
613 found_configs == 0) {
614 return SDL_EGL_SetError(
"Couldn't find matching EGL config",
"eglChooseConfig");
620 for (
i = 0;
i < found_configs;
i++ ) {
621 if (
_this->egl_data->egl_required_visual_id)
624 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display,
627 if (
_this->egl_data->egl_required_visual_id !=
format)
649 if (bitdiff < best_bitdiff || best_bitdiff == -1) {
650 _this->egl_data->egl_config = configs[
i];
652 best_bitdiff = bitdiff;
660 #ifdef DUMP_EGL_CONFIG
661 dumpconfig(
_this,
_this->egl_data->egl_config);
680 if (!
_this->egl_data) {
689 #if SDL_VIDEO_DRIVER_ANDROID
697 int egl_version_major =
_this->egl_data->egl_version_major;
698 int egl_version_minor =
_this->egl_data->egl_version_minor;
699 if (((egl_version_major < 1) || (egl_version_major == 1 && egl_version_minor < 5)) &&
700 !SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_debug")) {
708 if ((major_version < 3 || (minor_version == 0 && profile_es)) &&
710 (profile_mask == 0 || profile_es)) {
722 #ifdef EGL_KHR_create_context
726 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context")) {
728 attribs[attr++] = major_version;
730 attribs[attr++] = minor_version;
735 attribs[attr++] = profile_mask;
746 SDL_SetError(
"Could not create EGL context (context attributes are not supported)");
752 #ifdef EGL_KHR_create_context_no_error
753 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context_no_error")) {
759 SDL_SetError(
"EGL implementation does not support no_error contexts");
773 egl_context =
_this->egl_data->eglCreateContext(
_this->egl_data->egl_display,
774 _this->egl_data->egl_config,
778 SDL_EGL_SetError(
"Could not create EGL context",
"eglCreateContext");
782 _this->egl_data->egl_swapinterval = 0;
784 if (SDL_EGL_MakeCurrent(
_this, egl_surface, egl_context) < 0) {
786 char errorText[1024];
790 SDL_EGL_DeleteContext(
_this, egl_context);
806 if (!
_this->egl_data) {
813 if (!egl_context || !egl_surface) {
816 if (!
_this->egl_data->eglMakeCurrent(
_this->egl_data->egl_display,
817 egl_surface, egl_surface, egl_context)) {
818 return SDL_EGL_SetError(
"Unable to make EGL context current",
"eglMakeCurrent");
826 SDL_EGL_SetSwapInterval(
_THIS,
int interval)
830 if (!
_this->egl_data) {
834 status =
_this->egl_data->eglSwapInterval(
_this->egl_data->egl_display, interval);
836 _this->egl_data->egl_swapinterval = interval;
840 return SDL_EGL_SetError(
"Unable to set the EGL swap interval",
"eglSwapInterval");
844 SDL_EGL_GetSwapInterval(
_THIS)
846 if (!
_this->egl_data) {
851 return _this->egl_data->egl_swapinterval;
857 if (!
_this->egl_data->eglSwapBuffers(
_this->egl_data->egl_display, egl_surface)) {
858 return SDL_EGL_SetError(
"unable to show color buffer in an OS-native window",
"eglSwapBuffers");
869 if (!
_this->egl_data) {
874 _this->egl_data->eglDestroyContext(
_this->egl_data->egl_display, egl_context);
888 if (SDL_EGL_ChooseConfig(
_this) != 0) {
892 #if SDL_VIDEO_DRIVER_ANDROID
898 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display,
899 _this->egl_data->egl_config,
902 ANativeWindow_setBuffersGeometry(nw, 0, 0,
format);
910 #ifdef EGL_KHR_gl_colorspace
911 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_gl_colorspace")) {
917 SDL_SetError(
"EGL implementation does not support sRGB system framebuffers");
925 _this->egl_data->egl_display,
926 _this->egl_data->egl_config,
929 SDL_EGL_SetError(
"unable to create an EGL window surface",
"eglCreateWindowSurface");
937 if (!
_this->egl_data) {
942 _this->egl_data->eglDestroySurface(
_this->egl_data->egl_display, egl_surface);