e_comp_object: defer move,resize,clear when render_update_lock is enabled 97/284897/1 accepted/tizen/7.0/unified/20221201.164843
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 2 Nov 2022 10:46:32 +0000 (19:46 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Wed, 30 Nov 2022 07:28:50 +0000 (16:28 +0900)
there is a visual bug when client move and resize buffer when render_update_lock
is enabled because evas_object is resized and moved but buffer of client is not
updated. (buffer of render_update_lock is fill to evas_image_object)
and buffer of render_update_lock is cleared in comp_object if e_comp_object_clear
is called so defer clear of comp_object until render_update_lock is disabled.

Change-Id: Iabe67a558c7ea62d0f84cd6c041f2f24b32a3c1b

src/bin/e_comp_object.c

index 183b56f4e05bcb804771774b5d52c1d9055843ad..f272bdf1eb953f7f3fc020c641851716c0e92d2a 100644 (file)
@@ -168,8 +168,15 @@ typedef struct _E_Comp_Object
    E_Comp_Image_Filter  image_filter;
    Eina_Bool            set_mouse_callbacks;
 
-   int                  render_update_lock;
-   E_Comp_Wl_Buffer_Ref render_update_lock_buffer_ref;
+   struct
+     {
+        int lock;
+        E_Comp_Wl_Buffer_Ref buffer_ref;
+        Eina_Bool            pending_move_set;
+        int                  pending_move_x, pending_move_y;
+        Eina_Bool            pending_resize_set;
+        int                  pending_resize_w, pending_resize_h;
+     } render_update_lock;
 } E_Comp_Object;
 
 typedef struct _E_Input_Rect_Data
@@ -1523,6 +1530,14 @@ _e_comp_intercept_move(void *data, Evas_Object *obj, int x, int y)
    E_Comp_Object *cw = data;
    int ix, iy, fx, fy;
 
+   if (cw->render_update_lock.lock)
+     {
+        cw->render_update_lock.pending_move_x = x;
+        cw->render_update_lock.pending_move_y = y;
+        cw->render_update_lock.pending_move_set = EINA_TRUE;
+        return;
+     }
+
    if ((e_pixmap_type_get(cw->ec->pixmap) != E_PIXMAP_TYPE_EXT_OBJECT) &&
        (e_pixmap_usable_get(cw->ec->pixmap)) &&
        (cw->external_content))
@@ -1641,6 +1656,14 @@ _e_comp_intercept_resize(void *data, Evas_Object *obj, int w, int h)
    E_Comp_Object *cw = data;
    int pw = 0, ph = 0, fw, fh, iw, ih, prev_w, prev_h, x, y;
 
+   if (cw->render_update_lock.lock)
+     {
+        cw->render_update_lock.pending_resize_w = w;
+        cw->render_update_lock.pending_resize_h = h;
+        cw->render_update_lock.pending_resize_set = EINA_TRUE;
+        return;
+     }
+
    if (!e_util_strcmp("input_panel_surface", cw->ec->icccm.window_role))
      {
         e_client_size_set(cw->ec, w, h);
@@ -3376,11 +3399,11 @@ _e_comp_smart_del(Evas_Object *obj)
         cw->tbm_surface = NULL;
      }
 
-   if (cw->render_update_lock_buffer_ref.buffer)
+   if (cw->render_update_lock.buffer_ref.buffer)
      {
         ELOGF("COMP", "Clear buffer_ref of render_update_lock:%d",
-              cw->ec, cw->render_update_lock);
-        e_comp_wl_buffer_reference(&cw->render_update_lock_buffer_ref, NULL);
+              cw->ec, cw->render_update_lock.lock);
+        e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
      }
 
    e_comp_object_render_update_del(cw->smart_obj);
@@ -4568,7 +4591,7 @@ e_comp_object_render_update_add(Evas_Object *obj)
    API_ENTRY;
 
    if (cw->ec->input_only || (!cw->updates) || (!cw->redirected)) return;
-   if (cw->render_update_lock) return;
+   if (cw->render_update_lock.lock) return;
    if (e_object_is_del(E_OBJECT(cw->ec)))
      CRI("CAN'T RENDER A DELETED CLIENT!!! ec:%p", cw->ec);
    if (!e_pixmap_usable_get(cw->ec->pixmap)) return;
@@ -4707,6 +4730,8 @@ _e_comp_object_clear(E_Comp_Object *cw)
 
    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
 
+   if (cw->render_update_lock.lock) return;
+
    if (cw->ec->pixmap)
      e_pixmap_clear(cw->ec->pixmap);
    if (cw->native)
