mirror of
https://github.com/libretro/RetroArch
synced 2025-02-02 14:54:10 +00:00
Begin adding opaque interface to gfx_context.
This commit is contained in:
parent
171cb7ed79
commit
d0302c9800
@ -84,7 +84,7 @@ struct drm_fb
|
||||
};
|
||||
|
||||
static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo);
|
||||
static void gfx_ctx_destroy(void);
|
||||
static void gfx_ctx_destroy(void *data);
|
||||
|
||||
static void sighandler(int sig)
|
||||
{
|
||||
@ -92,16 +92,18 @@ static void sighandler(int sig)
|
||||
g_quit = 1;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_interval(unsigned interval)
|
||||
static void gfx_ctx_swap_interval(void *data, unsigned interval)
|
||||
{
|
||||
(void)data;
|
||||
g_interval = interval;
|
||||
if (interval > 1)
|
||||
RARCH_WARN("[KMS/EGL]: Swap intervals > 1 currently not supported. Will use swap interval of 1.\n");
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
static void gfx_ctx_check_window(void *data, bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
||||
{
|
||||
(void)data;
|
||||
(void)frame_count;
|
||||
(void)width;
|
||||
(void)height;
|
||||
@ -187,8 +189,9 @@ static void queue_flip(void)
|
||||
waiting_for_flip = true;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_buffers(void)
|
||||
static void gfx_ctx_swap_buffers(void *data)
|
||||
{
|
||||
(void)data;
|
||||
eglSwapBuffers(g_egl_dpy, g_egl_surf);
|
||||
|
||||
// I guess we have to wait for flip to have taken place before another flip can be queued up.
|
||||
@ -209,14 +212,16 @@ static void gfx_ctx_swap_buffers(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_set_resize(unsigned width, unsigned height)
|
||||
static void gfx_ctx_set_resize(void *data, unsigned width, unsigned height)
|
||||
{
|
||||
(void)data;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_update_window_title(void)
|
||||
static void gfx_ctx_update_window_title(void *data)
|
||||
{
|
||||
(void)data;
|
||||
char buf[128], buf_fps[128];
|
||||
bool fps_draw = g_settings.fps_show;
|
||||
gfx_get_fps(buf, sizeof(buf), fps_draw ? buf_fps : NULL, sizeof(buf_fps));
|
||||
@ -225,13 +230,14 @@ static void gfx_ctx_update_window_title(void)
|
||||
msg_queue_push(g_extern.msg_queue, buf_fps, 1, 1);
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
static void gfx_ctx_get_video_size(void *data, unsigned *width, unsigned *height)
|
||||
{
|
||||
(void)data;
|
||||
*width = g_fb_width;
|
||||
*height = g_fb_height;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init(void)
|
||||
static bool gfx_ctx_init(void *data)
|
||||
{
|
||||
int i;
|
||||
if (g_inited)
|
||||
@ -316,7 +322,7 @@ static bool gfx_ctx_init(void)
|
||||
return true;
|
||||
|
||||
error:
|
||||
gfx_ctx_destroy();
|
||||
gfx_ctx_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -358,7 +364,7 @@ static struct drm_fb *drm_fb_get_from_bo(struct gbm_bo *bo)
|
||||
return fb;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_set_video_mode(
|
||||
static bool gfx_ctx_set_video_mode(void *data,
|
||||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
@ -476,12 +482,13 @@ static bool gfx_ctx_set_video_mode(
|
||||
return true;
|
||||
|
||||
error:
|
||||
gfx_ctx_destroy();
|
||||
gfx_ctx_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
void gfx_ctx_destroy(void)
|
||||
void gfx_ctx_destroy(void *data)
|
||||
{
|
||||
(void)data;
|
||||
// Make sure we acknowledge all page-flips.
|
||||
if (waiting_for_flip)
|
||||
wait_flip(true);
|
||||
@ -558,14 +565,16 @@ void gfx_ctx_destroy(void)
|
||||
g_inited = false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||
static void gfx_ctx_input_driver(void *data, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
(void)data;
|
||||
*input = NULL;
|
||||
*input_data = NULL;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_has_focus(void)
|
||||
static bool gfx_ctx_has_focus(void *data)
|
||||
{
|
||||
(void)data;
|
||||
return g_inited;
|
||||
}
|
||||
|
||||
@ -574,8 +583,9 @@ static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
|
||||
return eglGetProcAddress(symbol);
|
||||
}
|
||||
|
||||
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
static bool gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
{
|
||||
(void)data;
|
||||
g_major = major;
|
||||
g_minor = minor;
|
||||
g_api = api;
|
||||
@ -596,16 +606,6 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned mino
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_drm_egl = {
|
||||
gfx_ctx_init,
|
||||
gfx_ctx_destroy,
|
||||
@ -621,8 +621,8 @@ const gfx_ctx_driver_t gfx_ctx_drm_egl = {
|
||||
gfx_ctx_swap_buffers,
|
||||
gfx_ctx_input_driver,
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"kms-egl",
|
||||
};
|
||||
|
@ -82,11 +82,12 @@ static int nul_handler(Display *dpy, XErrorEvent *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height);
|
||||
static void gfx_ctx_destroy(void);
|
||||
static void gfx_ctx_get_video_size(void *data, unsigned *width, unsigned *height);
|
||||
static void gfx_ctx_destroy(void *data);
|
||||
|
||||
static void gfx_ctx_swap_interval(unsigned interval)
|
||||
static void gfx_ctx_swap_interval(void *data, unsigned interval)
|
||||
{
|
||||
(void)data;
|
||||
g_interval = interval;
|
||||
|
||||
if (g_pglSwapIntervalEXT)
|
||||
@ -102,13 +103,13 @@ static void gfx_ctx_swap_interval(unsigned interval)
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
static void gfx_ctx_check_window(void *data, bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
||||
{
|
||||
(void)frame_count;
|
||||
|
||||
unsigned new_width = *width, new_height = *height;
|
||||
gfx_ctx_get_video_size(&new_width, &new_height);
|
||||
gfx_ctx_get_video_size(data, &new_width, &new_height);
|
||||
|
||||
if (new_width != *width || new_height != *height)
|
||||
{
|
||||
@ -156,20 +157,23 @@ static void gfx_ctx_check_window(bool *quit,
|
||||
*quit = g_quit;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_buffers(void)
|
||||
static void gfx_ctx_swap_buffers(void *data)
|
||||
{
|
||||
(void)data;
|
||||
if (g_is_double)
|
||||
glXSwapBuffers(g_dpy, g_glx_win);
|
||||
}
|
||||
|
||||
static void gfx_ctx_set_resize(unsigned width, unsigned height)
|
||||
static void gfx_ctx_set_resize(void *data, unsigned width, unsigned height)
|
||||
{
|
||||
(void)data;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_update_window_title(void)
|
||||
static void gfx_ctx_update_window_title(void *data)
|
||||
{
|
||||
(void)data;
|
||||
char buf[128], buf_fps[128];
|
||||
bool fps_draw = g_settings.fps_show;
|
||||
if (gfx_get_fps(buf, sizeof(buf), fps_draw ? buf_fps : NULL, sizeof(buf_fps)))
|
||||
@ -179,8 +183,10 @@ static void gfx_ctx_update_window_title(void)
|
||||
msg_queue_push(g_extern.msg_queue, buf_fps, 1, 1);
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
static void gfx_ctx_get_video_size(void *data, unsigned *width, unsigned *height)
|
||||
{
|
||||
(void)data;
|
||||
|
||||
if (!g_dpy || g_win == None)
|
||||
{
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
@ -207,7 +213,7 @@ static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init(void)
|
||||
static bool gfx_ctx_init(void *data)
|
||||
{
|
||||
if (g_inited)
|
||||
return false;
|
||||
@ -275,11 +281,11 @@ static bool gfx_ctx_init(void)
|
||||
return true;
|
||||
|
||||
error:
|
||||
gfx_ctx_destroy();
|
||||
gfx_ctx_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_set_video_mode(
|
||||
static bool gfx_ctx_set_video_mode(void *data,
|
||||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
@ -453,7 +459,7 @@ static bool gfx_ctx_set_video_mode(
|
||||
else
|
||||
RARCH_WARN("[GLX]: Context is not double buffered!.\n");
|
||||
|
||||
gfx_ctx_swap_interval(g_interval);
|
||||
gfx_ctx_swap_interval(data, g_interval);
|
||||
|
||||
// This can blow up on some drivers. It's not fatal, so override errors for this call.
|
||||
old_handler = XSetErrorHandler(nul_handler);
|
||||
@ -479,12 +485,13 @@ error:
|
||||
if (vi)
|
||||
XFree(vi);
|
||||
|
||||
gfx_ctx_destroy();
|
||||
gfx_ctx_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void)
|
||||
static void gfx_ctx_destroy(void *data)
|
||||
{
|
||||
(void)data;
|
||||
x11_destroy_input_context(&g_xim, &g_xic);
|
||||
|
||||
if (g_dpy && g_ctx)
|
||||
@ -549,15 +556,17 @@ static void gfx_ctx_destroy(void)
|
||||
g_core = false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||
static void gfx_ctx_input_driver(void *data, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
(void)data;
|
||||
void *xinput = input_x.init();
|
||||
*input = xinput ? &input_x : NULL;
|
||||
*input_data = xinput;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_has_focus(void)
|
||||
static bool gfx_ctx_has_focus(void *data)
|
||||
{
|
||||
(void)data;
|
||||
if (!g_inited)
|
||||
return false;
|
||||
|
||||
@ -573,27 +582,17 @@ static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
|
||||
return glXGetProcAddress((const GLubyte*)symbol);
|
||||
}
|
||||
|
||||
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
static bool gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
{
|
||||
(void)data;
|
||||
g_major = major;
|
||||
g_minor = minor;
|
||||
return api == GFX_CTX_OPENGL_API;
|
||||
}
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void gfx_ctx_show_mouse(bool state)
|
||||
static void gfx_ctx_show_mouse(void *data, bool state)
|
||||
{
|
||||
(void)data;
|
||||
x11_show_mouse(g_dpy, g_win, state);
|
||||
}
|
||||
|
||||
@ -613,8 +612,8 @@ const gfx_ctx_driver_t gfx_ctx_glx = {
|
||||
gfx_ctx_input_driver,
|
||||
gfx_ctx_get_proc_address,
|
||||
#ifdef HAVE_EGL
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
gfx_ctx_show_mouse,
|
||||
"glx",
|
||||
|
@ -76,8 +76,8 @@ static int nul_handler(Display *dpy, XErrorEvent *event)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height);
|
||||
static void gfx_ctx_destroy(void);
|
||||
static void gfx_ctx_get_video_size(void *data, unsigned *width, unsigned *height);
|
||||
static void gfx_ctx_destroy(void *data);
|
||||
|
||||
static void egl_report_error(void)
|
||||
{
|
||||
@ -109,8 +109,9 @@ static void egl_report_error(void)
|
||||
RARCH_ERR("[X/EGL]: #0x%x, %s\n", (unsigned)error, str);
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_interval(unsigned interval)
|
||||
static void gfx_ctx_swap_interval(void *data, unsigned interval)
|
||||
{
|
||||
(void)data;
|
||||
g_interval = interval;
|
||||
if (g_egl_dpy && eglGetCurrentContext())
|
||||
{
|
||||
@ -123,13 +124,13 @@ static void gfx_ctx_swap_interval(unsigned interval)
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_check_window(bool *quit,
|
||||
static void gfx_ctx_check_window(void *data, bool *quit,
|
||||
bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
|
||||
{
|
||||
(void)frame_count;
|
||||
|
||||
unsigned new_width = *width, new_height = *height;
|
||||
gfx_ctx_get_video_size(&new_width, &new_height);
|
||||
gfx_ctx_get_video_size(data, &new_width, &new_height);
|
||||
|
||||
if (new_width != *width || new_height != *height)
|
||||
{
|
||||
@ -173,19 +174,22 @@ static void gfx_ctx_check_window(bool *quit,
|
||||
*quit = g_quit;
|
||||
}
|
||||
|
||||
static void gfx_ctx_swap_buffers(void)
|
||||
static void gfx_ctx_swap_buffers(void *data)
|
||||
{
|
||||
(void)data;
|
||||
eglSwapBuffers(g_egl_dpy, g_egl_surf);
|
||||
}
|
||||
|
||||
static void gfx_ctx_set_resize(unsigned width, unsigned height)
|
||||
static void gfx_ctx_set_resize(void *data, unsigned width, unsigned height)
|
||||
{
|
||||
(void)data;
|
||||
(void)width;
|
||||
(void)height;
|
||||
}
|
||||
|
||||
static void gfx_ctx_update_window_title(void)
|
||||
static void gfx_ctx_update_window_title(void *data)
|
||||
{
|
||||
(void)data;
|
||||
char buf[128], buf_fps[128];
|
||||
bool fps_draw = g_settings.fps_show;
|
||||
if (gfx_get_fps(buf, sizeof(buf), fps_draw ? buf_fps : NULL, sizeof(buf_fps)))
|
||||
@ -195,8 +199,9 @@ static void gfx_ctx_update_window_title(void)
|
||||
msg_queue_push(g_extern.msg_queue, buf_fps, 1, 1);
|
||||
}
|
||||
|
||||
static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
static void gfx_ctx_get_video_size(void *data, unsigned *width, unsigned *height)
|
||||
{
|
||||
(void)data;
|
||||
if (!g_dpy || g_win == None)
|
||||
{
|
||||
Display *dpy = XOpenDisplay(NULL);
|
||||
@ -223,7 +228,7 @@ static void gfx_ctx_get_video_size(unsigned *width, unsigned *height)
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init(void)
|
||||
static bool gfx_ctx_init(void *data)
|
||||
{
|
||||
if (g_inited)
|
||||
return false;
|
||||
@ -294,14 +299,16 @@ static bool gfx_ctx_init(void)
|
||||
g_egl_dpy = eglGetDisplay((EGLNativeDisplayType)g_dpy);
|
||||
if (g_egl_dpy == EGL_NO_DISPLAY)
|
||||
{
|
||||
RARCH_ERR("[X/EGL]: EGL display not available (Error: 0x%x).\n", (unsigned)eglGetError());
|
||||
RARCH_ERR("[X/EGL]: EGL display not available.\n");
|
||||
egl_report_error();
|
||||
goto error;
|
||||
}
|
||||
|
||||
EGLint egl_major, egl_minor;
|
||||
if (!eglInitialize(g_egl_dpy, &egl_major, &egl_minor))
|
||||
{
|
||||
RARCH_ERR("[X/EGL]: Unable to initialize EGL (Error: 0x%x).\n", (unsigned)eglGetError());
|
||||
RARCH_ERR("[X/EGL]: Unable to initialize EGL.\n");
|
||||
egl_report_error();
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -323,11 +330,11 @@ static bool gfx_ctx_init(void)
|
||||
return true;
|
||||
|
||||
error:
|
||||
gfx_ctx_destroy();
|
||||
gfx_ctx_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_set_video_mode(
|
||||
static bool gfx_ctx_set_video_mode(void *data,
|
||||
unsigned width, unsigned height,
|
||||
bool fullscreen)
|
||||
{
|
||||
@ -464,7 +471,7 @@ static bool gfx_ctx_set_video_mode(
|
||||
if (g_quit_atom)
|
||||
XSetWMProtocols(g_dpy, g_win, &g_quit_atom, 1);
|
||||
|
||||
gfx_ctx_swap_interval(g_interval);
|
||||
gfx_ctx_swap_interval(data, g_interval);
|
||||
|
||||
// This can blow up on some drivers. It's not fatal, so override errors for this call.
|
||||
old_handler = XSetErrorHandler(nul_handler);
|
||||
@ -490,12 +497,13 @@ error:
|
||||
if (vi)
|
||||
XFree(vi);
|
||||
|
||||
gfx_ctx_destroy();
|
||||
gfx_ctx_destroy(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_destroy(void)
|
||||
static void gfx_ctx_destroy(void *data)
|
||||
{
|
||||
(void)data;
|
||||
x11_destroy_input_context(&g_xim, &g_xic);
|
||||
if (g_egl_dpy)
|
||||
{
|
||||
@ -559,15 +567,17 @@ static void gfx_ctx_destroy(void)
|
||||
g_inited = false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data)
|
||||
static void gfx_ctx_input_driver(void *data, const input_driver_t **input, void **input_data)
|
||||
{
|
||||
(void)data;
|
||||
void *xinput = input_x.init();
|
||||
*input = xinput ? &input_x : NULL;
|
||||
*input_data = xinput;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_has_focus(void)
|
||||
static bool gfx_ctx_has_focus(void *data)
|
||||
{
|
||||
(void)data;
|
||||
if (!g_inited)
|
||||
return false;
|
||||
|
||||
@ -583,8 +593,9 @@ static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
|
||||
return eglGetProcAddress(symbol);
|
||||
}
|
||||
|
||||
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
static bool gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
{
|
||||
(void)data;
|
||||
g_major = major;
|
||||
g_minor = minor;
|
||||
g_api = api;
|
||||
@ -605,18 +616,9 @@ static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned mino
|
||||
}
|
||||
}
|
||||
|
||||
static bool gfx_ctx_init_egl_image_buffer(const video_info_t *video)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool gfx_ctx_write_egl_image(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gfx_ctx_show_mouse(bool state)
|
||||
static void gfx_ctx_show_mouse(void *data, bool state)
|
||||
{
|
||||
(void)data;
|
||||
x11_show_mouse(g_dpy, g_win, state);
|
||||
}
|
||||
|
||||
@ -635,8 +637,8 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = {
|
||||
gfx_ctx_swap_buffers,
|
||||
gfx_ctx_input_driver,
|
||||
gfx_ctx_get_proc_address,
|
||||
gfx_ctx_init_egl_image_buffer,
|
||||
gfx_ctx_write_egl_image,
|
||||
NULL,
|
||||
NULL,
|
||||
gfx_ctx_show_mouse,
|
||||
"x-egl",
|
||||
};
|
||||
|
@ -56,6 +56,7 @@ static const gfx_ctx_driver_t *gfx_ctx_drivers[] = {
|
||||
#ifdef EMSCRIPTEN
|
||||
&gfx_ctx_emscripten,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
@ -70,14 +71,14 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < ARRAY_SIZE(gfx_ctx_drivers); i++)
|
||||
for (i = 0; gfx_ctx_drivers[i]; i++)
|
||||
{
|
||||
if (gfx_ctx_drivers[i]->bind_api(api, major, minor))
|
||||
if (gfx_ctx_drivers[i]->bind_api(data, api, major, minor))
|
||||
{
|
||||
if (gfx_ctx_drivers[i]->init())
|
||||
if (gfx_ctx_drivers[i]->init(data))
|
||||
return gfx_ctx_drivers[i];
|
||||
}
|
||||
}
|
||||
|
@ -40,62 +40,66 @@ enum gfx_ctx_api
|
||||
|
||||
typedef void (*gfx_ctx_proc_t)(void);
|
||||
|
||||
// The opaque void* argument should be the overlying driver data (e.g. gl_t for OpenGL contexts).
|
||||
// This will allow us in the future to have separate contexts to separate gl_t structs (if needed).
|
||||
// For now, this is only relevant for D3D.
|
||||
typedef struct gfx_ctx_driver
|
||||
{
|
||||
bool (*init)(void);
|
||||
void (*destroy)(void);
|
||||
bool (*init)(void *data);
|
||||
void (*destroy)(void *data);
|
||||
|
||||
bool (*bind_api)(enum gfx_ctx_api, unsigned major, unsigned minor); // Which API to bind to.
|
||||
bool (*bind_api)(void *data, enum gfx_ctx_api, unsigned major, unsigned minor); // Which API to bind to.
|
||||
|
||||
// Sets the swap interval.
|
||||
void (*swap_interval)(unsigned);
|
||||
void (*swap_interval)(void *data, unsigned);
|
||||
|
||||
// Sets video mode. Creates a window, etc.
|
||||
bool (*set_video_mode)(unsigned, unsigned, bool);
|
||||
bool (*set_video_mode)(void*, unsigned, unsigned, bool);
|
||||
|
||||
// Gets current window size.
|
||||
// If not initialized yet, it returns current screen size.
|
||||
void (*get_video_size)(unsigned*, unsigned*);
|
||||
void (*get_video_size)(void*, unsigned*, unsigned*);
|
||||
|
||||
// Translates a window size to an aspect ratio.
|
||||
// In most cases this will be just width / height, but
|
||||
// some contexts will better know which actual aspect ratio is used.
|
||||
// This can be NULL to assume the default behavior.
|
||||
float (*translate_aspect)(unsigned, unsigned);
|
||||
float (*translate_aspect)(void*, unsigned, unsigned);
|
||||
|
||||
// Asks driver to update window title (FPS, etc).
|
||||
void (*update_window_title)(void);
|
||||
void (*update_window_title)(void*);
|
||||
|
||||
// Queries for resize and quit events.
|
||||
// Also processes events.
|
||||
void (*check_window)(bool*, bool*, unsigned*, unsigned*, unsigned);
|
||||
void (*check_window)(void*, bool*, bool*, unsigned*, unsigned*, unsigned);
|
||||
|
||||
// Acknowledge a resize event. This is needed for some APIs. Most backends will ignore this.
|
||||
void (*set_resize)(unsigned, unsigned);
|
||||
void (*set_resize)(void*, unsigned, unsigned);
|
||||
|
||||
// Checks if window has input focus.
|
||||
bool (*has_focus)(void);
|
||||
bool (*has_focus)(void*);
|
||||
|
||||
// Swaps buffers. VBlank sync depends on earlier calls to swap_interval.
|
||||
void (*swap_buffers)(void);
|
||||
void (*swap_buffers)(void*);
|
||||
|
||||
// Most video backends will want to use a certain input driver.
|
||||
// Checks for it here.
|
||||
void (*input_driver)(const input_driver_t**, void**);
|
||||
void (*input_driver)(void*, const input_driver_t**, void**);
|
||||
|
||||
// Wraps whatever gl_proc_address() there is.
|
||||
// Does not take opaque, to avoid lots of ugly wrapper code.
|
||||
gfx_ctx_proc_t (*get_proc_address)(const char*);
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
// Returns true if this context supports EGLImage buffers for screen drawing and was initalized correctly.
|
||||
bool (*init_egl_image_buffer)(const video_info_t*);
|
||||
bool (*init_egl_image_buffer)(void*, const video_info_t*);
|
||||
// Writes the frame to the EGLImage and sets image_handle to it. Returns true if a new image handle is created.
|
||||
// Always returns true the first time it's called for a new index. The graphics core must handle a change in the handle correctly.
|
||||
bool (*write_egl_image)(const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle);
|
||||
bool (*write_egl_image)(void*, const void *frame, unsigned width, unsigned height, unsigned pitch, bool rgb32, unsigned index, void **image_handle);
|
||||
#endif
|
||||
|
||||
// Shows or hides mouse. Can be NULL if context doesn't have a concept of mouse pointer.
|
||||
void (*show_mouse)(bool state);
|
||||
void (*show_mouse)(void*, bool state);
|
||||
|
||||
// Human readable string.
|
||||
const char *ident;
|
||||
@ -116,7 +120,7 @@ extern const gfx_ctx_driver_t gfx_ctx_emscripten;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_null;
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(enum gfx_ctx_api api, unsigned major, unsigned minor); // Finds first suitable driver and initializes.
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor); // Finds first suitable driver and initializes.
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
59
gfx/gl.c
59
gfx/gl.c
@ -752,7 +752,7 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful
|
||||
|
||||
float device_aspect = 0.0f;
|
||||
if (gl->ctx_driver->translate_aspect)
|
||||
device_aspect = context_translate_aspect_func(width, height);
|
||||
device_aspect = context_translate_aspect_func(gl, width, height);
|
||||
else
|
||||
device_aspect = (float)width / height;
|
||||
|
||||
@ -1113,7 +1113,8 @@ static void gl_init_textures(void *data, const video_info_t *video)
|
||||
gl_t *gl = (gl_t*)data;
|
||||
#if defined(HAVE_EGL) && defined(HAVE_OPENGLES2)
|
||||
// Use regular textures if we use HW render.
|
||||
gl->egl_images = !gl->hw_render_use && check_eglimage_proc() && context_init_egl_image_buffer_func(video);
|
||||
gl->egl_images = !gl->hw_render_use && check_eglimage_proc() &&
|
||||
gl->ctx_context->init_egl_image_buffer && context_init_egl_image_buffer_func(gl, video);
|
||||
#else
|
||||
(void)video;
|
||||
#endif
|
||||
@ -1192,7 +1193,7 @@ static inline void gl_copy_frame(void *data, const void *frame, unsigned width,
|
||||
if (gl->egl_images)
|
||||
{
|
||||
EGLImageKHR img = 0;
|
||||
bool new_egl = context_write_egl_image_func(frame, width, height, pitch, (gl->base_size == 4), gl->tex_index, &img);
|
||||
bool new_egl = context_write_egl_image_func(gl, frame, width, height, pitch, (gl->base_size == 4), gl->tex_index, &img);
|
||||
|
||||
if (img == EGL_NO_IMAGE_KHR)
|
||||
{
|
||||
@ -1411,7 +1412,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
if (gl->should_resize)
|
||||
{
|
||||
gl->should_resize = false;
|
||||
context_set_resize_func(gl->win_width, gl->win_height);
|
||||
context_set_resize_func(gl, gl->win_width, gl->win_height);
|
||||
|
||||
// On resize, we might have to recreate our FBOs due to "Viewport" scale, and set a new viewport.
|
||||
gl_update_resize(gl);
|
||||
@ -1473,7 +1474,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (g_settings.video.black_frame_insertion)
|
||||
{
|
||||
context_swap_buffers_func();
|
||||
context_swap_buffers_func(gl);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
@ -1507,7 +1508,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
gl_render_overlay(gl);
|
||||
#endif
|
||||
|
||||
context_update_window_title_func();
|
||||
context_update_window_title_func(gl);
|
||||
|
||||
RARCH_PERFORMANCE_STOP(frame_run);
|
||||
|
||||
@ -1543,7 +1544,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
#endif
|
||||
#endif
|
||||
|
||||
context_swap_buffers_func();
|
||||
context_swap_buffers_func(gl);
|
||||
g_extern.frame_count++;
|
||||
|
||||
#ifdef HAVE_GL_SYNC
|
||||
@ -1660,7 +1661,7 @@ static void gl_free(void *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
context_destroy_func();
|
||||
context_destroy_func(gl);
|
||||
|
||||
free(gl->empty_buf);
|
||||
free(gl->conv_buffer);
|
||||
@ -1672,8 +1673,7 @@ static void gl_set_nonblock_state(void *data, bool state)
|
||||
RARCH_LOG("GL VSync => %s\n", state ? "off" : "on");
|
||||
|
||||
gl_t *gl = (gl_t*)data;
|
||||
(void)gl;
|
||||
context_swap_interval_func(state ? 0 : g_settings.video.swap_interval);
|
||||
context_swap_interval_func(gl, state ? 0 : g_settings.video.swap_interval);
|
||||
}
|
||||
|
||||
static bool resolve_extensions(gl_t *gl)
|
||||
@ -1878,7 +1878,7 @@ static void gl_init_pbo_readback(void *data)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const gfx_ctx_driver_t *gl_get_context(void)
|
||||
static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
|
||||
{
|
||||
const struct retro_hw_render_callback *cb = &g_extern.system.hw_render_callback;
|
||||
unsigned major = cb->version_major;
|
||||
@ -1904,13 +1904,13 @@ static const gfx_ctx_driver_t *gl_get_context(void)
|
||||
const gfx_ctx_driver_t *ctx = gfx_ctx_find_driver(g_settings.video.gl_context);
|
||||
if (ctx)
|
||||
{
|
||||
if (!ctx->bind_api(api, major, minor))
|
||||
if (!ctx->bind_api(gl, api, major, minor))
|
||||
{
|
||||
RARCH_ERR("Failed to bind API %s to context %s.\n", api_name, g_settings.video.gl_context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ctx->init())
|
||||
if (!ctx->init(gl))
|
||||
{
|
||||
RARCH_ERR("Failed to init GL context: %s.\n", ctx->ident);
|
||||
return NULL;
|
||||
@ -1925,7 +1925,7 @@ static const gfx_ctx_driver_t *gl_get_context(void)
|
||||
return ctx;
|
||||
}
|
||||
else
|
||||
return gfx_ctx_init_first(api, major, minor);
|
||||
return gfx_ctx_init_first(gl, api, major, minor);
|
||||
}
|
||||
|
||||
#ifdef GL_DEBUG
|
||||
@ -2026,7 +2026,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
if (!gl)
|
||||
return NULL;
|
||||
|
||||
gl->ctx_driver = gl_get_context();
|
||||
gl->ctx_driver = gl_get_context(gl);
|
||||
if (!gl->ctx_driver)
|
||||
{
|
||||
free(gl);
|
||||
@ -2037,10 +2037,10 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
|
||||
RARCH_LOG("Found GL context: %s\n", gl->ctx_driver->ident);
|
||||
|
||||
context_get_video_size_func(&gl->full_x, &gl->full_y);
|
||||
context_get_video_size_func(gl, &gl->full_x, &gl->full_y);
|
||||
RARCH_LOG("Detecting screen resolution %ux%u.\n", gl->full_x, gl->full_y);
|
||||
|
||||
context_swap_interval_func(video->vsync ? g_settings.video.swap_interval : 0);
|
||||
context_swap_interval_func(gl, video->vsync ? g_settings.video.swap_interval : 0);
|
||||
|
||||
unsigned win_width = video->width;
|
||||
unsigned win_height = video->height;
|
||||
@ -2050,7 +2050,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
win_height = gl->full_y;
|
||||
}
|
||||
|
||||
if (!context_set_video_mode_func(win_width, win_height, video->fullscreen))
|
||||
if (!context_set_video_mode_func(gl, win_width, win_height, video->fullscreen))
|
||||
{
|
||||
free(gl);
|
||||
return NULL;
|
||||
@ -2073,7 +2073,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
|
||||
if (!resolve_extensions(gl))
|
||||
{
|
||||
context_destroy_func();
|
||||
context_destroy_func(gl);
|
||||
free(gl);
|
||||
return NULL;
|
||||
}
|
||||
@ -2086,7 +2086,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
gl->fullscreen = video->fullscreen;
|
||||
|
||||
// Get real known video size, which might have been altered by context.
|
||||
context_get_video_size_func(&gl->win_width, &gl->win_height);
|
||||
context_get_video_size_func(gl, &gl->win_width, &gl->win_height);
|
||||
RARCH_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);
|
||||
|
||||
if (gl->full_x || gl->full_y) // We got bogus from gfx_ctx_get_video_size. Replace.
|
||||
@ -2123,7 +2123,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
if (!gl_shader_init(gl))
|
||||
{
|
||||
RARCH_ERR("[GL]: Shader init failed.\n");
|
||||
context_destroy_func();
|
||||
context_destroy_func(gl);
|
||||
free(gl);
|
||||
return NULL;
|
||||
}
|
||||
@ -2177,7 +2177,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
gl->conv_buffer = calloc(sizeof(uint32_t), gl->tex_w * gl->tex_h);
|
||||
if (!gl->conv_buffer)
|
||||
{
|
||||
context_destroy_func();
|
||||
context_destroy_func(gl);
|
||||
free(gl);
|
||||
return NULL;
|
||||
}
|
||||
@ -2193,7 +2193,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
#ifndef HAVE_GCMGL
|
||||
if (gl->hw_render_use && !gl_init_hw_render(gl, gl->tex_w, gl->tex_h))
|
||||
{
|
||||
context_destroy_func();
|
||||
context_destroy_func(gl);
|
||||
free(gl);
|
||||
return NULL;
|
||||
}
|
||||
@ -2201,7 +2201,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
#endif
|
||||
|
||||
if (input && input_data)
|
||||
context_input_driver_func(input, input_data);
|
||||
context_input_driver_func(gl, input, input_data);
|
||||
|
||||
#ifndef RARCH_CONSOLE
|
||||
if (g_settings.video.font_enable)
|
||||
@ -2217,7 +2217,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
|
||||
if (!gl_check_error())
|
||||
{
|
||||
context_destroy_func();
|
||||
context_destroy_func(gl);
|
||||
free(gl);
|
||||
return NULL;
|
||||
}
|
||||
@ -2230,7 +2230,7 @@ static bool gl_alive(void *data)
|
||||
gl_t *gl = (gl_t*)data;
|
||||
bool quit = false, resize = false;
|
||||
|
||||
context_check_window_func(&quit,
|
||||
context_check_window_func(gl, &quit,
|
||||
&resize, &gl->win_width, &gl->win_height,
|
||||
g_extern.frame_count);
|
||||
|
||||
@ -2245,8 +2245,7 @@ static bool gl_alive(void *data)
|
||||
static bool gl_focus(void *data)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
(void)gl;
|
||||
return context_has_focus_func();
|
||||
return context_has_focus_func(gl);
|
||||
}
|
||||
|
||||
static void gl_update_tex_filter_frame(gl_t *gl)
|
||||
@ -2538,7 +2537,7 @@ static void gl_overlay_enable(void *data, bool state)
|
||||
gl_t *gl = (gl_t*)data;
|
||||
gl->overlay_enable = state;
|
||||
if (gl->ctx_driver->show_mouse && gl->fullscreen)
|
||||
gl->ctx_driver->show_mouse(state);
|
||||
gl->ctx_driver->show_mouse(gl, state);
|
||||
}
|
||||
|
||||
static void gl_overlay_full_screen(void *data, bool enable)
|
||||
@ -2720,7 +2719,7 @@ static void gl_show_mouse(void *data, bool state)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
if (gl->ctx_driver->show_mouse)
|
||||
gl->ctx_driver->show_mouse(state);
|
||||
gl->ctx_driver->show_mouse(gl, state);
|
||||
}
|
||||
|
||||
static const video_poke_interface_t gl_poke_interface = {
|
||||
|
@ -37,25 +37,24 @@
|
||||
|
||||
#include "glsym/glsym.h"
|
||||
|
||||
#define context_get_video_size_func(win, height) gl->ctx_driver->get_video_size(win, height)
|
||||
#define context_update_window_title_func() gl->ctx_driver->update_window_title()
|
||||
#define context_destroy_func() gl->ctx_driver->destroy()
|
||||
#define context_translate_aspect_func(width, height) gl->ctx_driver->translate_aspect(width, height)
|
||||
#define context_set_resize_func(width, height) gl->ctx_driver->set_resize(width, height)
|
||||
#define context_swap_buffers_func() gl->ctx_driver->swap_buffers()
|
||||
#define context_post_render_func(gl) gl->ctx_driver->post_render(gl)
|
||||
#define context_swap_interval_func(var) gl->ctx_driver->swap_interval(var)
|
||||
#define context_has_focus_func() gl->ctx_driver->has_focus()
|
||||
#define context_check_window_func(quit, resize, width, height, frame_count) \
|
||||
gl->ctx_driver->check_window(quit, resize, width, height, frame_count)
|
||||
#define context_get_video_size_func(gl, win, height) gl->ctx_driver->get_video_size(gl, win, height)
|
||||
#define context_update_window_title_func(gl) gl->ctx_driver->update_window_title(gl)
|
||||
#define context_destroy_func(gl) gl->ctx_driver->destroy(gl)
|
||||
#define context_translate_aspect_func(gl, width, height) gl->ctx_driver->translate_aspect(gl, width, height)
|
||||
#define context_set_resize_func(gl, width, height) gl->ctx_driver->set_resize(gl, width, height)
|
||||
#define context_swap_buffers_func(gl) gl->ctx_driver->swap_buffers(gl)
|
||||
#define context_swap_interval_func(gl, var) gl->ctx_driver->swap_interval(gl, var)
|
||||
#define context_has_focus_func(gl) gl->ctx_driver->has_focus(gl)
|
||||
#define context_check_window_func(gl, quit, resize, width, height, frame_count) \
|
||||
gl->ctx_driver->check_window(gl, quit, resize, width, height, frame_count)
|
||||
|
||||
#define context_set_video_mode_func(width, height, fullscreen) gl->ctx_driver->set_video_mode(width, height, fullscreen)
|
||||
#define context_input_driver_func(input, input_data) gl->ctx_driver->input_driver(input, input_data)
|
||||
#define context_set_video_mode_func(gl, width, height, fullscreen) gl->ctx_driver->set_video_mode(gl, width, height, fullscreen)
|
||||
#define context_input_driver_func(gl, input, input_data) gl->ctx_driver->input_driver(gl, input, input_data)
|
||||
|
||||
#ifdef HAVE_EGL
|
||||
#define context_init_egl_image_buffer_func(video) gl->ctx_driver->init_egl_image_buffer(video)
|
||||
#define context_write_egl_image_func(frame, width, height, pitch, base_size, tex_index, img) \
|
||||
gl->ctx_driver->write_egl_image(frame, width, height, pitch, base_size, tex_index,img)
|
||||
#define context_init_egl_image_buffer_func(gl, video) gl->ctx_driver->init_egl_image_buffer(gl, video)
|
||||
#define context_write_egl_image_func(gl, frame, width, height, pitch, base_size, tex_index, img) \
|
||||
gl->ctx_driver->write_egl_image(gl, frame, width, height, pitch, base_size, tex_index,img)
|
||||
#endif
|
||||
|
||||
static inline bool gl_check_error(void)
|
||||
|
Loading…
x
Reference in New Issue
Block a user