e_hwc_window: add E_HWC_WINDOW_RESTRICTION_QUEUE_UNSET_WAITING 50/304350/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Tue, 16 Jan 2024 06:10:41 +0000 (15:10 +0900)
committerchangyeon lee <cyeon.lee@samsung.com>
Tue, 16 Jan 2024 08:23:52 +0000 (08:23 +0000)
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 247995038daf95c5fedf604afa02c7dd99fe918d..f80837ab915284a5a5306148e2469efa3047ddd6 100644 (file)
@@ -76,6 +76,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;
@@ -2299,6 +2300,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;
 
@@ -2677,6 +2685,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 d28ab21c01893e5ab8edd7307feee4cef618c89d..23bdbc5adfb9d04917d6618fa2d931d9a4492252 100644 (file)
@@ -1550,6 +1550,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,
@@ -1641,6 +1642,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;