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);
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) \
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
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);
_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
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);
}
}
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);
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);
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);
}
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;
{
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;
}
}
}
}
- 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);
{
/* 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();
{
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))
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 */
{
}
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);
}
{
if (!o->engine_data)
{
- o->preloading = EINA_TRUE;
+ o->preload = EVAS_IMAGE_PRELOADING;
evas_object_inform_call_image_preloaded(eo_obj);
return;
}
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);
}
}
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
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);
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);
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;
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;
+
#include "evas_image_private.h"
#define MY_CLASS EFL_CANVAS_IMAGE_INTERNAL_CLASS
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 = {
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);
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);
}
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)
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;
}
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);
}
}
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;
}
}
{
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);
}
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 */
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;
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;
}
}
_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 *
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);
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
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);
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);
}
else
*/
-
switch (im->cs.space)
{
case EVAS_COLORSPACE_ARGB8888:
if ((im->tex) &&
((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data)))
{
-#ifdef EVAS_CSERVE2
- if (evas_cache2_image_cached(ie))
- {
- evas_cache2_image_load_data(ie);
- evas_gl_common_texture_update(im->tex, im->im);
- evas_cache2_image_unload_data(ie);
- }
- else
-#endif
- {
- evas_cache_image_load_data(ie);
- evas_gl_common_texture_update(im->tex, im->im);
- evas_cache_image_unload_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 == EVAS_LOAD_ERROR_NONE) ||
+ (ie->load_error == EVAS_LOAD_ERROR_CANCELLED)))
{
-#ifdef EVAS_CSERVE2
- if (evas_cache2_image_cached(ie))
- {
- evas_cache2_image_load_data(ie);
- im->tex = evas_gl_common_texture_new(gc, im->im, im->disable_atlas);
- evas_cache2_image_unload_data(ie);
- }
- else
-#endif
- {
- 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);
- }
+ 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);
}
ie->flags.updated_data = EINA_FALSE;
im->dirty = 0;
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 == EVAS_LOAD_ERROR_NONE) ||
+ (ie->load_error == EVAS_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);
}
}
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;
if (!im) return;
evas_gl_common_image_preload_unwatch(gim);
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
- evas_cache2_image_preload_cancel(&im->cache_entry, target);
- else
-#endif
- 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);
}
}
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;
-#ifdef EVAS_CSERVE2
- if (evas_cserve2_use_get() && evas_cache2_image_cached(&im->cache_entry))
- {
- evas_cache2_image_preload_cancel(&im->cache_entry, target);
- return;
- }
-#endif
-
- evas_cache_image_preload_cancel(&im->cache_entry, target);
+ evas_cache_image_preload_cancel(&im->cache_entry, target, force);
}
static void