e_hwc_windows: fix the problem that window located under 24 depth window is visible 61/298861/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 13 Sep 2023 12:56:48 +0000 (21:56 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Thu, 14 Sep 2023 09:48:59 +0000 (18:48 +0900)
if tdm backend set target buffer to upper hw layer that used device type window,
window located under 24 depth window can be visible when evas object is visible.

so to fix the problem, hwc set transparent object when bottom ui window is device type
and target window is enabled.

Change-Id: I4b7d708708fe534bec4974b32f8a6a4ff41d750f

src/bin/e_hwc.h
src/bin/e_hwc_window.c
src/bin/e_hwc_window.h
src/bin/e_hwc_windows.c

index be96bf7..853cd99 100644 (file)
@@ -203,6 +203,8 @@ struct _E_Hwc
    Eina_List           *sync_callback_list;
 
    int                  gbm_format;
+
+   E_Hwc_Window        *below_transparent_window;
 };
 
 E_API extern int E_EVENT_HWC_ACTIVE;
index 2f11ce4..ac0b25f 100644 (file)
@@ -664,6 +664,7 @@ _e_hwc_window_del(E_Hwc_Window *hwc_window)
         hwc_window->queue = NULL;
      }
 
+   e_hwc_window_below_transparent_obj_set(hwc_window, EINA_FALSE);
    e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE, EINA_TRUE);
 
    e_object_del(E_OBJECT(hwc_window));
@@ -3203,3 +3204,96 @@ e_hwc_window_presentation_callback_call(E_Hwc_Window *hwc_window)
 
    return EINA_TRUE;
 }
+
+static void
+_e_hwc_window_below_transparent_obj_map_apply(E_Hwc_Window *hwc_window)
+{
+   E_Map *map;
+   int w, h;
+
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window->below_transparent_obj);
+
+   map = e_map_new();
+   EINA_SAFETY_ON_NULL_RETURN(map);
+
+   e_map_util_points_populate_from_object_full(map, hwc_window->ec->frame, 0);
+   e_map_util_points_color_set(map, 255, 255, 255, 255);
+   evas_object_geometry_get(hwc_window->below_transparent_obj, NULL, NULL, &w, &h);
+   e_map_point_image_uv_set(map, 0, 0, 0);
+   e_map_point_image_uv_set(map, 1, w, 0);
+   e_map_point_image_uv_set(map, 2, w, h);
+   e_map_point_image_uv_set(map, 3, 0, h);
+
+   e_comp_object_map_set(hwc_window->below_transparent_obj, map);
+   e_comp_object_map_enable_set(hwc_window->below_transparent_obj, EINA_TRUE);
+
+   e_map_free(map);
+}
+
+static void
+_e_hwc_window_below_transparent_obj_cb_resize(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (!(hwc_window = data)) return;
+
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window->ec);
+
+   _e_hwc_window_below_transparent_obj_map_apply(hwc_window);
+}
+
+EINTERN void
+e_hwc_window_below_transparent_obj_set(E_Hwc_Window *hwc_window, Eina_Bool set)
+{
+   Evas_Object *below_transparent_obj;
+
+   EINA_SAFETY_ON_NULL_RETURN(hwc_window);
+
+   if (set)
+     {
+        EINA_SAFETY_ON_NULL_RETURN(hwc_window->ec);
+
+        if (hwc_window->below_transparent_obj) return;
+
+        below_transparent_obj = evas_object_rectangle_add(e_comp->evas);
+        EINA_SAFETY_ON_NULL_RETURN(below_transparent_obj);
+
+        evas_object_pass_events_set(below_transparent_obj, EINA_TRUE);
+
+        evas_object_layer_set(below_transparent_obj, evas_object_layer_get(hwc_window->ec->frame));
+        evas_object_render_op_set(below_transparent_obj, EVAS_RENDER_COPY);
+
+        evas_object_color_set(below_transparent_obj, 0, 0, 0, 0);
+        evas_object_move(below_transparent_obj, hwc_window->ec->x, hwc_window->ec->y);
+        evas_object_resize(below_transparent_obj, 1, 1);
+        evas_object_name_set(below_transparent_obj, "hwc_below_transparent_obj");
+
+        hwc_window->below_transparent_obj = below_transparent_obj;
+
+        _e_hwc_window_below_transparent_obj_map_apply(hwc_window);
+
+        evas_object_smart_member_add(hwc_window->below_transparent_obj, hwc_window->ec->frame);
+        evas_object_lower(hwc_window->below_transparent_obj);
+        evas_object_show(hwc_window->below_transparent_obj);
+
+        evas_object_event_callback_add(hwc_window->ec->frame, EVAS_CALLBACK_RESIZE,
+                                       _e_hwc_window_below_transparent_obj_cb_resize,
+                                       hwc_window);
+
+        EHWINF("Set below_transparent_obj", hwc_window->ec, hwc_window->hwc, hwc_window);
+     }
+   else
+     {
+        if (!hwc_window->below_transparent_obj) return;
+
+        evas_object_smart_member_del(hwc_window->below_transparent_obj);
+        E_FREE_FUNC(hwc_window->below_transparent_obj, evas_object_del);
+
+        if (hwc_window->ec)
+          evas_object_event_callback_del_full(hwc_window->ec->frame, EVAS_CALLBACK_RESIZE,
+                                              _e_hwc_window_below_transparent_obj_cb_resize,
+                                              hwc_window);
+
+        EHWINF("Unset below_transparent_obj", hwc_window->ec, hwc_window->hwc, hwc_window);
+     }
+}
index ffda21f..3ce0fee 100644 (file)
@@ -164,6 +164,8 @@ struct _E_Hwc_Window
 
    E_Zone                        *zone;
    E_Object_Delfn                *zone_delfn;
