e_hwc_window: add E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING 49/304349/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Tue, 16 Jan 2024 06:10:41 +0000 (15:10 +0900)
committerTizen Window System <tizen.windowsystem@gmail.com>
Tue, 16 Jan 2024 08:23:31 +0000 (17:23 +0900)
after hwc use thread for copying backup buffer, hwc_window can
have queue buffer even if it unset queue.
it occurs flickering in below case.

1. hwc set DV state to window
2. tdm backend set CL state to window
3. evas compositor render with window at buffer 1
3. window 1 has queue buffer even if queue is unset
4. tdm backend set DV state to window because window 1 has queue buffer
5. evas compositor render without window at buffer 2
6. copy thread update buffer of window and tdm backend set CL state
7. hwc set CL state to window and commit buffer 1 at target window
8. hwc commit buffer 2 and window has flickering because it is not
   rendered in buffer 2

so hwc restrict device state if hwc window is queue unset wait state.

Change-Id: I80c79d8e9276a2a0c8d296e53c16aaadd02633db

src/bin/e_hwc_window.c
src/bin/e_hwc_window.h
src/bin/e_hwc_window_queue.c

index a0a1c17..5b5bc78 100644 (file)
@@ -77,6 +77,7 @@ typedef enum _E_Hwc_Window_Restriction
    E_HWC_WINDOW_RESTRICTION_BLEND_ALPHA,
    E_HWC_WINDOW_RESTRICTION_BLEND_EQUATION,
    E_HWC_WINDOW_RESTRICTION_ZONE,
+   E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING,
 } E_Hwc_Window_Restriction;
 
 static Eina_Bool ehw_trace = EINA_FALSE;
@@ -2300,6 +2301,13 @@ e_hwc_window_device_state_available_update(E_Hwc_Window *hwc_window)
         goto finish;
      }
 
+   if (hwc_window->queue_unset_waiting)
+     {
+        restriction = E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING;
+        available = EINA_FALSE;
+        goto finish;
+     }
+
 finish:
    hwc_window->restriction = restriction;
 
@@ -2678,6 +2686,8 @@ e_hwc_window_restriction_string_get(E_Hwc_Window *hwc_window)
        return "blend equation";
      case E_HWC_WINDOW_RESTRICTION_ZONE:
        return "zone";
+     case E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING:
+       return "queue unset waiting";
      default:
        return "UNKNOWN";
     }
index 3ce0fee..d405e29 100644 (file)
@@ -166,6 +166,8 @@ struct _E_Hwc_Window
    E_Object_Delfn                *zone_delfn;
 
    Evas_Object                   *below_transparent_obj;
+
+   Eina_Bool                      queue_unset_waiting;
 };
 
 struct _E_Hwc_Window_Target
index 1580cd4..9053453 100644 (file)
@@ -1551,6 +1551,7 @@ _e_hwc_window_queue_prepare_unset(E_Hwc_Window_Queue *queue)
    _e_hwc_window_queue_buffers_retrieve(queue);
 
    queue->state = E_HWC_WINDOW_QUEUE_STATE_UNSET_WAITING;
+   hwc_window->queue_unset_waiting = EINA_TRUE;
 
    EHWQINF("Unset Waiting user ehw:%p - {%s}",
             hwc_window->ec, queue->hwc, queue, hwc_window,
@@ -1642,6 +1643,7 @@ _e_hwc_window_queue_unset(E_Hwc_Window_Queue *queue)
            (queue->user->ec ? queue->user->ec->icccm.title : "UNKNOWN"));
 
    /* unset the hwc_window from the queue */
+   queue->user->queue_unset_waiting = EINA_FALSE;
    e_hwc_window_unref(queue->user);
    queue->user = NULL;