e_hwc_window_queue: Fix overwriting to the queue buffer of target queue 95/318595/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Mon, 20 Jan 2025 08:17:26 +0000 (17:17 +0900)
committerchangyeon lee <cyeon.lee@samsung.com>
Tue, 21 Jan 2025 03:12:35 +0000 (03:12 +0000)
Do not change queue state to unset until all buffers drawn by client
have been released even if queue is target.

Fetch null buffer if client is deleted and exported buffer is destroyed
for unreferencing the queue buffer.

Change-Id: Ib6c7fd304ad7b25199244c2a15f41bbcd081bddb

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

index b56b05c9057dfe77614ca5b47794b0347d02cae4..4da34ff3d7bc1bd9ad442a01b18447cf68cbb61a 100644 (file)
@@ -829,6 +829,7 @@ _e_hwc_window_del(E_Hwc_Window *hwc_window)
    e_hwc_window_state_set(hwc_window, E_HWC_WINDOW_STATE_NONE, EINA_TRUE);
 
    e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_VISIBLE);
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_BUFFER);
 
    e_object_del(E_OBJECT(hwc_window));
 }
@@ -1194,6 +1195,7 @@ _e_hwc_window_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
 
    e_hwc_window_restriction_set(hwc_window, E_HWC_WINDOW_RESTRICTION_DELETED);
    e_hwc_window_client_type_override(hwc_window);
+   e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_BUFFER);
 }
 
 static void
index c6491df00628efcca0711f6c90cae4b0d9b3db53..a6cf7ee98e73110a7b65afa2a645f338810ae98a 100644 (file)
@@ -513,6 +513,9 @@ _e_hwc_window_queue_exported_buffer_destroy_cb(struct wl_listener *listener, voi
            queue_buffer->tsurface, queue->tqueue,
            queue_buffer->exported_wl_buffer);
 
+   if (hwc_window)
+     e_hwc_window_changed_set(hwc_window, E_HWC_WINS_CHANGED_WIN_BUFFER);
+
    if (queue_buffer->reseted)
      {
         queue->buffers = eina_list_remove(queue->buffers, queue_buffer);
@@ -737,7 +740,7 @@ _e_hwc_window_queue_buffers_retrieve_done(E_Hwc_Window_Queue *queue)
         if (queue_buffer->copying)
           return EINA_FALSE;
 
-        if ((!queue->is_target) && (queue_buffer->acquired))
+        if ((queue_buffer->internal_enqueued) && (queue_buffer->acquired))
           return EINA_FALSE;
      }
 
@@ -1697,7 +1700,9 @@ _e_hwc_window_queue_cb_buffer_change(void *data, E_Client *ec)
 
    hwc_window = ec->hwc_window;
    if (!hwc_window) return;
-   if ((ec->exp_iconify.buffer_flush) && (e_policy_visibility_client_is_iconic(ec)))
+   if ((!e_view_client_visible_get(e_client_view_get(ec))) &&
+       (ec->exp_iconify.buffer_flush) &&
+       (e_policy_visibility_client_is_iconic(ec)))
      return;
 
    _e_hwc_window_queue_copy_thread_check_and_run(hwc_window);
@@ -2221,6 +2226,7 @@ e_hwc_window_queue_buffer_enqueue(E_Hwc_Window_Queue *queue, E_Hwc_Window_Queue_
    if (!queue->tqueue) return EINA_FALSE;
 
    queue_buffer->dequeued = EINA_FALSE;
+   queue_buffer->internal_enqueued = EINA_TRUE;
 
    user = queue->user;
    EHWQTRACE("ENQ ts:%p tq:%p",
@@ -2304,6 +2310,7 @@ e_hwc_window_queue_buffer_release(E_Hwc_Window_Queue *queue, E_Hwc_Window_Queue_
    queue_buffer->released = EINA_TRUE;
    queue_buffer->dequeued = EINA_FALSE;
    queue_buffer->acquired = EINA_FALSE;
+   queue_buffer->internal_enqueued = EINA_FALSE;
 
    if (queue->type == E_HWC_WINDOW_QUEUE_TYPE_GBM_SURFACE)
      {
@@ -2331,8 +2338,7 @@ e_hwc_window_queue_buffer_release(E_Hwc_Window_Queue *queue, E_Hwc_Window_Queue_
                        NULL, NULL, queue, queue_buffer, queue_buffer->tsurface);
           }
 
-        if ((!queue->is_target) &&
-            (queue->state == E_HWC_WINDOW_QUEUE_STATE_UNSET_WAITING))
+        if (queue->state == E_HWC_WINDOW_QUEUE_STATE_UNSET_WAITING)
           {
              if (_e_hwc_window_queue_buffers_retrieve_done(queue))
                _e_hwc_window_queue_unset(queue);
@@ -2432,6 +2438,15 @@ e_hwc_window_queue_buffer_reference(E_Hwc_Window_Queue_Buffer_Ref *ref, E_Hwc_Wi
                         EHWQINF("Wait detach ts:%p tq:%p", NULL, NULL, ref->buffer->queue,
                                 ref->buffer->tsurface, ref->buffer->queue->tqueue);
                      }
+                   else if ((ref->buffer->queue->state == E_HWC_WINDOW_QUEUE_STATE_UNSET_WAITING) &&
+                            (ref->buffer->copying))
+                     {
+                        ref->buffer->acquired = EINA_FALSE;
+                        ref->buffer->dequeued = EINA_TRUE;
+
+                        EHWQINF("Wait copying ts:%p tq:%p", NULL, NULL, ref->buffer->queue,
+                                ref->buffer->tsurface, ref->buffer->queue->tqueue);
+                     }
                    else
                      {
                         e_hwc_window_queue_buffer_release(ref->buffer->queue, ref->buffer);
@@ -2575,11 +2590,11 @@ e_hwc_window_queue_debug_info_get(Eldbus_Message_Iter *iter)
           {
              snprintf(info_str, sizeof(info_str),
                       " └─ [%2d] Queue_Buffer(%8p) tsurface(%8p) exported_wl_buffer(%u)"
-                      " exported(%d) usable(%d) released(%d) acquired(%d) dequeued(%d) copying(%d)",
+                      " exported(%d) usable(%d) released(%d) acquired(%d) dequeued(%d) copying(%d) internal_enqueued(%d)",
                       ++buf_idx, queue_buffer, queue_buffer->tsurface,
                       queue_buffer->exported_wl_buffer ? wl_resource_get_id(queue_buffer->exported_wl_buffer) : 0,
                       queue_buffer->exported, queue_buffer->usable, queue_buffer->released,
-                      queue_buffer->acquired, queue_buffer->dequeued, queue_buffer->copying);
+                      queue_buffer->acquired, queue_buffer->dequeued, queue_buffer->copying, queue_buffer->internal_enqueued);
              eldbus_message_iter_basic_append(line_array, 's', info_str);
           }
         eldbus_message_iter_basic_append(line_array, 's', "");
index 102413ea0feaab880c8d870e226b65eb3e81c582..897102b2ad28269440b30c403546548058f3ca64 100644 (file)
@@ -62,6 +62,7 @@ struct _E_Hwc_Window_Queue_Buffer
    struct wl_resource            *exported_wl_buffer;
    struct wl_listener             exported_destroy_listener;
    Eina_Bool                      exported;
+   Eina_Bool                      internal_enqueued;
    Eina_Bool                      usable;
    Eina_Bool                      released;
    Eina_Bool                      acquired;