Add HW context support to X/EGL and KMS/EGL.

This commit is contained in:
Themaister 2014-04-19 16:06:12 +02:00
parent f658112756
commit 105872a42c
9 changed files with 86 additions and 15 deletions

View File

@ -47,6 +47,8 @@
#include <sys/poll.h>
#include <fcntl.h>
static bool g_use_hw_ctx;
static EGLContext g_egl_hw_ctx;
static EGLContext g_egl_ctx;
static EGLSurface g_egl_surf;
static EGLDisplay g_egl_dpy;
@ -593,9 +595,19 @@ static bool gfx_ctx_set_video_mode(void *data,
goto error;
g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, (g_api == GFX_CTX_OPENGL_ES_API) ? gles_context_attribs : NULL);
if (!g_egl_ctx)
if (g_egl_ctx == EGL_NO_CONTEXT)
goto error;
if (g_use_hw_ctx)
{
g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_config, g_egl_ctx,
(g_api == GFX_CTX_OPENGL_ES_API) ? gles_context_attribs : NULL);
RARCH_LOG("[KMS/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);
if (g_egl_hw_ctx == EGL_NO_CONTEXT)
goto error;
}
g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_gbm_surface, NULL);
if (!g_egl_surf)
goto error;
@ -636,6 +648,9 @@ void gfx_ctx_destroy(void *data)
eglDestroyContext(g_egl_dpy, g_egl_ctx);
}
if (g_egl_hw_ctx)
eglDestroyContext(g_egl_dpy, g_egl_hw_ctx);
if (g_egl_surf)
eglDestroySurface(g_egl_dpy, g_egl_surf);
eglTerminate(g_egl_dpy);
@ -717,6 +732,14 @@ static bool gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, u
}
}
static void gfx_ctx_bind_hw_render(void *data, bool enable)
{
(void)data;
g_use_hw_ctx = enable;
if (g_egl_dpy)
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, enable ? g_egl_hw_ctx : g_egl_ctx);
}
const gfx_ctx_driver_t gfx_ctx_drm_egl = {
gfx_ctx_init,
gfx_ctx_destroy,
@ -736,5 +759,6 @@ const gfx_ctx_driver_t gfx_ctx_drm_egl = {
NULL,
NULL,
"kms-egl",
gfx_ctx_bind_hw_render,
};

View File

@ -40,6 +40,7 @@ static unsigned g_screen;
static XIM g_xim;
static XIC g_xic;
static bool g_use_hw_ctx;
static GLXContext g_ctx, g_hw_ctx;
static GLXFBConfig g_fbc;
static unsigned g_major;
@ -413,15 +414,26 @@ static bool gfx_ctx_set_video_mode(void *data,
*aptr = None;
g_ctx = glx_create_context_attribs(g_dpy, g_fbc, NULL, True, attribs);
g_hw_ctx = glx_create_context_attribs(g_dpy, g_fbc, g_ctx, True, attribs);
if (g_use_hw_ctx)
{
RARCH_LOG("[GLX]: Creating shared HW context.\n");
g_hw_ctx = glx_create_context_attribs(g_dpy, g_fbc, g_ctx, True, attribs);
if (!g_hw_ctx)
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
}
}
else
{
g_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, 0, True);
g_hw_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, g_ctx, True);
if (g_use_hw_ctx)
{
g_hw_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, g_ctx, True);
if (!g_hw_ctx)
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
}
}
if (!g_ctx || !g_hw_ctx)
if (!g_ctx)
{
RARCH_ERR("[GLX]: Failed to create new context.\n");
goto error;
@ -504,7 +516,8 @@ static void gfx_ctx_destroy(void *data)
glXMakeContextCurrent(g_dpy, None, None, NULL);
if (!driver.video_cache_context)
{
glXDestroyContext(g_dpy, g_hw_ctx);
if (g_hw_ctx)
glXDestroyContext(g_dpy, g_hw_ctx);
glXDestroyContext(g_dpy, g_ctx);
g_ctx = NULL;
g_hw_ctx = NULL;
@ -605,8 +618,13 @@ static void gfx_ctx_show_mouse(void *data, bool state)
static void gfx_ctx_bind_hw_render(void *data, bool enable)
{
(void)data;
RARCH_LOG("[GLX]: Binding context (%s): %p\n", enable ? "RetroArch" : "HW render", enable ? (void*)g_hw_ctx : (void*)g_ctx);
glXMakeContextCurrent(g_dpy, g_glx_win, g_glx_win, enable ? g_hw_ctx : g_ctx);
g_use_hw_ctx = enable;
if (g_dpy)
{
//RARCH_LOG("[GLX]: Binding context (%s): %p\n", enable ? "RetroArch" : "HW render", enable ? (void*)g_hw_ctx : (void*)g_ctx);
glXMakeContextCurrent(g_dpy, g_glx_win, g_glx_win, enable ? g_hw_ctx : g_ctx);
}
}
const gfx_ctx_driver_t gfx_ctx_glx = {

View File

@ -41,6 +41,8 @@ static unsigned g_screen;
static XIM g_xim;
static XIC g_xic;
static bool g_use_hw_ctx;
static EGLContext g_egl_hw_ctx;
static EGLContext g_egl_ctx;
static EGLSurface g_egl_surf;
static EGLDisplay g_egl_dpy;
@ -422,10 +424,19 @@ static bool gfx_ctx_set_video_mode(void *data,
(g_api == GFX_CTX_OPENGL_ES_API) ? egl_ctx_gles_attribs : NULL);
RARCH_LOG("[X/EGL]: Created context: %p.\n", (void*)g_egl_ctx);
if (!g_egl_ctx)
if (g_egl_ctx == EGL_NO_CONTEXT)
goto error;
if (g_use_hw_ctx)
{
g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_config, g_egl_ctx,
(g_api == GFX_CTX_OPENGL_ES_API) ? egl_ctx_gles_attribs : NULL);
RARCH_LOG("[X/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);
if (g_egl_hw_ctx == EGL_NO_CONTEXT)
goto error;
}
g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_win, NULL);
if (!g_egl_surf)
goto error;
@ -513,6 +524,9 @@ static void gfx_ctx_destroy(void *data)
eglDestroyContext(g_egl_dpy, g_egl_ctx);
}
if (g_egl_hw_ctx)
eglDestroyContext(g_egl_dpy, g_egl_hw_ctx);
if (g_egl_surf)
eglDestroySurface(g_egl_dpy, g_egl_surf);
eglTerminate(g_egl_dpy);
@ -622,6 +636,14 @@ static void gfx_ctx_show_mouse(void *data, bool state)
x11_show_mouse(g_dpy, g_win, state);
}
static void gfx_ctx_bind_hw_render(void *data, bool enable)
{
(void)data;
g_use_hw_ctx = enable;
if (g_egl_dpy)
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, enable ? g_egl_hw_ctx : g_egl_ctx);
}
const gfx_ctx_driver_t gfx_ctx_x_egl = {
gfx_ctx_init,
gfx_ctx_destroy,
@ -641,5 +663,6 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = {
NULL,
gfx_ctx_show_mouse,
"x-egl",
gfx_ctx_bind_hw_render,
};

View File

@ -1405,7 +1405,7 @@ static const gfx_ctx_driver_t *d3d_get_context(void)
major = 9;
#endif
minor = 0;
return gfx_ctx_init_first(driver.video_data, api, major, minor);
return gfx_ctx_init_first(driver.video_data, api, major, minor, false);
}
static void *d3d_init(const video_info_t *info, const input_driver_t **input,

View File

@ -71,13 +71,15 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
return NULL;
}
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, 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, bool hw_render_ctx)
{
unsigned i;
for (i = 0; gfx_ctx_drivers[i]; i++)
{
if (gfx_ctx_drivers[i]->bind_api(data, api, major, minor))
{
if (gfx_ctx_drivers[i]->bind_hw_render)
gfx_ctx_drivers[i]->bind_hw_render(data, hw_render_ctx);
if (gfx_ctx_drivers[i]->init(data))
return gfx_ctx_drivers[i];
}

View File

@ -123,7 +123,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(void *data, 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, bool hw_render_ctx); // Finds first suitable driver and initializes.
#ifdef __cplusplus
}

View File

@ -1927,6 +1927,10 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
return NULL;
}
// Enables or disables offscreen HW context.
if (ctx->bind_hw_render)
ctx->bind_hw_render(gl, cb->context_type != RETRO_HW_CONTEXT_NONE);
if (!ctx->init(gl))
{
RARCH_ERR("Failed to init GL context: %s.\n", ctx->ident);
@ -1942,7 +1946,7 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
return ctx;
}
else
return gfx_ctx_init_first(gl, api, major, minor);
return gfx_ctx_init_first(gl, api, major, minor, cb->context_type != RETRO_HW_CONTEXT_NONE);
}
#ifdef GL_DEBUG

View File

@ -87,7 +87,7 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo
if (!vg)
return NULL;
vg->driver = gfx_ctx_init_first(vg, GFX_CTX_OPENVG_API, 0, 0);
vg->driver = gfx_ctx_init_first(vg, GFX_CTX_OPENVG_API, 0, 0, false);
if (!vg->driver)
{

View File

@ -299,7 +299,7 @@ static const gfx_ctx_driver_t *d3d_get_context(void *data)
major = 9;
#endif
minor = 0;
return gfx_ctx_init_first(d3d, api, major, minor);
return gfx_ctx_init_first(d3d, api, major, minor, false);
}
static bool d3d_init_base(void *data, const video_info_t *info)