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 "/opt/vc/lib/libbrcmEGL.so" 48 #define DEFAULT_OGL_ES2 "/opt/vc/lib/libbrcmGLESv2.so" 49 #define ALT_EGL "/opt/vc/lib/libEGL.so" 50 #define ALT_OGL_ES2 "/opt/vc/lib/libGLESv2.so" 51 #define DEFAULT_OGL_ES_PVR "/opt/vc/lib/libGLES_CM.so" 52 #define DEFAULT_OGL_ES "/opt/vc/lib/libGLESv1_CM.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" 70 #define DEFAULT_OGL "libGL.so.1" 71 #define DEFAULT_EGL "libEGL.so.1" 72 #define DEFAULT_OGL_ES2 "libGLESv2.so.2" 73 #define DEFAULT_OGL_ES_PVR "libGLES_CM.so.1" 74 #define DEFAULT_OGL_ES "libGLESv1_CM.so.1" 77 #ifdef SDL_VIDEO_STATIC_ANGLE 78 #define LOAD_FUNC(NAME) \ 79 _this->egl_data->NAME = (void *)NAME; 81 #define LOAD_FUNC(NAME) \ 82 _this->egl_data->NAME = SDL_LoadFunction(_this->egl_data->dll_handle, #NAME); \ 83 if (!_this->egl_data->NAME) \ 85 return SDL_SetError("Could not retrieve EGL function " #NAME); \ 89 static const char * SDL_EGL_GetErrorName(
EGLint eglErrorCode)
91 #define SDL_EGL_ERROR_TRANSLATE(e) case e: return #e; 92 switch (eglErrorCode) {
112 int SDL_EGL_SetErrorEx(
const char *
message,
const char * eglFunctionName,
EGLint eglErrorCode)
114 const char * errorText = SDL_EGL_GetErrorName(eglErrorCode);
115 char altErrorText[32];
116 if (errorText[0] ==
'\0') {
119 errorText = altErrorText;
121 return SDL_SetError(
"%s (call to %s failed, reporting an error of %s)", message, eglFunctionName, errorText);
126 SDL_EGL_DISPLAY_EXTENSION,
127 SDL_EGL_CLIENT_EXTENSION
128 } SDL_EGL_ExtensionType;
130 static SDL_bool SDL_EGL_HasExtension(
_THIS, SDL_EGL_ExtensionType
type,
const char *ext)
133 const char *ext_override;
134 const char *egl_extstr;
135 const char *ext_start;
151 if (ext_override !=
NULL) {
152 int disable_ext =
SDL_atoi(ext_override);
153 if (disable_ext & 0x01 && type == SDL_EGL_DISPLAY_EXTENSION) {
155 }
else if (disable_ext & 0x02 && type == SDL_EGL_CLIENT_EXTENSION) {
162 case SDL_EGL_DISPLAY_EXTENSION:
165 case SDL_EGL_CLIENT_EXTENSION:
177 if (egl_extstr !=
NULL) {
178 ext_start = egl_extstr;
182 if (ext_start ==
NULL) {
186 if (ext_start == egl_extstr || *(ext_start - 1) ==
' ') {
187 if (ext_start[ext_len] ==
' ' || ext_start[ext_len] == 0) {
192 ext_start += ext_len;
193 while (*ext_start !=
' ' && *ext_start != 0) {
203 SDL_EGL_GetProcAddress(
_THIS,
const char *proc)
205 static char procname[1024];
209 #if !defined(SDL_VIDEO_DRIVER_ANDROID) 210 if (
_this->egl_data->eglGetProcAddress) {
211 retval =
_this->egl_data->eglGetProcAddress(proc);
228 SDL_EGL_UnloadLibrary(
_THIS)
230 if (
_this->egl_data) {
231 if (
_this->egl_data->egl_display) {
232 _this->egl_data->eglTerminate(
_this->egl_data->egl_display);
240 if (
_this->egl_data->egl_dll_handle) {
253 void *dll_handle =
NULL, *egl_dll_handle =
NULL;
255 int egl_version_major = 0, egl_version_minor = 0;
256 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT 257 const char *d3dcompiler;
260 if (
_this->egl_data) {
261 return SDL_SetError(
"OpenGL ES context already created");
264 _this->egl_data = (
struct SDL_EGL_VideoData *)
SDL_calloc(1,
sizeof(SDL_EGL_VideoData));
265 if (!
_this->egl_data) {
269 #if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT 273 d3dcompiler =
"d3dcompiler_46.dll";
275 d3dcompiler =
"d3dcompiler_43.dll";
285 #ifndef SDL_VIDEO_STATIC_ANGLE 292 if (egl_dll_handle ==
NULL) {
295 path = DEFAULT_OGL_ES2;
298 if (egl_dll_handle ==
NULL) {
305 path = DEFAULT_OGL_ES;
307 if (egl_dll_handle ==
NULL) {
308 path = DEFAULT_OGL_ES_PVR;
320 _this->egl_data->egl_dll_handle = egl_dll_handle;
322 if (egl_dll_handle ==
NULL) {
323 return SDL_SetError(
"Could not initialize OpenGL / GLES library");
327 if (egl_path !=
NULL) {
332 if (dll_handle !=
NULL) {
342 if (dll_handle ==
NULL) {
349 if (dll_handle !=
NULL) {
380 if (
_this->egl_data->eglQueryString) {
383 if (egl_version !=
NULL) {
384 if (
SDL_sscanf(egl_version,
"%d.%d", &egl_version_major, &egl_version_minor) != 2) {
385 egl_version_major = 0;
386 egl_version_minor = 0;
392 if (egl_version_major == 1 && egl_version_minor == 5) {
397 #if !defined(__WINRT__) 399 if (egl_version_major == 1 && egl_version_minor == 5) {
400 _this->egl_data->egl_display =
_this->egl_data->eglGetPlatformDisplay(platform, (
void *)(
size_t)native_display,
NULL);
402 if (SDL_EGL_HasExtension(
_this, SDL_EGL_CLIENT_EXTENSION,
"EGL_EXT_platform_base")) {
403 _this->egl_data->eglGetPlatformDisplayEXT = SDL_EGL_GetProcAddress(
_this,
"eglGetPlatformDisplayEXT");
404 if (
_this->egl_data->eglGetPlatformDisplayEXT) {
405 _this->egl_data->egl_display =
_this->egl_data->eglGetPlatformDisplayEXT(platform, (
void *)(
size_t)native_display,
NULL);
412 _this->egl_data->egl_display =
_this->egl_data->eglGetDisplay(native_display);
433 SDL_EGL_ChooseConfig(
_THIS)
438 #ifdef SDL_VIDEO_DRIVER_KMSDRM 446 int i,
j, best_bitdiff = -1, bitdiff;
448 if (!
_this->egl_data) {
491 #ifdef EGL_KHR_gl_colorspace 492 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_gl_colorspace")) {
498 return SDL_SetError(
"EGL implementation does not support sRGB system framebuffers");
504 #ifdef EGL_KHR_create_context 506 SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context")) {
523 if (
_this->egl_data->eglChooseConfig(
_this->egl_data->egl_display,
527 found_configs == 0) {
528 return SDL_EGL_SetError(
"Couldn't find matching EGL config",
"eglChooseConfig");
534 for (i = 0; i < found_configs; i++ ) {
548 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display, configs[i], attribs[j], &
value);
549 bitdiff +=
value - attribs[j + 1];
553 if (bitdiff < best_bitdiff || best_bitdiff == -1) {
554 _this->egl_data->egl_config = configs[
i];
556 best_bitdiff = bitdiff;
580 if (!
_this->egl_data) {
590 if ((major_version < 3 || (minor_version == 0 && profile_es)) &&
592 (profile_mask == 0 || profile_es)) {
601 attribs[attr++] =
SDL_max(major_version, 1);
604 #ifdef EGL_KHR_create_context 608 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context")) {
610 attribs[attr++] = major_version;
612 attribs[attr++] = minor_version;
617 attribs[attr++] = profile_mask;
628 SDL_SetError(
"Could not create EGL context (context attributes are not supported)");
634 #ifdef EGL_KHR_create_context_no_error 635 if (SDL_EGL_HasExtension(
_this, SDL_EGL_DISPLAY_EXTENSION,
"EGL_KHR_create_context_no_error")) {
641 SDL_SetError(
"EGL implementation does not support no_error contexts");
655 egl_context =
_this->egl_data->eglCreateContext(
_this->egl_data->egl_display,
656 _this->egl_data->egl_config,
657 share_context, attribs);
660 SDL_EGL_SetError(
"Could not create EGL context",
"eglCreateContext");
664 _this->egl_data->egl_swapinterval = 0;
666 if (SDL_EGL_MakeCurrent(
_this, egl_surface, egl_context) < 0) {
668 char errorText[1024];
672 SDL_EGL_DeleteContext(
_this, egl_context);
688 if (!
_this->egl_data) {
695 if (!egl_context || !egl_surface) {
698 if (!
_this->egl_data->eglMakeCurrent(
_this->egl_data->egl_display,
699 egl_surface, egl_surface, egl_context)) {
700 return SDL_EGL_SetError(
"Unable to make EGL context current",
"eglMakeCurrent");
708 SDL_EGL_SetSwapInterval(
_THIS,
int interval)
712 if (!
_this->egl_data) {
716 status =
_this->egl_data->eglSwapInterval(
_this->egl_data->egl_display, interval);
718 _this->egl_data->egl_swapinterval = interval;
722 return SDL_EGL_SetError(
"Unable to set the EGL swap interval",
"eglSwapInterval");
726 SDL_EGL_GetSwapInterval(
_THIS)
728 if (!
_this->egl_data) {
733 return _this->egl_data->egl_swapinterval;
739 if (!
_this->egl_data->eglSwapBuffers(
_this->egl_data->egl_display, egl_surface)) {
740 return SDL_EGL_SetError(
"unable to show color buffer in an OS-native window",
"eglSwapBuffers");
751 if (!
_this->egl_data) {
757 _this->egl_data->eglDestroyContext(
_this->egl_data->egl_display, egl_context);
767 if (SDL_EGL_ChooseConfig(
_this) != 0) {
771 #if SDL_VIDEO_DRIVER_ANDROID 777 _this->egl_data->eglGetConfigAttrib(
_this->egl_data->egl_display,
778 _this->egl_data->egl_config,
781 ANativeWindow_setBuffersGeometry(nw, 0, 0, format);
785 surface =
_this->egl_data->eglCreateWindowSurface(
786 _this->egl_data->egl_display,
787 _this->egl_data->egl_config,
790 SDL_EGL_SetError(
"unable to create an EGL window surface",
"eglCreateWindowSurface");
798 if (!
_this->egl_data) {
803 _this->egl_data->eglDestroySurface(
_this->egl_data->egl_display, egl_surface);
#define EGL_BAD_PARAMETER
#define EGL_CONTEXT_FLAGS_KHR
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
BOOL WIN_IsWindowsVistaOrGreater(void)
EGLAPI const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
GLuint GLsizei const GLchar * message
#define EGL_SAMPLE_BUFFERS
#define EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
static screen_context_t context
EGLAPI EGLint EGLAPIENTRY eglGetError(void)
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_OPENGL_ES_API
#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...
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define EGL_GL_COLORSPACE_SRGB_KHR
void * SDL_calloc(size_t nmemb, size_t size)
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define EGL_OPENGL_ES_BIT
#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
int framebuffer_srgb_capable
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 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
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_OPENGL_ES2_BIT
EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)