evas map: calc map geometry when it is out of screen
authorShinwoo Kim <cinoo.kim@samsung.com>
Tue, 27 Nov 2018 02:21:51 +0000 (11:21 +0900)
committerHermet Park <hermetpark@gmail.com>
Wed, 5 Dec 2018 05:43:46 +0000 (14:43 +0900)
Summary:
The map geometry(cur.map->normal_geometry) is calculated only if
evas_render_updates_internal_loop calls evas_render_mapped as below.

evas_render_mapped
   -> evas_object_map_update
   -> evas_object_map_update
   -> _evas_map_calc_map_geometry

If the mapped object is not on screen, then evas_render_updates_internal_loop
does not call evas_render_mapped, because the mapped object is not active.

The mapped object is not active(i.e. is_active is  0) always because cache.clip
data including visilbe and geometry is not updated after the object goes out
of screen.

Usually the unmapped object updates its cache.clip data with updated geometry
even though it is out of screen as below.

_efl_canvas_object_efl_gfx_entity_position_set
   -> evas_object_recalc_clippees
   -> evas_object_clip_recalc
   -> evas_object_clip_recalc_do

So the mapped object geometry(cur.map->normal_geometry) should be updated in
evas_object_clip_recalc_do if it is out of screen.

Test Plan:
Sample code

{F3455674}

{F3455673}

{F3455672}

{F3455671}

Reviewers: Hermet, jypark

Subscribers: cedric, #reviewers, #committers

Tags: #efl

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

src/lib/evas/canvas/evas_object_main.c

index e0f02da..69e2fcf 100644 (file)
@@ -364,11 +364,29 @@ evas_object_clip_recalc_do(Evas_Object_Protected_Data *obj, Evas_Object_Protecte
    int cx, cy, cw, ch, cr, cg, cb, ca;
    int nx, ny, nw, nh, nr, ng, nb, na;
    Eina_Bool cvis, nvis;
+   Evas_Public_Data *e;
 
    evas_object_coords_recalc(obj->object, obj);
 
    if (EINA_UNLIKELY((!!obj->map) && (obj->map->cur.map) && (obj->map->cur.usemap)))
      {
+        e = obj->layer->evas;
+        if (!evas_object_is_active(obj->object, obj) &&
+            ((obj->map->cur.map->normal_geometry.x +
+              obj->map->cur.map->normal_geometry.w <= 0) ||
+             (obj->map->cur.map->normal_geometry.y +
+              obj->map->cur.map->normal_geometry.h <= 0) ||
+             (obj->map->cur.map->normal_geometry.x >= e->output.w) ||
+              obj->map->cur.map->normal_geometry.y >= e->output.h))
+          {
+             /* out of screen, but need to calc map geometry to update cache */
+             cy = obj->map->cur.map->normal_geometry.y;
+             cx = obj->map->cur.map->normal_geometry.x;
+             cw = obj->cur->geometry.w;
+             ch = obj->cur->geometry.h;
+             evas_object_map_update(obj->object, cx, cy, cw, ch, cw, ch);
+          }
+
         cx = obj->map->cur.map->normal_geometry.x;
         cy = obj->map->cur.map->normal_geometry.y;
         cw = obj->map->cur.map->normal_geometry.w;