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
struct SDL_VideoDevice::@31 gl_config
#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...
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_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
#define EGL_CONTEXT_MINOR_VERSION_KHR
GLsizei const GLfloat * value
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)
int framebuffer_srgb_capable
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)