e_hwc_window_queue: add e_hwc_window_queue_buffer_reference 00/271300/1
authorChangyeon Lee <cyeon.lee@samsung.com>
Thu, 20 Jan 2022 05:12:01 +0000 (14:12 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Fri, 18 Feb 2022 02:15:09 +0000 (11:15 +0900)
if busy of queue_buffer is zero, queue_buffer is released to queue

Change-Id: Id657902f9ecd211ff1cde1b72098724c49958fa0

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

index 0d0e9cbfe4f7ad6554ef6efc65eaa3b5ed37e19f..ae3663cf88b249668efa9e5f40b0e84831e015d5 100644 (file)
@@ -366,6 +366,8 @@ _e_hwc_window_queue_buffer_create(E_Hwc_Window_Queue *queue, tbm_surface_h tsurf
    queue_buffer->tsurface = tsurface;
    queue_buffer->gbo = gbo;
 
+   wl_signal_init(&queue_buffer->destroy_signal);
+
    queue->buffers = eina_list_append(queue->buffers, queue_buffer);
 
    EHWQTRACE("CREATE queue buffer:%p tq:%p tsurface:%p",
@@ -390,6 +392,8 @@ _e_hwc_window_queue_buffer_destroy(E_Hwc_Window_Queue_Buffer *queue_buffer)
              (queue_buffer->queue ? queue_buffer->queue->tqueue : NULL),
              queue_buffer->tsurface);
 
+   wl_signal_emit(&queue_buffer->destroy_signal, queue_buffer);
+
    E_FREE(queue_buffer);
 }
 
@@ -1838,6 +1842,49 @@ e_hwc_window_queue_acquirable_buffers_get(E_Hwc_Window_Queue *queue)
    return acquirable_buffers;
 }
 
+static void
+_e_hwc_widnow_queue_buffer_reference_cb_destroy(struct wl_listener *listener, void *data)
+{
+   E_Hwc_Window_Queue_Buffer_Ref *buffer_ref;
+
+   buffer_ref = container_of(listener, E_Hwc_Window_Queue_Buffer_Ref, destroy_listener);
+   if ((E_Hwc_Window_Queue_Buffer *)data != buffer_ref->buffer) return;
+   buffer_ref->buffer = NULL;
+}
+
+EINTERN void
+e_hwc_window_queue_buffer_reference(E_Hwc_Window_Queue_Buffer_Ref *ref, E_Hwc_Window_Queue_Buffer *buffer)
+{
+   if ((ref->buffer) && (buffer != ref->buffer))
+     {
+        ref->buffer->busy--;
+        EHWQTRACE("UNREF ts:%p tq:%p busy:%d", NULL, NULL, ref->buffer->queue,
+                  ref->buffer->tsurface, ref->buffer->queue->tqueue, ref->buffer->busy);
+        if (ref->buffer->busy == 0)
+          {
+             if (ref->buffer->queue)
+               e_hwc_window_queue_buffer_release(ref->buffer->queue, ref->buffer);
+          }
+
+        if (ref->destroy_listener.notify)
+          {
+             wl_list_remove(&ref->destroy_listener.link);
+             ref->destroy_listener.notify = NULL;
+          }
+     }
+
+   if ((buffer) && (buffer != ref->buffer))
+     {
+        buffer->busy++;
+        wl_signal_add(&buffer->destroy_signal, &ref->destroy_listener);
+        EHWQTRACE("  REF ts:%p tq:%p busy:%d", NULL, NULL, buffer->queue,
+                  buffer->tsurface, buffer->queue->tqueue, buffer->busy);
+     }
+
+   ref->buffer = buffer;
+   ref->destroy_listener.notify = _e_hwc_widnow_queue_buffer_reference_cb_destroy;
+}
+
 EINTERN int
 e_hwc_window_queue_size_get(E_Hwc_Window_Queue *queue)
 {
index 1d689fbab5929cc723adbf1acef1fc3f62d11f03..c3af64d8e6644ae535e207dbad5b4ad3c86efca3 100644 (file)
@@ -1,9 +1,12 @@
 #ifdef E_TYPEDEFS
 
+#include <wayland-server.h>
+
 # define E_HWC_WINDOW_QUEUE_BUFFER_FLAGS 7777
 
 typedef struct _E_Hwc_Window_Queue               E_Hwc_Window_Queue;
 typedef struct _E_Hwc_Window_Queue_Buffer        E_Hwc_Window_Queue_Buffer;
+typedef struct _E_Hwc_Window_Queue_Buffer_Ref    E_Hwc_Window_Queue_Buffer_Ref;
 
 typedef enum _E_Hwc_Window_Queue_State
 {
@@ -23,6 +26,12 @@ typedef enum _E_Hwc_Window_Queue_Type
    E_HWC_WINDOW_QUEUE_TYPE_GBM_SURFACE,
 } E_Hwc_Window_Queue_Type;
 
+struct _E_Hwc_Window_Queue_Buffer_Ref
+{
+   E_Hwc_Window_Queue_Buffer     *buffer;
+   struct wl_listener             destroy_listener;
+};
+
 #else
 #ifndef E_HWC_WINDOW_QUEUE_H
 #define E_HWC_WINDOW_QUEUE_H
@@ -68,6 +77,10 @@ struct _E_Hwc_Window_Queue_Buffer
    Eina_Bool                      acquired;
    Eina_Bool                      dequeued;
    Eina_Bool                      reseted;
+
+   int                            busy;
+
+   struct wl_signal               destroy_signal;
 };
 
 EINTERN Eina_Bool            e_hwc_window_queue_init(void);
@@ -88,6 +101,7 @@ EINTERN Eina_Bool                   e_hwc_window_queue_buffer_enqueue(E_Hwc_Wind
 EINTERN E_Hwc_Window_Queue_Buffer * e_hwc_window_queue_buffer_acquire(E_Hwc_Window_Queue *queue);
 EINTERN Eina_Bool                   e_hwc_window_queue_buffer_release(E_Hwc_Window_Queue *queue, E_Hwc_Window_Queue_Buffer *queue_buffer);
 EINTERN Eina_Bool                   e_hwc_window_queue_clear(E_Hwc_Window_Queue *queue);
+EINTERN void                        e_hwc_window_queue_buffer_reference(E_Hwc_Window_Queue_Buffer_Ref *ref, E_Hwc_Window_Queue_Buffer *buffer);
 
 EINTERN Eina_List *                 e_hwc_window_queue_acquirable_buffers_get(E_Hwc_Window_Queue *queue);
 EINTERN int                         e_hwc_window_queue_size_get(E_Hwc_Window_Queue *queue);