From 423d8a22961436299df0feca17b03544678b8c0f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 3 Sep 2018 15:19:02 +0900 Subject: [PATCH] evas image: fix a bug in image preloading. Summary: Current preloading is too buggy since it's on thread-based. This is a fundamental improvement to fix a bug. The critical issue here is, When preloading img object suddenly cancel its preloading, the object possibly cannot render image next then because renderer doesn't have any idea when async cancelling is finished. Renderer just tries to render regardless of image loading status, and this could occur no-texture(in gl case) image object. So, here improvement is, adding a notification for async cancelled so that putting img objects to redraw images properly after their preloading is cancelled. The best scenario to reproduce this bug is this one. Evas_Object *img2 = evas_object_image_filled_add(evas); evas_object_image_file_set(img2, "test.jpg", NULL); evas_object_image_preload(img2, EINA_FALSE); evas_object_resize(img2, 200, 200); evas_object_show(img2); Evas_Object *img = evas_object_image_filled_add(evas); evas_object_image_file_set(img, "test.jpg", NULL); evas_object_image_preload(img, EINA_FALSE); evas_object_move(img, 200, 200); evas_object_resize(img, 200, 200); evas_object_show(img); evas_object_image_preload(img2, EINA_TRUE); If you run this on gl backend, occasionally happens rendering fail. Yet there other bugs on preloading feature.... @fix Reviewers: #committers, raster Subscribers: cedric, #reviewers, #committers, zmike Tags: #efl Differential Revision: https://phab.enlightenment.org/D6919 --- src/lib/evas/cache/evas_cache.h | 2 +- src/lib/evas/cache/evas_cache_image.c | 61 +++++++-------- src/lib/evas/canvas/efl_canvas_image.c | 12 +-- src/lib/evas/canvas/evas_image_legacy.c | 25 +++---- src/lib/evas/canvas/evas_image_private.h | 9 ++- src/lib/evas/canvas/evas_object_image.c | 74 ++++++++----------- src/lib/evas/canvas/evas_object_inform.c | 10 ++- src/lib/evas/include/evas_common_private.h | 3 +- src/lib/evas/include/evas_private.h | 4 +- .../evas/engines/gl_common/evas_gl_image.c | 17 +++-- .../evas/engines/gl_generic/evas_engine.c | 4 +- .../engines/software_generic/evas_engine.c | 4 +- 12 files changed, 111 insertions(+), 114 deletions(-) diff --git a/src/lib/evas/cache/evas_cache.h b/src/lib/evas/cache/evas_cache.h index 1edd9e0f2b..b7bcb7d660 100644 --- a/src/lib/evas/cache/evas_cache.h +++ b/src/lib/evas/cache/evas_cache.h @@ -162,7 +162,7 @@ EAPI Engine_Image_Entry* evas_cache_engine_image_size_set(Engine_Image_Entr EAPI void evas_cache_engine_image_load_data(Engine_Image_Entry *eim); EAPI void evas_cache_image_preload_data(Image_Entry *im, const Eo *target, void (*preloaded_cb)(void *data), void *preloaded_data); -EAPI void evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target); +EAPI void evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target, Eina_Bool force); EAPI int evas_cache_async_frozen_get(void); EAPI void evas_cache_async_freeze(void); diff --git a/src/lib/evas/cache/evas_cache_image.c b/src/lib/evas/cache/evas_cache_image.c index 9be38b928d..52440a23eb 100644 --- a/src/lib/evas/cache/evas_cache_image.c +++ b/src/lib/evas/cache/evas_cache_image.c @@ -28,7 +28,7 @@ struct _Evas_Cache_Preload static SLK(engine_lock); static int _evas_cache_mutex_init = 0; -static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target); +static void _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target, Eina_Bool force); #define FREESTRC(Var) \ if (Var) \ @@ -71,7 +71,7 @@ _evas_cache_image_dirty_del(Image_Entry *im) if (!im->cache) return; im->flags.dirty = 0; im->flags.cached = 0; - im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im)); + im->cache->dirty = eina_inlist_remove(im->cache->dirty, EINA_INLIST_GET(im)); } static void @@ -175,7 +175,7 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie) if (ie->preload) { ie->flags.delete_me = 1; - _evas_cache_image_entry_preload_remove(ie, NULL); + _evas_cache_image_entry_preload_remove(ie, NULL, EINA_TRUE); return; } _evas_cache_image_dirty_del(ie); @@ -364,8 +364,6 @@ _evas_cache_image_async_heavy(void *data) _evas_cache_image_entry_surface_alloc(cache, current, current->w, current->h); } - else - current->flags.loaded = 1; } current->channel = pchannel; // check the unload cancel flag @@ -393,7 +391,8 @@ _evas_cache_image_preloaded_notify(Image_Entry *ie) EINA_INLIST_GET(ie->targets)); if (!tmp->delete_me && tmp->preloaded_cb) tmp->preloaded_cb(tmp->preloaded_data); - evas_object_inform_call_image_preloaded((Evas_Object*) tmp->target); + if (!tmp->preload_cancel) + evas_object_inform_call_image_preloaded((Eo*) tmp->target); free(tmp); } } @@ -410,8 +409,8 @@ _evas_cache_image_async_end(void *data) ie->preload = NULL; ie->flags.preload_done = ie->flags.loaded; ie->flags.updated_data = 1; - ie->flags.preload_pending = 0; + ie->flags.loaded = EINA_TRUE; _evas_cache_image_preloaded_notify(ie); evas_cache_image_drop(ie); @@ -438,16 +437,6 @@ _evas_cache_image_async_cancel(void *data) evas_cache_image_drop(ie); return; } - if (ie->targets) - { - ie->cache->preload = eina_list_append(ie->cache->preload, ie); - ie->flags.pending = 0; - ie->flags.preload_pending = 1; - ie->preload = evas_preload_thread_run(_evas_cache_image_async_heavy, - _evas_cache_image_async_end, - _evas_cache_image_async_cancel, - ie); - } if (ie->references == 0) { SLKL(engine_lock); @@ -456,6 +445,21 @@ _evas_cache_image_async_cancel(void *data) cache = ie->cache; } if (ie->flags.loaded) _evas_cache_image_async_end(ie); + //On Cancelling, they need to draw image directly. + else + { + while (ie->targets) + { + Evas_Cache_Target *tg = ie->targets; + ie->targets = (Evas_Cache_Target *) + eina_inlist_remove(EINA_INLIST_GET(ie->targets), + EINA_INLIST_GET(tg)); + //FIXME: What/When they properly get a notification? Call in advance for compatibility. + evas_object_inform_call_image_preloaded((Eo*) tg->target); + free(tg); + } + } + evas_cache_image_drop(ie); if (cache) evas_cache_image_flush(cache); } @@ -498,8 +502,10 @@ _evas_cache_image_entry_preload_add(Image_Entry *ie, const Eo *target, void (*pr return 1; } +/* force: remove preload forcely. If one object cancel preload and draw image direcltly, + * all other targets of that preload will be affected this as well. */ static void -_evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target) +_evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target, Eina_Bool force) { Evas_Cache_Target *tg; @@ -511,12 +517,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target) { if (tg->target == target) { - // FIXME: No callback when we cancel only for one target ? - ie->targets = (Evas_Cache_Target *) - eina_inlist_remove(EINA_INLIST_GET(ie->targets), - EINA_INLIST_GET(tg)); - - free(tg); + tg->preload_cancel = EINA_TRUE; break; } } @@ -533,7 +534,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target) } } - if ((!ie->targets) && (ie->preload) && (!ie->flags.pending)) + if ((!ie->targets || force) && (ie->preload && !ie->flags.pending)) { ie->cache->preload = eina_list_remove(ie->cache->preload, ie); ie->cache->pending = eina_list_append(ie->cache->pending, ie); @@ -614,7 +615,7 @@ evas_cache_image_shutdown(Evas_Cache_Image *cache) { /* By doing that we are protecting us from destroying image when the cache is no longer available. */ im->flags.delete_me = 1; - _evas_cache_image_entry_preload_remove(im, NULL); + _evas_cache_image_entry_preload_remove(im, NULL, EINA_TRUE); } evas_async_events_process(); @@ -863,7 +864,7 @@ evas_cache_image_drop(Image_Entry *im) { if (im->preload) { - _evas_cache_image_entry_preload_remove(im, NULL); + _evas_cache_image_entry_preload_remove(im, NULL, EINA_TRUE); return; } if ((im->flags.dirty) || (im->load_failed)) @@ -1170,7 +1171,7 @@ evas_cache_image_unload_data(Image_Entry *im) evas_cache_image_drop(im); return; } - evas_cache_image_preload_cancel(im, NULL); + evas_cache_image_preload_cancel(im, NULL, EINA_TRUE); if (SLKT(im->lock) == EINA_FALSE) /* can't get image lock - busy async load */ { @@ -1270,11 +1271,11 @@ evas_cache_image_preload_data(Image_Entry *im, const Eo *target, void (*preloade } EAPI void -evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target) +evas_cache_image_preload_cancel(Image_Entry *im, const Eo *target, Eina_Bool force) { if (!target) return; evas_cache_image_ref(im); - _evas_cache_image_entry_preload_remove(im, target); + _evas_cache_image_entry_preload_remove(im, target, force); evas_cache_image_drop(im); } diff --git a/src/lib/evas/canvas/efl_canvas_image.c b/src/lib/evas/canvas/efl_canvas_image.c index f2ee207d4b..429de18200 100644 --- a/src/lib/evas/canvas/efl_canvas_image.c +++ b/src/lib/evas/canvas/efl_canvas_image.c @@ -75,7 +75,7 @@ _image_preload_internal(Eo *eo_obj, Evas_Image_Data *o, Eina_Bool cancel) { if (!o->engine_data) { - o->preloading = EINA_TRUE; + o->preload = EVAS_IMAGE_PRELOADING; evas_object_inform_call_image_preloaded(eo_obj); return; } @@ -84,17 +84,17 @@ _image_preload_internal(Eo *eo_obj, Evas_Image_Data *o, Eina_Bool cancel) Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); if (cancel) { - if (o->preloading) + if (o->preload & EVAS_IMAGE_PRELOADING) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload |= EVAS_IMAGE_PRELOAD_CANCEL; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE); } } else { - if (!o->preloading) + if (o->preload == EVAS_IMAGE_PRELOAD_NONE) { - o->preloading = EINA_TRUE; + o->preload = EVAS_IMAGE_PRELOADING; ENFN->image_data_preload_request(ENC, o->engine_data, eo_obj); } } diff --git a/src/lib/evas/canvas/evas_image_legacy.c b/src/lib/evas/canvas/evas_image_legacy.c index defd059781..7f8d48693d 100644 --- a/src/lib/evas/canvas/evas_image_legacy.c +++ b/src/lib/evas/canvas/evas_image_legacy.c @@ -67,10 +67,8 @@ EAPI void evas_object_image_preload(Evas_Object *eo_obj, Eina_Bool cancel) { EVAS_IMAGE_API(eo_obj); - if (cancel) - _evas_image_load_async_cancel(eo_obj); - else - _evas_image_load_async_start(eo_obj); + if (cancel) _evas_image_load_async_cancel(eo_obj); + else _evas_image_load_async_start(eo_obj); } EAPI Eina_Bool @@ -1084,15 +1082,15 @@ evas_object_image_data_convert(Evas_Object *eo_obj, Evas_Colorspace to_cspace) evas_object_async_block(obj); o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS); - if ((o->preloading) && (o->engine_data)) - { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); - } if (!o->engine_data) return NULL; if (o->video_surface) o->pixels->video.update_pixels(o->pixels->video.data, eo_obj, &o->pixels->video); if (o->cur->cspace == to_cspace) return NULL; + if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data)) + { + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE); + } data = NULL; engine_data = ENFN->image_data_get(ENC, o->engine_data, 0, &data, &o->load_error, NULL); result = _evas_image_data_convert_internal(o, data, to_cspace); @@ -1113,13 +1111,12 @@ evas_object_image_reload(Evas_Object *eo_obj) evas_object_async_block(obj); o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS); - if ((o->preloading) && (o->engine_data)) + if ((!o->cur->f) || (o->pixels_checked_out > 0)) return; + if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data)) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE); } - if ((!o->cur->f) || - (o->pixels_checked_out > 0)) return; if (o->engine_data) o->engine_data = ENFN->image_dirty_region(ENC, o->engine_data, 0, 0, o->cur->image.w, o->cur->image.h); diff --git a/src/lib/evas/canvas/evas_image_private.h b/src/lib/evas/canvas/evas_image_private.h index d475e1cdc3..ef76267968 100644 --- a/src/lib/evas/canvas/evas_image_private.h +++ b/src/lib/evas/canvas/evas_image_private.h @@ -93,6 +93,11 @@ struct _Evas_Object_Image_State Eina_Bool opaque : 1; }; +#define EVAS_IMAGE_PRELOAD_NONE 0x00 +#define EVAS_IMAGE_PRELOADING 0x01 +#define EVAS_IMAGE_PRELOADED 0x04 +#define EVAS_IMAGE_PRELOAD_CANCEL 0x08 + struct _Evas_Image_Data { const Evas_Object_Image_State *cur; @@ -117,13 +122,13 @@ struct _Evas_Image_Data short w, h; } file_size; + unsigned char preload; //See above EVAS_IMAGE_PRELOAD*** + Eina_Bool changed : 1; Eina_Bool dirty_pixels : 1; Eina_Bool filled : 1; Eina_Bool filled_set : 1; Eina_Bool proxyrendering : 1; - Eina_Bool preloading : 1; //on preloading - Eina_Bool preloaded: 1; //just finsihed preloading Eina_Bool video_surface : 1; Eina_Bool video_visible : 1; Eina_Bool created : 1; diff --git a/src/lib/evas/canvas/evas_object_image.c b/src/lib/evas/canvas/evas_object_image.c index 140e10b184..896603301e 100644 --- a/src/lib/evas/canvas/evas_object_image.c +++ b/src/lib/evas/canvas/evas_object_image.c @@ -1,3 +1,4 @@ + #include "evas_image_private.h" #define MY_CLASS EFL_CANVAS_IMAGE_INTERNAL_CLASS @@ -78,8 +79,7 @@ static const Evas_Object_Func object_func = evas_object_image_has_opaque_rect, evas_object_image_get_opaque_rect, evas_object_image_can_map, - evas_object_image_render_prepare, // render_prepare - NULL + evas_object_image_render_prepare // render_prepare }; static const Evas_Object_Image_Load_Opts default_load_opts = { @@ -163,10 +163,10 @@ _evas_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_I EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); } - if ((o->preloading) && (o->engine_data)) + if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data)) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE); } if (o->cur->source) _evas_image_proxy_unset(eo_obj, obj, o); if (o->cur->scene) _evas_image_3d_unset(eo_obj, obj, o); @@ -278,10 +278,10 @@ _evas_image_init_set(const Eina_File *f, const char *key, if (o->engine_data) { - if (o->preloading) + if (o->preload & EVAS_IMAGE_PRELOADING) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE); } ENFN->image_free(ENC, o->engine_data); } @@ -376,10 +376,10 @@ _evas_image_orientation_set(Eo *eo_obj, Evas_Image_Data *o, Evas_Image_Orient or if (o->cur->orient == orient) return; - if ((o->preloading) && (o->engine_data)) + if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data)) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE); } if (o->engine_data) @@ -777,10 +777,10 @@ _efl_canvas_image_internal_efl_gfx_buffer_alpha_set(Eo *eo_obj, Evas_Image_Data Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); evas_object_async_block(obj); - if ((o->preloading) && (o->engine_data)) + if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data)) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE); } has_alpha = !!has_alpha; @@ -1126,10 +1126,10 @@ _evas_image_unload(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Eina_Bo } if (o->engine_data) { - if (o->preloading) + if (o->preload & EVAS_IMAGE_PRELOADING) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE); } ENFN->image_free(ENC, o->engine_data); } @@ -1237,12 +1237,17 @@ _evas_image_load_post_update(Evas_Object *eo_obj, Evas_Object_Protected_Data *ob } EINA_COW_IMAGE_STATE_WRITE_END(o, state_write); o->changed = EINA_TRUE; - o->preloaded = EINA_TRUE; + o->preload = EVAS_IMAGE_PRELOADED; if (resize_call) evas_object_inform_call_image_resize(eo_obj); evas_object_change(eo_obj, obj); + + //preloading error check + if (ENFN->image_load_error_get) + o->load_error = ENFN->image_load_error_get(ENC, o->engine_data); } else { + o->preload = EVAS_IMAGE_PRELOAD_NONE; o->load_error = EVAS_LOAD_ERROR_GENERIC; } } @@ -1348,10 +1353,10 @@ evas_object_image_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj) { if (o->engine_data && ENC) { - if (o->preloading) + if (o->preload & EVAS_IMAGE_PRELOADING) { - o->preloading = EINA_FALSE; - ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj); + o->preload = EVAS_IMAGE_PRELOAD_NONE; + ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE); } ENFN->image_free(ENC, o->engine_data); } @@ -1743,7 +1748,7 @@ evas_object_image_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, v Evas_Image_Data *o = type_private_data; /* image is not ready yet, skip rendering. Leave it to next frame */ - if (o->preloading) return; + if (o->preload == EVAS_IMAGE_PRELOADING) return; if ((o->cur->fill.w < 1) || (o->cur->fill.h < 1)) return; /* no error message, already printed in pre_render */ @@ -2245,8 +2250,7 @@ evas_object_image_render_pre(Evas_Object *eo_obj, Eina_Bool changed_prep = EINA_TRUE; /* image is not ready yet, skip rendering. Leave it to next frame */ - if (o->preloading) return; - + if (o->preload & EVAS_IMAGE_PRELOADING) return; /* dont pre-render the obj twice! */ if (obj->pre_render_done) return; obj->pre_render_done = EINA_TRUE; @@ -2376,10 +2380,10 @@ evas_object_image_render_pre(Evas_Object *eo_obj, goto done; } //pre-loading is finished - if (o->preloaded) + if (o->preload == EVAS_IMAGE_PRELOADED) { evas_object_render_pre_prev_cur_add(&e->clip_changes, eo_obj, obj); - o->preloaded = EINA_FALSE; + o->preload = EVAS_IMAGE_PRELOAD_NONE; goto done; } } @@ -3383,23 +3387,7 @@ Eina_Bool _evas_object_image_preloading_get(const Evas_Object *eo_obj) { Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); - return o->preloading; -} - -void -_evas_object_image_preloading_set(Evas_Object *eo_obj, Eina_Bool preloading) -{ - Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); - o->preloading = preloading; -} - -void -_evas_object_image_preloading_check(Evas_Object *eo_obj) -{ - Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); - Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS); - if (ENFN->image_load_error_get) - o->load_error = ENFN->image_load_error_get(ENC, o->engine_data); + return o->preload; } Evas_Object * diff --git a/src/lib/evas/canvas/evas_object_inform.c b/src/lib/evas/canvas/evas_object_inform.c index ae436917cf..f15d37521a 100644 --- a/src/lib/evas/canvas/evas_object_inform.c +++ b/src/lib/evas/canvas/evas_object_inform.c @@ -66,10 +66,14 @@ evas_object_inform_call_image_preloaded(Evas_Object *eo_obj) int event_id; EINA_SAFETY_ON_NULL_RETURN(obj); - if (!_evas_object_image_preloading_get(eo_obj)) return; + + unsigned char preload = _evas_object_image_preloading_get(eo_obj); + + //Even cancelled, obj needs to draw image. _evas_image_load_post_update(eo_obj, obj); - _evas_object_image_preloading_check(eo_obj); - _evas_object_image_preloading_set(eo_obj, 0); + + 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); diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index ef85db5a6a..e51e60d4f9 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -556,7 +556,8 @@ struct _Evas_Cache_Target void *data; void (*preloaded_cb) (void *data); //Call when preloading done. void *preloaded_data; - Eina_Bool delete_me; + Eina_Bool delete_me : 1; + Eina_Bool preload_cancel : 1; }; struct _Image_Timestamp diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h index 9b5a7a2119..76bb46cfa2 100644 --- a/src/lib/evas/include/evas_private.h +++ b/src/lib/evas/include/evas_private.h @@ -1346,7 +1346,7 @@ struct _Evas_Func void *(*image_data_put) (void *engine, void *image, DATA32 *image_data); Eina_Bool (*image_data_direct_get) (void *engine, void *image, int plane, Eina_Slice *slice, Evas_Colorspace *cspace, Eina_Bool load); void (*image_data_preload_request) (void *engine, void *image, const Eo *target); - void (*image_data_preload_cancel) (void *engine, void *image, const Eo *target); + void (*image_data_preload_cancel) (void *engine, void *image, const Eo *target, Eina_Bool force); void *(*image_alpha_set) (void *engine, void *image, int has_alpha); int (*image_alpha_get) (void *engine, void *image); void *(*image_orient_set) (void *engine, void *image, Evas_Image_Orient orient); @@ -1598,8 +1598,6 @@ const Evas_Smart_Cb_Description *evas_smart_cb_description_find(const Evas_Smart Evas_Object *_evas_object_image_source_get(Evas_Object *obj); Eina_Bool _evas_object_image_preloading_get(const Evas_Object *obj); -void _evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading); -void _evas_object_image_preloading_check(Evas_Object *obj); Evas_Object *_evas_object_image_video_parent_get(Evas_Object *obj); void _evas_object_image_video_overlay_show(Evas_Object *obj); void _evas_object_image_video_overlay_hide(Evas_Object *obj); diff --git a/src/modules/evas/engines/gl_common/evas_gl_image.c b/src/modules/evas/engines/gl_common/evas_gl_image.c index 3aa40ead42..9ea18e5306 100644 --- a/src/modules/evas/engines/gl_common/evas_gl_image.c +++ b/src/modules/evas/engines/gl_common/evas_gl_image.c @@ -793,7 +793,6 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) } else */ - switch (im->cs.space) { case EVAS_COLORSPACE_ARGB8888: @@ -811,13 +810,15 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) if ((im->tex) && ((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data))) { - evas_cache_image_load_data(ie); + ie->load_error = evas_cache_image_load_data(ie); evas_gl_common_texture_update(im->tex, im->im); evas_cache_image_unload_data(ie); } - else if (!im->tex && !ie->load_error) + else if (!im->tex && + ((ie->load_error == EFL_GFX_IMAGE_LOAD_ERROR_NONE) || + (ie->load_error == EFL_GFX_IMAGE_LOAD_ERROR_CANCELLED))) { - evas_cache_image_load_data(ie); + ie->load_error = evas_cache_image_load_data(ie); im->tex = evas_gl_common_texture_new(gc, im->im, im->disable_atlas); evas_cache_image_unload_data(ie); } @@ -827,13 +828,15 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im) case EVAS_COLORSPACE_ETC1_ALPHA: if ((im->tex) && (im->dirty)) { - evas_cache_image_load_data(ie); + ie->load_error = evas_cache_image_load_data(ie); evas_gl_common_texture_rgb_a_pair_update(im->tex, im->im); evas_cache_image_unload_data(ie); } - else if (!im->tex && !ie->load_error) + else if (!im->tex && + ((ie->load_error == EFL_GFX_IMAGE_LOAD_ERROR_NONE) || + (ie->load_error == EFL_GFX_IMAGE_LOAD_ERROR_CANCELLED))) { - evas_cache_image_load_data(ie); + ie->load_error = evas_cache_image_load_data(ie); im->tex = evas_gl_common_texture_rgb_a_pair_new(gc, im->im); evas_cache_image_unload_data(ie); } diff --git a/src/modules/evas/engines/gl_generic/evas_engine.c b/src/modules/evas/engines/gl_generic/evas_engine.c index 28be4be74b..5d0771a058 100644 --- a/src/modules/evas/engines/gl_generic/evas_engine.c +++ b/src/modules/evas/engines/gl_generic/evas_engine.c @@ -1120,7 +1120,7 @@ eng_image_data_preload_request(void *engine EINA_UNUSED, void *image, const Eo * } static void -eng_image_data_preload_cancel(void *engine EINA_UNUSED, void *image, const Eo *target) +eng_image_data_preload_cancel(void *engine EINA_UNUSED, void *image, const Eo *target, Eina_Bool force) { Evas_GL_Image *gim = image; RGBA_Image *im; @@ -1131,7 +1131,7 @@ eng_image_data_preload_cancel(void *engine EINA_UNUSED, void *image, const Eo *t if (!im) return; evas_gl_common_image_preload_unwatch(gim); - evas_cache_image_preload_cancel(&im->cache_entry, target); + evas_cache_image_preload_cancel(&im->cache_entry, target, force); // if (gim->tex) evas_gl_preload_target_unregister(gim->tex, (Eo*) target); } diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c index 9c936944e2..c8f0ce2e0b 100644 --- a/src/modules/evas/engines/software_generic/evas_engine.c +++ b/src/modules/evas/engines/software_generic/evas_engine.c @@ -2214,13 +2214,13 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *ta } static void -eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *target) +eng_image_data_preload_cancel(void *data EINA_UNUSED, void *image, const Eo *target, Eina_Bool force) { RGBA_Image *im = image; if (!im) return; - evas_cache_image_preload_cancel(&im->cache_entry, target); + evas_cache_image_preload_cancel(&im->cache_entry, target, force); } static void