client: add active_flush_invalid flag
[platform/core/uifw/wayland-tbm.git] / src / wayland-tbm-client.c
index 175f894..df6553d 100644 (file)
@@ -91,6 +91,9 @@ struct wayland_tbm_surface_queue {
        int usage;
        struct wl_list attach_bufs;
 
+       int active_flush_invalid;
+       int active_flush_reset;
+
        tbm_surface_queue_h tbm_queue;
 
        struct wl_tbm *wl_tbm;
@@ -1026,7 +1029,7 @@ __wayland_tbm_client_surface_alloc_cb(tbm_surface_queue_h surface_queue, void *d
 
        pthread_mutex_lock(&queue_info->lock);
 
-       if (queue_info->is_active && queue_info->active_flush) {
+       if (queue_info->is_active && queue_info->active_flush && !queue_info->active_flush_invalid) {
                wl_list_for_each_reverse(buffer, &queue_info->attach_bufs, link) {
                        if (!buffer->allocated && buffer->usable && !buffer->expire) {
                                if (_wayland_tbm_client_is_valid_attach_bufs(queue_info, buffer)) {
@@ -1150,6 +1153,23 @@ fail_alloc:
        wl_buffer_destroy(wl_buffer);
 }
 
+static int
+_wayland_tbm_client_is_active_flush_valid(struct wayland_tbm_surface_queue *queue_info)
+{
+       struct wayland_tbm_buffer *buffer;
+
+       if (wl_list_empty(&queue_info->attach_bufs)) return 0;
+
+       wl_list_for_each_reverse(buffer, &queue_info->attach_bufs, link) {
+               if (buffer->expire) continue;
+
+               if (_wayland_tbm_client_is_valid_attach_bufs(queue_info, buffer))
+                       return 1;
+       }
+
+       return 0;
+}
+
 static void
 handle_tbm_queue_active(void *data,
                        struct wl_tbm_queue *wl_tbm_queue,
@@ -1177,9 +1197,19 @@ handle_tbm_queue_active(void *data,
        queue_info->is_active = 1;
        queue_info->usage = usage;
 
-       if (need_flush)
+       if (need_flush) {
                queue_info->active_flush = need_flush;
 
+               if (!_wayland_tbm_client_is_active_flush_valid(queue_info)) {
+                       WL_TBM_LOG("active_flush invalid queue");
+                       queue_info->active_flush_invalid = 1;
+                       pthread_mutex_unlock(&queue_info->lock);
+                       return;
+               }
+
+               queue_info->active_flush_reset = 1;
+       }
+
        tbm_queue = queue_info->tbm_queue;
 
        pthread_mutex_unlock(&queue_info->lock);
@@ -1218,8 +1248,6 @@ handle_tbm_queue_deactive(void *data,
                return;
        }
 
-       queue_info->is_active = 0;
-
        if (queue_info->active_flush) {
                queue_info->active_flush = 0;
 
@@ -1235,10 +1263,15 @@ handle_tbm_queue_deactive(void *data,
                        _wayland_tbm_client_queue_get_attach_bufs(queue_info, 1, surfaces, &count);
                        /* flush the attached surfaces */
                        _wayland_tbm_client_queue_destroy_unused_attach_bufs(queue_info, &flush);
-                       need_flush = 1;
+
+                       if (!queue_info->active_flush_invalid)
+                               need_flush = 1;
                }
        }
 
+       queue_info->is_active = 0;
+       queue_info->active_flush_invalid = 0;
+
        tbm_queue = queue_info->tbm_queue;
        queue_size = queue_info->queue_size;
 
@@ -1412,9 +1445,11 @@ _handle_tbm_surface_queue_reset_notify(tbm_surface_queue_h surface_queue,
                void *data)
 {
        struct wayland_tbm_surface_queue *queue_info = data;
+       int recover_size = 0;
        int width;
        int height;
        int format;
+       int queue_size;
 
 #ifdef DEBUG_TRACE
        WL_TBM_TRACE(" pid:%d", getpid());
@@ -1423,6 +1458,7 @@ _handle_tbm_surface_queue_reset_notify(tbm_surface_queue_h surface_queue,
        width = tbm_surface_queue_get_width(surface_queue);
        height = tbm_surface_queue_get_height(surface_queue);
        format = tbm_surface_queue_get_format(surface_queue);
+       queue_size = tbm_surface_queue_get_size(surface_queue);
 
        pthread_mutex_lock(&queue_info->lock);
 
@@ -1430,7 +1466,22 @@ _handle_tbm_surface_queue_reset_notify(tbm_surface_queue_h surface_queue,
        queue_info->height = height;
        queue_info->format = format;
 
+       if (queue_info->is_active && queue_info->active_flush) {
+               if (queue_info->active_flush_reset) {
+                       queue_info->active_flush_reset = 0;
+               }
+               else {
+                       WL_TBM_LOG("active_flush invalid queue");
+                       queue_info->active_flush_invalid = 1;
+                       if (queue_size != queue_info->queue_size)
+                               recover_size = queue_info->queue_size;
+               }
+       }
+
        pthread_mutex_unlock(&queue_info->lock);
+
+       if (recover_size)
+               tbm_surface_queue_set_size(surface_queue, recover_size, 0);
 }
 
 static void
@@ -1631,6 +1682,11 @@ wayland_tbm_client_queue_check_activate(struct wayland_tbm_client *tbm_client, t
        }
 
        if (queue_info->active_flush) {
+               if (queue_info->active_flush_invalid) {
+                       pthread_mutex_unlock(&queue_info->lock);
+                       return 0;
+               }
+
                if (wl_list_empty(&queue_info->attach_bufs)) {
                        pthread_mutex_unlock(&queue_info->lock);
                        return 0;