@@ -4827,6 +4852,7 @@ e_comp_object_native_surface_set(Evas_Object *obj, Eina_Bool set)
    EINA_SAFETY_ON_NULL_RETURN(cw->ec);
    if (cw->ec->input_only) return;
    if (cw->external_content) return;
+   if (cw->render_update_lock.lock) return;
    set = !!set;
 
    memset(&ns, 0, sizeof(Evas_Native_Surface));
@@ -4925,6 +4951,11 @@ e_comp_object_dirty(Evas_Object *obj)
    API_ENTRY;
    if (cw->external_content) return;
    if (!cw->redirected) return;
+   if (cw->render_update_lock.lock)
+     {
+        ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
+        return;
+     }
    /* only actually dirty if pixmap is available */
    if (!e_pixmap_resource_get(cw->ec->pixmap))
      {
@@ -5023,6 +5054,11 @@ e_comp_object_render(Evas_Object *obj)
    /* if comp object is not redirected state, comp object should not be set by newly committed data
       because image size of comp object is 1x1 and it should not be shown on canvas */
    if (!cw->redirected) return EINA_TRUE;
+   if (cw->render_update_lock.lock)
+     {
+        ELOGF("COMP", "Render update locked:%d", cw->ec, cw->render_update_lock.lock);
+        return EINA_TRUE;
+     }
    e_comp_object_render_update_del(obj);
    if (!e_pixmap_size_get(cw->ec->pixmap, &pw, &ph)) return EINA_FALSE;
 
@@ -6544,17 +6580,17 @@ e_comp_object_render_update_lock(Evas_Object *obj)
 {
    API_ENTRY EINA_FALSE;
 
-   cw->render_update_lock++;
-
-   if (cw->render_update_lock == 1)
+   if (cw->render_update_lock.lock == 0)
      {
-        e_comp_wl_buffer_reference(&cw->render_update_lock_buffer_ref,
+        _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
+        e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref,
                                    e_pixmap_resource_get(cw->ec->pixmap));
         e_comp_object_render_update_del(obj);
-        _e_comp_object_hook_call(E_COMP_OBJECT_HOOK_RENDER_UPDATE_LOCK_SET, cw->ec);
         ELOGF("COMP", "Render update lock enabled", cw->ec);
      }
 
+   cw->render_update_lock.lock++;
+
    return EINA_TRUE;
 }
 
@@ -6563,15 +6599,43 @@ e_comp_object_render_update_unlock(Evas_Object *obj)
 {
    API_ENTRY;
 
-   if (cw->render_update_lock == 0)
+   if (cw->render_update_lock.lock == 0)
      return;
 
-   cw->render_update_lock--;
+   cw->render_update_lock.lock--;
 
-   if (cw->render_update_lock == 0)
+   if (cw->render_update_lock.lock == 0)
      {
-        e_comp_wl_buffer_reference(&cw->render_update_lock_buffer_ref, NULL);
-        e_comp_object_render_update_add(obj);
+
+        if (cw->render_update_lock.pending_move_set)
+          {
+             evas_object_move(obj,
+                              cw->render_update_lock.pending_move_x,
+                              cw->render_update_lock.pending_move_y);
+             cw->render_update_lock.pending_move_x = 0;
+             cw->render_update_lock.pending_move_y = 0;
+             cw->render_update_lock.pending_move_set = EINA_FALSE;
+          }
+
+        if (cw->render_update_lock.pending_resize_set)
+          {
+             evas_object_resize(obj,
+                                cw->render_update_lock.pending_resize_w,
+                                cw->render_update_lock.pending_resize_h);
+             cw->render_update_lock.pending_resize_w = 0;
+             cw->render_update_lock.pending_resize_h = 0;
+             cw->render_update_lock.pending_resize_set = EINA_FALSE;
+          }
+
+        e_comp_wl_buffer_reference(&cw->render_update_lock.buffer_ref, NULL);
+
+        if ((cw->ec->exp_iconify.buffer_flush) &&
+            (e_policy_visibility_client_is_iconic(cw->ec)) &&
+            (cw->ec->comp_data) && (!cw->ec->comp_data->buffer_ref.buffer))
+          e_comp_object_clear(obj);
+        else
+          e_comp_object_render_update_add(obj);
+
         ELOGF("COMP", "Render update lock disabled", cw->ec);
      }
 }
@@ -6581,7 +6645,7 @@ e_comp_object_render_update_lock_get(Evas_Object *obj)
 {
    API_ENTRY EINA_FALSE;
 
-   if (cw->render_update_lock > 0)
+   if (cw->render_update_lock.lock > 0)
      return EINA_TRUE;
 
    return EINA_FALSE;