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:
Hermet Park 2018-09-03 15:19:02 +09:00
parent 4e0b2c2fff
commit 423d8a2296
12 changed files with 111 additions and 114 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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