mirror of
https://github.com/libretro/RetroArch
synced 2025-03-02 19:13:34 +00:00
Add HAVE_DYNAMIC_EGL option
This commit is contained in:
parent
fa2a748631
commit
4380b73ca6
@ -1284,8 +1284,14 @@ endif
|
||||
ifeq ($(HAVE_EGL), 1)
|
||||
DEFINES += -DHAVE_EGL
|
||||
DEF_FLAGS += $(EGL_CFLAGS)
|
||||
LIBS += $(EGL_LIBS)
|
||||
OBJ += gfx/common/egl_common.o
|
||||
|
||||
ifeq ($(HAVE_DYNAMIC_EGL), 1)
|
||||
DEFINES += -DHAVE_DYNAMIC_EGL
|
||||
else
|
||||
LIBS += $(EGL_LIBS)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_SDL2), 1)
|
||||
@ -1965,8 +1971,6 @@ endif
|
||||
ifeq ($(HAVE_ANGLE), 1)
|
||||
OBJ += gfx/common/angle_common.o
|
||||
DEFINES += -DHAVE_ANGLE
|
||||
# TODO/FIXME - should perhaps set these libraries as separate CFLAG variables in qb system
|
||||
LIBS += -lEGL
|
||||
endif
|
||||
|
||||
# Record
|
||||
|
@ -88,7 +88,11 @@ static bool angle_try_initialize(egl_ctx_data_t* egl,
|
||||
void* display_data, const EGLint* display_attr,
|
||||
EGLint* major, EGLint* minor)
|
||||
{
|
||||
EGLDisplay dpy = EGL_NO_DISPLAY;
|
||||
EGLDisplay dpy = EGL_NO_DISPLAY;
|
||||
#if defined(HAVE_DYNAMIC) && defined(HAVE_DYNAMIC_EGL)
|
||||
if (!egl_init_dll())
|
||||
return false;
|
||||
#endif
|
||||
|
||||
PFNEGLGETPLATFORMDISPLAYEXTPROC ptr_eglGetPlatformDisplayEXT =
|
||||
(PFNEGLGETPLATFORMDISPLAYEXTPROC)egl_get_proc_address("eglGetPlatformDisplayEXT");
|
||||
|
@ -38,9 +38,149 @@ bool g_egl_inited = false;
|
||||
unsigned g_egl_major = 0;
|
||||
unsigned g_egl_minor = 0;
|
||||
|
||||
#if defined(HAVE_DYNAMIC) && defined(HAVE_DYNAMIC_EGL)
|
||||
#include <dynamic/dylib.h>
|
||||
|
||||
typedef EGLBoolean(* PFN_EGL_QUERY_SURFACE)(
|
||||
EGLDisplay dpy,
|
||||
EGLSurface surface,
|
||||
EGLint attribute,
|
||||
EGLint *value);
|
||||
typedef void *(* PFN_EGL_GET_PROC_ADDRESS)(const char *procname);
|
||||
typedef EGLSurface(*PFN_EGL_CREATE_WINDOW_SURFACE) (EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLNativeWindowType win,
|
||||
const EGLint * attrib_list);
|
||||
typedef EGLContext(*PFN_EGL_CREATE_CONTEXT)(EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_context,
|
||||
const EGLint * attrib_list);
|
||||
typedef EGLBoolean(*PFN_EGL_GET_CONFIGS) (EGLDisplay dpy, EGLConfig * configs,
|
||||
EGLint config_size, EGLint * num_config);
|
||||
typedef EGLint(*PFN_EGL_GET_ERROR) (void);
|
||||
typedef EGLDisplay(*PFN_EGL_GET_DISPLAY) (EGLNativeDisplayType display_id);
|
||||
typedef EGLBoolean(*PFN_EGL_CHOOSE_CONFIG) (EGLDisplay dpy,
|
||||
const EGLint * attrib_list,
|
||||
EGLConfig * configs,
|
||||
EGLint config_size, EGLint * num_config);
|
||||
typedef EGLBoolean(*PFN_EGL_TERMINATE)(EGLDisplay dpy);
|
||||
typedef EGLBoolean(*PFN_EGL_INITIALIZE)(EGLDisplay dpy, EGLint * major,
|
||||
EGLint * minor);
|
||||
typedef EGLBoolean(*PFN_EGL_BIND_API) (EGLenum api);
|
||||
typedef EGLBoolean(*PFN_EGL_MAKE_CURRENT) (EGLDisplay dpy, EGLSurface draw,
|
||||
EGLSurface read, EGLContext ctx);
|
||||
typedef EGLBoolean(*PFN_EGL_DESTROY_SURFACE) (EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean(*PFN_EGL_DESTROY_CONTEXT) (EGLDisplay dpy, EGLContext ctx);
|
||||
typedef EGLContext(*PFN_EGL_GET_CURRENT_CONTEXT) (void);
|
||||
typedef const char *(*PFN_EGL_QUERY_STRING) (EGLDisplay dpy, EGLint name);
|
||||
typedef EGLBoolean(*PFN_EGL_GET_CONFIG_ATTRIB) (EGLDisplay dpy,
|
||||
EGLConfig config,
|
||||
EGLint attribute, EGLint * value);
|
||||
typedef EGLBoolean(*PFN_EGL_SWAP_BUFFERS) (EGLDisplay dpy, EGLSurface surface);
|
||||
typedef EGLBoolean(*PFN_EGL_SWAP_INTERVAL) (EGLDisplay dpy, EGLint interval);
|
||||
|
||||
static PFN_EGL_QUERY_SURFACE _egl_query_surface;
|
||||
static PFN_EGL_GET_PROC_ADDRESS _egl_get_proc_address;
|
||||
static PFN_EGL_CREATE_WINDOW_SURFACE _egl_create_window_surface;
|
||||
static PFN_EGL_CREATE_CONTEXT _egl_create_context;
|
||||
static PFN_EGL_GET_CONFIGS _egl_get_configs;
|
||||
static PFN_EGL_GET_ERROR _egl_get_error;
|
||||
static PFN_EGL_GET_DISPLAY _egl_get_display;
|
||||
static PFN_EGL_CHOOSE_CONFIG _egl_choose_config;
|
||||
static PFN_EGL_TERMINATE _egl_terminate;
|
||||
static PFN_EGL_INITIALIZE _egl_initialize;
|
||||
static PFN_EGL_BIND_API _egl_bind_api;
|
||||
static PFN_EGL_MAKE_CURRENT _egl_make_current;
|
||||
static PFN_EGL_DESTROY_SURFACE _egl_destroy_surface;
|
||||
static PFN_EGL_DESTROY_CONTEXT _egl_destroy_context;
|
||||
static PFN_EGL_GET_CURRENT_CONTEXT _egl_get_current_context;
|
||||
static PFN_EGL_QUERY_STRING _egl_query_string;
|
||||
static PFN_EGL_GET_CONFIG_ATTRIB _egl_get_config_attrib;
|
||||
static PFN_EGL_SWAP_BUFFERS _egl_swap_buffers;
|
||||
static PFN_EGL_SWAP_INTERVAL _egl_swap_interval;
|
||||
|
||||
#else
|
||||
#define _egl_query_surface(a, b, c, d) eglQuerySurface(a, b, c, d)
|
||||
#define _egl_get_proc_address(a) eglGetProcAddress(a)
|
||||
#define _egl_create_window_surface(a, b, c, d) eglCreateWindowSurface(a, b, c, d)
|
||||
#define _egl_create_context(a, b, c, d) eglCreateContext(a, b, c, d)
|
||||
#define _egl_get_configs(a, b, c, d) eglGetConfigs(a, b, c, d)
|
||||
#define _egl_get_display(a) eglGetDisplay(a)
|
||||
#define _egl_choose_config(a, b, c, d, e) eglChooseConfig(a, b, c, d, e)
|
||||
#define _egl_make_current(a, b, c, d) eglMakeCurrent(a, b, c, d)
|
||||
#define _egl_initialize(a, b, c) eglInitialize(a, b, c)
|
||||
#define _egl_destroy_surface(a, b) eglDestroySurface(a, b)
|
||||
#define _egl_destroy_context(a, b) eglDestroyContext(a, b)
|
||||
#define _egl_get_current_context() eglGetCurrentContext()
|
||||
#define _egl_get_error() eglGetError()
|
||||
#define _egl_terminate(dpy) eglTerminate(dpy)
|
||||
#define _egl_bind_api(a) eglBindAPI(a)
|
||||
#define _egl_query_string(a, b) eglQueryString(a, b)
|
||||
#define _egl_get_config_attrib(a, b, c, d) eglGetConfigAttrib(a, b, c, d)
|
||||
#define _egl_swap_buffers(a, b) eglSwapBuffers(a, b)
|
||||
#define _egl_swap_interval(a, b) eglSwapInterval(a, b)
|
||||
#endif
|
||||
|
||||
bool egl_init_dll(void)
|
||||
{
|
||||
#if defined(HAVE_DYNAMIC) && defined(HAVE_DYNAMIC_EGL)
|
||||
static dylib_t egl_dll;
|
||||
|
||||
if (!egl_dll)
|
||||
{
|
||||
egl_dll = dylib_load("libEGL.dll");
|
||||
if (egl_dll)
|
||||
{
|
||||
/* Setup function callbacks once */
|
||||
_egl_query_surface = (PFN_EGL_QUERY_SURFACE)dylib_proc(
|
||||
egl_dll, "eglQuerySurface");
|
||||
_egl_get_proc_address = (PFN_EGL_GET_PROC_ADDRESS)dylib_proc(
|
||||
egl_dll, "eglGetProcAddress");
|
||||
_egl_create_window_surface = (PFN_EGL_CREATE_WINDOW_SURFACE)dylib_proc(
|
||||
egl_dll, "eglCreateWindowSurface");
|
||||
_egl_create_context = (PFN_EGL_CREATE_CONTEXT)dylib_proc(
|
||||
egl_dll, "eglCreateContext");
|
||||
_egl_get_configs = (PFN_EGL_GET_CONFIGS)dylib_proc(
|
||||
egl_dll, "eglGetConfigs");
|
||||
_egl_get_error = (PFN_EGL_GET_ERROR)dylib_proc(
|
||||
egl_dll, "eglGetError");
|
||||
_egl_get_display = (PFN_EGL_GET_DISPLAY)dylib_proc(
|
||||
egl_dll, "eglGetDisplay");
|
||||
_egl_choose_config = (PFN_EGL_CHOOSE_CONFIG)dylib_proc(
|
||||
egl_dll, "eglChooseConfig");
|
||||
_egl_terminate = (PFN_EGL_TERMINATE)dylib_proc(
|
||||
egl_dll, "eglTerminate");
|
||||
_egl_initialize = (PFN_EGL_INITIALIZE)dylib_proc(
|
||||
egl_dll, "eglInitialize");
|
||||
_egl_bind_api = (PFN_EGL_BIND_API)dylib_proc(
|
||||
egl_dll, "eglBindAPI");
|
||||
_egl_make_current = (PFN_EGL_MAKE_CURRENT)dylib_proc(
|
||||
egl_dll, "eglMakeCurrent");
|
||||
_egl_destroy_surface = (PFN_EGL_DESTROY_SURFACE)dylib_proc(
|
||||
egl_dll, "eglDestroySurface");
|
||||
_egl_destroy_context = (PFN_EGL_DESTROY_CONTEXT)dylib_proc(
|
||||
egl_dll, "eglDestroyContext");
|
||||
_egl_get_current_context = (PFN_EGL_GET_CURRENT_CONTEXT)dylib_proc(
|
||||
egl_dll, "eglGetCurrentContext");
|
||||
_egl_query_string = (PFN_EGL_QUERY_STRING)dylib_proc(
|
||||
egl_dll, "eglQueryString");
|
||||
_egl_get_config_attrib = (PFN_EGL_GET_CONFIG_ATTRIB)dylib_proc(
|
||||
egl_dll, "eglGetConfigAttrib");
|
||||
_egl_swap_buffers = (PFN_EGL_SWAP_BUFFERS)dylib_proc(
|
||||
egl_dll, "eglSwapBuffers");
|
||||
_egl_swap_interval = (PFN_EGL_SWAP_INTERVAL)dylib_proc(
|
||||
egl_dll, "eglSwapInterval");
|
||||
}
|
||||
}
|
||||
|
||||
if (egl_dll)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
void egl_report_error(void)
|
||||
{
|
||||
EGLint error = eglGetError();
|
||||
EGLint error = _egl_get_error();
|
||||
const char *str = NULL;
|
||||
switch (error)
|
||||
{
|
||||
@ -106,28 +246,28 @@ void egl_report_error(void)
|
||||
|
||||
gfx_ctx_proc_t egl_get_proc_address(const char *symbol)
|
||||
{
|
||||
return eglGetProcAddress(symbol);
|
||||
return _egl_get_proc_address(symbol);
|
||||
}
|
||||
|
||||
void egl_terminate(EGLDisplay dpy)
|
||||
{
|
||||
eglTerminate(dpy);
|
||||
_egl_terminate(dpy);
|
||||
}
|
||||
|
||||
static bool egl_get_config_attrib(EGLDisplay dpy, EGLConfig config, EGLint attribute,
|
||||
EGLint *value)
|
||||
{
|
||||
return eglGetConfigAttrib(dpy, config, attribute, value);
|
||||
return _egl_get_config_attrib(dpy, config, attribute, value);
|
||||
}
|
||||
|
||||
bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
|
||||
{
|
||||
return eglInitialize(dpy, major, minor);
|
||||
return _egl_initialize(dpy, major, minor);
|
||||
}
|
||||
|
||||
bool egl_bind_api(EGLenum egl_api)
|
||||
{
|
||||
return eglBindAPI(egl_api);
|
||||
return _egl_bind_api(egl_api);
|
||||
}
|
||||
|
||||
void egl_destroy(egl_ctx_data_t *egl)
|
||||
@ -144,16 +284,16 @@ void egl_destroy(egl_ctx_data_t *egl)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
eglMakeCurrent(egl->dpy,
|
||||
_egl_make_current(egl->dpy,
|
||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
if (egl->ctx != EGL_NO_CONTEXT)
|
||||
eglDestroyContext(egl->dpy, egl->ctx);
|
||||
_egl_destroy_context(egl->dpy, egl->ctx);
|
||||
|
||||
if (egl->hw_ctx != EGL_NO_CONTEXT)
|
||||
eglDestroyContext(egl->dpy, egl->hw_ctx);
|
||||
_egl_destroy_context(egl->dpy, egl->hw_ctx);
|
||||
|
||||
if (egl->surf != EGL_NO_SURFACE)
|
||||
eglDestroySurface(egl->dpy, egl->surf);
|
||||
_egl_destroy_surface(egl->dpy, egl->surf);
|
||||
egl_terminate(egl->dpy);
|
||||
}
|
||||
|
||||
@ -180,7 +320,7 @@ void egl_bind_hw_render(egl_ctx_data_t *egl, bool enable)
|
||||
if (egl->surf == EGL_NO_SURFACE)
|
||||
return;
|
||||
|
||||
eglMakeCurrent(egl->dpy, egl->surf,
|
||||
_egl_make_current(egl->dpy, egl->surf,
|
||||
egl->surf,
|
||||
enable ? egl->hw_ctx : egl->ctx);
|
||||
}
|
||||
@ -192,7 +332,7 @@ void egl_swap_buffers(void *data)
|
||||
egl->dpy != EGL_NO_DISPLAY &&
|
||||
egl->surf != EGL_NO_SURFACE
|
||||
)
|
||||
eglSwapBuffers(egl->dpy, egl->surf);
|
||||
_egl_swap_buffers(egl->dpy, egl->surf);
|
||||
}
|
||||
|
||||
void egl_set_swap_interval(egl_ctx_data_t *egl, int interval)
|
||||
@ -205,11 +345,11 @@ void egl_set_swap_interval(egl_ctx_data_t *egl, int interval)
|
||||
|
||||
if (egl->dpy == EGL_NO_DISPLAY)
|
||||
return;
|
||||
if (!(eglGetCurrentContext()))
|
||||
if (!_egl_get_current_context())
|
||||
return;
|
||||
|
||||
RARCH_LOG("[EGL]: eglSwapInterval(%u)\n", interval);
|
||||
if (!eglSwapInterval(egl->dpy, interval))
|
||||
if (!_egl_swap_interval(egl->dpy, interval))
|
||||
{
|
||||
RARCH_ERR("[EGL]: eglSwapInterval() failed.\n");
|
||||
egl_report_error();
|
||||
@ -225,8 +365,8 @@ void egl_get_video_size(egl_ctx_data_t *egl, unsigned *width, unsigned *height)
|
||||
{
|
||||
EGLint gl_width, gl_height;
|
||||
|
||||
eglQuerySurface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width);
|
||||
eglQuerySurface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height);
|
||||
_egl_query_surface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width);
|
||||
_egl_query_surface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height);
|
||||
*width = gl_width;
|
||||
*height = gl_height;
|
||||
}
|
||||
@ -236,7 +376,7 @@ bool check_egl_version(int minMajorVersion, int minMinorVersion)
|
||||
{
|
||||
int count;
|
||||
int major, minor;
|
||||
const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
|
||||
const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_VERSION);
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
@ -260,7 +400,7 @@ bool check_egl_version(int minMajorVersion, int minMinorVersion)
|
||||
bool check_egl_client_extension(const char *name)
|
||||
{
|
||||
size_t nameLen;
|
||||
const char *str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
const char *str = _egl_query_string(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
|
||||
/* The EGL implementation doesn't support client extensions at all. */
|
||||
if (!str)
|
||||
@ -332,7 +472,7 @@ static EGLDisplay get_egl_display(EGLenum platform, void *native)
|
||||
* implementation doesn't support eglGetPlatformDisplay. In this case, try
|
||||
* eglGetDisplay and hope for the best. */
|
||||
RARCH_LOG("[EGL] Falling back to eglGetDisplay\n");
|
||||
return eglGetDisplay((EGLNativeDisplayType) native);
|
||||
return _egl_get_display((EGLNativeDisplayType) native);
|
||||
}
|
||||
|
||||
bool egl_get_native_visual_id(egl_ctx_data_t *egl, EGLint *value)
|
||||
@ -376,7 +516,7 @@ bool egl_init_context_common(
|
||||
if (!egl)
|
||||
return false;
|
||||
|
||||
if (!eglGetConfigs(egl->dpy, NULL, 0, count) || *count < 1)
|
||||
if (!_egl_get_configs(egl->dpy, NULL, 0, count) || *count < 1)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No configs to choose from.\n");
|
||||
return false;
|
||||
@ -386,7 +526,7 @@ bool egl_init_context_common(
|
||||
if (!configs)
|
||||
return false;
|
||||
|
||||
if (!eglChooseConfig(egl->dpy, attrib_ptr,
|
||||
if (!_egl_choose_config(egl->dpy, attrib_ptr,
|
||||
configs, *count, &matched) || !matched)
|
||||
{
|
||||
RARCH_ERR("[EGL]: No EGL configs with appropriate attributes.\n");
|
||||
@ -446,7 +586,7 @@ bool egl_init_context(egl_ctx_data_t *egl,
|
||||
|
||||
bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs)
|
||||
{
|
||||
EGLContext ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT,
|
||||
EGLContext ctx = _egl_create_context(egl->dpy, egl->config, EGL_NO_CONTEXT,
|
||||
egl_attribs);
|
||||
|
||||
if (ctx == EGL_NO_CONTEXT)
|
||||
@ -457,7 +597,7 @@ bool egl_create_context(egl_ctx_data_t *egl, const EGLint *egl_attribs)
|
||||
|
||||
if (egl->use_hw_ctx)
|
||||
{
|
||||
egl->hw_ctx = eglCreateContext(egl->dpy, egl->config, egl->ctx,
|
||||
egl->hw_ctx = _egl_create_context(egl->dpy, egl->config, egl->ctx,
|
||||
egl_attribs);
|
||||
RARCH_LOG("[EGL]: Created shared context: %p.\n", (void*)egl->hw_ctx);
|
||||
|
||||
@ -475,16 +615,16 @@ bool egl_create_surface(egl_ctx_data_t *egl, void *native_window)
|
||||
EGL_NONE,
|
||||
};
|
||||
|
||||
egl->surf = eglCreateWindowSurface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs);
|
||||
egl->surf = _egl_create_window_surface(egl->dpy, egl->config, (NativeWindowType)native_window, window_attribs);
|
||||
|
||||
if (egl->surf == EGL_NO_SURFACE)
|
||||
return false;
|
||||
|
||||
/* Connect the context to the surface. */
|
||||
if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx))
|
||||
if (!_egl_make_current(egl->dpy, egl->surf, egl->surf, egl->ctx))
|
||||
return false;
|
||||
|
||||
RARCH_LOG("[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext());
|
||||
RARCH_LOG("[EGL]: Current context: %p.\n", (void*)_egl_get_current_context());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -95,6 +95,8 @@ bool egl_default_accept_config_cb(void *display_data, EGLDisplay dpy, EGLConfig
|
||||
|
||||
bool egl_initialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
|
||||
bool egl_init_dll(void);
|
||||
|
||||
bool egl_init_context_common(
|
||||
egl_ctx_data_t *egl, EGLint *count,
|
||||
const EGLint *attrib_ptr,
|
||||
|
@ -84,6 +84,7 @@ HAVE_SUNXI=no # Sunxi video support
|
||||
HAVE_WAYLAND=auto # Wayland support
|
||||
C89_WAYLAND=no
|
||||
CXX_WAYLAND=no
|
||||
HAVE_DYNAMIC_EGL=no # Dynamic library EGL support
|
||||
HAVE_EGL=auto # EGL context support
|
||||
HAVE_VG=auto # OpenVG support
|
||||
HAVE_CG=auto # Cg shader support
|
||||
|
Loading…
x
Reference in New Issue
Block a user