From 90531c41ff7f925884247db83026c7d0314d8f99 Mon Sep 17 00:00:00 2001 From: mike_m Date: Thu, 13 Oct 2011 02:22:29 +0000 Subject: [PATCH] evas: Use clists to store the render recalculation list Rather than trying to avoid removing the list element that is currently being processed, keep two lists and move elements to the processed list before recalculating them. Remove items from the list head only, and always append them to the tail. Use the fact that an item can be removed from a clist without needing to know which list it is in. Signed-off-by: Mike McCormack git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@64030 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/canvas/evas_main.c | 3 +- src/lib/canvas/evas_object_smart.c | 73 ++++++++++++++------------------------ src/lib/include/evas_private.h | 4 +-- 3 files changed, 30 insertions(+), 50 deletions(-) diff --git a/src/lib/canvas/evas_main.c b/src/lib/canvas/evas_main.c index d3e4c8c..c658fb1 100644 --- a/src/lib/canvas/evas_main.c +++ b/src/lib/canvas/evas_main.c @@ -120,6 +120,7 @@ evas_new(void) e->viewport.h = 1; e->hinting = EVAS_FONT_HINTING_BYTECODE; e->name_hash = eina_hash_string_superfast_new(NULL); + eina_clist_init(&e->calc_list); #define EVAS_ARRAY_SET(E, Array) \ eina_array_step_set(&E->Array, sizeof (E->Array), 4096); @@ -253,8 +254,6 @@ evas_free(Evas *e) EINA_LIST_FREE(e->touch_points, touch_point) free(touch_point); - eina_list_free(e->calc_list); - e->magic = 0; free(e); } diff --git a/src/lib/canvas/evas_object_smart.c b/src/lib/canvas/evas_object_smart.c index f516aa7..9abaf7f 100644 --- a/src/lib/canvas/evas_object_smart.c +++ b/src/lib/canvas/evas_object_smart.c @@ -11,7 +11,6 @@ struct _Evas_Object_Smart void *data; Eina_List *callbacks; Eina_Inlist *contained; - Eina_List *calc_node; Evas_Smart_Cb_Description_Array callbacks_descriptions; int walking_list; Eina_Bool deletions_waiting : 1; @@ -551,38 +550,15 @@ evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) // XXX: do i need this? if (obj->delete_me) return; - + + /* remove this entry from calc_list or processed list */ + if (eina_clist_element_is_linked(&obj->calc_entry)) + eina_clist_remove(&obj->calc_entry); + value = !!value; if (value) - { - Evas *e = obj->layer->evas; - - if (o->need_recalculate) - { - if ((o->calc_node) && (e->calc_list_current != o->calc_node)) - e->calc_list = eina_list_demote_list(e->calc_list, - o->calc_node); - else - e->calc_list = eina_list_append(e->calc_list, obj); - } - else - e->calc_list = eina_list_append(e->calc_list, obj); - o->calc_node = eina_list_last(e->calc_list); - } - else - { - Evas *e = obj->layer->evas; - - if (o->need_recalculate) - { - if ((o->calc_node) && (e->calc_list_current != o->calc_node)) - e->calc_list = eina_list_remove_list(e->calc_list, - o->calc_node); - o->calc_node = NULL; - - } - } - + eina_clist_add_tail(&obj->layer->evas->calc_list, &obj->calc_entry); + if (o->need_recalculate == value) return; if (obj->recalculate_cycle > 256) @@ -654,32 +630,40 @@ evas_smart_objects_calculate_count_get(const Evas *e) void evas_call_smarts_calculate(Evas *e) { + Eina_Clist processed = EINA_CLIST_INIT(processed); + Eina_Clist *elem; Evas_Object *obj; - Eina_List *l; // printf("+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------v\n"); evas_event_freeze(e); e->in_smart_calc++; - - EINA_LIST_FOREACH(e->calc_list, l, obj) + + while (NULL != (elem = eina_clist_head(&e->calc_list))) { - Evas_Object_Smart *o = obj->object_data; - + Evas_Object_Smart *o; + + /* move the item to the processed list */ + obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry); + eina_clist_remove(&obj->calc_entry); if (obj->delete_me) continue; - e->calc_list_current = l; + eina_clist_add_tail(&processed, &obj->calc_entry); + + o = obj->object_data; + if (o->need_recalculate) { o->need_recalculate = 0; obj->smart.smart->smart_class->calculate(obj); } - if (o->calc_node == l) o->calc_node = NULL; - e->calc_list_current = NULL; } - EINA_LIST_FREE(e->calc_list, obj) + + while (NULL != (elem = eina_clist_head(&processed))) { + obj = EINA_CLIST_ENTRY(elem, Evas_Object, calc_entry); obj->recalculate_cycle = 0; + eina_clist_remove(&obj->calc_entry); } - e->calc_list_current = NULL; + e->in_smart_calc--; if (e->in_smart_calc == 0) e->smart_calc_count++; evas_event_thaw(e); @@ -745,12 +729,9 @@ evas_object_smart_cleanup(Evas_Object *obj) o = (Evas_Object_Smart *)(obj->object_data); if (o->magic == MAGIC_OBJ_SMART) { - Evas *e = obj->layer->evas; + if (obj->calc_entry.next) + eina_clist_remove(&obj->calc_entry); - if ((o->calc_node) && (e->calc_list_current != o->calc_node)) - e->calc_list = eina_list_remove_list(e->calc_list, - o->calc_node); - o->calc_node = NULL; while (o->contained) evas_object_smart_member_del((Evas_Object *)o->contained); diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index bb16f47..b1c1a49 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -347,8 +347,7 @@ struct _Evas Eina_Array calculate_objects; Eina_Array clip_changes; - Eina_List *calc_list; - Eina_List *calc_list_current; + Eina_Clist calc_list; Eina_List *video_objects; Eina_List *post_events; // free me on evas_free @@ -567,6 +566,7 @@ struct _Evas_Object unsigned char delete_me; unsigned char recalculate_cycle; + Eina_Clist calc_entry; Evas_Object_Pointer_Mode pointer_mode : 1; -- 2.7.4