forked from enlightenment/efl
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
This commit is contained in:
parent
4e0b2c2fff
commit
423d8a2296
|
@ -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_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_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 int evas_cache_async_frozen_get(void);
|
||||||
EAPI void evas_cache_async_freeze(void);
|
EAPI void evas_cache_async_freeze(void);
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct _Evas_Cache_Preload
|
||||||
static SLK(engine_lock);
|
static SLK(engine_lock);
|
||||||
static int _evas_cache_mutex_init = 0;
|
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) \
|
#define FREESTRC(Var) \
|
||||||
if (Var) \
|
if (Var) \
|
||||||
|
@ -175,7 +175,7 @@ _evas_cache_image_entry_delete(Evas_Cache_Image *cache, Image_Entry *ie)
|
||||||
if (ie->preload)
|
if (ie->preload)
|
||||||
{
|
{
|
||||||
ie->flags.delete_me = 1;
|
ie->flags.delete_me = 1;
|
||||||
_evas_cache_image_entry_preload_remove(ie, NULL);
|
_evas_cache_image_entry_preload_remove(ie, NULL, EINA_TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_evas_cache_image_dirty_del(ie);
|
_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,
|
_evas_cache_image_entry_surface_alloc(cache, current,
|
||||||
current->w, current->h);
|
current->w, current->h);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
current->flags.loaded = 1;
|
|
||||||
}
|
}
|
||||||
current->channel = pchannel;
|
current->channel = pchannel;
|
||||||
// check the unload cancel flag
|
// check the unload cancel flag
|
||||||
|
@ -393,7 +391,8 @@ _evas_cache_image_preloaded_notify(Image_Entry *ie)
|
||||||
EINA_INLIST_GET(ie->targets));
|
EINA_INLIST_GET(ie->targets));
|
||||||
if (!tmp->delete_me && tmp->preloaded_cb)
|
if (!tmp->delete_me && tmp->preloaded_cb)
|
||||||
tmp->preloaded_cb(tmp->preloaded_data);
|
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);
|
free(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -410,8 +409,8 @@ _evas_cache_image_async_end(void *data)
|
||||||
ie->preload = NULL;
|
ie->preload = NULL;
|
||||||
ie->flags.preload_done = ie->flags.loaded;
|
ie->flags.preload_done = ie->flags.loaded;
|
||||||
ie->flags.updated_data = 1;
|
ie->flags.updated_data = 1;
|
||||||
|
|
||||||
ie->flags.preload_pending = 0;
|
ie->flags.preload_pending = 0;
|
||||||
|
ie->flags.loaded = EINA_TRUE;
|
||||||
|
|
||||||
_evas_cache_image_preloaded_notify(ie);
|
_evas_cache_image_preloaded_notify(ie);
|
||||||
evas_cache_image_drop(ie);
|
evas_cache_image_drop(ie);
|
||||||
|
@ -438,16 +437,6 @@ _evas_cache_image_async_cancel(void *data)
|
||||||
evas_cache_image_drop(ie);
|
evas_cache_image_drop(ie);
|
||||||
return;
|
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)
|
if (ie->references == 0)
|
||||||
{
|
{
|
||||||
SLKL(engine_lock);
|
SLKL(engine_lock);
|
||||||
|
@ -456,6 +445,21 @@ _evas_cache_image_async_cancel(void *data)
|
||||||
cache = ie->cache;
|
cache = ie->cache;
|
||||||
}
|
}
|
||||||
if (ie->flags.loaded) _evas_cache_image_async_end(ie);
|
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);
|
evas_cache_image_drop(ie);
|
||||||
if (cache) evas_cache_image_flush(cache);
|
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;
|
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
|
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;
|
Evas_Cache_Target *tg;
|
||||||
|
|
||||||
|
@ -511,12 +517,7 @@ _evas_cache_image_entry_preload_remove(Image_Entry *ie, const Eo *target)
|
||||||
{
|
{
|
||||||
if (tg->target == target)
|
if (tg->target == target)
|
||||||
{
|
{
|
||||||
// FIXME: No callback when we cancel only for one target ?
|
tg->preload_cancel = EINA_TRUE;
|
||||||
ie->targets = (Evas_Cache_Target *)
|
|
||||||
eina_inlist_remove(EINA_INLIST_GET(ie->targets),
|
|
||||||
EINA_INLIST_GET(tg));
|
|
||||||
|
|
||||||
free(tg);
|
|
||||||
break;
|
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->preload = eina_list_remove(ie->cache->preload, ie);
|
||||||
ie->cache->pending = eina_list_append(ie->cache->pending, 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. */
|
/* By doing that we are protecting us from destroying image when the cache is no longer available. */
|
||||||
im->flags.delete_me = 1;
|
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();
|
evas_async_events_process();
|
||||||
|
|
||||||
|
@ -863,7 +864,7 @@ evas_cache_image_drop(Image_Entry *im)
|
||||||
{
|
{
|
||||||
if (im->preload)
|
if (im->preload)
|
||||||
{
|
{
|
||||||
_evas_cache_image_entry_preload_remove(im, NULL);
|
_evas_cache_image_entry_preload_remove(im, NULL, EINA_TRUE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((im->flags.dirty) || (im->load_failed))
|
if ((im->flags.dirty) || (im->load_failed))
|
||||||
|
@ -1170,7 +1171,7 @@ evas_cache_image_unload_data(Image_Entry *im)
|
||||||
evas_cache_image_drop(im);
|
evas_cache_image_drop(im);
|
||||||
return;
|
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 */
|
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
|
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;
|
if (!target) return;
|
||||||
evas_cache_image_ref(im);
|
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);
|
evas_cache_image_drop(im);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ _image_preload_internal(Eo *eo_obj, Evas_Image_Data *o, Eina_Bool cancel)
|
||||||
{
|
{
|
||||||
if (!o->engine_data)
|
if (!o->engine_data)
|
||||||
{
|
{
|
||||||
o->preloading = EINA_TRUE;
|
o->preload = EVAS_IMAGE_PRELOADING;
|
||||||
evas_object_inform_call_image_preloaded(eo_obj);
|
evas_object_inform_call_image_preloaded(eo_obj);
|
||||||
return;
|
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);
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||||
if (cancel)
|
if (cancel)
|
||||||
{
|
{
|
||||||
if (o->preloading)
|
if (o->preload & EVAS_IMAGE_PRELOADING)
|
||||||
{
|
{
|
||||||
o->preloading = EINA_FALSE;
|
o->preload |= EVAS_IMAGE_PRELOAD_CANCEL;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
ENFN->image_data_preload_request(ENC, o->engine_data, eo_obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,8 @@ EAPI void
|
||||||
evas_object_image_preload(Evas_Object *eo_obj, Eina_Bool cancel)
|
evas_object_image_preload(Evas_Object *eo_obj, Eina_Bool cancel)
|
||||||
{
|
{
|
||||||
EVAS_IMAGE_API(eo_obj);
|
EVAS_IMAGE_API(eo_obj);
|
||||||
if (cancel)
|
if (cancel) _evas_image_load_async_cancel(eo_obj);
|
||||||
_evas_image_load_async_cancel(eo_obj);
|
else _evas_image_load_async_start(eo_obj);
|
||||||
else
|
|
||||||
_evas_image_load_async_start(eo_obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Eina_Bool
|
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);
|
evas_object_async_block(obj);
|
||||||
o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
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->engine_data) return NULL;
|
||||||
if (o->video_surface)
|
if (o->video_surface)
|
||||||
o->pixels->video.update_pixels(o->pixels->video.data, eo_obj, &o->pixels->video);
|
o->pixels->video.update_pixels(o->pixels->video.data, eo_obj, &o->pixels->video);
|
||||||
if (o->cur->cspace == to_cspace) return NULL;
|
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;
|
data = NULL;
|
||||||
engine_data = ENFN->image_data_get(ENC, o->engine_data, 0, &data, &o->load_error, 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);
|
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);
|
evas_object_async_block(obj);
|
||||||
o = efl_data_scope_get(eo_obj, EFL_CANVAS_IMAGE_INTERNAL_CLASS);
|
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;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
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)
|
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);
|
o->engine_data = ENFN->image_dirty_region(ENC, o->engine_data, 0, 0, o->cur->image.w, o->cur->image.h);
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,11 @@ struct _Evas_Object_Image_State
|
||||||
Eina_Bool opaque : 1;
|
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
|
struct _Evas_Image_Data
|
||||||
{
|
{
|
||||||
const Evas_Object_Image_State *cur;
|
const Evas_Object_Image_State *cur;
|
||||||
|
@ -117,13 +122,13 @@ struct _Evas_Image_Data
|
||||||
short w, h;
|
short w, h;
|
||||||
} file_size;
|
} file_size;
|
||||||
|
|
||||||
|
unsigned char preload; //See above EVAS_IMAGE_PRELOAD***
|
||||||
|
|
||||||
Eina_Bool changed : 1;
|
Eina_Bool changed : 1;
|
||||||
Eina_Bool dirty_pixels : 1;
|
Eina_Bool dirty_pixels : 1;
|
||||||
Eina_Bool filled : 1;
|
Eina_Bool filled : 1;
|
||||||
Eina_Bool filled_set : 1;
|
Eina_Bool filled_set : 1;
|
||||||
Eina_Bool proxyrendering : 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_surface : 1;
|
||||||
Eina_Bool video_visible : 1;
|
Eina_Bool video_visible : 1;
|
||||||
Eina_Bool created : 1;
|
Eina_Bool created : 1;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#include "evas_image_private.h"
|
#include "evas_image_private.h"
|
||||||
|
|
||||||
#define MY_CLASS EFL_CANVAS_IMAGE_INTERNAL_CLASS
|
#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_has_opaque_rect,
|
||||||
evas_object_image_get_opaque_rect,
|
evas_object_image_get_opaque_rect,
|
||||||
evas_object_image_can_map,
|
evas_object_image_can_map,
|
||||||
evas_object_image_render_prepare, // render_prepare
|
evas_object_image_render_prepare // render_prepare
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const Evas_Object_Image_Load_Opts default_load_opts = {
|
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);
|
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;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
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->source) _evas_image_proxy_unset(eo_obj, obj, o);
|
||||||
if (o->cur->scene) _evas_image_3d_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->engine_data)
|
||||||
{
|
{
|
||||||
if (o->preloading)
|
if (o->preload & EVAS_IMAGE_PRELOADING)
|
||||||
{
|
{
|
||||||
o->preloading = EINA_FALSE;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE);
|
||||||
}
|
}
|
||||||
ENFN->image_free(ENC, o->engine_data);
|
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->cur->orient == orient) return;
|
||||||
|
|
||||||
if ((o->preloading) && (o->engine_data))
|
if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data))
|
||||||
{
|
{
|
||||||
o->preloading = EINA_FALSE;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o->engine_data)
|
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_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
evas_object_async_block(obj);
|
evas_object_async_block(obj);
|
||||||
if ((o->preloading) && (o->engine_data))
|
if ((o->preload & EVAS_IMAGE_PRELOADING) && (o->engine_data))
|
||||||
{
|
{
|
||||||
o->preloading = EINA_FALSE;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
has_alpha = !!has_alpha;
|
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->engine_data)
|
||||||
{
|
{
|
||||||
if (o->preloading)
|
if (o->preload & EVAS_IMAGE_PRELOADING)
|
||||||
{
|
{
|
||||||
o->preloading = EINA_FALSE;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE);
|
||||||
}
|
}
|
||||||
ENFN->image_free(ENC, o->engine_data);
|
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);
|
EINA_COW_IMAGE_STATE_WRITE_END(o, state_write);
|
||||||
o->changed = EINA_TRUE;
|
o->changed = EINA_TRUE;
|
||||||
o->preloaded = EINA_TRUE;
|
o->preload = EVAS_IMAGE_PRELOADED;
|
||||||
if (resize_call) evas_object_inform_call_image_resize(eo_obj);
|
if (resize_call) evas_object_inform_call_image_resize(eo_obj);
|
||||||
evas_object_change(eo_obj, 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
|
else
|
||||||
{
|
{
|
||||||
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
o->load_error = EVAS_LOAD_ERROR_GENERIC;
|
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->engine_data && ENC)
|
||||||
{
|
{
|
||||||
if (o->preloading)
|
if (o->preload & EVAS_IMAGE_PRELOADING)
|
||||||
{
|
{
|
||||||
o->preloading = EINA_FALSE;
|
o->preload = EVAS_IMAGE_PRELOAD_NONE;
|
||||||
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj);
|
ENFN->image_data_preload_cancel(ENC, o->engine_data, eo_obj, EINA_FALSE);
|
||||||
}
|
}
|
||||||
ENFN->image_free(ENC, o->engine_data);
|
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;
|
Evas_Image_Data *o = type_private_data;
|
||||||
|
|
||||||
/* image is not ready yet, skip rendering. Leave it to next frame */
|
/* 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))
|
if ((o->cur->fill.w < 1) || (o->cur->fill.h < 1))
|
||||||
return; /* no error message, already printed in pre_render */
|
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;
|
Eina_Bool changed_prep = EINA_TRUE;
|
||||||
|
|
||||||
/* image is not ready yet, skip rendering. Leave it to next frame */
|
/* 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! */
|
/* dont pre-render the obj twice! */
|
||||||
if (obj->pre_render_done) return;
|
if (obj->pre_render_done) return;
|
||||||
obj->pre_render_done = EINA_TRUE;
|
obj->pre_render_done = EINA_TRUE;
|
||||||
|
@ -2376,10 +2380,10 @@ evas_object_image_render_pre(Evas_Object *eo_obj,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
//pre-loading is finished
|
//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);
|
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;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3383,23 +3387,7 @@ Eina_Bool
|
||||||
_evas_object_image_preloading_get(const Evas_Object *eo_obj)
|
_evas_object_image_preloading_get(const Evas_Object *eo_obj)
|
||||||
{
|
{
|
||||||
Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
Evas_Image_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
||||||
return o->preloading;
|
return o->preload;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Evas_Object *
|
Evas_Object *
|
||||||
|
|
|
@ -66,10 +66,14 @@ evas_object_inform_call_image_preloaded(Evas_Object *eo_obj)
|
||||||
int event_id;
|
int event_id;
|
||||||
|
|
||||||
EINA_SAFETY_ON_NULL_RETURN(obj);
|
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_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();
|
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_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_IMAGE_PRELOADED, NULL, event_id, EFL_GFX_IMAGE_EVENT_PRELOAD);
|
||||||
|
|
|
@ -556,7 +556,8 @@ struct _Evas_Cache_Target
|
||||||
void *data;
|
void *data;
|
||||||
void (*preloaded_cb) (void *data); //Call when preloading done.
|
void (*preloaded_cb) (void *data); //Call when preloading done.
|
||||||
void *preloaded_data;
|
void *preloaded_data;
|
||||||
Eina_Bool delete_me;
|
Eina_Bool delete_me : 1;
|
||||||
|
Eina_Bool preload_cancel : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Image_Timestamp
|
struct _Image_Timestamp
|
||||||
|
|
|
@ -1346,7 +1346,7 @@ struct _Evas_Func
|
||||||
void *(*image_data_put) (void *engine, void *image, DATA32 *image_data);
|
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);
|
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_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);
|
void *(*image_alpha_set) (void *engine, void *image, int has_alpha);
|
||||||
int (*image_alpha_get) (void *engine, void *image);
|
int (*image_alpha_get) (void *engine, void *image);
|
||||||
void *(*image_orient_set) (void *engine, void *image, Evas_Image_Orient orient);
|
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);
|
Evas_Object *_evas_object_image_source_get(Evas_Object *obj);
|
||||||
Eina_Bool _evas_object_image_preloading_get(const 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);
|
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_show(Evas_Object *obj);
|
||||||
void _evas_object_image_video_overlay_hide(Evas_Object *obj);
|
void _evas_object_image_video_overlay_hide(Evas_Object *obj);
|
||||||
|
|
|
@ -793,7 +793,6 @@ evas_gl_common_image_update(Evas_Engine_GL_Context *gc, Evas_GL_Image *im)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*/
|
*/
|
||||||
|
|
||||||
switch (im->cs.space)
|
switch (im->cs.space)
|
||||||
{
|
{
|
||||||
case EVAS_COLORSPACE_ARGB8888:
|
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) &&
|
if ((im->tex) &&
|
||||||
((im->dirty) || (ie->animated.animated) || (ie->flags.updated_data)))
|
((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_gl_common_texture_update(im->tex, im->im);
|
||||||
evas_cache_image_unload_data(ie);
|
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);
|
im->tex = evas_gl_common_texture_new(gc, im->im, im->disable_atlas);
|
||||||
evas_cache_image_unload_data(ie);
|
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:
|
case EVAS_COLORSPACE_ETC1_ALPHA:
|
||||||
if ((im->tex) && (im->dirty))
|
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_gl_common_texture_rgb_a_pair_update(im->tex, im->im);
|
||||||
evas_cache_image_unload_data(ie);
|
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);
|
im->tex = evas_gl_common_texture_rgb_a_pair_new(gc, im->im);
|
||||||
evas_cache_image_unload_data(ie);
|
evas_cache_image_unload_data(ie);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1120,7 +1120,7 @@ eng_image_data_preload_request(void *engine EINA_UNUSED, void *image, const Eo *
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
Evas_GL_Image *gim = image;
|
||||||
RGBA_Image *im;
|
RGBA_Image *im;
|
||||||
|
@ -1131,7 +1131,7 @@ eng_image_data_preload_cancel(void *engine EINA_UNUSED, void *image, const Eo *t
|
||||||
if (!im) return;
|
if (!im) return;
|
||||||
|
|
||||||
evas_gl_common_image_preload_unwatch(gim);
|
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);
|
// if (gim->tex) evas_gl_preload_target_unregister(gim->tex, (Eo*) target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2214,13 +2214,13 @@ eng_image_data_preload_request(void *data EINA_UNUSED, void *image, const Eo *ta
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
RGBA_Image *im = image;
|
||||||
|
|
||||||
if (!im) return;
|
if (!im) return;
|
||||||
|
|
||||||
evas_cache_image_preload_cancel(&im->cache_entry, target);
|
evas_cache_image_preload_cancel(&im->cache_entry, target, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue