e_comp_object: convert damage according to evas_map coordinate 34/243434/3 accepted/tizen/unified/20200908.021114 submit/tizen/20200907.115522 submit/tizen/20200907.215450
authorChangyeon Lee <cyeon.lee@samsung.com>
Mon, 7 Sep 2020 09:58:18 +0000 (18:58 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Mon, 7 Sep 2020 11:00:15 +0000 (20:00 +0900)
for example size of evas_object is 100x100 and evas_object is mapped by 200x200 size,
enlgithenment add damage coordinate(50x50+0+0) base on 100x100 size.
it seems that current efl add damage (50x50+0+0) to gl with eglSetDamageRegionKHR.
but damage of gl coordinate should be (100x100+0+0).
so this patch convert damage according to evas_map coordinate.

Change-Id: I53d3f4323125a95b627e120e29cb1a0361fdb372

src/bin/e_comp_object.c

index 4e64d9f..a31a802 100644 (file)
@@ -713,6 +713,93 @@ _e_comp_object_map_transform_rect(E_Client *ec, int sx, int sy, int sw, int sh,
    if (dh) *dh = MAX(y1, y2) - my;
 }
 
+static void
+_e_comp_object_map_damage_transform_rect(E_Client *ec, Evas_Map *m, int sx, int sy, int sw, int sh,
+                                         int *dx, int *dy, int *dw, int *dh)
+{
+   E_Util_Transform_Rect rect = {sx, sy, sw, sh};
+   E_Util_Transform_Rect_Vertex sv, dv;
+   int bw, bh;
+   int i;
+
+   e_pixmap_size_get(ec->pixmap, &bw, &bh);
+
+   sv = e_util_transform_rect_to_vertices(&rect);
+
+   for (i = 0; i < 4; i++)
+     {
+        double x = 0.0, y = 0.0;
+
+        evas_map_coords_get(m, sv.vertices[i].vertex[0], sv.vertices[i].vertex[1], &x, &y, 0);
+
+        /* if evas decide coordinate is outside of map, it returns (0, 0)
+           in this case, full damage is added.
+         */
+        if ((i != 0) && (x == 0.0) && (y == 0.0))
+          goto full;
+
+        dv.vertices[i].vertex[0] = x;
+        dv.vertices[i].vertex[1] = y;
+        dv.vertices[i].vertex[2] = 1.0;
+        dv.vertices[i].vertex[3] = 1.0;
+     }
+
+   rect = e_util_transform_vertices_to_rect(&dv);
+
+   if (dx) *dx = rect.x;
+   if (dy) *dy = rect.y;
+   if (dw) *dw = rect.w;
+   if (dh) *dh = rect.h;
+
+   return;
+
+full:
+   if (dx) *dx = 0;
+   if (dy) *dy = 0;
+   if (dw) *dw = bw;
+   if (dh) *dh = bh;
+
+   return;
+}
+
+static Evas_Map *
+_e_comp_object_map_damage_transform_get(E_Client *ec)
+{
+   const Evas_Map *m;
+   Evas_Map *m2 = NULL;
+   int bw, bh;
+   int i;
+
+   if (!evas_object_map_enable_get(ec->frame))
+     return NULL;
+
+   m = evas_object_map_get(ec->frame);
+   if (!m)
+     return NULL;
+
+   e_pixmap_size_get(ec->pixmap, &bw, &bh);
+   if ((bw == 0) || (bh == 0))
+     return NULL;
+
+   m2 = evas_map_new(4);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(m2, NULL);
+
+   evas_map_point_coord_set(m2, 0, 0, 0, 0);
+   evas_map_point_coord_set(m2, 1, bw, 0, 0);
+   evas_map_point_coord_set(m2, 2, bw, bh, 0);
+   evas_map_point_coord_set(m2, 3, 0, bh, 0);
+
+   for (i = 0; i < 4; i++)
+     {
+        int map_x, map_y;
+
+        evas_map_point_coord_get(m, i, &map_x, &map_y, NULL);
+        evas_map_point_image_uv_set(m2, i, map_x, map_y);
+     }
+
+   return m2;
+}
+
 /////////////////////////////////////
 
 /* handle evas mouse-in events on client object */
@@ -4664,6 +4751,7 @@ e_comp_object_dirty(Evas_Object *obj)
    Evas_Object *o;
    int w, h, tw, th;
    Eina_Bool dirty, visible;
+   Evas_Map *m = NULL;
 
    API_ENTRY;
    if (cw->external_content) return;
@@ -4702,6 +4790,7 @@ e_comp_object_dirty(Evas_Object *obj)
 
    e_comp_object_native_surface_set(obj, 1);
 
+   m = _e_comp_object_map_damage_transform_get(cw->ec);
    it = eina_tiler_iterator_new(cw->updates);
    EINA_ITERATOR_FOREACH(it, rect)
      {
@@ -4709,13 +4798,24 @@ e_comp_object_dirty(Evas_Object *obj)
          * of evas engine and doesn't convert damage according to evas_map.
          * so damage of evas_object_image use surface coordinate.
          */
-        evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
+        if (m)
+          {
+             int damage_x, damage_y, damage_w, damage_h;
+
+             _e_comp_object_map_damage_transform_rect(cw->ec, m, rect->x, rect->y, rect->w, rect->h,
+                                                      &damage_x, &damage_y, &damage_w, &damage_h);
+             evas_object_image_data_update_add(cw->obj, damage_x, damage_y, damage_w, damage_h);
+          }
+        else
+          evas_object_image_data_update_add(cw->obj, rect->x, rect->y, rect->w, rect->h);
+
         EINA_LIST_FOREACH(cw->obj_mirror, ll, o)
           evas_object_image_data_update_add(o, rect->x, rect->y, rect->w, rect->h);
         if (cw->pending_updates)
           eina_tiler_rect_add(cw->pending_updates, rect);
      }
    eina_iterator_free(it);
+   if (m) evas_map_free(m);
    if (cw->pending_updates)
      eina_tiler_clear(cw->updates);
    else