surface_queue: add user alloc function 40/62040/1 accepted/tizen/ivi/20160315.002521 accepted/tizen/mobile/20160315.002431 accepted/tizen/tv/20160315.002445 accepted/tizen/wearable/20160315.002502 submit/tizen/20160314.083728
authorSangjin Lee <lsj119@samsung.com>
Thu, 3 Mar 2016 07:24:01 +0000 (16:24 +0900)
committerSangjin Lee <lsj119@samsung.com>
Mon, 14 Mar 2016 04:44:02 +0000 (13:44 +0900)
Change-Id: I4819847e5aa4e38c1d57a03cc2d24418089786e9

src/tbm_surface_queue.c
src/tbm_surface_queue.h

index f10fba6..908f8fb 100644 (file)
@@ -115,6 +115,11 @@ struct _tbm_surface_queue {
 
        const tbm_surface_queue_interface *impl;
        void *impl_data;
+
+       //For external buffer allocation
+       tbm_surface_alloc_cb alloc_cb;
+       tbm_surface_free_cb free_cb;
+       void *alloc_cb_data;
 };
 
 static queue_node *
@@ -130,9 +135,6 @@ _queue_node_create(void)
 static void
 _queue_node_delete(queue_node *node)
 {
-       if (node->surface)
-               tbm_surface_destroy(node->surface);
-
        LIST_DEL(&node->item_link);
        LIST_DEL(&node->link);
        free(node);
@@ -234,6 +236,22 @@ _queue_get_node(tbm_surface_queue_h surface_queue, int type,
 }
 
 static void
+_queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
+{
+       if (node->surface) {
+               if (surface_queue->free_cb) {
+                       surface_queue->free_cb(surface_queue,
+                                       surface_queue->alloc_cb_data,
+                                       node->surface);
+               } else {
+                       tbm_surface_destroy(node->surface);
+               }
+       }
+
+       _queue_node_delete(node);
+}
+
+static void
 _queue_init(queue *queue)
 {
        LIST_INITHEAD(&queue->head);
@@ -323,7 +341,7 @@ _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
 
        node = _queue_get_node(surface_queue, 0, surface, &queue_type);
        if (node)
-               _queue_node_delete(node);
+               _queue_delete_node(surface_queue, node);
 }
 
 void
@@ -566,6 +584,27 @@ tbm_surface_queue_remove_acquirable_cb(
        return TBM_SURFACE_QUEUE_ERROR_NONE;
 }
 
+tbm_surface_queue_error_e
+tbm_surface_queue_set_alloc_cb(
+       tbm_surface_queue_h surface_queue,
+       tbm_surface_alloc_cb alloc_cb,
+       tbm_surface_free_cb free_cb,
+       void *data)
+{
+       TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL,
+                              TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+
+       pthread_mutex_lock(&surface_queue->lock);
+
+       surface_queue->alloc_cb = alloc_cb;
+       surface_queue->free_cb = free_cb;
+       surface_queue->alloc_cb_data = data;
+
+       pthread_mutex_unlock(&surface_queue->lock);
+
+       return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
+
 int
 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
 {
@@ -865,7 +904,7 @@ tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
                surface_queue->impl->destroy(surface_queue);
 
        LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
-               _queue_node_delete(node);
+               _queue_delete_node(surface_queue, node);
        }
 
        _notify_remove_all(&surface_queue->destory_noti);
@@ -898,7 +937,7 @@ tbm_surface_queue_reset(tbm_surface_queue_h
 
        /* Destory surface and Push to free_queue */
        LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
-               _queue_node_delete(node);
+               _queue_delete_node(surface_queue, node);
        }
 
        /* Reset queue */
@@ -919,6 +958,39 @@ tbm_surface_queue_reset(tbm_surface_queue_h
        return TBM_SURFACE_QUEUE_ERROR_NONE;
 }
 
+tbm_surface_queue_error_e
+tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
+{
+       TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL,
+                              TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
+
+       queue_node *node = NULL, *tmp = NULL;
+
+       pthread_mutex_lock(&surface_queue->lock);
+
+       /* Destory surface and Push to free_queue */
+       LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
+               _queue_delete_node(surface_queue, node);
+       }
+
+       /* Reset queue */
+       _queue_init(&surface_queue->free_queue);
+       _queue_init(&surface_queue->dirty_queue);
+       LIST_INITHEAD(&surface_queue->list);
+
+       if (surface_queue->impl && surface_queue->impl->reset)
+               surface_queue->impl->reset(surface_queue);
+
+       _notify_emit(surface_queue, &surface_queue->reset_noti);
+       if (surface_queue->reset_cb)
+               surface_queue->reset_cb(surface_queue, surface_queue->reset_cb_data);
+
+       pthread_mutex_unlock(&surface_queue->lock);
+       pthread_cond_signal(&surface_queue->free_cond);
+
+       return TBM_SURFACE_QUEUE_ERROR_NONE;
+}
+
 typedef struct {
        int queue_size;
        int num_attached;
@@ -956,11 +1028,18 @@ __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
        if (data->queue_size == data->num_attached)
                return;
 
-       surface = tbm_surface_internal_create_with_flags(surface_queue->width,
-                       surface_queue->height,
-                       surface_queue->format,
-                       data->flags);
-       TBM_RETURN_IF_FAIL(surface != NULL);
+       if (surface_queue->alloc_cb) {
+               surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
+               TBM_RETURN_IF_FAIL(surface != NULL);
+               tbm_surface_internal_ref(surface);
+       } else {
+               surface = tbm_surface_internal_create_with_flags(surface_queue->width,
+                               surface_queue->height,
+                               surface_queue->format,
+                               data->flags);
+               TBM_RETURN_IF_FAIL(surface != NULL);
+       }
+
        _tbm_surface_queue_attach(surface_queue, surface);
        tbm_surface_internal_unref(surface);
        data->num_attached++;
@@ -1046,11 +1125,18 @@ __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
        if (data->queue_size == data->num_attached)
                return;
 
-       surface = tbm_surface_internal_create_with_flags(surface_queue->width,
-                       surface_queue->height,
-                       surface_queue->format,
-                       data->flags);
-       TBM_RETURN_IF_FAIL(surface != NULL);
+       if (surface_queue->alloc_cb) {
+               surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
+               TBM_RETURN_IF_FAIL(surface != NULL);
+               tbm_surface_internal_ref(surface);
+       } else {
+               surface = tbm_surface_internal_create_with_flags(surface_queue->width,
+                               surface_queue->height,
+                               surface_queue->format,
+                               data->flags);
+               TBM_RETURN_IF_FAIL(surface != NULL);
+       }
+
        _tbm_surface_queue_attach(surface_queue, surface);
        tbm_surface_internal_unref(surface);
        data->num_attached++;
index bfbec83..5435fc4 100644 (file)
@@ -48,6 +48,12 @@ typedef struct _tbm_surface_queue *tbm_surface_queue_h;
 typedef void (*tbm_surface_queue_notify_cb) (tbm_surface_queue_h surface_queue,
                void *data);
 
+typedef tbm_surface_h (*tbm_surface_alloc_cb) (tbm_surface_queue_h surface_queue,
+               void *data);
+
+typedef void (*tbm_surface_free_cb) (tbm_surface_queue_h surface_queue,
+               void *data, tbm_surface_h surface);
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -79,6 +85,8 @@ int tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue);
 tbm_surface_queue_error_e tbm_surface_queue_reset(
                tbm_surface_queue_h surface_queue, int width, int height, int format);
 
+tbm_surface_queue_error_e tbm_surface_queue_flush(tbm_surface_queue_h surface_queue);
+
 tbm_surface_queue_error_e tbm_surface_queue_add_reset_cb(
        tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
        void *data);
@@ -111,6 +119,12 @@ tbm_surface_queue_error_e tbm_surface_queue_remove_acquirable_cb(
        tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
        void *data);
 
+tbm_surface_queue_error_e tbm_surface_queue_set_alloc_cb(
+       tbm_surface_queue_h surface_queue,
+       tbm_surface_alloc_cb alloc_cb,
+       tbm_surface_free_cb free_cb,
+       void *data);
+
 /*The functions of queue factory*/
 tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width,
                int height, int format, int flags);