From 1cf574cfbe72622ff1ee482710de4e9e49c09802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Higor=20Eur=C3=ADpedes?= Date: Tue, 8 Dec 2015 13:54:03 -0300 Subject: [PATCH] Move most of egl_common globals into egl_ctx_data_t --- gfx/common/egl_common.c | 132 +++++++++--------- gfx/common/egl_common.h | 54 ++++++-- gfx/drivers_context/drm_egl_ctx.c | 51 ++++--- gfx/drivers_context/wayland_ctx.c | 215 +++++++++++++++--------------- gfx/drivers_context/xegl_ctx.c | 79 ++++++----- gfx/video_context_driver.c | 1 + gfx/video_context_driver.h | 2 +- 7 files changed, 288 insertions(+), 246 deletions(-) diff --git a/gfx/common/egl_common.c b/gfx/common/egl_common.c index 0f1b463d8b..bb21a0cb11 100644 --- a/gfx/common/egl_common.c +++ b/gfx/common/egl_common.c @@ -23,16 +23,11 @@ #endif volatile sig_atomic_t g_egl_quit; - -EGLContext g_egl_ctx; -EGLContext g_egl_hw_ctx; -EGLSurface g_egl_surf; -EGLDisplay g_egl_dpy; -EGLConfig g_egl_config; -enum gfx_ctx_api g_egl_api; bool g_egl_inited; -static bool g_egl_use_hw_ctx; -unsigned g_interval; + +enum gfx_ctx_api g_egl_api; +unsigned g_egl_major = 0; +unsigned g_egl_minor = 0; void egl_report_error(void) { @@ -79,11 +74,12 @@ gfx_ctx_proc_t egl_get_proc_address(const char *symbol) void egl_destroy(void *data) { - if (g_egl_dpy) + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + if (egl->dpy) { #if defined HAVE_OPENGL #if !defined(RARCH_MOBILE) - if (g_egl_ctx != EGL_NO_CONTEXT) + if (egl->ctx != EGL_NO_CONTEXT) { glFlush(); glFinish(); @@ -91,71 +87,74 @@ void egl_destroy(void *data) #endif #endif - eglMakeCurrent(g_egl_dpy, + eglMakeCurrent(egl->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (g_egl_ctx != EGL_NO_CONTEXT) - eglDestroyContext(g_egl_dpy, g_egl_ctx); + if (egl->ctx != EGL_NO_CONTEXT) + eglDestroyContext(egl->dpy, egl->ctx); - if (g_egl_hw_ctx != EGL_NO_CONTEXT) - eglDestroyContext(g_egl_dpy, g_egl_hw_ctx); + if (egl->hw_ctx != EGL_NO_CONTEXT) + eglDestroyContext(egl->dpy, egl->hw_ctx); - if (g_egl_surf != EGL_NO_SURFACE) - eglDestroySurface(g_egl_dpy, g_egl_surf); - eglTerminate(g_egl_dpy); + if (egl->surf != EGL_NO_SURFACE) + eglDestroySurface(egl->dpy, egl->surf); + eglTerminate(egl->dpy); } /* Be as careful as possible in deinit. * If we screw up, any TTY will not restore. */ - g_egl_ctx = EGL_NO_CONTEXT; - g_egl_hw_ctx = EGL_NO_CONTEXT; - g_egl_surf = EGL_NO_SURFACE; - g_egl_dpy = EGL_NO_DISPLAY; - g_egl_config = 0; + egl->ctx = EGL_NO_CONTEXT; + egl->hw_ctx = EGL_NO_CONTEXT; + egl->surf = EGL_NO_SURFACE; + egl->dpy = EGL_NO_DISPLAY; + egl->config = 0; g_egl_quit = 0; - g_egl_api = GFX_CTX_NONE; + egl->api = GFX_CTX_NONE; g_egl_inited = false; } void egl_bind_hw_render(void *data, bool enable) { - g_egl_use_hw_ctx = enable; + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + egl->use_hw_ctx = enable; - if (g_egl_dpy == EGL_NO_DISPLAY) + if (egl->dpy == EGL_NO_DISPLAY) return; - if (g_egl_surf == EGL_NO_SURFACE) + if (egl->surf == EGL_NO_SURFACE) return; - eglMakeCurrent(g_egl_dpy, g_egl_surf, - g_egl_surf, - enable ? g_egl_hw_ctx : g_egl_ctx); + eglMakeCurrent(egl->dpy, egl->surf, + egl->surf, + enable ? egl->hw_ctx : egl->ctx); } void egl_swap_buffers(void *data) { - if (g_egl_dpy == EGL_NO_DISPLAY) + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + if (egl->dpy == EGL_NO_DISPLAY) return; - if (g_egl_surf == EGL_NO_SURFACE) + if (egl->surf == EGL_NO_SURFACE) return; - eglSwapBuffers(g_egl_dpy, g_egl_surf); + eglSwapBuffers(egl->dpy, egl->surf); } void egl_set_swap_interval(void *data, unsigned interval) { + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; /* Can be called before initialization. * Some contexts require that swap interval * is known at startup time. */ - g_interval = interval; + egl->interval = interval; - if (g_egl_dpy == EGL_NO_DISPLAY) + if (egl->dpy == EGL_NO_DISPLAY) return; if (!(eglGetCurrentContext())) return; RARCH_LOG("[EGL]: eglSwapInterval(%u)\n", interval); - if (!eglSwapInterval(g_egl_dpy, interval)) + if (!eglSwapInterval(egl->dpy, interval)) { RARCH_ERR("[EGL]: eglSwapInterval() failed.\n"); egl_report_error(); @@ -164,15 +163,17 @@ void egl_set_swap_interval(void *data, unsigned interval) void egl_get_video_size(void *data, unsigned *width, unsigned *height) { + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + *width = 0; *height = 0; - if (g_egl_dpy != EGL_NO_DISPLAY && g_egl_surf != EGL_NO_SURFACE) + if (egl->dpy != EGL_NO_DISPLAY && egl->surf != EGL_NO_SURFACE) { EGLint gl_width, gl_height; - eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_WIDTH, &gl_width); - eglQuerySurface(g_egl_dpy, g_egl_surf, EGL_HEIGHT, &gl_height); + eglQuerySurface(egl->dpy, egl->surf, EGL_WIDTH, &gl_width); + eglQuerySurface(egl->dpy, egl->surf, EGL_HEIGHT, &gl_height); *width = gl_width; *height = gl_height; } @@ -196,59 +197,66 @@ void egl_install_sighandlers(void) sigaction(SIGTERM, &sa, NULL); } -bool egl_init_context(NativeDisplayType display, +bool egl_init_context(void *data, NativeDisplayType display, EGLint *major, EGLint *minor, EGLint *n, const EGLint *attrib_ptr) { - g_egl_dpy = eglGetDisplay(display); - if (!g_egl_dpy) + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + egl->dpy = eglGetDisplay(display); + if (!egl->dpy) { RARCH_ERR("[EGL]: Couldn't get EGL display.\n"); return false; } - if (!eglInitialize(g_egl_dpy, major, minor)) + if (!eglInitialize(egl->dpy, major, minor)) return false; RARCH_LOG("[EGL]: EGL version: %d.%d\n", *major, *minor); - if (!eglChooseConfig(g_egl_dpy, attrib_ptr, &g_egl_config, 1, n) || *n != 1) + if (!eglChooseConfig(egl->dpy, attrib_ptr, &egl->config, 1, n) || *n != 1) return false; + egl->api = g_egl_api; + egl->major = g_egl_major; + egl->minor = g_egl_minor; + return true; } -bool egl_create_context(EGLint *egl_attribs) +bool egl_create_context(void *data, EGLint *egl_attribs) { - g_egl_ctx = eglCreateContext(g_egl_dpy, g_egl_config, EGL_NO_CONTEXT, + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + egl->ctx = eglCreateContext(egl->dpy, egl->config, EGL_NO_CONTEXT, egl_attribs); - g_egl_hw_ctx = NULL; + egl->hw_ctx = NULL; - if (g_egl_ctx == EGL_NO_CONTEXT) + if (egl->ctx == EGL_NO_CONTEXT) return false; - if (g_egl_use_hw_ctx) + if (egl->use_hw_ctx) { - g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_egl_config, g_egl_ctx, + egl->hw_ctx = eglCreateContext(egl->dpy, egl->config, egl->ctx, egl_attribs); - RARCH_LOG("[EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx); + RARCH_LOG("[EGL]: Created shared context: %p.\n", (void*)egl->hw_ctx); - if (g_egl_hw_ctx == EGL_NO_CONTEXT) + if (egl->hw_ctx == EGL_NO_CONTEXT) return false;; } return true; } -bool egl_create_surface(NativeWindowType native_window) +bool egl_create_surface(void *data, NativeWindowType native_window) { - g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_egl_config, native_window, NULL); + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + egl->surf = eglCreateWindowSurface(egl->dpy, egl->config, native_window, NULL); - if (g_egl_surf == EGL_NO_SURFACE) + if (egl->surf == EGL_NO_SURFACE) return false; /* Connect the context to the surface. */ - if (!eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, g_egl_ctx)) + if (!eglMakeCurrent(egl->dpy, egl->surf, egl->surf, egl->ctx)) return false; RARCH_LOG("[EGL]: Current context: %p.\n", (void*)eglGetCurrentContext()); @@ -256,9 +264,10 @@ bool egl_create_surface(NativeWindowType native_window) return true; } -bool egl_get_native_visual_id(EGLint *value) +bool egl_get_native_visual_id(void *data, EGLint *value) { - if (!eglGetConfigAttrib(g_egl_dpy, g_egl_config, + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + if (!eglGetConfigAttrib(egl->dpy, egl->config, EGL_NATIVE_VISUAL_ID, value)) { RARCH_ERR("[EGL]: egl_get_native_visual_id failed.\n"); @@ -268,9 +277,10 @@ bool egl_get_native_visual_id(EGLint *value) return true; } -bool egl_has_config(void) +bool egl_has_config(void *data) { - if (!g_egl_config) + egl_ctx_data_t *egl = (egl_ctx_data_t*)data; + if (!egl->config) { RARCH_ERR("[EGL]: No EGL configurations available.\n"); return false; diff --git a/gfx/common/egl_common.h b/gfx/common/egl_common.h index 5532b66799..ef08294414 100644 --- a/gfx/common/egl_common.h +++ b/gfx/common/egl_common.h @@ -29,16 +29,44 @@ extern "C" { #endif -extern volatile sig_atomic_t g_egl_quit; +/* Put this structure as the first member of egl-based contexts + * like this: + * typedef struct + * { + * egl_ctx_data_t egl; + * int member0; + * char member1; + * .... + * } my_ctx_data_t; + * + * You can call egl functions passing the data pointer you receive + * or using &ctx_data->egl. It's up to you. + */ +typedef struct +{ + EGLContext ctx; + EGLContext hw_ctx; + EGLSurface surf; + EGLDisplay dpy; + EGLConfig config; + unsigned interval; -extern EGLContext g_egl_ctx; -extern EGLContext g_egl_hw_ctx; -extern EGLSurface g_egl_surf; -extern EGLDisplay g_egl_dpy; -extern EGLConfig g_egl_config; -extern enum gfx_ctx_api g_egl_api; + unsigned major; + unsigned minor; + enum gfx_ctx_api api; + + /* egl "private" */ + bool use_hw_ctx; +} egl_ctx_data_t; + +extern volatile sig_atomic_t g_egl_quit; extern bool g_egl_inited; -extern unsigned g_interval; + +/* bind_api is called before init so we need these, please + * try no to use them outside of bind_api() and init() */ +extern enum gfx_ctx_api g_egl_api; +extern unsigned g_egl_major; +extern unsigned g_egl_minor; void egl_report_error(void); @@ -56,17 +84,17 @@ void egl_get_video_size(void *data, unsigned *width, unsigned *height); void egl_install_sighandlers(void); -bool egl_init_context(NativeDisplayType display, +bool egl_init_context(void *data, NativeDisplayType display, EGLint *major, EGLint *minor, EGLint *n, const EGLint *attrib_ptr); -bool egl_create_context(EGLint *egl_attribs); +bool egl_create_context(void *data, EGLint *egl_attribs); -bool egl_create_surface(NativeWindowType native_window); +bool egl_create_surface(void *data, NativeWindowType native_window); -bool egl_get_native_visual_id(EGLint *value); +bool egl_get_native_visual_id(void *data, EGLint *value); -bool egl_has_config(void); +bool egl_has_config(void *data); #ifdef __cplusplus } diff --git a/gfx/drivers_context/drm_egl_ctx.c b/gfx/drivers_context/drm_egl_ctx.c index 2ae4ff6675..bcc678a26d 100644 --- a/gfx/drivers_context/drm_egl_ctx.c +++ b/gfx/drivers_context/drm_egl_ctx.c @@ -59,15 +59,12 @@ static bool waiting_for_flip; typedef struct gfx_ctx_drm_egl_data { + egl_ctx_data_t egl; RFILE *g_drm; unsigned g_fb_width; unsigned g_fb_height; } gfx_ctx_drm_egl_data_t; -static unsigned g_major; - -static unsigned g_minor; - struct drm_fb { struct gbm_bo *bo; @@ -117,7 +114,8 @@ error: static void gfx_ctx_drm_egl_swap_interval(void *data, unsigned interval) { - g_interval = interval; + gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*)data; + drm->egl.interval = interval; if (interval > 1) RARCH_WARN("[KMS/EGL]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n"); } @@ -206,6 +204,7 @@ static bool queue_flip(void) static void gfx_ctx_drm_egl_swap_buffers(void *data) { + gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*)data; egl_swap_buffers(data); /* I guess we have to wait for flip to have taken @@ -213,7 +212,7 @@ static void gfx_ctx_drm_egl_swap_buffers(void *data) * * If true, we are still waiting for a flip * (nonblocking mode, so just drop the frame). */ - if (wait_flip(g_interval)) + if (wait_flip(drm->egl.interval)) return; waiting_for_flip = queue_flip(); @@ -289,7 +288,7 @@ static void gfx_ctx_drm_egl_destroy_resources(gfx_ctx_drm_egl_data_t *drm) /* Make sure we acknowledge all page-flips. */ wait_flip(true); - egl_destroy(NULL); + egl_destroy(drm); /* Restore original CRTC. */ drm_restore_crtc(); @@ -388,14 +387,14 @@ error: return NULL; } -static EGLint *egl_fill_attribs(EGLint *attr) +static EGLint *egl_fill_attribs(gfx_ctx_drm_egl_data_t *drm, EGLint *attr) { - switch (g_egl_api) + switch (drm->egl.api) { #ifdef EGL_KHR_create_context case GFX_CTX_OPENGL_API: { - unsigned version = g_major * 1000 + g_minor; + unsigned version = drm->egl.major * 1000 + drm->egl.minor; bool core = version >= 3001; #ifdef GL_DEBUG bool debug = true; @@ -408,9 +407,9 @@ static EGLint *egl_fill_attribs(EGLint *attr) if (core) { *attr++ = EGL_CONTEXT_MAJOR_VERSION_KHR; - *attr++ = g_major; + *attr++ = drm->egl.major; *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; - *attr++ = g_minor; + *attr++ = drm->egl.minor; /* Technically, we don't have core/compat until 3.2. * Version 3.1 is either compat or not depending @@ -434,12 +433,12 @@ static EGLint *egl_fill_attribs(EGLint *attr) case GFX_CTX_OPENGL_ES_API: *attr++ = EGL_CONTEXT_CLIENT_VERSION; - *attr++ = g_major ? (EGLint)g_major : 2; + *attr++ = drm->egl.major ? (EGLint)drm->egl.major : 2; #ifdef EGL_KHR_create_context - if (g_minor > 0) + if (drm->egl.minor > 0) { *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; - *attr++ = g_minor; + *attr++ = drm->egl.minor; } #endif break; @@ -510,7 +509,7 @@ static bool gfx_ctx_drm_egl_set_video_mode(void *data, break; case GFX_CTX_OPENGL_ES_API: #ifdef EGL_KHR_create_context - if (g_major >= 3) + if (drm->egl.major >= 3) attrib_ptr = egl_attribs_gles3; else #endif @@ -583,27 +582,27 @@ static bool gfx_ctx_drm_egl_set_video_mode(void *data, } - if (!egl_init_context((EGLNativeDisplayType)g_gbm_dev, &major, + if (!egl_init_context(drm, (EGLNativeDisplayType)g_gbm_dev, &major, &minor, &n, attrib_ptr)) { egl_report_error(); goto error; } - attr = egl_fill_attribs(egl_attribs); + attr = egl_fill_attribs(drm, egl_attribs); egl_attribs_ptr = &egl_attribs[0]; - if (!egl_create_context((attr != egl_attribs_ptr) ? egl_attribs_ptr : NULL)) + if (!egl_create_context(drm, (attr != egl_attribs_ptr) ? egl_attribs_ptr : NULL)) { egl_report_error(); goto error; } - if (!egl_create_surface((EGLNativeWindowType)g_gbm_surface)) + if (!egl_create_surface(drm, (EGLNativeWindowType)g_gbm_surface)) goto error; glClear(GL_COLOR_BUFFER_BIT); - egl_swap_buffers(NULL); + egl_swap_buffers(drm); g_bo = gbm_surface_lock_front_buffer(g_gbm_surface); fb = drm_fb_get_from_bo(g_bo); @@ -662,14 +661,14 @@ static bool gfx_ctx_drm_egl_has_windowed(void *data) return false; } -static bool gfx_ctx_drm_egl_bind_api(void *data, +static bool gfx_ctx_drm_egl_bind_api(void *video_driver, enum gfx_ctx_api api, unsigned major, unsigned minor) { - (void)data; + (void)video_driver; - g_major = major; - g_minor = minor; - g_egl_api = api; + g_egl_major = major; + g_egl_minor = minor; + g_egl_api = api; switch (api) { diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 2a04a1d556..f6628326bf 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -28,26 +28,22 @@ typedef struct gfx_ctx_wayland_data { - bool g_resize; - int g_fd; - unsigned g_width; - unsigned g_height; - struct wl_display *g_dpy; - struct wl_registry *g_registry; - struct wl_compositor *g_compositor; - struct wl_surface *g_surface; - struct wl_shell_surface *g_shell_surf; - struct wl_shell *g_shell; - struct wl_egl_window *g_win; - struct wl_keyboard *g_wl_keyboard; - struct wl_pointer *g_wl_pointer; + egl_ctx_data_t egl; + bool resize; + int fd; + unsigned width; + unsigned height; + struct wl_display *dpy; + struct wl_registry *registry; + struct wl_compositor *compositor; + struct wl_surface *surface; + struct wl_shell_surface *shell_surf; + struct wl_shell *shell; + struct wl_egl_window *win; + struct wl_keyboard *wl_keyboard; + struct wl_pointer *wl_pointer; } gfx_ctx_wayland_data_t; - -static unsigned g_major; -static unsigned g_minor; - - #ifndef EGL_OPENGL_ES3_BIT_KHR #define EGL_OPENGL_ES3_BIT_KHR 0x0040 #endif @@ -70,11 +66,11 @@ static void shell_surface_handle_configure(void *data, (void)shell_surface; (void)edges; - wl->g_width = width; - wl->g_height = height; + wl->width = width; + wl->height = height; RARCH_LOG("[Wayland/EGL]: Surface configure: %u x %u.\n", - wl->g_width, wl->g_height); + wl->width, wl->height); } static void shell_surface_handle_popup_done(void *data, @@ -99,9 +95,9 @@ static void registry_handle_global(void *data, struct wl_registry *reg, (void)version; if (!strcmp(interface, "wl_compositor")) - wl->g_compositor = (struct wl_compositor*)wl_registry_bind(reg, id, &wl_compositor_interface, 1); + wl->compositor = (struct wl_compositor*)wl_registry_bind(reg, id, &wl_compositor_interface, 1); else if (!strcmp(interface, "wl_shell")) - wl->g_shell = (struct wl_shell*)wl_registry_bind(reg, id, &wl_shell_interface, 1); + wl->shell = (struct wl_shell*)wl_registry_bind(reg, id, &wl_shell_interface, 1); } static void registry_handle_global_remove(void *data, @@ -127,37 +123,37 @@ static void gfx_ctx_wl_destroy_resources(gfx_ctx_wayland_data_t *wl) if (!wl) return; - egl_destroy(NULL); + egl_destroy(wl); - if (wl->g_win) - wl_egl_window_destroy(wl->g_win); - if (wl->g_shell) - wl_shell_destroy(wl->g_shell); - if (wl->g_compositor) - wl_compositor_destroy(wl->g_compositor); - if (wl->g_registry) - wl_registry_destroy(wl->g_registry); - if (wl->g_shell_surf) - wl_shell_surface_destroy(wl->g_shell_surf); - if (wl->g_surface) - wl_surface_destroy(wl->g_surface); + if (wl->win) + wl_egl_window_destroy(wl->win); + if (wl->shell) + wl_shell_destroy(wl->shell); + if (wl->compositor) + wl_compositor_destroy(wl->compositor); + if (wl->registry) + wl_registry_destroy(wl->registry); + if (wl->shell_surf) + wl_shell_surface_destroy(wl->shell_surf); + if (wl->surface) + wl_surface_destroy(wl->surface); - if (wl->g_dpy) + if (wl->dpy) { - wl_display_flush(wl->g_dpy); - wl_display_disconnect(wl->g_dpy); + wl_display_flush(wl->dpy); + wl_display_disconnect(wl->dpy); } - wl->g_win = NULL; - wl->g_shell = NULL; - wl->g_compositor = NULL; - wl->g_registry = NULL; - wl->g_dpy = NULL; - wl->g_shell_surf = NULL; - wl->g_surface = NULL; + wl->win = NULL; + wl->shell = NULL; + wl->compositor = NULL; + wl->registry = NULL; + wl->dpy = NULL; + wl->shell_surf = NULL; + wl->surface = NULL; - wl->g_width = 0; - wl->g_height = 0; + wl->width = 0; + wl->height = 0; } static void flush_wayland_fd(void) @@ -166,24 +162,24 @@ static void flush_wayland_fd(void) gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*) gfx_ctx_data_get_ptr(); - wl_display_dispatch_pending(wl->g_dpy); - wl_display_flush(wl->g_dpy); + wl_display_dispatch_pending(wl->dpy); + wl_display_flush(wl->dpy); - fd.fd = wl->g_fd; + fd.fd = wl->fd; fd.events = POLLIN | POLLOUT | POLLERR | POLLHUP; if (poll(&fd, 1, 0) > 0) { if (fd.revents & (POLLERR | POLLHUP)) { - close(wl->g_fd); + close(wl->fd); g_egl_quit = true; } if (fd.revents & POLLIN) - wl_display_dispatch(wl->g_dpy); + wl_display_dispatch(wl->dpy); if (fd.revents & POLLOUT) - wl_display_flush(wl->g_dpy); + wl_display_flush(wl->dpy); } } @@ -216,7 +212,7 @@ static void gfx_ctx_wl_set_resize(void *data, unsigned width, unsigned height) { gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; - wl_egl_window_resize(wl->g_win, width, height, 0, 0); + wl_egl_window_resize(wl->win, width, height, 0, 0); } static void gfx_ctx_wl_update_window_title(void *data) @@ -228,7 +224,7 @@ static void gfx_ctx_wl_update_window_title(void *data) if (video_monitor_get_fps(buf, sizeof(buf), buf_fps, sizeof(buf_fps))) - wl_shell_surface_set_title(wl->g_shell_surf, buf); + wl_shell_surface_set_title(wl->shell_surf, buf); if (settings->fps_show) runloop_msg_queue_push(buf_fps, 1, 1, false); @@ -239,8 +235,8 @@ static void gfx_ctx_wl_get_video_size(void *data, { gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; - *width = wl->g_width; - *height = wl->g_height; + *width = wl->width; + *height = wl->height; } #define DEFAULT_WINDOWED_WIDTH 640 @@ -293,14 +289,14 @@ static void *gfx_ctx_wl_init(void *video_driver) if (!wl) return NULL; - switch (g_egl_api) + switch (wl->egl.api) { case GFX_CTX_OPENGL_API: attrib_ptr = egl_attribs_gl; break; case GFX_CTX_OPENGL_ES_API: #ifdef EGL_KHR_create_context - if (g_major >= 3) + if (g_egl_major >= 3) attrib_ptr = egl_attribs_gles3; else #endif @@ -315,39 +311,40 @@ static void *gfx_ctx_wl_init(void *video_driver) g_egl_quit = 0; - wl->g_dpy = wl_display_connect(NULL); - if (!wl->g_dpy) + wl->dpy = wl_display_connect(NULL); + if (!wl->dpy) { RARCH_ERR("Failed to connect to Wayland server.\n"); goto error; } - wl->g_registry = wl_display_get_registry(wl->g_dpy); - wl_registry_add_listener(wl->g_registry, ®istry_listener, NULL); - wl_display_dispatch(wl->g_dpy); + wl->registry = wl_display_get_registry(wl->dpy); + wl_registry_add_listener(wl->registry, ®istry_listener, wl); + wl_display_dispatch(wl->dpy); + wl_display_roundtrip(wl->dpy); - if (!wl->g_compositor) + if (!wl->compositor) { RARCH_ERR("Failed to create compositor.\n"); goto error; } - if (!wl->g_shell) + if (!wl->shell) { RARCH_ERR("Failed to create shell.\n"); goto error; } - wl->g_fd = wl_display_get_fd(wl->g_dpy); + wl->fd = wl_display_get_fd(wl->dpy); - if (!egl_init_context((EGLNativeDisplayType)wl->g_dpy, + if (!egl_init_context(wl, (EGLNativeDisplayType)wl->dpy, &major, &minor, &n, attrib_ptr)) { egl_report_error(); goto error; } - if (n == 0 || !egl_has_config()) + if (n == 0 || !egl_has_config(wl)) goto error; return wl; @@ -361,14 +358,14 @@ error: return NULL; } -static EGLint *egl_fill_attribs(EGLint *attr) +static EGLint *egl_fill_attribs(gfx_ctx_wayland_data_t *wl, EGLint *attr) { - switch (g_egl_api) + switch (wl->egl.api) { #ifdef EGL_KHR_create_context case GFX_CTX_OPENGL_API: { - unsigned version = g_major * 1000 + g_minor; + unsigned version = wl->egl.major * 1000 + wl->egl.minor; bool core = version >= 3001; #ifdef GL_DEBUG bool debug = true; @@ -381,9 +378,9 @@ static EGLint *egl_fill_attribs(EGLint *attr) if (core) { *attr++ = EGL_CONTEXT_MAJOR_VERSION_KHR; - *attr++ = g_major; + *attr++ = wl->egl.major; *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; - *attr++ = g_minor; + *attr++ = wl->egl.minor; /* Technically, we don't have core/compat until 3.2. * Version 3.1 is either compat or not depending on GL_ARB_compatibility. */ if (version >= 3002) @@ -405,12 +402,12 @@ static EGLint *egl_fill_attribs(EGLint *attr) case GFX_CTX_OPENGL_ES_API: *attr++ = EGL_CONTEXT_CLIENT_VERSION; /* Same as EGL_CONTEXT_MAJOR_VERSION */ - *attr++ = g_major ? (EGLint)g_major : 2; + *attr++ = wl->egl.major ? (EGLint)wl->egl.major : 2; #ifdef EGL_KHR_create_context - if (g_minor > 0) + if (wl->egl.minor > 0) { *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; - *attr++ = g_minor; + *attr++ = wl->egl.minor; } #endif break; @@ -445,33 +442,33 @@ static bool gfx_ctx_wl_set_video_mode(void *data, egl_install_sighandlers(); - attr = egl_fill_attribs(egl_attribs); + attr = egl_fill_attribs(wl, egl_attribs); - wl->g_width = width ? width : DEFAULT_WINDOWED_WIDTH; - wl->g_height = height ? height : DEFAULT_WINDOWED_HEIGHT; + wl->width = width ? width : DEFAULT_WINDOWED_WIDTH; + wl->height = height ? height : DEFAULT_WINDOWED_HEIGHT; - wl->g_surface = wl_compositor_create_surface(wl->g_compositor); - wl->g_win = wl_egl_window_create(wl->g_surface, wl->g_width, wl->g_height); - wl->g_shell_surf = wl_shell_get_shell_surface(wl->g_shell, wl->g_surface); + wl->surface = wl_compositor_create_surface(wl->compositor); + wl->win = wl_egl_window_create(wl->surface, wl->width, wl->height); + wl->shell_surf = wl_shell_get_shell_surface(wl->shell, wl->surface); - wl_shell_surface_add_listener(wl->g_shell_surf, &shell_surface_listener, NULL); - wl_shell_surface_set_toplevel(wl->g_shell_surf); - wl_shell_surface_set_class(wl->g_shell_surf, "RetroArch"); - wl_shell_surface_set_title(wl->g_shell_surf, "RetroArch"); + wl_shell_surface_add_listener(wl->shell_surf, &shell_surface_listener, NULL); + wl_shell_surface_set_toplevel(wl->shell_surf); + wl_shell_surface_set_class(wl->shell_surf, "RetroArch"); + wl_shell_surface_set_title(wl->shell_surf, "RetroArch"); - if (!egl_create_context((attr != egl_attribs) ? egl_attribs : NULL)) + if (!egl_create_context(wl, (attr != egl_attribs) ? egl_attribs : NULL)) { egl_report_error(); goto error; } - if (!egl_create_surface((EGLNativeWindowType)wl->g_win)) + if (!egl_create_surface(wl, (EGLNativeWindowType)wl->win)) goto error; - egl_set_swap_interval(data, g_interval); + egl_set_swap_interval(wl, wl->egl.interval); if (fullscreen) - wl_shell_surface_set_fullscreen(wl->g_shell_surf, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL); + wl_shell_surface_set_fullscreen(wl->shell_surf, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL); flush_wayland_fd(); return true; @@ -513,14 +510,12 @@ static bool gfx_ctx_wl_has_windowed(void *data) return true; } -static bool gfx_ctx_wl_bind_api(void *data, +static bool gfx_ctx_wl_bind_api(void *video_driver, enum gfx_ctx_api api, unsigned major, unsigned minor) { - (void)data; - - g_major = major; - g_minor = minor; - g_egl_api = api; + g_egl_major = major; + g_egl_minor = minor; + g_egl_api = api; switch (api) { @@ -660,25 +655,25 @@ struct wl_seat *seat, unsigned caps) { gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wl->g_wl_keyboard) + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wl->wl_keyboard) { - wl->g_wl_keyboard = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(wl->g_wl_keyboard, &keyboard_listener, NULL); + wl->wl_keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(wl->wl_keyboard, &keyboard_listener, NULL); } - else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wl->g_wl_keyboard) + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wl->wl_keyboard) { - wl_keyboard_destroy(wl->g_wl_keyboard); - wl->g_wl_keyboard = NULL; + wl_keyboard_destroy(wl->wl_keyboard); + wl->wl_keyboard = NULL; } - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl->g_wl_pointer) + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wl->wl_pointer) { - wl->g_wl_pointer = wl_seat_get_pointer(seat); - wl_pointer_add_listener(wl->g_wl_pointer, &pointer_listener, NULL); + wl->wl_pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(wl->wl_pointer, &pointer_listener, NULL); } - else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->g_wl_pointer) + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wl->wl_pointer) { - wl_pointer_destroy(wl->g_wl_pointer); - wl->g_wl_pointer = NULL; + wl_pointer_destroy(wl->wl_pointer); + wl->wl_pointer = NULL; } } diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index 08c50bab79..eb5739dd4a 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -27,11 +27,11 @@ #define EGL_OPENGL_ES3_BIT_KHR 0x0040 #endif -static XF86VidModeModeInfo g_desktop_mode; -static bool g_should_reset_mode; - -static unsigned g_major; -static unsigned g_minor; +typedef struct { + egl_ctx_data_t egl; + XF86VidModeModeInfo desktop_mode; + bool should_reset_mode; +} xegl_ctx_data_t; static int egl_nul_handler(Display *dpy, XErrorEvent *event) { @@ -42,6 +42,8 @@ static int egl_nul_handler(Display *dpy, XErrorEvent *event) static void gfx_ctx_xegl_destroy(void *data) { + xegl_ctx_data_t *xegl = (xegl_ctx_data_t*)data; + x11_input_ctx_destroy(); egl_destroy(data); @@ -54,12 +56,14 @@ static void gfx_ctx_xegl_destroy(void *data) x11_colormap_destroy(); - if (g_should_reset_mode) + if (xegl->should_reset_mode) { - x11_exit_fullscreen(g_x11_dpy, &g_desktop_mode); - g_should_reset_mode = false; + x11_exit_fullscreen(g_x11_dpy, &xegl->desktop_mode); + xegl->should_reset_mode = false; } + free(data); + /* Do not close g_x11_dpy. We'll keep one for the entire application * lifecycle to work-around nVidia EGL limitations. */ @@ -112,20 +116,26 @@ static void *gfx_ctx_xegl_init(void *video_driver) const EGLint *attrib_ptr; EGLint major, minor; EGLint n; + xegl_ctx_data_t *xegl; + if (g_egl_inited) return NULL; XInitThreads(); - switch (g_egl_api) + xegl = (xegl_ctx_data_t*)calloc(1, sizeof(xegl_ctx_data_t)); + if (!xegl) + return NULL; + + switch (xegl->egl.api) { case GFX_CTX_OPENGL_API: attrib_ptr = egl_attribs_gl; break; case GFX_CTX_OPENGL_ES_API: #ifdef EGL_KHR_create_context - if (g_major >= 3) + if (xegl->egl.major >= 3) attrib_ptr = egl_attribs_gles3; else #endif @@ -141,33 +151,33 @@ static void *gfx_ctx_xegl_init(void *video_driver) if (!x11_connect()) goto error; - if (!egl_init_context((EGLNativeDisplayType)g_x11_dpy, + if (!egl_init_context(xegl, (EGLNativeDisplayType)g_x11_dpy, &major, &minor, &n, attrib_ptr)) { egl_report_error(); goto error; } - if (n == 0 || !egl_has_config()) + if (n == 0 || !egl_has_config(xegl)) goto error; - return (void*)"xegl"; + return xegl; error: - gfx_ctx_xegl_destroy(video_driver); + gfx_ctx_xegl_destroy(xegl); return NULL; } -static EGLint *xegl_fill_attribs(EGLint *attr) +static EGLint *xegl_fill_attribs(xegl_ctx_data_t *xegl, EGLint *attr) { - switch (g_egl_api) + switch (xegl->egl.api) { #ifdef EGL_KHR_create_context case GFX_CTX_OPENGL_API: { const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); - unsigned version = g_major * 1000 + g_minor; + unsigned version = xegl->egl.major * 1000 + xegl->egl.minor; bool core = version >= 3001; #ifdef GL_DEBUG bool debug = true; @@ -178,9 +188,9 @@ static EGLint *xegl_fill_attribs(EGLint *attr) if (core) { *attr++ = EGL_CONTEXT_MAJOR_VERSION_KHR; - *attr++ = g_major; + *attr++ = xegl->egl.major; *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; - *attr++ = g_minor; + *attr++ = xegl->egl.minor; /* Technically, we don't have core/compat until 3.2. * Version 3.1 is either compat or not depending @@ -206,12 +216,12 @@ static EGLint *xegl_fill_attribs(EGLint *attr) case GFX_CTX_OPENGL_ES_API: /* Same as EGL_CONTEXT_MAJOR_VERSION. */ *attr++ = EGL_CONTEXT_CLIENT_VERSION; - *attr++ = g_major ? (EGLint)g_major : 2; + *attr++ = xegl->egl.major ? (EGLint)xegl->egl.major : 2; #ifdef EGL_KHR_create_context - if (g_minor > 0) + if (xegl->egl.minor > 0) { *attr++ = EGL_CONTEXT_MINOR_VERSION_KHR; - *attr++ = g_minor; + *attr++ = xegl->egl.minor; } #endif break; @@ -240,6 +250,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, XSetWindowAttributes swa = {0}; XVisualInfo *vi = NULL; settings_t *settings = config_get_ptr(); + xegl_ctx_data_t *xegl = (xegl_ctx_data_t*)data; int (*old_handler)(Display*, XErrorEvent*) = NULL; @@ -248,9 +259,9 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, windowed_full = settings->video.windowed_fullscreen; attr = egl_attribs; - attr = xegl_fill_attribs(attr); + attr = xegl_fill_attribs(xegl, attr); - if (!egl_get_native_visual_id(&vid)) + if (!egl_get_native_visual_id(xegl, &vid)) goto error; temp.visualid = vid; @@ -266,9 +277,9 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, if (fullscreen && !windowed_full) { - if (x11_enter_fullscreen(g_x11_dpy, width, height, &g_desktop_mode)) + if (x11_enter_fullscreen(g_x11_dpy, width, height, &xegl->desktop_mode)) { - g_should_reset_mode = true; + xegl->should_reset_mode = true; true_full = true; } else @@ -306,13 +317,13 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); - if (!egl_create_context((attr != egl_attribs) ? egl_attribs : NULL)) + if (!egl_create_context(xegl, (attr != egl_attribs) ? egl_attribs : NULL)) { egl_report_error(); goto error; } - if (!egl_create_surface((EGLNativeWindowType)g_x11_win)) + if (!egl_create_surface(xegl, (EGLNativeWindowType)g_x11_win)) goto error; x11_set_window_attr(g_x11_dpy, g_x11_win); @@ -356,7 +367,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, x11_event_queue_check(&event); x11_install_quit_atom(); - egl_set_swap_interval(data, g_interval); + egl_set_swap_interval(xegl, xegl->egl.interval); /* This can blow up on some drivers. It's not fatal, * so override errors for this call. @@ -367,7 +378,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, XSetErrorHandler(old_handler); XFree(vi); - g_egl_inited = true; + g_egl_inited = true; if (!x11_input_ctx_new(true_full)) goto error; @@ -423,13 +434,11 @@ static bool gfx_ctx_xegl_has_windowed(void *data) return true; } -static bool gfx_ctx_xegl_bind_api(void *data, +static bool gfx_ctx_xegl_bind_api(void *video_driver, enum gfx_ctx_api api, unsigned major, unsigned minor) { - (void)data; - - g_major = major; - g_minor = minor; + g_egl_major = major; + g_egl_minor = minor; g_egl_api = api; switch (api) diff --git a/gfx/video_context_driver.c b/gfx/video_context_driver.c index cbd31a5607..716c074a69 100644 --- a/gfx/video_context_driver.c +++ b/gfx/video_context_driver.c @@ -103,6 +103,7 @@ void gfx_ctx_free(void) if (current_video_context->destroy) current_video_context->destroy(video_context_data); current_video_context = NULL; + video_context_data = NULL; } const char *gfx_ctx_get_ident(void) diff --git a/gfx/video_context_driver.h b/gfx/video_context_driver.h index 7ace778d5d..191cc8db92 100644 --- a/gfx/video_context_driver.h +++ b/gfx/video_context_driver.h @@ -64,7 +64,7 @@ typedef struct gfx_ctx_driver void (*destroy)(void *data); /* Which API to bind to. */ - bool (*bind_api)(void *data, enum gfx_ctx_api, + bool (*bind_api)(void *video_driver, enum gfx_ctx_api, unsigned major, unsigned minor); /* Sets the swap interval. */