summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-07-27 14:10:29 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-07-27 14:15:09 +0900
commitc45ae022c8d23a9e7aa7590d9ac7615a5d61882b (patch)
treea978b46903132bcf2846f41b3b74c0bd41a10a21
parent17823d21ea6bb9dcadafa95b2d18557200beb8a2 (diff)
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
-rw-r--r--src/lib/evas/canvas/evas_render.c21
-rw-r--r--src/lib/evas/filters/evas_filter.c3
-rw-r--r--src/lib/evas/include/evas_common_private.h2
-rw-r--r--src/lib/evas/include/evas_private.h2
-rw-r--r--src/modules/evas/engines/gl_generic/evas_engine.c7
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c21
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 6af4cd6492..80faf6f3c5 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -1520,7 +1520,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
1520 (e->engine.data.output, context, 1520 (e->engine.data.output, context,
1521 mask->mask->surface, 1521 mask->mask->surface,
1522 mask->cur->geometry.x + off_x, 1522 mask->cur->geometry.x + off_x,
1523 mask->cur->geometry.y + off_y); 1523 mask->cur->geometry.y + off_y,
1524 e, do_async);
1524 } 1525 }
1525 } 1526 }
1526 } 1527 }
@@ -1548,7 +1549,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
1548 else 1549 else
1549 e->engine.func->context_clip_unset(e->engine.data.output, context); 1550 e->engine.func->context_clip_unset(e->engine.data.output, context);
1550 e->engine.func->context_clip_image_set 1551 e->engine.func->context_clip_image_set
1551 (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y); 1552 (e->engine.data.output, context, oldm_sfc, oldm_x, oldm_y, e, do_async);
1552 } 1553 }
1553 1554
1554 // FIXME: needs to cache these maps and 1555 // FIXME: needs to cache these maps and
@@ -1607,7 +1608,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
1607 (e->engine.data.output, ctx, 1608 (e->engine.data.output, ctx,
1608 mask->mask->surface, 1609 mask->mask->surface,
1609 mask->cur->geometry.x + off_x, 1610 mask->cur->geometry.x + off_x,
1610 mask->cur->geometry.y + off_y); 1611 mask->cur->geometry.y + off_y,
1612 e, do_async);
1611 } 1613 }
1612 } 1614 }
1613 1615
@@ -1666,7 +1668,8 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
1666 (e->engine.data.output, ctx, 1668 (e->engine.data.output, ctx,
1667 mask->mask->surface, 1669 mask->mask->surface,
1668 mask->cur->geometry.x + off_x, 1670 mask->cur->geometry.x + off_x,
1669 mask->cur->geometry.y + off_y); 1671 mask->cur->geometry.y + off_y,
1672 e, do_async);
1670 } 1673 }
1671 } 1674 }
1672 } 1675 }
@@ -1681,7 +1684,7 @@ evas_render_mapped(Evas_Public_Data *e, Evas_Object *eo_obj,
1681 else 1684 else
1682 e->engine.func->context_clip_unset(e->engine.data.output, ctx); 1685 e->engine.func->context_clip_unset(e->engine.data.output, ctx);
1683 e->engine.func->context_clip_image_set 1686 e->engine.func->context_clip_image_set
1684 (e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y); 1687 (e->engine.data.output, ctx, oldm_sfc, oldm_x, oldm_y, e, do_async);
1685 } 1688 }
1686 if (!use_mapped_ctx) 1689 if (!use_mapped_ctx)
1687 e->engine.func->context_free(e->engine.data.output, ctx); 1690 e->engine.func->context_free(e->engine.data.output, ctx);
@@ -1943,7 +1946,8 @@ evas_render_mask_subrender(Evas_Public_Data *evas,
1943 ENFN->context_clip_image_set(ENDT, ctx, 1946 ENFN->context_clip_image_set(ENDT, ctx,
1944 prev_mask->mask->surface, 1947 prev_mask->mask->surface,
1945 prev_mask->cur->geometry.x - x, 1948 prev_mask->cur->geometry.x - x,
1946 prev_mask->cur->geometry.y - y); 1949 prev_mask->cur->geometry.y - y,
1950 evas, EINA_FALSE);
1947 } 1951 }
1948 evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface, 1952 evas_render_mapped(evas, mask->object, mask, ctx, mdata->surface,
1949 -x, -y, 2, 0, 0, evas->output.w, evas->output.h, 1953 -x, -y, 2, 0, 0, evas->output.w, evas->output.h,
@@ -2508,7 +2512,8 @@ evas_render_updates_internal(Evas *eo_e,
2508 e->engine.data.context, 2512 e->engine.data.context,
2509 mask->mask->surface, 2513 mask->mask->surface,
2510 mask->cur->geometry.x + off_x, 2514 mask->cur->geometry.x + off_x,
2511 mask->cur->geometry.y + off_y); 2515 mask->cur->geometry.y + off_y,
2516 e, do_async);
2512 } 2517 }
2513 } 2518 }
2514 2519
@@ -2534,7 +2539,7 @@ evas_render_updates_internal(Evas *eo_e,
2534 2539
2535 if (mask) 2540 if (mask)
2536 { 2541 {
2537 e->engine.func->context_clip_image_unset 2542 e->engine.func->context_clip_image_unset
2538 (e->engine.data.output, e->engine.data.context); 2543 (e->engine.data.output, e->engine.data.context);
2539 } 2544 }
2540 } 2545 }
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 5d22df2efd..16efbbafde 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -1637,7 +1637,8 @@ _filter_target_render(Evas_Filter_Context *ctx)
1637 1637
1638 if (ctx->target.mask) 1638 if (ctx->target.mask)
1639 ENFN->context_clip_image_set(ENDT, drawctx, 1639 ENFN->context_clip_image_set(ENDT, drawctx,
1640 ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y); 1640 ctx->target.mask, ctx->target.mask_x, ctx->target.mask_y,
1641 ctx->evas, EINA_FALSE);
1641 else 1642 else
1642 ENFN->context_clip_image_unset(ENDT, drawctx); 1643 ENFN->context_clip_image_unset(ENDT, drawctx);
1643 1644
diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h
index 934daa8f57..0f01545317 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -738,9 +738,11 @@ struct _RGBA_Draw_Context
738 } col; 738 } col;
739 struct RGBA_Draw_Context_clip { 739 struct RGBA_Draw_Context_clip {
740 int x, y, w, h; 740 int x, y, w, h;
741 Evas_Public_Data *evas; // for async unref
741 void *mask; 742 void *mask;
742 int mask_x, mask_y; 743 int mask_x, mask_y;
743 Eina_Bool use : 1; 744 Eina_Bool use : 1;
745 Eina_Bool async : 1;
744 } clip; 746 } clip;
745 Cutout_Rects cutout; 747 Cutout_Rects cutout;
746 struct { 748 struct {
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 2e54ab046d..01b43401a5 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -1264,7 +1264,7 @@ struct _Evas_Func
1264 Eina_Bool (*canvas_alpha_get) (void *data, void *context); 1264 Eina_Bool (*canvas_alpha_get) (void *data, void *context);
1265 void (*context_free) (void *data, void *context); 1265 void (*context_free) (void *data, void *context);
1266 void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h); 1266 void (*context_clip_set) (void *data, void *context, int x, int y, int w, int h);
1267 void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y); 1267 void (*context_clip_image_set) (void *data, void *context, void *surface, int x, int y, Evas_Public_Data *evas, Eina_Bool do_async);
1268 void (*context_clip_image_unset) (void *data, void *context); 1268 void (*context_clip_image_unset) (void *data, void *context);
1269 void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y); 1269 void (*context_clip_image_get) (void *data, void *context, void **surface, int *x, int *y);
1270 void (*context_clip_clip) (void *data, void *context, int x, int y, int w, int h); 1270 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 caa2da6d7b..9c9d560004 100644
--- a/src/modules/evas/engines/gl_generic/evas_engine.c
+++ b/src/modules/evas/engines/gl_generic/evas_engine.c
@@ -2073,7 +2073,8 @@ eng_context_clip_image_unset(void *data EINA_UNUSED, void *context)
2073} 2073}
2074 2074
2075static void 2075static void
2076eng_context_clip_image_set(void *data, void *context, void *surface, int x, int y) 2076eng_context_clip_image_set(void *data, void *context, void *surface, int x, int y,
2077 Evas_Public_Data *evas, Eina_Bool do_async)
2077{ 2078{
2078 RGBA_Draw_Context *ctx = context; 2079 RGBA_Draw_Context *ctx = context;
2079 Evas_GL_Image *im = surface; 2080 Evas_GL_Image *im = surface;
@@ -2091,6 +2092,10 @@ eng_context_clip_image_set(void *data, void *context, void *surface, int x, int
2091 ctx->clip.mask_x = x; 2092 ctx->clip.mask_x = x;
2092 ctx->clip.mask_y = y; 2093 ctx->clip.mask_y = y;
2093 2094
2095 // useless in gl since the engines are sync only
2096 ctx->clip.evas = evas;
2097 ctx->clip.async = do_async;
2098
2094 if (im) 2099 if (im)
2095 { 2100 {
2096 if (!noinc) evas_gl_common_image_ref(im); 2101 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 234be121fd..3b50c4f1be 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)
452 if (ctx->clip.mask) 452 if (ctx->clip.mask)
453 { 453 {
454 Image_Entry *ie = ctx->clip.mask; 454 Image_Entry *ie = ctx->clip.mask;
455#ifdef EVAS_CSERVE2 455
456 if (evas_cserve2_use_get()) 456 if (ctx->clip.async)
457 evas_cache2_image_close(ie); 457 evas_unref_queue_image_put(ctx->clip.evas, ie);
458 else 458 else
459 {
460#ifdef EVAS_CSERVE2
461 if (evas_cserve2_use_get())
462 evas_cache2_image_close(ie);
463 else
459#endif 464#endif
460 evas_cache_image_drop(ie); 465 evas_cache_image_drop(ie);
461 // Is the above code safe? Hmmm... 466 }
462 //evas_unref_queue_image_put(EVAS???, &ctx->clip.ie->cache_entry);
463 ctx->clip.mask = NULL; 467 ctx->clip.mask = NULL;
464 } 468 }
465} 469}
466 470
467static void 471static void
468eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y) 472eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface, int x, int y,
473 Evas_Public_Data *evas, Eina_Bool do_async)
469{ 474{
470 RGBA_Draw_Context *ctx = context; 475 RGBA_Draw_Context *ctx = context;
471 Eina_Bool noinc = EINA_FALSE; 476 Eina_Bool noinc = EINA_FALSE;
@@ -481,6 +486,8 @@ eng_context_clip_image_set(void *data EINA_UNUSED, void *context, void *surface,
481 ctx->clip.mask = surface; 486 ctx->clip.mask = surface;
482 ctx->clip.mask_x = x; 487 ctx->clip.mask_x = x;
483 ctx->clip.mask_y = y; 488 ctx->clip.mask_y = y;
489 ctx->clip.evas = evas;
490 ctx->clip.async = do_async;
484 491
485 if (surface) 492 if (surface)
486 { 493 {