From ee5446fb131fa925acc5a9b0d6cae3706ca0e562 Mon Sep 17 00:00:00 2001 From: Mike McCormack 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 SVN revision: 64030 --- legacy/evas/src/lib/canvas/evas_main.c | 3 +- .../evas/src/lib/canvas/evas_object_smart.c | 73 +++++++------------ legacy/evas/src/lib/include/evas_private.h | 4 +- 3 files changed, 30 insertions(+), 50 deletions(-) diff --git a/legacy/evas/src/lib/canvas/evas_main.c b/legacy/evas/src/lib/canvas/evas_main.c index d3e4c8c52d..c658fb1088 100644 --- a/legacy/evas/src/lib/canvas/evas_main.c +++ b/legacy/evas/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/legacy/evas/src/lib/canvas/evas_object_smart.c b/legacy/evas/src/lib/canvas/evas_object_smart.c index f516aa7632..9abaf7f5f4 100644 --- a/legacy/evas/src/lib/canvas/evas_object_smart.c +++ b/legacy/evas/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/legacy/evas/src/lib/include/evas_private.h b/legacy/evas/src/lib/include/evas_private.h index bb16f47530..b1c1a49b66 100644 --- a/legacy/evas/src/lib/include/evas_private.h +++ b/legacy/evas/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;