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)
static SDL_VideoDevice * _this
#define SDL_HINT_VIDEO_WIN_D3DCOMPILER
A variable specifying which shader compiler to preload when using the Chrome ANGLE binaries...
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
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_CONTEXT_MINOR_VERSION_KHR
GLsizei const GLfloat * value
#define EGL_MAX_SWAP_INTERVAL
#define EGL_LUMINANCE_SIZE
#define EGL_BIND_TO_TEXTURE_RGB
int framebuffer_srgb_capable
struct SDL_VideoDevice::@36 gl_config
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)
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)