Begin adding opaque interface to gfx_context.

This commit is contained in:
Themaister 2014-03-09 16:50:18 +01:00
parent 171cb7ed79
commit d0302c9800
7 changed files with 164 additions and 160 deletions

View File

@ -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",
};

View File

@ -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",

View File

@ -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",
};

View File

@ -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];
}
}

View File

@ -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
}

View File

@ -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 = {

View File

@ -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)