edje: reduce overhead of setting text and color class in theme.

This reduce by 10% some elementary tests case that was provided
by some crazy french.
This commit is contained in:
Cedric BAIL 2014-07-06 22:50:32 +02:00
parent e3192c374d
commit 1b54047ac4
3 changed files with 147 additions and 160 deletions

View File

@ -207,31 +207,6 @@ edje_shutdown(void)
} }
/* Private Routines */ /* Private Routines */
static void
_class_member_free(Eina_Hash *hash,
void (*_edje_class_member_direct_del)(const char *class, void *l))
{
const char *color_class;
Eina_Iterator *it;
Eina_List *class_kill = NULL;
if (hash)
{
it = eina_hash_iterator_key_new(hash);
EINA_ITERATOR_FOREACH(it, color_class)
class_kill = eina_list_append(class_kill, color_class);
eina_iterator_free(it);
EINA_LIST_FREE(class_kill, color_class)
{
void *l;
l = eina_hash_find(hash, color_class);
_edje_class_member_direct_del(color_class, l);
}
eina_hash_free(hash);
}
}
void void
_edje_del(Edje *ed) _edje_del(Edje *ed)
{ {
@ -279,8 +254,8 @@ _edje_del(Edje *ed)
free(cb); free(cb);
} }
_class_member_free(ed->members.text_class, _edje_text_class_member_direct_del); _edje_color_class_member_clean(ed);
_class_member_free(ed->members.color_class, _edje_color_class_member_direct_del); _edje_text_class_members_clean(ed);
} }
void void

View File

@ -1323,11 +1323,6 @@ struct _Edje
Eina_List *groups; Eina_List *groups;
struct {
Eina_Hash *text_class;
Eina_Hash *color_class;
} members;
Edje_Perspective *persp; Edje_Perspective *persp;
const Edje_Signal_Callback_Group *callbacks; const Edje_Signal_Callback_Group *callbacks;
@ -2071,9 +2066,9 @@ const char * _edje_text_font_get(const char *base, const char *new,
Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part); Edje_Real_Part *_edje_real_part_get(const Edje *ed, const char *part);
Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part); Edje_Real_Part *_edje_real_part_recursive_get(Edje **ed, const char *part);
Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class); Edje_Color_Class *_edje_color_class_find(const Edje *ed, const char *color_class);
void _edje_color_class_member_direct_del(const char *color_class, void *lookup);
void _edje_color_class_member_add(Edje *ed, const char *color_class); void _edje_color_class_member_add(Edje *ed, const char *color_class);
void _edje_color_class_member_del(Edje *ed, const char *color_class); void _edje_color_class_member_del(Edje *ed, const char *color_class);
void _edje_color_class_member_clean(Edje *ed);
void _edje_color_class_on_del(Edje *ed, Edje_Part *ep); void _edje_color_class_on_del(Edje *ed, Edje_Part *ep);
void _edje_color_class_members_free(void); void _edje_color_class_members_free(void);
void _edje_color_class_hash_free(void); void _edje_color_class_hash_free(void);
@ -2081,10 +2076,9 @@ void _edje_color_class_hash_free(void);
Edje_Text_Class *_edje_text_class_find(Edje *ed, const char *text_class); Edje_Text_Class *_edje_text_class_find(Edje *ed, const char *text_class);
void _edje_text_class_member_add(Edje *ed, const char *text_class); void _edje_text_class_member_add(Edje *ed, const char *text_class);
void _edje_text_class_member_del(Edje *ed, const char *text_class); void _edje_text_class_member_del(Edje *ed, const char *text_class);
void _edje_text_class_member_direct_del(const char *text_class, void *lookup);
void _edje_text_class_members_free(void); void _edje_text_class_members_free(void);
void _edje_text_class_hash_free(void); void _edje_text_class_hash_free(void);
void _edje_text_class_members_clean(Edje *ed);
Edje *_edje_fetch(const Evas_Object *obj) EINA_PURE; Edje *_edje_fetch(const Evas_Object *obj) EINA_PURE;
int _edje_util_freeze(Edje *ed); int _edje_util_freeze(Edje *ed);
int _edje_util_thaw(Edje *ed); int _edje_util_thaw(Edje *ed);

