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
This commit is contained in:
Hermet Park 2018-10-23 14:49:46 +09:00
parent 7f77938fa8
commit 36fc2e6a93
3 changed files with 19 additions and 9 deletions

View File

@ -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 *

View File

@ -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

View File

@ -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);