edje: fix an overflow issue for state values 61/193061/1
authorYoungbok Shin <youngb.shin@samsung.com>
Wed, 14 Nov 2018 07:43:13 +0000 (16:43 +0900)
committerYoungbok Shin <youngb.shin@samsung.com>
Wed, 14 Nov 2018 07:47:03 +0000 (16:47 +0900)
Summary:
Whenever _edje_recalc_do() is called, a state value of
Edje structure is increased. This increased value will be stored
in Edje_Real_Part and Edje_Real_Part_State for calculation optimazation.
But, once the state value is overflowed, it ruins calculation logic.
@fix

Test Plan:
Run an Edje file which has infinite animation for over an hour.
I'll attach an example to phab.

Reviewers: raster, cedric, woohyun, Hermet

Reviewed By: Hermet

Subscribers: #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D7264

Change-Id: If4d941fa9e5496fdd694625d7f4c1f36b2345abb
Signed-off-by: Youngbok Shin <youngb.shin@samsung.com>
src/lib/edje/edje_calc.c

index 095a702..340cef7 100644 (file)
@@ -943,6 +943,9 @@ _edje_recalc_do(Edje *ed)
 {
    unsigned short i;
    Eina_Bool need_calc;
+#ifdef EDJE_CALC_CACHE
+   Eina_Bool need_reinit_state = EINA_FALSE;
+#endif
 
 // XXX: dont need this with current smart calc infra. remove me later
 //   ed->postponed = EINA_FALSE;
@@ -951,6 +954,16 @@ _edje_recalc_do(Edje *ed)
    if (!ed->dirty) return;
    ed->dirty = EINA_FALSE;
    ed->state++;
+
+   /* Avoid overflow problem */
+   if (ed->state == USHRT_MAX)
+     {
+        ed->state = 0;
+#ifdef EDJE_CALC_CACHE
+        need_reinit_state = EINA_TRUE;
+#endif
+     }
+
    for (i = 0; i < ed->table_parts_size; i++)
      {
         Edje_Real_Part *ep;
@@ -958,6 +971,15 @@ _edje_recalc_do(Edje *ed)
         ep = ed->table_parts[i];
         ep->calculated = FLAG_NONE; // FIXME: this is dubious (see below)
         ep->calculating = FLAG_NONE;
+#ifdef EDJE_CALC_CACHE
+        if (need_reinit_state)
+          {
+             ep->state = 0;
+             ep->param1.state = 0;
+             if (ep->param2)
+               ep->param2->state = 0;
+          }
+#endif
      }
    for (i = 0; i < ed->table_parts_size; i++)
      {