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>
38 #ifdef EGL_KHR_create_context
40 #ifndef EGL_OPENGL_ES3_BIT_KHR
41 #define EGL_OPENGL_ES3_BIT_KHR 0x00000040
45 #if SDL_VIDEO_DRIVER_RPI
47 #define DEFAULT_EGL ( vc4 ? "libEGL.so.1" : "libbrcmEGL.so" )
48 #define DEFAULT_OGL_ES2 ( vc4 ? "libGLESv2.so.2" : "libbrcmGLESv2.so" )
49 #define ALT_EGL "libEGL.so"
50 #define ALT_OGL_ES2 "libGLESv2.so"
51 #define DEFAULT_OGL_ES_PVR ( vc4 ? "libGLES_CM.so.1" : "libbrcmGLESv2.so" )
52 #define DEFAULT_OGL_ES ( vc4 ? "libGLESv1_CM.so.1" : "libbrcmGLESv2.so" )
54 #elif SDL_VIDEO_DRIVER_ANDROID || SDL_VIDEO_DRIVER_VIVANTE
56 #define DEFAULT_EGL "libEGL.so"
57 #define DEFAULT_OGL_ES2 "libGLESv2.so"
58 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so"
59 #define DEFAULT_OGL_ES "libGLESv1_CM.so"
61 #elif SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
63 #define DEFAULT_EGL "libEGL.dll"
64 #define DEFAULT_OGL_ES2 "libGLESv2.dll"
65 #define DEFAULT_OGL_ES_PVR "libGLES_CM.dll"
66 #define DEFAULT_OGL_ES "libGLESv1_CM.dll"
68 #elif SDL_VIDEO_DRIVER_COCOA
70 #define DEFAULT_EGL "libEGL.dylib"
71 #define DEFAULT_OGL_ES2 "libGLESv2.dylib"
72 #define DEFAULT_OGL_ES_PVR "libGLES_CM.dylib" //???
73 #define DEFAULT_OGL_ES "libGLESv1_CM.dylib" //???
77 #define DEFAULT_OGL "libGL.so.1"
78 #define DEFAULT_EGL "libEGL.so.1"
79 #define DEFAULT_OGL_ES2 "libGLESv2.so.2"
80 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1"
81 #define DEFAULT_OGL_ES "libGLESv1_CM.so.1"
84 #ifdef SDL_VIDEO_STATIC_ANGLE
85 #define LOAD_FUNC(NAME) \
86 _this->egl_data->NAME = (void *)NAME;
88 #define LOAD_FUNC(NAME) \
89 _this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \
90 if (!_this->egl_data->NAME) \
92 return SDL_SetError("Could not retrieve EGL function " #NAME); \
96 static const char * SDL_EGL_GetErrorName(
EGLint eglErrorCode)
98 #define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e;
99 switch (eglErrorCode) {
119 int SDL_EGL_SetErrorEx(
const char *
message,
const char * eglFunctionName,
EGLint eglErrorCode)
121 const char * errorText = SDL_EGL_GetErrorName(eglErrorCode);
122 char altErrorText[32];
123 if (errorText[0] ==
'\0') {
126 errorText = altErrorText;
128 return SDL_SetError(
"%s (call to %s failed, reporting an error of %s)", message, eglFunctionName, errorText);
133 SDL_EGL_DISPLAY_EXTENSION,
134 SDL_EGL_CLIENT_EXTENSION
135 } SDL_EGL_ExtensionType;
137 static SDL_bool SDL_EGL_HasExtension(
_THIS, SDL_EGL_ExtensionType
type,
const char *ext)
140 const char *ext_override;
141 const char *egl_extstr;
142 const char *ext_start;
158 if (ext_override !=
NULL) {
159 int disable_ext =
SDL_atoi(ext_override);
160 if (disable_ext & 0x01 && type == SDL_EGL_DISPLAY_EXTENSION) {
162 }
else if (disable_ext & 0x02 && type == SDL_EGL_CLIENT_EXTENSION) {
169 case SDL_EGL_DISPLAY_EXTENSION:
172 case SDL_EGL_CLIENT_EXTENSION:
184 if (egl_extstr !=
NULL) {
185 ext_start = egl_extstr;
189 if (ext_start ==
NULL) {
193 if (ext_start == egl_extstr || *(ext_start - 1) ==
' ') {
194 if (ext_start[ext_len] ==
' ' || ext_start[ext_len] == 0) {
199 ext_start += ext_len;
200 while (*ext_start !=
' ' && *ext_start != 0) {
210 SDL_EGL_GetProcAddress(
_THIS,
const char *proc)
212 static char procname[1024];
216 #if !defined(SDL_VIDEO_DRIVER_ANDROID)
217 if (
_this->egl_data->eglGetProcAddress) {
218 retval =
_this->egl_data->eglGetProcAddress(proc);
235 SDL_EGL_UnloadLibrary(
_THIS)
237 if (
_this->egl_data) {
238 if (
_this->egl_data->egl_display) {
239 _this->egl_data->eglTerminate(
_this->egl_data->egl_display);
247 if (
_this->egl_data->egl_dll_handle) {
260 void *dll_handle =
NULL, *egl_dll_handle =
NULL;
262 int egl_version_major = 0, egl_version_minor = 0;
263 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
264 const char *d3dcompiler;
266 #if SDL_VIDEO_DRIVER_RPI
270 if (
_this->egl_data) {
274 _this->egl_data = (
struct SDL_EGL_VideoData *)
SDL_calloc(1,
sizeof(SDL_EGL_VideoData));
275 if (!
_this->egl_data) {
279 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT
283 d3dcompiler =
"d3dcompiler_46.dll";
285 d3dcompiler =
"d3dcompiler_43.dll";
295 #ifndef SDL_VIDEO_STATIC_ANGLE
302 if (egl_dll_handle ==
NULL) {
305 path = DEFAULT_OGL_ES2;
308 if (egl_dll_handle ==
NULL && !vc4) {
315 path = DEFAULT_OGL_ES;
317 if (egl_dll_handle ==
NULL) {
318 path = DEFAULT_OGL_ES_PVR;
322 if (egl_dll_handle ==
NULL && !vc4) {
336 _this->egl_data->egl_dll_handle = egl_dll_handle;
338 if (egl_dll_handle ==
NULL) {
339 return SDL_SetError(
"Could not initialize OpenGL / GLES library");
343 if (egl_path !=
NULL) {
348 if (dll_handle !=
NULL) {
358 if (dll_handle ==
NULL && !vc4) {
365 if (dll_handle !=
NULL) {
397 if (
_this->egl_data->eglQueryString) {
400 if (egl_version !=
NULL) {
401 if (
SDL_sscanf(egl_version,
"%d.%d", &egl_version_major, &egl_version_minor) != 2) {
402 egl_version_major = 0;
403 egl_version_minor = 0;
409 _this->egl_data->egl_version_major = egl_version_major;
410 _this->egl_data->egl_version_minor = egl_version_minor;
412 if (egl_version_major == 1 && egl_version_minor == 5) {
417 #if !defined(__WINRT__)
419 if (egl_version_major == 1 && egl_version_minor == 5) {
420 _this->egl_data->egl_display =
_this->egl_data->eglGetPlatformDisplay(platform, (
void *)(
size_t)native_display,
NULL);
422 if (SDL_EGL_HasExtension(
_this, SDL_EGL_CLIENT_EXTENSION,
"EGL_EXT_platform_base")) {
423 _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(
_this,
"eglGetPlatformDisplayEXT");
424 if (
_this->egl_data->eglGetPlatformDisplayEXT) {
425 _this->egl_data->egl_display =
_this->egl_data->eglGetPlatformDisplayEXT(platform, (
void *)(
size_t)native_display,
NULL);
432 _this->egl_data->egl_display =
_this->egl_data->eglGetDisplay(native_display);
452 #ifdef DUMP_EGL_CONFIG
454 #define ATTRIBUTE(_attr) { _attr, #_attr }
461 Attribute attributes[] = {
501 for (attr = 0 ; attr<
sizeof(attributes)/
sizeof(Attribute) ; attr++) {
503 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display, config, attributes[attr].attribute, &value);
504 SDL_Log(
"\t%-32s: %10d (0x%08x)\n", attributes[attr].
name, value, value);
511 SDL_EGL_ChooseConfig(
_THIS)
516 #ifdef SDL_VIDEO_DRIVER_KMSDRM
524 int i,
j, best_bitdiff = -1, bitdiff;
526 if (!
_this->egl_data) {
570 #ifdef EGL_KHR_create_context
572 SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context")) {
587 if (
_this->egl_data->egl_surfacetype) {
589 attribs[i++] =
_this->egl_data->egl_surfacetype;
594 if (
_this->egl_data->eglChooseConfig(
_this->egl_data->egl_display,
598 found_configs == 0) {
599 return SDL_EGL_SetError(
"Couldn't find matching EGL config",
"eglChooseConfig");
605 for (i = 0; i < found_configs; i++ ) {
619 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display, configs[i], attribs[j], &
value);
620 bitdiff +=
value - attribs[j + 1];
624 if (bitdiff < best_bitdiff || best_bitdiff == -1) {
625 _this->egl_data->egl_config = configs[
i];
627 best_bitdiff = bitdiff;
635 #ifdef DUMP_EGL_CONFIG
636 dumpconfig(
_this,
_this->egl_data->egl_config);
655 if (!
_this->egl_data) {
664 #if SDL_VIDEO_DRIVER_ANDROID
672 int egl_version_major =
_this->egl_data->egl_version_major;
673 int egl_version_minor =
_this->egl_data->egl_version_minor;
674 if (((egl_version_major < 1) || (egl_version_major == 1 && egl_version_minor < 5)) &&
675 !SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_debug")) {
683 if ((major_version < 3 || (minor_version == 0 && profile_es)) &&
685 (profile_mask == 0 || profile_es)) {
694 attribs[attr++] =
SDL_max(major_version, 1);
697 #ifdef EGL_KHR_create_context
701 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context")) {
703 attribs[attr++] = major_version;
705 attribs[attr++] = minor_version;
710 attribs[attr++] = profile_mask;
721 SDL_SetError(
"Could not create EGL context (context attributes are not supported)");
727 #ifdef EGL_KHR_create_context_no_error
728 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context_no_error")) {
734 SDL_SetError(
"EGL implementation does not support no_error contexts");
748 egl_context =
_this->egl_data->eglCreateContext(
_this->egl_data->egl_display,
749 _this->egl_data->egl_config,
750 share_context, attribs);
753 SDL_EGL_SetError(
"Could not create EGL context",
"eglCreateContext");
757 _this->egl_data->egl_swapinterval = 0;
759 if (SDL_EGL_MakeCurrent(
_this, egl_surface, egl_context) < 0) {
761 char errorText[1024];
765 SDL_EGL_DeleteContext(
_this, egl_context);
781 if (!
_this->egl_data) {
788 if (!egl_context || !egl_surface) {
791 if (!
_this->egl_data->eglMakeCurrent(
_this->egl_data->egl_display,
792 egl_surface, egl_surface, egl_context)) {
793 return SDL_EGL_SetError(
"Unable to make EGL context current",
"eglMakeCurrent");
801 SDL_EGL_SetSwapInterval(
_THIS,
int interval)
805 if (!
_this->egl_data) {
809 status =
_this->egl_data->eglSwapInterval(
_this->egl_data->egl_display, interval);
811 _this->egl_data->egl_swapinterval = interval;
815 return SDL_EGL_SetError(
"Unable to set the EGL swap interval",
"eglSwapInterval");
819 SDL_EGL_GetSwapInterval(
_THIS)
821 if (!
_this->egl_data) {
826 return _this->egl_data->egl_swapinterval;
832 if (!
_this->egl_data->eglSwapBuffers(
_this->egl_data->egl_display, egl_surface)) {
833 return SDL_EGL_SetError(
"unable to show color buffer in an OS-native window",
"eglSwapBuffers");
844 if (!
_this->egl_data) {
849 _this->egl_data->eglDestroyContext(
_this->egl_data->egl_display, egl_context);
863 if (SDL_EGL_ChooseConfig(
_this) != 0) {
867 #if SDL_VIDEO_DRIVER_ANDROID
873 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display,
874 _this->egl_data->egl_config,
877 ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
881 #ifdef EGL_KHR_gl_colorspace
882 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_gl_colorspace")) {
888 SDL_SetError(
"EGL implementation does not support sRGB system framebuffers");
895 surface =
_this->egl_data->eglCreateWindowSurface(
896 _this->egl_data->egl_display,
897 _this->egl_data->egl_config,
900 SDL_EGL_SetError(
"unable to create an EGL window surface",
"eglCreateWindowSurface");
908 if (!
_this->egl_data) {
913 _this->egl_data->eglDestroySurface(
_this->egl_data->egl_display, egl_surface);
#define EGL_BAD_PARAMETER
#define EGL_CONTEXT_FLAGS_KHR
#define EGL_MIN_SWAP_INTERVAL
#define EGL_NATIVE_VISUAL_TYPE
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
#define EGL_NATIVE_RENDERABLE
BOOL WIN_IsWindowsVistaOrGreater(void)
#define EGL_TRANSPARENT_GREEN_VALUE
EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
#define EGL_MAX_PBUFFER_HEIGHT
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
#define EGL_BIND_TO_TEXTURE_RGBA
#define EGL_ALPHA_MASK_SIZE
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
GLuint GLsizei const GLchar * message
#define EGL_TRANSPARENT_TYPE
#define EGL_SAMPLE_BUFFERS
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
static screen_context_t context
#define EGL_CONFIG_CAVEAT
EGLAPI EGLint EGLAPIENTRY eglGetError(void)
EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY eglGetProcAddress(const char *procname)
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
#define EGL_MAX_PBUFFER_WIDTH
#define EGL_OPENGL_ES_API
#define EGL_COLOR_BUFFER_TYPE
GLuint GLint GLboolean GLint GLenum access
GLuint const GLchar * name
#define EGL_BAD_CURRENT_SURFACE
#define EGL_NATIVE_VISUAL_ID
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
struct SDL_VideoDevice::@32 gl_config
static SDL_VideoDevice * _this
#define SDL_HINT_VIDEO_WIN_D3DCOMPILER
A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries...
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define EGL_GL_COLORSPACE_SRGB_KHR
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define EGL_OPENGL_ES_BIT
#define EGL_TRANSPARENT_RED_VALUE
#define EGL_CONTEXT_CLIENT_VERSION
#define EGL_OPENGL_ES3_BIT_KHR
#define EGL_CONTEXT_MAJOR_VERSION_KHR
#define EGL_CONTEXT_OPENGL_NO_ERROR_KHR
#define EGL_CONTEXT_MINOR_VERSION_KHR
GLsizei const GLfloat * value
#define EGL_MAX_SWAP_INTERVAL
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
#define EGL_LUMINANCE_SIZE
#define EGL_BIND_TO_TEXTURE_RGB
int framebuffer_srgb_capable
int share_with_current_context
#define SDL_OutOfMemory()
#define EGL_MATCH_NATIVE_PIXMAP
#define SDL_GL_GetCurrentContext
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
#define EGL_BAD_ATTRIBUTE
GLuint GLuint GLsizei GLenum type
#define SDL_arraysize(array)
EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
GLsizei const GLchar *const * path
void * SDL_LoadFunction(void *handle, const char *name)
#define EGL_BAD_NATIVE_WINDOW
EGLSurface EGLint attribute
EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
#define EGL_BAD_NATIVE_PIXMAP
#define EGL_NOT_INITIALIZED
#define EGL_GL_COLORSPACE_KHR
#define EGL_RENDERABLE_TYPE
#define EGL_MAX_PBUFFER_PIXELS
#define EGL_TRANSPARENT_BLUE_VALUE
#define EGL_OPENGL_ES2_BIT
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)