+
+   Evas_Object                   *below_transparent_obj;
 };
 
 struct _E_Hwc_Window_Target
@@ -272,5 +274,7 @@ EINTERN Eina_Bool                 e_hwc_window_presentation_callback_pending_tak
 EINTERN Eina_Bool                 e_hwc_window_presentation_callback_take(E_Hwc_Window *hwc_window, E_Hwc_Presentation_Callback_List *src_list);
 EINTERN Eina_Bool                 e_hwc_window_presentation_callback_call(E_Hwc_Window *hwc_window);
 
+EINTERN void                      e_hwc_window_below_transparent_obj_set(E_Hwc_Window *hwc_window, Eina_Bool set);
+
 #endif // E_HWC_WINDOW_H
 #endif
index 88d27f4..a6c84eb 100644 (file)
@@ -2988,6 +2988,73 @@ _e_hwc_windows_buffer_clear(E_Hwc *hwc, tbm_surface_h tsurface)
    tbm_surface_unmap(tsurface);
 }
 
+static E_Hwc_Window *
+_e_hwc_windows_visible_ui_window_bottom_get(E_Hwc *hwc)
+{
+   E_Hwc_Window *hwc_window;
+   Eina_List *l;
+
+   EINA_LIST_REVERSE_FOREACH(hwc->visible_windows, l, hwc_window)
+     {
+        if (hwc_window->state == E_HWC_WINDOW_STATE_VIDEO)
+          continue;
+
+        return hwc_window;
+     }
+
+   return NULL;
+}
+
+static E_Hwc_Window *
+_e_hwc_windows_below_transparent_window_find(E_Hwc *hwc)
+{
+   E_Hwc_Window *hwc_window;
+
+   if (hwc->hwc_mode != E_HWC_MODE_HYBRID) return NULL;
+
+   hwc_window = _e_hwc_windows_visible_ui_window_bottom_get(hwc);
+   if (!hwc_window) return NULL;
+
+   if (hwc_window->state != E_HWC_WINDOW_STATE_DEVICE) return NULL;
+   if (!hwc_window->ec) return NULL;
+   if (hwc_window->ec->argb) return NULL;
+
+   return hwc_window;
+}
+
+static void
+_e_hwc_windows_below_transparent_window_update(E_Hwc *hwc)
+{
+   E_Hwc_Window *hwc_window;
+
+   hwc_window = _e_hwc_windows_below_transparent_window_find(hwc);
+   if (hwc_window)
+     {
+        if (hwc->below_transparent_window == hwc_window)
+          return;
+
+        if (hwc->below_transparent_window)
+          {
+             e_hwc_window_below_transparent_obj_set(hwc->below_transparent_window, EINA_FALSE);
+             e_hwc_window_unref(hwc->below_transparent_window);
+             hwc->below_transparent_window = NULL;
+          }
+
+        e_hwc_window_below_transparent_obj_set(hwc_window, EINA_TRUE);
+        e_hwc_window_ref(hwc_window);
+        hwc->below_transparent_window = hwc_window;
+     }
+   else
+     {
+        if (!hwc->below_transparent_window)
+          return;
+
+        e_hwc_window_below_transparent_obj_set(hwc->below_transparent_window, EINA_FALSE);
+        e_hwc_window_unref(hwc->below_transparent_window);
+        hwc->below_transparent_window = NULL;
+     }
+}
+
 /* evaluate the hwc_windows */
 static Eina_Bool
 _e_hwc_windows_evaluate(E_Hwc *hwc, E_Output_Display_Mode display_mode)
@@ -3049,6 +3116,8 @@ _e_hwc_windows_evaluate(E_Hwc *hwc, E_Output_Display_Mode display_mode)
         _e_hwc_windows_target_state_set(hwc->target_hwc_window, E_HWC_WINDOW_STATE_NONE);
      }
 
+   _e_hwc_windows_below_transparent_window_update(hwc);
+
    /* skip the target_buffer when the window is on trainsition of the composition */
    if ((hwc_mode != E_HWC_MODE_FULL) &&
        (!hwc->pp_set) && (display_mode != E_OUTPUT_DISPLAY_MODE_MIRROR) &&