View File

@ -34,12 +34,12 @@ struct _Edje_List_Foreach_Data
Eina_List *list; Eina_List *list;
}; };
typedef struct _Edje_List_Refcount Edje_List_Refcount; typedef struct _Edje_Refcount Edje_Refcount;
struct _Edje_List_Refcount struct _Edje_Refcount
{ {
EINA_REFCOUNT; EINA_REFCOUNT;
Eina_List *lookup; Edje *ed;
}; };
static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata); static Eina_Bool _edje_color_class_list_foreach(const Eina_Hash *hash, const void *key, void *data, void *fdata);
@ -140,94 +140,116 @@ _edje_user_def_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *child EINA_U
} }
static void static void
_edje_class_member_direct_del(const char *class, Edje_List_Refcount *lookup, Eina_Hash *hash) _edje_class_member_add(Edje *ed, Eina_Hash **ghash, const char *class)
{ {
Eina_List *members; Eina_Hash *members;
Edje_Refcount *er;
if (!lookup) return; if ((!ed) || (!ghash) || (!class)) return;
members = eina_hash_find(hash, class);
if (members)
members = eina_list_remove_list(members, lookup->lookup);
eina_hash_set(hash, class, members);
free(lookup);
}
static void if (!*ghash) *ghash = eina_hash_string_superfast_new(NULL);
_edje_class_member_add(Edje *ed, Eina_Hash **ehash, Eina_Hash **ghash, const char *class)
{
Edje_List_Refcount *lookup;
Eina_List *members;
if ((!ed) || (!ehash) || (!ghash) || (!class)) return; members = eina_hash_find(*ghash, class);
if (!members)
lookup = eina_hash_find(*ehash, class);
if (lookup)
{ {
EINA_REFCOUNT_REF(lookup); members = eina_hash_pointer_new(NULL);
return; eina_hash_add(*ghash, class, members);
} }
lookup = malloc(sizeof (Edje_List_Refcount)); er = eina_hash_find(members, &ed);
if (!lookup) return; if (!er)
EINA_REFCOUNT_INIT(lookup); {
er = calloc(1, sizeof (Edje_Refcount));
er->ed = ed;
EINA_REFCOUNT_INIT(er);
ed->all_part_change = EINA_TRUE; eina_hash_add(members, &er->ed, er);
/* Get members list */ }
members = eina_hash_find(*ghash, class); else
{
/* Update the member list */ EINA_REFCOUNT_REF(er);
lookup->lookup = members = eina_list_prepend(members, ed); }
/* Don't loose track of members list */
if (!*ehash)
*ehash = eina_hash_string_small_new(NULL);
eina_hash_add(*ehash, class, lookup);
/* Reset the member list to the right pointer */
if (!*ghash)
*ghash = eina_hash_string_superfast_new(NULL);
eina_hash_set(*ghash, class, members);
} }
static void static void
_edje_class_member_del(Eina_Hash **ehash, Eina_Hash **ghash, const char *class) _edje_class_member_del(Edje *ed, Eina_Hash **ghash, const char *class)
{ {
Edje_List_Refcount *lookup; Edje_Refcount *lookup;
Eina_List *members; Eina_Hash *members;
if ((!ehash) || (!ghash) || (!class)) return; if ((!ed) || (!ghash) || (!class)) return;
members = eina_hash_find(*ghash, class); members = eina_hash_find(*ghash, class);
if (!members) return; if (!members) return;
lookup = eina_hash_find(*ehash, class); lookup = eina_hash_find(members, class);
if (!lookup) return; if (!lookup) return;
EINA_REFCOUNT_UNREF(lookup) EINA_REFCOUNT_UNREF(lookup)
{ {
members = eina_list_remove_list(members, lookup->lookup); eina_hash_del(members, &lookup->ed, lookup);
eina_hash_set(*ghash, class, members);
eina_hash_del(*ehash, class, lookup);
free(lookup); free(lookup);
}
}
static Eina_Bool if (eina_hash_population(members) == 0)
member_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) {
{ eina_hash_del(*ghash, class, members);
eina_list_free(data); eina_hash_free(members);
return EINA_TRUE; }
}
} }
static void static void
_edje_class_members_free(Eina_Hash **ghash) _edje_class_members_free(Eina_Hash **ghash)
{ {
Eina_Iterator *it;
Eina_Hash *members;
if (!ghash || !*ghash) return; if (!ghash || !*ghash) return;
eina_hash_foreach(*ghash, member_list_free, NULL);
it = eina_hash_iterator_data_new(*ghash);
EINA_ITERATOR_FOREACH(it, members)
{
Eina_Iterator *it2;
Edje_Refcount *er;
it2 = eina_hash_iterator_data_new(members);
EINA_ITERATOR_FOREACH(it2, er)
free(er);
eina_iterator_free(it2);
eina_hash_free(members);
}
eina_iterator_free(it);
eina_hash_free(*ghash); eina_hash_free(*ghash);
*ghash = NULL; *ghash = NULL;
} }
static void
_edje_class_members_clean(Edje *ed, Eina_Hash *ghash)
{
Eina_Iterator *it;
Eina_Hash *members;
if (!ed || !ghash) return ;
it = eina_hash_iterator_data_new(ghash);
EINA_ITERATOR_FOREACH(it, members)
{
Edje_Refcount *lookup;
lookup = eina_hash_find(members, &ed);
if (!lookup) continue;
EINA_REFCOUNT_UNREF(lookup)
{
eina_hash_del(members, &lookup->ed, lookup);
free(lookup);
}
}
eina_iterator_free(it);
}
/************************** API Routines **************************/ /************************** API Routines **************************/
#define FASTFREEZE 1 #define FASTFREEZE 1
@ -478,7 +500,9 @@ _edje_object_thaw(Eo *obj EINA_UNUSED, Edje *ed)
EAPI Eina_Bool EAPI Eina_Bool
edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3) edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2, int g2, int b2, int a2, int r3, int g3, int b3, int a3)
{ {
Eina_List *members; Eina_Hash *members;
Eina_Iterator *it;
Edje_Refcount *er;
Edje_Color_Class *cc; Edje_Color_Class *cc;
if (!color_class) return EINA_FALSE; if (!color_class) return EINA_FALSE;
@ -528,20 +552,18 @@ edje_color_class_set(const char *color_class, int r, int g, int b, int a, int r2
cc->a3 = a3; cc->a3 = a3;
members = eina_hash_find(_edje_color_class_member_hash, color_class); members = eina_hash_find(_edje_color_class_member_hash, color_class);
while (members) it = eina_hash_iterator_data_new(members);
EINA_ITERATOR_FOREACH(it, er)
{ {
Edje *ed; er->ed->dirty = EINA_TRUE;
er->ed->recalc_call = EINA_TRUE;
ed = eina_list_data_get(members);
ed->dirty = EINA_TRUE;
ed->recalc_call = EINA_TRUE;
#ifdef EDJE_CALC_CACHE #ifdef EDJE_CALC_CACHE
ed->all_part_change = EINA_TRUE; er->ed->all_part_change = EINA_TRUE;
#endif #endif
_edje_recalc(ed); _edje_recalc(er->ed);
_edje_emit(ed, "color_class,set", color_class); _edje_emit(er->ed, "color_class,set", color_class);
members = eina_list_next(members);
} }
eina_iterator_free(it);
return EINA_TRUE; return EINA_TRUE;
} }
@ -583,7 +605,9 @@ void
edje_color_class_del(const char *color_class) edje_color_class_del(const char *color_class)
{ {
Edje_Color_Class *cc; Edje_Color_Class *cc;
Eina_List *members; Eina_Hash *members;
Eina_Iterator *it;
Edje_Refcount *er;
if (!color_class) return; if (!color_class) return;
@ -595,20 +619,18 @@ edje_color_class_del(const char *color_class)
free(cc); free(cc);
members = eina_hash_find(_edje_color_class_member_hash, color_class); members = eina_hash_find(_edje_color_class_member_hash, color_class);
while (members) it = eina_hash_iterator_data_new(members);
EINA_ITERATOR_FOREACH(it, er)
{ {
Edje *ed; er->ed->dirty = EINA_TRUE;
er->ed->recalc_call = EINA_TRUE;
ed = eina_list_data_get(members);
ed->dirty = EINA_TRUE;
ed->recalc_call = EINA_TRUE;
#ifdef EDJE_CALC_CACHE #ifdef EDJE_CALC_CACHE
ed->all_part_change = EINA_TRUE; er->ed->all_part_change = EINA_TRUE;
#endif #endif
_edje_recalc(ed); _edje_recalc(er->ed);
_edje_emit(ed, "color_class,del", color_class); _edje_emit(er->ed, "color_class,del", color_class);
members = eina_list_next(members);
} }
eina_iterator_free(it);
} }
Eina_List * Eina_List *
@ -782,7 +804,9 @@ edje_object_color_class_del(Evas_Object *obj, const char *color_class)
EAPI Eina_Bool EAPI Eina_Bool
edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size) edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size size)
{ {
Eina_List *members; Eina_Hash *members;
Eina_Iterator *it;
Edje_Refcount *er;
Edje_Text_Class *tc; Edje_Text_Class *tc;
if (!text_class) return EINA_FALSE; if (!text_class) return EINA_FALSE;
@ -820,21 +844,19 @@ edje_text_class_set(const char *text_class, const char *font, Evas_Font_Size siz
/* Tell all members of the text class to recalc */ /* Tell all members of the text class to recalc */
members = eina_hash_find(_edje_text_class_member_hash, text_class); members = eina_hash_find(_edje_text_class_member_hash, text_class);
while (members) it = eina_hash_iterator_data_new(members);
EINA_ITERATOR_FOREACH(it, er)
{ {
Edje *ed; er->ed->dirty = EINA_TRUE;
er->ed->recalc_call = EINA_TRUE;
ed = eina_list_data_get(members); _edje_textblock_styles_cache_free(er->ed, text_class);
ed->dirty = EINA_TRUE; _edje_textblock_style_all_update(er->ed);
ed->recalc_call = EINA_TRUE;
_edje_textblock_styles_cache_free(ed, text_class);
_edje_textblock_style_all_update(ed);
#ifdef EDJE_CALC_CACHE #ifdef EDJE_CALC_CACHE
ed->text_part_change = EINA_TRUE; er->ed->text_part_change = EINA_TRUE;
#endif #endif
_edje_recalc(ed); _edje_recalc(er->ed);
members = eina_list_next(members);
} }
eina_iterator_free(it);
return EINA_TRUE; return EINA_TRUE;
} }
@ -842,7 +864,9 @@ void
edje_text_class_del(const char *text_class) edje_text_class_del(const char *text_class)
{ {
Edje_Text_Class *tc; Edje_Text_Class *tc;
Eina_List *members; Eina_Hash *members;
Eina_Iterator *it;
Edje_Refcount *er;
if (!text_class) return; if (!text_class) return;
@ -855,20 +879,18 @@ edje_text_class_del(const char *text_class)
free(tc); free(tc);
members = eina_hash_find(_edje_text_class_member_hash, text_class); members = eina_hash_find(_edje_text_class_member_hash, text_class);
while (members) it = eina_hash_iterator_data_new(members);
EINA_ITERATOR_FOREACH(it, er)
{ {
Edje *ed; er->ed->dirty = EINA_TRUE;
_edje_textblock_styles_cache_free(er->ed, text_class);
ed = eina_list_data_get(members); _edje_textblock_style_all_update(er->ed);
ed->dirty = EINA_TRUE;
_edje_textblock_styles_cache_free(ed, text_class);
_edje_textblock_style_all_update(ed);
#ifdef EDJE_CALC_CACHE #ifdef EDJE_CALC_CACHE
ed->text_part_change = EINA_TRUE; er->ed->text_part_change = EINA_TRUE;
#endif #endif
_edje_recalc(ed); _edje_recalc(er->ed);
members = eina_list_next(members);
} }
eina_iterator_free(it);
} }
Eina_List * Eina_List *
@ -4674,13 +4696,7 @@ _edje_color_class_find(const Edje *ed, const char *color_class)
void void
_edje_color_class_member_add(Edje *ed, const char *color_class) _edje_color_class_member_add(Edje *ed, const char *color_class)
{ {
_edje_class_member_add(ed, &ed->members.color_class, &_edje_color_class_member_hash, color_class); _edje_class_member_add(ed, &_edje_color_class_member_hash, color_class);
}
void
_edje_color_class_member_direct_del(const char *color_class, void *l)
{
_edje_class_member_direct_del(color_class, l, _edje_color_class_member_hash);
} }
void void
@ -4688,16 +4704,19 @@ _edje_color_class_member_del(Edje *ed, const char *color_class)
{ {
if ((!ed) || (!color_class)) return; if ((!ed) || (!color_class)) return;
_edje_class_member_del(&ed->members.color_class, &_edje_color_class_member_hash, color_class); _edje_class_member_del(ed, &_edje_color_class_member_hash, color_class);
} }
void void
_edje_color_class_members_free(void) _edje_color_class_members_free(void)
{ {
if (!_edje_color_class_member_hash) return; _edje_class_members_free(&_edje_color_class_member_hash);
eina_hash_foreach(_edje_color_class_member_hash, member_list_free, NULL); }
eina_hash_free(_edje_color_class_member_hash);
_edje_color_class_member_hash = NULL; void
_edje_color_class_member_clean(Edje *ed)
{
_edje_class_members_clean(ed, _edje_color_class_member_hash);
} }
static Eina_Bool static Eina_Bool
@ -4745,17 +4764,10 @@ _edje_text_class_find(Edje *ed, const char *text_class)
return eina_hash_find(_edje_text_class_hash, text_class); return eina_hash_find(_edje_text_class_hash, text_class);
} }
void
_edje_text_class_member_direct_del(const char *text_class,
void *l)
{
_edje_class_member_direct_del(text_class, l, _edje_text_class_member_hash);
}
void void
_edje_text_class_member_add(Edje *ed, const char *text_class) _edje_text_class_member_add(Edje *ed, const char *text_class)
{ {
_edje_class_member_add(ed, &ed->members.text_class, &_edje_text_class_member_hash, text_class); _edje_class_member_add(ed, &_edje_text_class_member_hash, text_class);
} }
void void
@ -4763,7 +4775,7 @@ _edje_text_class_member_del(Edje *ed, const char *text_class)
{ {
if ((!ed) || (!text_class)) return; if ((!ed) || (!text_class)) return;
_edje_class_member_del(&ed->members.text_class, &_edje_text_class_member_hash, text_class); _edje_class_member_del(ed, &_edje_text_class_member_hash, text_class);
} }
void void
@ -4772,6 +4784,12 @@ _edje_text_class_members_free(void)
_edje_class_members_free(&_edje_text_class_member_hash); _edje_class_members_free(&_edje_text_class_member_hash);
} }
void
_edje_text_class_members_clean(Edje *ed)
{
_edje_class_members_clean(ed, _edje_text_class_member_hash);
}
static Eina_Bool static Eina_Bool
text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED) text_class_hash_list_free(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
{ {