From 36fc2e6a935a024efd4bd2bf1cacee272104e5af Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 23 Oct 2018 14:49:46 +0900 Subject: [PATCH] evas image: fix non-rendered preload image. Summary: This is one more corner-case issue that I found, When second image doesn't use preload (but still share the resource) canvas engine triggers cancellation for first image preload function. Unluckly, preload thread is cancelled on the intermediate rendering, First image is not going to rendered, even image turn it changed states. Because end of that frame, canvas reset/flushed all active objects. Here changes to retain the changes status to redraw it in the next frame. Test Plan: img1 = image_add; image_file_set(img1, "test.jpg"); image_preload(img1, true); show(img); img2 = image_add; image_file_set(img2, "test.jpg"); //same resource image_preload(img2, false); show(img2); img1 is invisible. Reviewers: #committers Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7157 --- src/lib/evas/canvas/evas_object_image.c | 3 +++ src/lib/evas/canvas/evas_object_inform.c | 17 +++++++++++------ src/lib/evas/canvas/evas_render.c | 8 +++++--- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 8aa9ded3b8..667b8cb354 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -2691,6 +2691,9 @@ evas_object_image_render_post(Evas_Object *eo_obj EINA_UNUSED, evas_object_cur_prev(obj); eina_cow_memcpy(evas_object_image_state_cow, (const Eina_Cow_Data **)&o->prev, o->cur); /* FIXME: copy strings across */ + + //Somehow(preloading cancelled) image has been changed, need to redraw. + if (o->changed) evas_object_change(eo_obj, obj); } static void * diff --git a/src/lib/evas/canvas/evas_object_inform.c b/src/lib/evas/canvas/evas_object_inform.c index f15d37521a..8fb780e66c 100644 --- a/src/lib/evas/canvas/evas_object_inform.c +++ b/src/lib/evas/canvas/evas_object_inform.c @@ -72,12 +72,17 @@ evas_object_inform_call_image_preloaded(Evas_Object *eo_obj) //Even cancelled, obj needs to draw image. _evas_image_load_post_update(eo_obj, obj); - if (!(preload & EVAS_IMAGE_PRELOADING) || - (preload & EVAS_IMAGE_PRELOAD_CANCEL)) return; - - event_id = _evas_object_event_new(); - evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_IMAGE_PRELOADED, NULL, event_id, EFL_GFX_IMAGE_EVENT_PRELOAD); - _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); + if ((preload & EVAS_IMAGE_PRELOADING) || + /* Boom! This cancellation call stack is in the intermediate render sequence. Need better idea. + So far, this cancellation is triggered by other non-preload image instances, + which doesn't require preloading. So by mechasnim we cancel preload other instances as well. + and mimic as it finished preloading done. */ + (preload & EVAS_IMAGE_PRELOAD_CANCEL)) + { + event_id = _evas_object_event_new(); + evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_IMAGE_PRELOADED, NULL, event_id, EFL_GFX_IMAGE_EVENT_PRELOAD); + _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); + } } void diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c index 17f16c769e..cbd13d315b 100644 --- a/src/lib/evas/canvas/evas_render.c +++ b/src/lib/evas/canvas/evas_render.c @@ -1341,9 +1341,9 @@ pending_change(void *data, void *gdata EINA_UNUSED) if (obj->pre_render_done) { RD(0, " OBJ %s pending change %i -> 0, pre %i\n", RDNAME(obj), obj->changed, obj->pre_render_done); + evas_object_change_reset(obj); obj->func->render_post(eo_obj, obj, obj->private_data); obj->pre_render_done = EINA_FALSE; - evas_object_change_reset(obj); } else if (!_evas_render_can_render(eo_obj, obj) && (!obj->is_active) && (!obj->render_pre) && @@ -1351,6 +1351,8 @@ pending_change(void *data, void *gdata EINA_UNUSED) { evas_object_change_reset(obj); } + + //FIXME: after evas_object_change_reset(), obj->changed is always false... return obj->changed ? EINA_TRUE : EINA_FALSE; } @@ -3593,9 +3595,9 @@ evas_render_updates_internal(Evas *eo_e, if ((clean_them) || (obj->changed && do_draw)) { RD(0, " OBJ %s render_post()\n", RDNAME(obj)); - obj->func->render_post(eo_obj, obj, obj->private_data); obj->restack = EINA_FALSE; evas_object_change_reset(obj); + obj->func->render_post(eo_obj, obj, obj->private_data); } } @@ -3645,9 +3647,9 @@ evas_render_updates_internal(Evas *eo_e, obj->pre_render_done = EINA_FALSE; if ((obj->changed) && (do_draw)) { - obj->func->render_post(eo_obj, obj, obj->private_data); obj->restack = EINA_FALSE; evas_object_change_reset(obj); + obj->func->render_post(eo_obj, obj, obj->private_data); } } eina_evlog("-render_post_reset", eo_e, 0.0, NULL);