From 08889de92b616ca8a8d198a1adb5b040e30abf53 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Mon, 1 Sep 2014 16:50:19 +0900 Subject: [PATCH] Evas GL: Add some thread safety This is only the core evas gl support. TODO: gl_x11 and other engines --- src/lib/evas/canvas/evas_gl.c | 25 ++++++++++++++++++----- src/modules/evas/engines/gl_common/evas_gl_core.c | 17 +++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/lib/evas/canvas/evas_gl.c b/src/lib/evas/canvas/evas_gl.c index ab04237..38a8468 100644 --- a/src/lib/evas/canvas/evas_gl.c +++ b/src/lib/evas/canvas/evas_gl.c @@ -10,6 +10,7 @@ struct _Evas_GL Eina_List *contexts; Eina_List *surfaces; + Eina_Lock lck; }; struct _Evas_GL_Context @@ -36,6 +37,7 @@ evas_gl_new(Evas *e) evas_gl->magic = MAGIC_EVAS_GL; evas_gl->evas = eo_data_ref(e, EVAS_CANVAS_CLASS); + LKI(evas_gl->lck); if (!evas_gl->evas->engine.func->gl_context_create) { @@ -54,7 +56,6 @@ evas_gl_free(Evas_GL *evas_gl) return; MAGIC_CHECK_END(); - // Delete undeleted surfaces while (evas_gl->surfaces) evas_gl_surface_destroy(evas_gl, evas_gl->surfaces->data); @@ -65,6 +66,7 @@ evas_gl_free(Evas_GL *evas_gl) eo_data_unref(evas_gl->evas->evas, evas_gl->evas); evas_gl->magic = 0; + LKD(evas_gl->lck); free(evas_gl); } @@ -101,7 +103,7 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int return NULL; } - if ( (width <= 0) || (height <= 0)) + if ((width <= 0) || (height <= 0)) { ERR("Invalid surface dimensions: %d, %d", width, height); return NULL; @@ -121,7 +123,9 @@ evas_gl_surface_create(Evas_GL *evas_gl, Evas_GL_Config *config, int width, int } // Keep track of the surface creations + LKL(evas_gl->lck); evas_gl->surfaces = eina_list_prepend(evas_gl->surfaces, surf); + LKU(evas_gl->lck); return surf; } @@ -144,7 +148,9 @@ evas_gl_surface_destroy(Evas_GL *evas_gl, Evas_GL_Surface *surf) evas_gl->evas->engine.func->gl_surface_destroy(evas_gl->evas->engine.data.output, surf->data); // Remove it from the list + LKL(evas_gl->lck); evas_gl->surfaces = eina_list_remove(evas_gl->surfaces, surf); + LKU(evas_gl->lck); // Delete the object free(surf); @@ -188,7 +194,9 @@ evas_gl_context_create(Evas_GL *evas_gl, Evas_GL_Context *share_ctx) } // Keep track of the context creations + LKL(evas_gl->lck); evas_gl->contexts = eina_list_prepend(evas_gl->contexts, ctx); + LKU(evas_gl->lck); return ctx; @@ -212,7 +220,9 @@ evas_gl_context_destroy(Evas_GL *evas_gl, Evas_GL_Context *ctx) evas_gl->evas->engine.func->gl_context_destroy(evas_gl->evas->engine.data.output, ctx->data); // Remove it from the list + LKL(evas_gl->lck); evas_gl->contexts = eina_list_remove(evas_gl->contexts, ctx); + LKU(evas_gl->lck); // Delete the object free(ctx); @@ -227,7 +237,7 @@ evas_gl_make_current(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_GL_Context *c MAGIC_CHECK(evas_gl, Evas_GL, MAGIC_EVAS_GL); return EINA_FALSE; MAGIC_CHECK_END(); - + if ((surf) && (ctx)) ret = (Eina_Bool)evas_gl->evas->engine.func->gl_make_current(evas_gl->evas->engine.data.output, surf->data, ctx->data); else if ((!surf) && (!ctx)) @@ -268,7 +278,13 @@ evas_gl_native_surface_get(Evas_GL *evas_gl, Evas_GL_Surface *surf, Evas_Native_ return EINA_FALSE; MAGIC_CHECK_END(); - if ((!surf) || (!ns)) + if (!surf) + { + ERR("Invalid surface!"); + return EINA_FALSE; + } + + if (!ns) { ERR("Invalid input parameters!"); return EINA_FALSE; @@ -286,5 +302,4 @@ evas_gl_api_get(Evas_GL *evas_gl) MAGIC_CHECK_END(); return (Evas_GL_API*)evas_gl->evas->engine.func->gl_api_get(evas_gl->evas->engine.data.output); - } diff --git a/src/modules/evas/engines/gl_common/evas_gl_core.c b/src/modules/evas/engines/gl_common/evas_gl_core.c index 89842b5..59cafac 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_core.c +++ b/src/modules/evas/engines/gl_common/evas_gl_core.c @@ -817,6 +817,8 @@ _surface_context_list_print() #define YELLOW "\e[1;33m" #define RED "\e[1;31m" + LKL(evgl_engine->resource_lock); + DBG( YELLOW "-----------------------------------------------" RESET); DBG("Total Number of active Evas GL Surfaces: %d", eina_list_count(evgl_engine->surfaces)); @@ -864,6 +866,8 @@ _surface_context_list_print() } DBG( YELLOW "-----------------------------------------------" RESET); + LKU(evgl_engine->resource_lock); + #undef RESET #undef GREEN #undef YELLOW @@ -1315,6 +1319,8 @@ evgl_engine_init(void *eng_data, const EVGL_Interface *efunc) goto error; } + LKI(evgl_engine->resource_lock); + // Assign functions evgl_engine->funcs = efunc; @@ -1381,6 +1387,7 @@ error: { if (evgl_engine->resource_key) eina_tls_free(evgl_engine->resource_key); + LKD(evgl_engine->resource_lock); free(evgl_engine); } evgl_engine = NULL; @@ -1403,6 +1410,8 @@ evgl_engine_shutdown(void *eng_data) // Destroy internal resources _evgl_tls_resource_destroy(eng_data); + LKD(evgl_engine->resource_lock); + // Free engine free(evgl_engine); evgl_engine = NULL; @@ -1505,7 +1514,9 @@ evgl_surface_create(void *eng_data, Evas_GL_Config *cfg, int w, int h) } // Keep track of all the created surfaces + LKL(evgl_engine->resource_lock); evgl_engine->surfaces = eina_list_prepend(evgl_engine->surfaces, sfc); + LKU(evgl_engine->resource_lock); return sfc; @@ -1570,7 +1581,9 @@ evgl_surface_destroy(void *eng_data, EVGL_Surface *sfc) } // Remove it from the list + LKL(evgl_engine->resource_lock); evgl_engine->surfaces = eina_list_remove(evgl_engine->surfaces, sfc); + LKU(evgl_engine->resource_lock); free(sfc); sfc = NULL; @@ -1613,7 +1626,9 @@ evgl_context_create(void *eng_data, EVGL_Context *share_ctx) } // Keep track of all the created context + LKL(evgl_engine->resource_lock); evgl_engine->contexts = eina_list_prepend(evgl_engine->contexts, ctx); + LKU(evgl_engine->resource_lock); return ctx; } @@ -1655,7 +1670,9 @@ evgl_context_destroy(void *eng_data, EVGL_Context *ctx) } // Remove it from the list + LKL(evgl_engine->resource_lock); evgl_engine->contexts = eina_list_remove(evgl_engine->contexts, ctx); + LKU(evgl_engine->resource_lock); // Free context free(ctx); -- 2.7.4