struct yagl_egl_backend *backend;
};
-static void yagl_egl_ensure_current(struct yagl_egl_interface *iface)
+static YAGL_DEFINE_TLS(struct yagl_egl_api_ts*, egl_api_ts);
+
+static uint32_t yagl_egl_get_ctx_id(struct yagl_egl_interface *iface)
{
- struct yagl_egl_interface_impl *egl_iface = (struct yagl_egl_interface_impl*)iface;
- egl_iface->backend->ensure_current(egl_iface->backend);
+ if (egl_api_ts) {
+ return egl_api_ts->context ? egl_api_ts->context->res.handle : 0;
+ } else {
+ return 0;
+ }
}
-static void yagl_egl_unensure_current(struct yagl_egl_interface *iface)
+static void yagl_egl_ensure_ctx(struct yagl_egl_interface *iface, uint32_t ctx_id)
{
struct yagl_egl_interface_impl *egl_iface = (struct yagl_egl_interface_impl*)iface;
- egl_iface->backend->unensure_current(egl_iface->backend);
+ uint32_t current_ctx_id = yagl_egl_get_ctx_id(iface);
+
+ if (!current_ctx_id || (ctx_id && (current_ctx_id != ctx_id))) {
+ egl_iface->backend->ensure_current(egl_iface->backend);
+ }
}
-static YAGL_DEFINE_TLS(struct yagl_egl_api_ts*, egl_api_ts);
+static void yagl_egl_unensure_ctx(struct yagl_egl_interface *iface, uint32_t ctx_id)
+{
+ struct yagl_egl_interface_impl *egl_iface = (struct yagl_egl_interface_impl*)iface;
+ uint32_t current_ctx_id = yagl_egl_get_ctx_id(iface);
+
+ if (!current_ctx_id || (ctx_id && (current_ctx_id != ctx_id))) {
+ egl_iface->backend->unensure_current(egl_iface->backend);
+ }
+}
static __inline bool yagl_validate_display(yagl_host_handle dpy_,
struct yagl_egl_display **dpy,
egl_iface = g_malloc0(sizeof(*egl_iface));
- egl_iface->base.ensure_ctx = &yagl_egl_ensure_current;
- egl_iface->base.unensure_ctx = &yagl_egl_unensure_current;
+ egl_iface->base.get_ctx_id = &yagl_egl_get_ctx_id;
+ egl_iface->base.ensure_ctx = &yagl_egl_ensure_ctx;
+ egl_iface->base.unensure_ctx = &yagl_egl_unensure_ctx;
egl_iface->backend = egl_api->backend;
/*
void yagl_gles_api_ts_cleanup(struct yagl_gles_api_ts *gles_api_ts)
{
if (gles_api_ts->num_arrays > 0) {
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_api_ts->driver->DeleteBuffers(gles_api_ts->num_arrays,
gles_api_ts->arrays);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
}
g_free(gles_api_ts->arrays);
struct yagl_object base;
struct yagl_gles_driver *driver;
+
+ uint32_t ctx_id;
};
typedef enum
static void yagl_gles_object_add(GLuint local_name,
GLuint global_name,
+ uint32_t ctx_id,
void (*destroy_func)(struct yagl_object */*obj*/))
{
struct yagl_gles_object *obj;
obj->base.global_name = global_name;
obj->base.destroy = destroy_func;
obj->driver = gles_api_ts->driver;
+ obj->ctx_id = ctx_id;
yagl_object_map_add(cur_ts->ps->object_map,
local_name,
YAGL_LOG_FUNC_ENTER(yagl_gles_buffer_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_obj->driver->DeleteBuffers(1, &obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
g_free(gles_obj);
YAGL_LOG_FUNC_ENTER(yagl_gles_texture_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_obj->driver->DeleteTextures(1, &obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
g_free(gles_obj);
YAGL_LOG_FUNC_ENTER(yagl_gles_framebuffer_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(gles_obj->ctx_id);
gles_obj->driver->DeleteFramebuffers(1, &obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(gles_obj->ctx_id);
g_free(gles_obj);
YAGL_LOG_FUNC_ENTER(yagl_gles_renderbuffer_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_obj->driver->DeleteRenderbuffers(1, &obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
g_free(gles_obj);
YAGL_LOG_FUNC_ENTER(yagl_gles_program_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_obj->driver->DeleteProgram(obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
g_free(gles_obj);
YAGL_LOG_FUNC_ENTER(yagl_gles_shader_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_obj->driver->DeleteShader(obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
g_free(gles_obj);
YAGL_LOG_FUNC_ENTER(yagl_gles_vertex_array_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(gles_obj->ctx_id);
gles_obj->driver->DeleteVertexArrays(1, &obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(gles_obj->ctx_id);
g_free(gles_obj);
yagl_gles_object_add(arrays[i],
global_name,
+ yagl_get_ctx_id(),
&yagl_gles_vertex_array_destroy);
}
}
yagl_gles_object_add(buffers[i],
global_name,
+ 0,
&yagl_gles_buffer_destroy);
}
}
* might be called without an active context, but
* which needs to create a texture.
*/
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
gles_api_ts->driver->GenTextures(1, &global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
yagl_gles_object_add(textures[i],
global_name,
+ 0,
&yagl_gles_texture_destroy);
}
}
yagl_gles_object_add(framebuffers[i],
global_name,
+ yagl_get_ctx_id(),
&yagl_gles_framebuffer_destroy);
}
}
yagl_gles_object_add(renderbuffers[i],
global_name,
+ 0,
&yagl_gles_renderbuffer_destroy);
}
}
yagl_gles_object_add(program,
global_name,
+ 0,
&yagl_gles_program_destroy);
}
yagl_gles_object_add(shader,
global_name,
+ 0,
&yagl_gles_shader_destroy);
}
{
struct yagl_egl_offscreen *egl_offscreen = (struct yagl_egl_offscreen*)backend;
- if (egl_offscreen_ts && egl_offscreen_ts->dpy) {
- return;
- }
-
egl_offscreen->egl_driver->make_current(egl_offscreen->egl_driver,
egl_offscreen->ensure_dpy,
egl_offscreen->ensure_sfc,
struct yagl_egl_offscreen *egl_offscreen = (struct yagl_egl_offscreen*)backend;
if (egl_offscreen_ts && egl_offscreen_ts->dpy) {
- return;
+ egl_offscreen->egl_driver->make_current(egl_offscreen->egl_driver,
+ egl_offscreen_ts->dpy->native_dpy,
+ egl_offscreen_ts->sfc_draw,
+ egl_offscreen_ts->sfc_read,
+ egl_offscreen_ts->ctx->native_ctx);
+ } else {
+ egl_offscreen->egl_driver->make_current(egl_offscreen->egl_driver,
+ egl_offscreen->ensure_dpy,
+ EGL_NO_SURFACE,
+ EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
}
-
- egl_offscreen->egl_driver->make_current(egl_offscreen->egl_driver,
- egl_offscreen->ensure_dpy,
- EGL_NO_SURFACE,
- EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
}
static void yagl_egl_offscreen_destroy(struct yagl_egl_backend *backend)
YAGL_LOG_FUNC_ENTER(yagl_egl_offscreen_context_destroy, NULL);
if (egl_offscreen_ctx->rp_pbo) {
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
egl_offscreen->gles_driver->DeleteBuffers(1, &egl_offscreen_ctx->rp_pbo);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
}
egl_offscreen->egl_driver->context_destroy(egl_offscreen->egl_driver,
YAGL_LOG_FUNC_ENTER(yagl_egl_offscreen_image_destroy, "%u", obj->global_name);
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
image->driver->DeleteTextures(1, &obj->global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
g_free(image);
image = g_malloc(sizeof(*image));
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
egl_offscreen->gles_driver->GenTextures(1, &image->base.global_name);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
image->base.destroy = &yagl_egl_offscreen_image_destroy;
image->driver = egl_offscreen->gles_driver;
{
struct yagl_egl_onscreen *egl_onscreen = (struct yagl_egl_onscreen*)backend;
- if (egl_onscreen_ts && egl_onscreen_ts->dpy) {
- return;
- }
-
egl_onscreen->egl_driver->make_current(egl_onscreen->egl_driver,
egl_onscreen->ensure_dpy,
egl_onscreen->ensure_sfc,
struct yagl_egl_onscreen *egl_onscreen = (struct yagl_egl_onscreen*)backend;
if (egl_onscreen_ts && egl_onscreen_ts->dpy) {
- return;
+ if (egl_onscreen_ts->sfc_draw && egl_onscreen_ts->sfc_read) {
+ egl_onscreen->egl_driver->make_current(egl_onscreen->egl_driver,
+ egl_onscreen_ts->dpy->native_dpy,
+ egl_onscreen_ts->sfc_draw->dummy_native_sfc,
+ egl_onscreen_ts->sfc_read->dummy_native_sfc,
+ egl_onscreen_ts->ctx->native_ctx);
+ } else {
+ egl_onscreen->egl_driver->make_current(egl_onscreen->egl_driver,
+ egl_onscreen_ts->dpy->native_dpy,
+ egl_onscreen_ts->ctx->null_sfc,
+ egl_onscreen_ts->ctx->null_sfc,
+ egl_onscreen_ts->ctx->native_ctx);
+ }
+ } else {
+ egl_onscreen->egl_driver->make_current(egl_onscreen->egl_driver,
+ egl_onscreen->ensure_dpy,
+ EGL_NO_SURFACE,
+ EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
}
-
- egl_onscreen->egl_driver->make_current(egl_onscreen->egl_driver,
- egl_onscreen->ensure_dpy,
- EGL_NO_SURFACE,
- EGL_NO_SURFACE,
- EGL_NO_CONTEXT);
}
static void yagl_egl_onscreen_destroy(struct yagl_egl_backend *backend)
YAGL_LOG_FUNC_ENTER(yagl_egl_onscreen_context_destroy, NULL);
if (egl_onscreen_ctx->fb) {
- yagl_ensure_ctx();
+ yagl_ensure_ctx(egl_onscreen_ctx->fb_ctx_id);
egl_onscreen->gles_driver->DeleteFramebuffers(1, &egl_onscreen_ctx->fb);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(egl_onscreen_ctx->fb_ctx_id);
}
if (egl_onscreen_ctx->null_sfc != EGL_NO_SURFACE) {
}
egl_onscreen->gles_driver->GenFramebuffers(1, &ctx->fb);
+ ctx->fb_ctx_id = yagl_get_ctx_id();
}
bool yagl_egl_onscreen_context_setup_surfaceless(struct yagl_egl_onscreen_context *ctx)
* Onscreen GLES API redirects framebuffer zero to this framebuffer.
*/
GLuint fb;
+ uint32_t fb_ctx_id;
/*
* Config with which this context was created, used
if (((osfc->ws_sfc->base.width != ws_sfc->base.width) ||
(osfc->ws_sfc->base.height != ws_sfc->base.height)) &&
osfc->rb) {
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
egl_onscreen->gles_driver->DeleteRenderbuffers(1, &osfc->rb);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
osfc->rb = 0;
}
}
if (osfc->rb) {
- yagl_ensure_ctx();
+ yagl_ensure_ctx(0);
egl_onscreen->gles_driver->DeleteRenderbuffers(1, &osfc->rb);
- yagl_unensure_ctx();
+ yagl_unensure_ctx(0);
}
yagl_eglb_surface_cleanup(sfc);
struct yagl_egl_interface
{
- void (*ensure_ctx)(struct yagl_egl_interface */*iface*/);
+ uint32_t (*get_ctx_id)(struct yagl_egl_interface */*iface*/);
- void (*unensure_ctx)(struct yagl_egl_interface */*iface*/);
+ void (*ensure_ctx)(struct yagl_egl_interface */*iface*/, uint32_t /*ctx_id*/);
+
+ void (*unensure_ctx)(struct yagl_egl_interface */*iface*/, uint32_t /*ctx_id*/);
};
#endif
{
}
-void yagl_ensure_ctx(void)
+uint32_t yagl_get_ctx_id(void)
{
assert(cur_ts);
- cur_ts->ps->egl_iface->ensure_ctx(cur_ts->ps->egl_iface);
+ return cur_ts->ps->egl_iface->get_ctx_id(cur_ts->ps->egl_iface);
}
-void yagl_unensure_ctx(void)
+void yagl_ensure_ctx(uint32_t ctx_id)
{
assert(cur_ts);
- cur_ts->ps->egl_iface->unensure_ctx(cur_ts->ps->egl_iface);
+ cur_ts->ps->egl_iface->ensure_ctx(cur_ts->ps->egl_iface, ctx_id);
+}
+
+void yagl_unensure_ctx(uint32_t ctx_id)
+{
+ assert(cur_ts);
+ cur_ts->ps->egl_iface->unensure_ctx(cur_ts->ps->egl_iface, ctx_id);
}
* @{
*/
-void yagl_ensure_ctx(void);
-void yagl_unensure_ctx(void);
+uint32_t yagl_get_ctx_id(void);
+void yagl_ensure_ctx(uint32_t ctx_id);
+void yagl_unensure_ctx(uint32_t ctx_id);
/*
* @}