From: Jiyoun Park Date: Wed, 4 May 2011 02:36:03 +0000 (+0900) Subject: Evas_cache: fix preload bug X-Git-Tag: 2.0_alpha~335 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b7ca5e45486aed506dfeb5c26ba0c9571d134fc4;p=framework%2Fuifw%2Fevas.git Evas_cache: fix preload bug if app or widget call preload more than twice to same object, evas add two target for one object when object free before preload done, it make crash because object is already free , but second target reference object is still remain. Change-Id: I05bdca2b61b0989094091504722b838138b505fe --- diff --git a/src/lib/cache/evas_cache_image.c b/src/lib/cache/evas_cache_image.c index 629f583..07a474a 100755 --- a/src/lib/cache/evas_cache_image.c +++ b/src/lib/cache/evas_cache_image.c @@ -448,6 +448,8 @@ _evas_cache_image_async_cancel(void *data) if (cache) evas_cache_image_flush(cache); } +// note - preload_add assumes a target is ONLY added ONCE to the image +// entry. make sure you only add once, or remove first, then add static int _evas_cache_image_entry_preload_add(Image_Entry *ie, const void *target) { diff --git a/src/lib/canvas/evas_object_image.c b/src/lib/canvas/evas_object_image.c index 2940f9d..f3c1dc5 100644 --- a/src/lib/canvas/evas_object_image.c +++ b/src/lib/canvas/evas_object_image.c @@ -75,6 +75,7 @@ struct _Evas_Object_Image unsigned char dirty_pixels : 1; unsigned char filled : 1; unsigned char proxyrendering : 1; + unsigned char preloading : 1; }; /* private methods for image objects */ @@ -351,9 +352,13 @@ evas_object_image_file_set(Evas_Object *obj, const char *file, const char *key) o->prev.key = NULL; if (o->engine_data) { - obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, - o->engine_data, - obj); + if (o->preloading) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data); } @@ -929,6 +934,13 @@ evas_object_image_size_set(Evas_Object *obj, int w, int h) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if (w < 1) w = 1; if (h < 1) h = 1; if (w > 32768) return; @@ -1084,6 +1096,13 @@ evas_object_image_data_convert(Evas_Object *obj, Evas_Colorspace to_cspace) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return NULL; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if (!o->engine_data) return NULL; if (!o->cur.cspace == to_cspace) return NULL; data = NULL; @@ -1116,6 +1135,13 @@ evas_object_image_data_set(Evas_Object *obj, void *data) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } #ifdef EVAS_FRAME_QUEUING if (o->engine_data) evas_common_pipe_op_image_flush(o->engine_data); @@ -1277,17 +1303,32 @@ evas_object_image_preload(Evas_Object *obj, Eina_Bool cancel) MAGIC_CHECK_END(); if (!o->engine_data) { + o->preloading = 1; evas_object_inform_call_image_preloaded(obj); return; } + // FIXME: if already busy preloading, then dont request again until + // preload done if (cancel) - obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, - o->engine_data, - obj); + { + if (o->preloading) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } + } else - obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output, - o->engine_data, - obj); + { + if (!o->preloading) + { + o->preloading = 1; + obj->layer->evas->engine.func->image_data_preload_request(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } + } } /** @@ -1325,6 +1366,13 @@ evas_object_image_data_copy_set(Evas_Object *obj, void *data) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if ((o->cur.image.w <= 0) || (o->cur.image.h <= 0)) return; if (o->engine_data) @@ -1420,6 +1468,13 @@ evas_object_image_alpha_set(Evas_Object *obj, Eina_Bool has_alpha) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if (((has_alpha) && (o->cur.has_alpha)) || ((!has_alpha) && (!o->cur.has_alpha))) return; @@ -1556,6 +1611,13 @@ evas_object_image_reload(Evas_Object *obj) MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if ((!o->cur.file) || (o->pixels_checked_out > 0)) return; if (o->engine_data) @@ -1673,6 +1735,13 @@ evas_object_image_pixels_import(Evas_Object *obj, Evas_Pixel_Import_Source *pixe return 0; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if ((pixels->w != o->cur.image.w) || (pixels->h != o->cur.image.h)) return 0; switch (pixels->format) { @@ -2061,6 +2130,13 @@ evas_object_image_colorspace_set(Evas_Object *obj, Evas_Colorspace cspace) return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } #ifdef EVAS_FRAME_QUEUING if ((Evas_Colorspace)o->cur.cspace != cspace) { @@ -2121,6 +2197,13 @@ evas_object_image_native_surface_set(Evas_Object *obj, Evas_Native_Surface *surf MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); return; MAGIC_CHECK_END(); + if ((o->preloading) && (o->engine_data)) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } if (o->cur.source) _proxy_unset(obj); if (!obj->layer->evas->engine.func->image_native_set) return; if ((surf) && @@ -2640,9 +2723,13 @@ evas_object_image_unload(Evas_Object *obj, Eina_Bool dirty) } if (o->engine_data) { - obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, - o->engine_data, - obj); + if (o->preloading) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data); } @@ -2819,9 +2906,13 @@ evas_object_image_free(Evas_Object *obj) if (o->cur.source) _proxy_unset(obj); if (o->engine_data) { - obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, - o->engine_data, - obj); + if (o->preloading) + { + o->preloading = 0; + obj->layer->evas->engine.func->image_data_preload_cancel(obj->layer->evas->engine.data.output, + o->engine_data, + obj); + } obj->layer->evas->engine.func->image_free(obj->layer->evas->engine.data.output, o->engine_data); } @@ -2876,12 +2967,6 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su obj->layer->evas->engine.func->context_render_op_set(output, context, obj->cur.render_op); - if (0) - printf("Proxy: %p Source: %p Surface %p Redraw %s Type %s/%s %p %d %d\n", - obj, o->cur.source,o->cur.source->proxy.surface, - o->cur.source->proxy.redraw?"yep ":"nope",o->cur.source->type, - o_type,obj->cur.map,obj->cur.map->count, obj->cur.usemap); - if (!o->cur.source) { pixels = o->engine_data; @@ -3756,4 +3841,23 @@ evas_object_image_filled_resize_listener(void *data __UNUSED__, Evas *e __UNUSED evas_object_image_fill_set(obj, 0, 0, w, h); } + +Eina_Bool +_evas_object_image_preloading_get(const Evas_Object *obj) +{ + Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data); + if (!o) return EINA_FALSE; + MAGIC_CHECK(o, Evas_Object_Image, MAGIC_OBJ_IMAGE); + return EINA_FALSE; + MAGIC_CHECK_END(); + return o->preloading; +} + +void +_evas_object_image_preloading_set(Evas_Object *obj, Eina_Bool preloading) +{ + Evas_Object_Image *o = (Evas_Object_Image *)(obj->object_data); + o->preloading = preloading; +} + /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ diff --git a/src/lib/canvas/evas_object_inform.c b/src/lib/canvas/evas_object_inform.c index d1dd645..f22b6f0 100644 --- a/src/lib/canvas/evas_object_inform.c +++ b/src/lib/canvas/evas_object_inform.c @@ -60,6 +60,8 @@ evas_object_inform_call_changed_size_hints(Evas_Object *obj) void evas_object_inform_call_image_preloaded(Evas_Object *obj) { + if (!_evas_object_image_preloading_get(obj)) return; + _evas_object_image_preloading_set(obj, 0); _evas_object_event_new(); evas_object_event_callback_call(obj, EVAS_CALLBACK_IMAGE_PRELOADED, NULL); diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index e5b9eb4..fb9bb53 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -754,6 +754,8 @@ void evas_smart_cb_descriptions_fix(Evas_Smart_Cb_Description_Array *a) EINA_ARG Eina_Bool evas_smart_cb_descriptions_resize(Evas_Smart_Cb_Description_Array *a, unsigned int size) EINA_ARG_NONNULL(1); const Evas_Smart_Cb_Description *evas_smart_cb_description_find(const Evas_Smart_Cb_Description_Array *a, const char *name) EINA_ARG_NONNULL(1, 2) EINA_PURE; +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_smart_del(Evas_Object *obj); void evas_object_smart_cleanup(Evas_Object *obj); void evas_object_smart_member_raise(Evas_Object *member);