jpeg pushed a commit to branch efl-1.14. http://git.enlightenment.org/core/efl.git/commit/?id=d3c185024a858bd0c3987516f2111f47e147d789
commit d3c185024a858bd0c3987516f2111f47e147d789 Author: Jean-Philippe Andre <jp.an...@samsung.com> Date: Mon Jul 27 14:10:29 2015 +0900 Evas masking: Fix crash in async rendering There was a FIXME comment... >_< Improper management of image resources in async render led to a rare crash. This should fix that. @fix --- src/lib/evas/canvas/evas_render.c | 21 +++++++++++++-------- src/lib/evas/filters/evas_filter.c | 3 ++- src/lib/evas/include/evas_common_private.h | 2 ++ src/lib/evas/include/evas_private.h | 2 +- src/modules/evas/engines/gl_generic/evas_engine.c | 7 ++++++- .../evas/engines/software_generic/evas_engine.c | 21 ++++++++++++++------- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index d172cd3..600b760 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1482,7 +1482,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, (e->engine.data.output, context, mask->mask->surface, mask->cur->geometry.x + off_x, - mask->cur->geometry.y + off_y); + mask->cur->geometry.y + off_y, + e, do_async); } } } @@ -1510,7 +1511,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, else e->engine.func->context_clip_unset(e->engine.data.output, context); e->engine.func->context_clip_image_set - (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y); + (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y, e, do_async); } // FIXME: needs to cache these maps and @@ -1569,7 +1570,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, (e->engine.data.output, ctx, mask->mask->surface, mask->cur->geometry.x + off_x, - mask->cur->geometry.y + off_y); + mask->cur->geometry.y + off_y, + e, do_async); } } @@ -1628,7 +1630,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, (e->engine.data.output, ctx, mask->mask->surface, mask->cur->geometry.x + off_x, - mask->cur->geometry.y + off_y); + mask->cur->geometry.y + off_y, + e, do_async); } } } @@ -1643,7 +1646,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj, else e->engine.func->context_clip_unset(e->engine.data.output, ctx); e->engine.func->context_clip_image_set - (e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y); + (e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y, e, do_async); } if (!use_mapped_ctx) e->engine.func->context_free(e->engine.data.output, ctx); @@ -1905,7 +1908,8 @@ evas_render_mask_subrender(Evas_Public_Data *evas, ENFN->context_clip_image_set(ENDT, ctx, prev_mask->mask->surface, prev_mask->cur->geometry.x - x, - prev_mask->cur->geometry.y - y); + prev_mask->cur->geometry.y - y, + evas, EINA_FALSE); } evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface, -x, -y, 2, 0, 0, evas->output.w, evas->output.h, @@ -2442,7 +2446,8 @@ evas_render_updates_internal(Evas *eo_e, e->engine.data.context, mask->mask->surface, mask->cur->geometry.x + off_x, - mask->cur->geometry.y + off_y); + mask->cur->geometry.y + off_y, + e, do_async); } } @@ -2468,7 +2473,7 @@ evas_render_updates_internal(Evas *eo_e, if (mask) { - e->engine.func->context_clip_image_unset + e->engine.func->context_clip_image_unset (e->engine.data.output, e->engine.data.context); } } diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c index 0f24870..42771d2 100644 --- a/src/lib/evas/filters/evas_filter.c +++ b/src/lib/evas/filters/evas_filter.c @@ -1643,7 +1643,8 @@ _filter_target_render(Evas_Filter_Context *ctx) if (ctx->target.mask) ENFN->context_clip_image_set(ENDT, drawctx, - ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y); + ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y, + ctx->evas, EINA_FALSE); else ENFN->context_clip_image_unset(ENDT, drawctx); diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index 6b4cf5e..8e52804 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -710,9 +710,11 @@ struct _RGBA_Draw_Context } col; struct RGBA_Draw_Context_clip { int x, y, w, h; + Evas_Public_Data *evas; // for async unref void *mask; int mask_x, mask_y; Eina_Bool use : 1; + Eina_Bool async : 1; } clip; Cutout_Rects cutout; struct { diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index af2592b..76b6d6d 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1197,7 +1197,7 @@ struct _Evas_Func Eina_Bool (*canvas_alpha_get) (void *data, void *context); void (*context_free) (void *data, void *context); void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h); - void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y); + void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y, Evas_Public_Data *evas, Eina_Bool do_async); void (*context_clip_image_unset) (void *data, void *context); void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y); void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h); diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 0e3b14e..03c1e6b 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -2048,7 +2048,8 @@ eng_context_clip_image_unset(void *data EINA_UNUSED, void *context) } static void -eng_context_clip_image_set(void *data, void *context, void *surface, int x, int y) +eng_context_clip_image_set(void *data, void *context, void *surface, int x, int y, + Evas_Public_Data *evas, Eina_Bool do_async) { RGBA_Draw_Context *ctx = context; Evas_GL_Image *im = surface; @@ -2066,6 +2067,10 @@ eng_context_clip_image_set(void *data, void *context, void *surface, int x, int ctx->clip.mask_x = x; ctx->clip.mask_y = y; + // useless in gl since the engines are sync only + ctx->clip.evas = evas; + ctx->clip.async = do_async; + if (im) { if (!noinc) evas_gl_common_image_ref(im); diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index dfdcb5c..11b6e43 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -452,20 +452,25 @@ eng_context_clip_image_unset(void *data EINA_UNUSED, void *context) if (ctx->clip.mask) { Image_Entry *ie = ctx->clip.mask; -#ifdef EVAS_CSERVE2 - if (evas_cserve2_use_get()) - evas_cache2_image_close(ie); + + if (ctx->clip.async) + evas_unref_queue_image_put(ctx->clip.evas, ie); else + { +#ifdef EVAS_CSERVE2 + if (evas_cserve2_use_get()) + evas_cache2_image_close(ie); + else #endif - evas_cache_image_drop(ie); - // Is the above code safe? Hmmm... - //evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry); + evas_cache_image_drop(ie); + } ctx->clip.mask = NULL; } } static void -eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y) +eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y, + Evas_Public_Data *evas, Eina_Bool do_async) { RGBA_Draw_Context *ctx = context; Eina_Bool noinc = EINA_FALSE; @@ -481,6 +486,8 @@ eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, ctx->clip.mask = surface; ctx->clip.mask_x = x; ctx->clip.mask_y = y; + ctx->clip.evas = evas; + ctx->clip.async = do_async; if (surface) { --