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 a0a1c17c34defd0300e42cf39facd1b39cacdcd1..5b5bc785e3496d3ab0daa849465a763c09e66c49 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 3ce0fee943518f9f225a5ef71958d7e44ad96e60..d405e29ba3dd8671d20b7302ce2bdc635d5a20de 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 1580cd489c21477e14be0f806ed35cb8da70ef6f..90534532741aa27218096f4888a6b2bfec73fb1c 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;