diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog index 247fc54a34..f127ad8675 100644 --- a/legacy/evas/ChangeLog +++ b/legacy/evas/ChangeLog @@ -888,4 +888,5 @@ 2012-07-17 Cedric Bail * Fix garbage left by mapped smart object when they fly away from the canvas. + * Fix map life cycle. diff --git a/legacy/evas/NEWS b/legacy/evas/NEWS index 8caf2b01f3..4075b4c7c8 100644 --- a/legacy/evas/NEWS +++ b/legacy/evas/NEWS @@ -22,6 +22,7 @@ Fixes: * Add svg rendering with Esvg * Don't accept broken map. * Fix garbage left by mapped smart object when they fly away from the canvas. + * Fix map life cycle. Removal: * Remove EVAS_FRAME_QUEUING, EVAS_SLI, METRIC_CACHE and WORD_CACHE. diff --git a/legacy/evas/src/lib/canvas/evas_map.c b/legacy/evas/src/lib/canvas/evas_map.c index 23c8de10d8..df3f1653fe 100644 --- a/legacy/evas/src/lib/canvas/evas_map.c +++ b/legacy/evas/src/lib/canvas/evas_map.c @@ -42,36 +42,46 @@ _evas_map_calc_map_geometry(Evas_Object *obj) // It has an infinite loop bug. if (obj->prev.map) { - // FIXME: this causes an infinite loop somewhere... hard to debug - if (obj->prev.map->count == obj->cur.map->count) + if (obj->prev.map != obj->cur.map) { - const Evas_Map_Point *p2; - - p = obj->cur.map->points; - p_end = p + obj->cur.map->count; - p2 = obj->prev.map->points; - - for (; p < p_end; p++, p2++) + // FIXME: this causes an infinite loop somewhere... hard to debug + if (obj->prev.map->count == obj->cur.map->count) { - if ((p->a != p2->a) || - (p->r != p2->r) || - (p->g != p2->g) || - (p->b != p2->b)) + const Evas_Map_Point *p2; + + p = obj->cur.map->points; + p_end = p + obj->cur.map->count; + p2 = obj->prev.map->points; + + for (; p < p_end; p++, p2++) { - ch = 1; - break; + if ((p->a != p2->a) || + (p->r != p2->r) || + (p->g != p2->g) || + (p->b != p2->b)) + { + ch = 1; + break; + } + if ((p->x != p2->x) || + (p->y != p2->y) || + (p->z != p2->z)) + { + ch = 1; + break; + } } - if ((p->x != p2->x) || - (p->y != p2->y) || - (p->z != p2->z)) + + if (!ch) { - ch = 1; - break; + if (obj->cache_map) evas_map_free(obj->cache_map); + obj->cache_map = obj->cur.map; + obj->cur.map = obj->prev.map; } } + else + ch = 1; } - else - ch = 1; } else ch = 1; @@ -468,8 +478,19 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) obj->cur.map->surface = NULL; } obj->prev.geometry = obj->cur.map->normal_geometry; - _evas_map_free(obj, obj->cur.map); - obj->cur.map = NULL; + + if (obj->prev.map == obj->cur.map) + obj->cur.map = NULL; + else if (!obj->cache_map) + { + obj->cache_map = obj->cur.map; + obj->cur.map = NULL; + } + else + { + _evas_map_free(obj, obj->cur.map); + obj->cur.map = NULL; + } if (!obj->prev.map) { @@ -485,6 +506,15 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map) return; } + if (obj->prev.map == obj->cur.map) + obj->cur.map = NULL; + + if (!obj->cur.map) + { + obj->cur.map = obj->cache_map; + obj->cache_map = NULL; + } + // We do have the same exact count of point in this map, so just copy it if ((obj->cur.map) && (obj->cur.map->count == map->count)) _evas_map_copy(obj->cur.map, map); diff --git a/legacy/evas/src/lib/canvas/evas_object_image.c b/legacy/evas/src/lib/canvas/evas_object_image.c index b18ac653be..cefbd059bf 100644 --- a/legacy/evas/src/lib/canvas/evas_object_image.c +++ b/legacy/evas/src/lib/canvas/evas_object_image.c @@ -3456,7 +3456,7 @@ evas_object_image_render_post(Evas_Object *obj) EINA_LIST_FREE(o->pixel_updates, r) eina_rectangle_free(r); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); o->prev = o->cur; o->changed = 0; /* FIXME: copy strings across */ diff --git a/legacy/evas/src/lib/canvas/evas_object_line.c b/legacy/evas/src/lib/canvas/evas_object_line.c index b58fe4053b..177421dc2f 100644 --- a/legacy/evas/src/lib/canvas/evas_object_line.c +++ b/legacy/evas/src/lib/canvas/evas_object_line.c @@ -379,7 +379,7 @@ evas_object_line_render_post(Evas_Object *obj) /* remove those pesky changes */ evas_object_clip_changes_clean(obj); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); o->prev = o->cur; o->changed = EINA_FALSE; } diff --git a/legacy/evas/src/lib/canvas/evas_object_main.c b/legacy/evas/src/lib/canvas/evas_object_main.c index 44eb6bdd7f..d20be57e2a 100644 --- a/legacy/evas/src/lib/canvas/evas_object_main.c +++ b/legacy/evas/src/lib/canvas/evas_object_main.c @@ -40,6 +40,17 @@ evas_object_change_reset(Evas_Object *obj) obj->changed_pchange = EINA_FALSE; } +void +evas_object_cur_prev(Evas_Object *obj) +{ + if (obj->cur.map != obj->prev.map) + { + if (obj->cache_map) evas_map_free(obj->cache_map); + obj->cache_map = obj->prev.map; + } + obj->prev = obj->cur; +} + void evas_object_free(Evas_Object *obj, int clean_layer) { @@ -50,6 +61,8 @@ evas_object_free(Evas_Object *obj, int clean_layer) #endif if (!strcmp(obj->type, "image")) evas_object_image_video_surface_set(obj, NULL); evas_object_map_set(obj, NULL); + if (obj->prev.map) evas_map_free(obj->prev.map); + if (obj->cache_map) evas_map_free(obj->cache_map); evas_object_grabs_cleanup(obj); evas_object_intercept_cleanup(obj); if (obj->smart.parent) was_smart_child = 1; diff --git a/legacy/evas/src/lib/canvas/evas_object_polygon.c b/legacy/evas/src/lib/canvas/evas_object_polygon.c index 0bb740ac18..34931b2c06 100644 --- a/legacy/evas/src/lib/canvas/evas_object_polygon.c +++ b/legacy/evas/src/lib/canvas/evas_object_polygon.c @@ -439,7 +439,7 @@ evas_object_polygon_render_post(Evas_Object *obj) /* remove those pesky changes */ evas_object_clip_changes_clean(obj); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); o->changed = 0; } diff --git a/legacy/evas/src/lib/canvas/evas_object_rectangle.c b/legacy/evas/src/lib/canvas/evas_object_rectangle.c index da38342cff..fa90f42b1c 100644 --- a/legacy/evas/src/lib/canvas/evas_object_rectangle.c +++ b/legacy/evas/src/lib/canvas/evas_object_rectangle.c @@ -279,7 +279,7 @@ evas_object_rectangle_render_post(Evas_Object *obj) /* remove those pesky changes */ evas_object_clip_changes_clean(obj); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); } static int diff --git a/legacy/evas/src/lib/canvas/evas_object_smart.c b/legacy/evas/src/lib/canvas/evas_object_smart.c index 28ed4cbf5b..82f03688c8 100644 --- a/legacy/evas/src/lib/canvas/evas_object_smart.c +++ b/legacy/evas/src/lib/canvas/evas_object_smart.c @@ -1234,7 +1234,7 @@ evas_object_smart_render_pre(Evas_Object *obj) static void evas_object_smart_render_post(Evas_Object *obj) { - obj->prev = obj->cur; + evas_object_cur_prev(obj); } static unsigned int evas_object_smart_id_get(Evas_Object *obj) diff --git a/legacy/evas/src/lib/canvas/evas_object_text.c b/legacy/evas/src/lib/canvas/evas_object_text.c index 606496d492..2afc588645 100644 --- a/legacy/evas/src/lib/canvas/evas_object_text.c +++ b/legacy/evas/src/lib/canvas/evas_object_text.c @@ -1795,7 +1795,7 @@ evas_object_text_render_post(Evas_Object *obj) /* remove those pesky changes */ evas_object_clip_changes_clean(obj); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); o->prev = o->cur; o->changed = 0; } diff --git a/legacy/evas/src/lib/canvas/evas_object_textblock.c b/legacy/evas/src/lib/canvas/evas_object_textblock.c index 914a815995..51db5d6064 100644 --- a/legacy/evas/src/lib/canvas/evas_object_textblock.c +++ b/legacy/evas/src/lib/canvas/evas_object_textblock.c @@ -9869,7 +9869,7 @@ evas_object_textblock_render_post(Evas_Object *obj) /* remove those pesky changes */ evas_object_clip_changes_clean(obj); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); /* o->prev = o->cur; */ /* o->changed = 0; */ } diff --git a/legacy/evas/src/lib/canvas/evas_object_textgrid.c b/legacy/evas/src/lib/canvas/evas_object_textgrid.c index ae7693ec82..f04751873b 100644 --- a/legacy/evas/src/lib/canvas/evas_object_textgrid.c +++ b/legacy/evas/src/lib/canvas/evas_object_textgrid.c @@ -841,7 +841,7 @@ evas_object_textgrid_render_post(Evas_Object *obj) /* remove those pesky changes */ evas_object_clip_changes_clean(obj); /* move cur to prev safely for object data */ - obj->prev = obj->cur; + evas_object_cur_prev(obj); o->prev = o->cur; o->changed = 0; diff --git a/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index 18d440af15..ad6785a719 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/src/lib/include/evas_private.h @@ -543,6 +543,7 @@ struct _Evas_Object Eina_Bool parent_cached_surface : 1; } cur, prev; + Evas_Map *cache_map; char *name; Evas_Intercept_Func *interceptors; @@ -911,6 +912,7 @@ extern "C" { Evas_Object *evas_object_new(Evas *e); void evas_object_change_reset(Evas_Object *obj); +void evas_object_cur_prev(Evas_Object *obj); void evas_object_free(Evas_Object *obj, int clean_layer); void evas_object_update_bounding_box(Evas_Object *obj); void evas_object_inject(Evas_Object *obj, Evas *e);