1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 #include "tbm_bufmgr_int.h"
41 #define TBM_QUEUE_DEBUG 0
44 #define TBM_QUEUE_TRACE(fmt, ...) { if (bTrace&0x1) fprintf(stderr, "[TBM:TRACE(%d)(%s:%d)] " fmt, getpid(), __func__, __LINE__, ##__VA_ARGS__); }
46 #define TBM_QUEUE_TRACE(fmt, ...)
50 #define TBM_LOCK() TBM_LOG_D("[LOCK] %s:%d surface:%p\n", __func__, __LINE__, surface_queue)
51 #define TBM_UNLOCK() TBM_LOG_D("[UNLOCK] %s:%d surface:%p\n", __func__, __LINE__, surface_queue)
57 static tbm_bufmgr g_surf_queue_bufmgr;
58 static pthread_mutex_t tbm_surf_queue_lock;
59 void _tbm_surface_queue_mutex_unlock(void);
62 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
64 TBM_LOG_E("'%s' failed.\n", #cond);\
65 _tbm_surf_queue_mutex_unlock();\
70 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
72 TBM_LOG_E("'%s' failed.\n", #cond);\
73 _tbm_surf_queue_mutex_unlock();\
78 typedef enum _queue_node_type {
80 QUEUE_NODE_TYPE_DEQUEUE,
81 QUEUE_NODE_TYPE_ENQUEUE,
82 QUEUE_NODE_TYPE_ACQUIRE,
83 QUEUE_NODE_TYPE_RELEASE
87 struct list_head head;
92 tbm_surface_h surface;
94 struct list_head item_link;
95 struct list_head link;
99 unsigned int priv_flags; /*for each queue*/
103 struct list_head link;
105 tbm_surface_queue_notify_cb cb;
109 typedef struct _tbm_surface_queue_interface {
110 void (*init)(tbm_surface_queue_h queue);
111 void (*reset)(tbm_surface_queue_h queue);
112 void (*destroy)(tbm_surface_queue_h queue);
113 void (*need_attach)(tbm_surface_queue_h queue);
115 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
116 void (*release)(tbm_surface_queue_h queue, queue_node *node);
117 queue_node *(*dequeue)(tbm_surface_queue_h queue);
118 queue_node *(*acquire)(tbm_surface_queue_h queue);
119 } tbm_surface_queue_interface;
121 struct _tbm_surface_queue {
129 struct list_head list;
131 struct list_head destory_noti;
132 struct list_head dequeuable_noti;
133 struct list_head dequeue_noti;
134 struct list_head acquirable_noti;
135 struct list_head reset_noti;
137 pthread_mutex_t lock;
138 pthread_cond_t free_cond;
139 pthread_cond_t dirty_cond;
141 const tbm_surface_queue_interface *impl;
144 //For external buffer allocation
145 tbm_surface_alloc_cb alloc_cb;
146 tbm_surface_free_cb free_cb;
149 struct list_head item_link; /* link of surface queue */
152 /* LCOV_EXCL_START */
155 _tbm_surf_queue_mutex_init(void)
157 static bool tbm_surf_queue_mutex_init = false;
159 if (tbm_surf_queue_mutex_init)
162 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
163 TBM_LOG_E("fail: tbm_surf_queue mutex init\n");
167 tbm_surf_queue_mutex_init = true;
173 _tbm_surf_queue_mutex_lock(void)
175 if (!_tbm_surf_queue_mutex_init())
178 pthread_mutex_lock(&tbm_surf_queue_lock);
182 _tbm_surf_queue_mutex_unlock(void)
184 pthread_mutex_unlock(&tbm_surf_queue_lock);
188 _init_tbm_surf_queue_bufmgr(void)
190 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
194 _deinit_tbm_surf_queue_bufmgr(void)
196 if (!g_surf_queue_bufmgr)
199 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
200 g_surf_queue_bufmgr = NULL;
204 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
206 tbm_surface_queue_h old_data = NULL, tmp = NULL;
208 if (surface_queue == NULL || g_surf_queue_bufmgr == NULL) {
209 TBM_TRACE("error: tbm_surface_queue(%p)\n", surface_queue);
213 if (!LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
214 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surf_queue_bufmgr->surf_queue_list, item_link) {
215 if (old_data == surface_queue) {
216 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
221 TBM_TRACE("error: tbm_surface_queue(%p)\n", surface_queue);
226 _queue_node_create(void)
228 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
230 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
236 _queue_node_delete(queue_node *node)
238 LIST_DEL(&node->item_link);
239 LIST_DEL(&node->link);
244 _queue_is_empty(queue *queue)
246 if (LIST_IS_EMPTY(&queue->head))
253 _queue_node_push_back(queue *queue, queue_node *node)
255 LIST_ADDTAIL(&node->item_link, &queue->head);
260 _queue_node_push_front(queue *queue, queue_node *node)
262 LIST_ADD(&node->item_link, &queue->head);
267 _queue_node_pop_front(queue *queue)
269 queue_node *node = NULL;
271 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
273 LIST_DEL(&node->item_link);
280 _queue_node_pop(queue *queue, queue_node *node)
282 LIST_DEL(&node->item_link);
289 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
290 tbm_surface_h surface, int *out_type)
292 queue_node *node = NULL;
293 queue_node *tmp = NULL;
296 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
300 if (type & FREE_QUEUE) {
301 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head,
303 if (node->surface == surface) {
305 *out_type = FREE_QUEUE;
312 if (type & DIRTY_QUEUE) {
313 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->dirty_queue.head,
315 if (node->surface == surface) {
317 *out_type = DIRTY_QUEUE;
324 if (type & NODE_LIST) {
325 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
326 if (node->surface == surface) {
328 *out_type = NODE_LIST;
339 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
342 if (surface_queue->free_cb) {
343 surface_queue->free_cb(surface_queue,
344 surface_queue->alloc_cb_data,
348 tbm_surface_destroy(node->surface);
351 _queue_node_delete(node);
355 _queue_init(queue *queue)
357 LIST_INITHEAD(&queue->head);
363 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
366 TBM_RETURN_IF_FAIL(cb != NULL);
368 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
370 TBM_RETURN_IF_FAIL(item != NULL);
372 LIST_INITHEAD(&item->link);
376 LIST_ADDTAIL(&item->link, list);
380 _notify_remove(struct list_head *list,
381 tbm_surface_queue_notify_cb cb, void *data)
383 queue_notify *item = NULL, *tmp = NULL;
385 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
386 if (item->cb == cb && item->data == data) {
387 LIST_DEL(&item->link);
393 TBM_LOG_E("Cannot find notifiy\n");
397 _notify_remove_all(struct list_head *list)
399 queue_notify *item = NULL, *tmp = NULL;
401 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
402 LIST_DEL(&item->link);
408 _notify_emit(tbm_surface_queue_h surface_queue,
409 struct list_head *list)
411 queue_notify *item = NULL, *tmp = NULL;
413 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
414 item->cb(surface_queue, item->data);
419 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
421 queue_node *node = NULL;
422 queue_node *tmp = NULL;
425 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
426 if (node->type == type)
434 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
435 tbm_surface_h surface)
437 queue_node *node = NULL;
439 node = _queue_node_create();
440 TBM_RETURN_IF_FAIL(node != NULL);
442 tbm_surface_internal_ref(surface);
443 node->surface = surface;
445 LIST_ADDTAIL(&node->link, &surface_queue->list);
446 _queue_node_push_back(&surface_queue->free_queue, node);
450 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
451 tbm_surface_h surface)
453 queue_node *node = NULL;
456 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
458 _queue_delete_node(surface_queue, node);
462 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
463 queue_node *node, int push_back)
466 _queue_node_push_back(&surface_queue->dirty_queue, node);
468 _queue_node_push_front(&surface_queue->dirty_queue, node);
472 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
474 queue_node *node = NULL;
476 if (_queue_is_empty(&surface_queue->free_queue)) {
477 if (surface_queue->impl && surface_queue->impl->need_attach)
478 surface_queue->impl->need_attach(surface_queue);
480 if (_queue_is_empty(&surface_queue->free_queue))
484 node = _queue_node_pop_front(&surface_queue->free_queue);
490 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
492 queue_node *node = NULL;
494 if (_queue_is_empty(&surface_queue->dirty_queue))
497 node = _queue_node_pop_front(&surface_queue->dirty_queue);
503 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
504 queue_node *node, int push_back)
507 _queue_node_push_back(&surface_queue->free_queue, node);
509 _queue_node_push_front(&surface_queue->free_queue, node);
513 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
515 int width, int height, int format,
516 const tbm_surface_queue_interface *impl, void *data)
518 TBM_RETURN_IF_FAIL(surface_queue != NULL);
519 TBM_RETURN_IF_FAIL(impl != NULL);
521 memset(surface_queue, 0x00, sizeof(struct _tbm_surface_queue));
523 if (!g_surf_queue_bufmgr)
524 _init_tbm_surf_queue_bufmgr();
526 pthread_mutex_init(&surface_queue->lock, NULL);
527 pthread_cond_init(&surface_queue->free_cond, NULL);
528 pthread_cond_init(&surface_queue->dirty_cond, NULL);
530 surface_queue->queue_size = queue_size;
531 surface_queue->width = width;
532 surface_queue->height = height;
533 surface_queue->format = format;
534 surface_queue->impl = impl;
535 surface_queue->impl_data = data;
537 _queue_init(&surface_queue->free_queue);
538 _queue_init(&surface_queue->dirty_queue);
539 LIST_INITHEAD(&surface_queue->list);
541 LIST_INITHEAD(&surface_queue->destory_noti);
542 LIST_INITHEAD(&surface_queue->acquirable_noti);
543 LIST_INITHEAD(&surface_queue->dequeuable_noti);
544 LIST_INITHEAD(&surface_queue->dequeue_noti);
545 LIST_INITHEAD(&surface_queue->reset_noti);
547 if (surface_queue->impl && surface_queue->impl->init)
548 surface_queue->impl->init(surface_queue);
550 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
553 tbm_surface_queue_error_e
554 tbm_surface_queue_add_destroy_cb(
555 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
558 _tbm_surf_queue_mutex_lock();
560 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
561 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
563 pthread_mutex_lock(&surface_queue->lock);
565 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
567 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
569 pthread_mutex_unlock(&surface_queue->lock);
571 _tbm_surf_queue_mutex_unlock();
573 return TBM_SURFACE_QUEUE_ERROR_NONE;
576 tbm_surface_queue_error_e
577 tbm_surface_queue_remove_destroy_cb(
578 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
581 _tbm_surf_queue_mutex_lock();
583 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
584 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
586 pthread_mutex_lock(&surface_queue->lock);
588 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
590 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
592 pthread_mutex_unlock(&surface_queue->lock);
594 _tbm_surf_queue_mutex_unlock();
596 return TBM_SURFACE_QUEUE_ERROR_NONE;
599 tbm_surface_queue_error_e
600 tbm_surface_queue_add_dequeuable_cb(
601 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
604 _tbm_surf_queue_mutex_lock();
606 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
607 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
609 pthread_mutex_lock(&surface_queue->lock);
611 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
613 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
615 pthread_mutex_unlock(&surface_queue->lock);
617 _tbm_surf_queue_mutex_unlock();
619 return TBM_SURFACE_QUEUE_ERROR_NONE;
622 tbm_surface_queue_error_e
623 tbm_surface_queue_remove_dequeuable_cb(
624 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
627 _tbm_surf_queue_mutex_lock();
629 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
630 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
632 pthread_mutex_lock(&surface_queue->lock);
634 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
636 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
638 pthread_mutex_unlock(&surface_queue->lock);
640 _tbm_surf_queue_mutex_unlock();
642 return TBM_SURFACE_QUEUE_ERROR_NONE;
645 tbm_surface_queue_error_e
646 tbm_surface_queue_add_dequeue_cb(
647 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
650 _tbm_surf_queue_mutex_lock();
652 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
653 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
655 pthread_mutex_lock(&surface_queue->lock);
657 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
659 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
661 pthread_mutex_unlock(&surface_queue->lock);
663 _tbm_surf_queue_mutex_unlock();
665 return TBM_SURFACE_QUEUE_ERROR_NONE;
668 tbm_surface_queue_error_e
669 tbm_surface_queue_remove_dequeue_cb(
670 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
673 _tbm_surf_queue_mutex_lock();
675 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
676 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
678 pthread_mutex_lock(&surface_queue->lock);
680 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
682 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
684 pthread_mutex_unlock(&surface_queue->lock);
686 _tbm_surf_queue_mutex_unlock();
688 return TBM_SURFACE_QUEUE_ERROR_NONE;
691 tbm_surface_queue_error_e
692 tbm_surface_queue_add_acquirable_cb(
693 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
696 _tbm_surf_queue_mutex_lock();
698 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
699 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
701 pthread_mutex_lock(&surface_queue->lock);
703 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
705 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
707 pthread_mutex_unlock(&surface_queue->lock);
709 _tbm_surf_queue_mutex_unlock();
711 return TBM_SURFACE_QUEUE_ERROR_NONE;
714 tbm_surface_queue_error_e
715 tbm_surface_queue_remove_acquirable_cb(
716 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
719 _tbm_surf_queue_mutex_lock();
721 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
722 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
724 pthread_mutex_lock(&surface_queue->lock);
726 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
728 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
730 pthread_mutex_unlock(&surface_queue->lock);
732 _tbm_surf_queue_mutex_unlock();
734 return TBM_SURFACE_QUEUE_ERROR_NONE;
737 tbm_surface_queue_error_e
738 tbm_surface_queue_set_alloc_cb(
739 tbm_surface_queue_h surface_queue,
740 tbm_surface_alloc_cb alloc_cb,
741 tbm_surface_free_cb free_cb,
744 _tbm_surf_queue_mutex_lock();
746 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
747 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
749 pthread_mutex_lock(&surface_queue->lock);
751 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
753 surface_queue->alloc_cb = alloc_cb;
754 surface_queue->free_cb = free_cb;
755 surface_queue->alloc_cb_data = data;
757 pthread_mutex_unlock(&surface_queue->lock);
759 _tbm_surf_queue_mutex_unlock();
761 return TBM_SURFACE_QUEUE_ERROR_NONE;
765 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
769 _tbm_surf_queue_mutex_lock();
771 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
773 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
775 width = surface_queue->width;
777 _tbm_surf_queue_mutex_unlock();
783 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
787 _tbm_surf_queue_mutex_lock();
789 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
791 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
793 height = surface_queue->height;
795 _tbm_surf_queue_mutex_unlock();
801 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
805 _tbm_surf_queue_mutex_lock();
807 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
809 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
811 format = surface_queue->format;
813 _tbm_surf_queue_mutex_unlock();
819 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
823 _tbm_surf_queue_mutex_lock();
825 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
827 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
829 queue_size = surface_queue->queue_size;
831 _tbm_surf_queue_mutex_unlock();
836 tbm_surface_queue_error_e
837 tbm_surface_queue_add_reset_cb(
838 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
841 _tbm_surf_queue_mutex_lock();
843 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
844 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
846 pthread_mutex_lock(&surface_queue->lock);
848 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
850 _notify_add(&surface_queue->reset_noti, reset_cb, data);
852 pthread_mutex_unlock(&surface_queue->lock);
854 _tbm_surf_queue_mutex_unlock();
856 return TBM_SURFACE_QUEUE_ERROR_NONE;
859 tbm_surface_queue_error_e
860 tbm_surface_queue_remove_reset_cb(
861 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
864 _tbm_surf_queue_mutex_lock();
866 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
867 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
869 pthread_mutex_lock(&surface_queue->lock);
871 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
873 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
875 pthread_mutex_unlock(&surface_queue->lock);
877 _tbm_surf_queue_mutex_unlock();
879 return TBM_SURFACE_QUEUE_ERROR_NONE;
882 tbm_surface_queue_error_e
883 tbm_surface_queue_enqueue(tbm_surface_queue_h
884 surface_queue, tbm_surface_h surface)
886 queue_node *node = NULL;
889 _tbm_surf_queue_mutex_lock();
891 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
892 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
893 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
894 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
897 tbm_surface_internal_dump_buffer(surface, "enqueue");
899 pthread_mutex_lock(&surface_queue->lock);
901 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
903 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
904 if (node == NULL || queue_type != NODE_LIST) {
905 TBM_LOG_E("tbm_surface_queue_enqueue::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n",
907 pthread_mutex_unlock(&surface_queue->lock);
909 _tbm_surf_queue_mutex_unlock();
910 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
913 if (surface_queue->impl && surface_queue->impl->enqueue)
914 surface_queue->impl->enqueue(surface_queue, node);
916 _tbm_surface_queue_enqueue(surface_queue, node, 1);
918 if (_queue_is_empty(&surface_queue->dirty_queue)) {
919 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
920 pthread_mutex_unlock(&surface_queue->lock);
922 _tbm_surf_queue_mutex_unlock();
923 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
926 node->type = QUEUE_NODE_TYPE_ENQUEUE;
928 pthread_mutex_unlock(&surface_queue->lock);
929 pthread_cond_signal(&surface_queue->dirty_cond);
931 _tbm_surf_queue_mutex_unlock();
933 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
935 return TBM_SURFACE_QUEUE_ERROR_NONE;
938 tbm_surface_queue_error_e
939 tbm_surface_queue_dequeue(tbm_surface_queue_h
940 surface_queue, tbm_surface_h *surface)
942 queue_node *node = NULL;
944 _tbm_surf_queue_mutex_lock();
946 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
947 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
948 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
949 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
951 pthread_mutex_lock(&surface_queue->lock);
953 if (surface_queue->impl && surface_queue->impl->dequeue)
954 node = surface_queue->impl->dequeue(surface_queue);
956 node = _tbm_surface_queue_dequeue(surface_queue);
960 pthread_mutex_unlock(&surface_queue->lock);
962 _tbm_surf_queue_mutex_unlock();
963 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
966 if (node->surface == NULL) {
968 TBM_LOG_E("_queue_node_pop_front failed\n");
969 pthread_mutex_unlock(&surface_queue->lock);
971 _tbm_surf_queue_mutex_unlock();
972 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
975 node->type = QUEUE_NODE_TYPE_DEQUEUE;
976 *surface = node->surface;
978 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
980 pthread_mutex_unlock(&surface_queue->lock);
982 _tbm_surf_queue_mutex_unlock();
984 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
986 return TBM_SURFACE_QUEUE_ERROR_NONE;
990 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
992 _tbm_surf_queue_mutex_lock();
994 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
996 pthread_mutex_lock(&surface_queue->lock);
998 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1000 if (_queue_is_empty(&surface_queue->free_queue)) {
1001 if (surface_queue->impl && surface_queue->impl->need_attach)
1002 surface_queue->impl->need_attach(surface_queue);
1004 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1005 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1006 _tbm_surf_queue_mutex_unlock();
1011 if (_queue_is_empty(&surface_queue->free_queue)) {
1013 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE)) {
1015 _tbm_surf_queue_mutex_unlock();
1017 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1019 _tbm_surf_queue_mutex_lock();
1021 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1022 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1023 _tbm_surf_queue_mutex_unlock();
1027 pthread_mutex_unlock(&surface_queue->lock);
1029 _tbm_surf_queue_mutex_unlock();
1033 pthread_mutex_unlock(&surface_queue->lock);
1035 _tbm_surf_queue_mutex_unlock();
1039 pthread_mutex_unlock(&surface_queue->lock);
1041 _tbm_surf_queue_mutex_unlock();
1046 tbm_surface_queue_error_e
1047 tbm_surface_queue_release(tbm_surface_queue_h
1048 surface_queue, tbm_surface_h surface)
1050 queue_node *node = NULL;
1053 _tbm_surf_queue_mutex_lock();
1055 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1056 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1057 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1058 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1060 pthread_mutex_lock(&surface_queue->lock);
1062 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1064 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1065 if (node == NULL || queue_type != NODE_LIST) {
1066 TBM_LOG_E("tbm_surface_queue_release::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n",
1068 pthread_mutex_unlock(&surface_queue->lock);
1070 _tbm_surf_queue_mutex_unlock();
1071 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1074 if (surface_queue->impl && surface_queue->impl->release)
1075 surface_queue->impl->release(surface_queue, node);
1077 _tbm_surface_queue_release(surface_queue, node, 1);
1079 if (_queue_is_empty(&surface_queue->free_queue)) {
1080 pthread_mutex_unlock(&surface_queue->lock);
1082 _tbm_surf_queue_mutex_unlock();
1083 return TBM_SURFACE_QUEUE_ERROR_NONE;
1086 node->type = QUEUE_NODE_TYPE_RELEASE;
1088 pthread_mutex_unlock(&surface_queue->lock);
1089 pthread_cond_signal(&surface_queue->free_cond);
1091 _tbm_surf_queue_mutex_unlock();
1093 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1095 return TBM_SURFACE_QUEUE_ERROR_NONE;
1098 tbm_surface_queue_error_e
1099 tbm_surface_queue_acquire(tbm_surface_queue_h
1100 surface_queue, tbm_surface_h *surface)
1102 queue_node *node = NULL;
1104 _tbm_surf_queue_mutex_lock();
1106 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1107 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1108 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1109 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1111 pthread_mutex_lock(&surface_queue->lock);
1113 if (surface_queue->impl && surface_queue->impl->acquire)
1114 node = surface_queue->impl->acquire(surface_queue);
1116 node = _tbm_surface_queue_acquire(surface_queue);
1120 pthread_mutex_unlock(&surface_queue->lock);
1122 _tbm_surf_queue_mutex_unlock();
1123 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1126 if (node->surface == NULL) {
1128 TBM_LOG_E("_queue_node_pop_front failed\n");
1129 pthread_mutex_unlock(&surface_queue->lock);
1131 _tbm_surf_queue_mutex_unlock();
1132 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1135 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1137 *surface = node->surface;
1139 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1141 pthread_mutex_unlock(&surface_queue->lock);
1143 _tbm_surf_queue_mutex_unlock();
1146 tbm_surface_internal_dump_buffer(*surface, "acquire");
1148 return TBM_SURFACE_QUEUE_ERROR_NONE;
1152 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1154 _tbm_surf_queue_mutex_lock();
1156 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1158 pthread_mutex_lock(&surface_queue->lock);
1160 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1162 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1164 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE)) {
1166 _tbm_surf_queue_mutex_unlock();
1168 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1170 _tbm_surf_queue_mutex_lock();
1172 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1173 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1174 _tbm_surf_queue_mutex_unlock();
1178 pthread_mutex_unlock(&surface_queue->lock);
1180 _tbm_surf_queue_mutex_unlock();
1184 pthread_mutex_unlock(&surface_queue->lock);
1186 _tbm_surf_queue_mutex_unlock();
1190 pthread_mutex_unlock(&surface_queue->lock);
1192 _tbm_surf_queue_mutex_unlock();
1198 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1200 queue_node *node = NULL, *tmp = NULL;
1202 _tbm_surf_queue_mutex_lock();
1204 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1206 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1208 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1209 _queue_delete_node(surface_queue, node);
1212 if (surface_queue->impl && surface_queue->impl->destroy)
1213 surface_queue->impl->destroy(surface_queue);
1215 _notify_emit(surface_queue, &surface_queue->destory_noti);
1217 _notify_remove_all(&surface_queue->destory_noti);
1218 _notify_remove_all(&surface_queue->acquirable_noti);
1219 _notify_remove_all(&surface_queue->dequeuable_noti);
1220 _notify_remove_all(&surface_queue->reset_noti);
1222 pthread_mutex_destroy(&surface_queue->lock);
1224 LIST_DEL(&surface_queue->item_link);
1226 free(surface_queue);
1227 surface_queue = NULL;
1229 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1230 _deinit_tbm_surf_queue_bufmgr();
1232 _tbm_surf_queue_mutex_unlock();
1235 tbm_surface_queue_error_e
1236 tbm_surface_queue_reset(tbm_surface_queue_h
1237 surface_queue, int width, int height, int format)
1239 queue_node *node = NULL, *tmp = NULL;
1241 _tbm_surf_queue_mutex_lock();
1243 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1244 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1246 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1248 if (width == surface_queue->width && height == surface_queue->height &&
1249 format == surface_queue->format) {
1250 _tbm_surf_queue_mutex_unlock();
1251 return TBM_SURFACE_QUEUE_ERROR_NONE;
1254 pthread_mutex_lock(&surface_queue->lock);
1256 surface_queue->width = width;
1257 surface_queue->height = height;
1258 surface_queue->format = format;
1260 /* Destory surface and Push to free_queue */
1261 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1262 _queue_delete_node(surface_queue, node);
1266 _queue_init(&surface_queue->free_queue);
1267 _queue_init(&surface_queue->dirty_queue);
1268 LIST_INITHEAD(&surface_queue->list);
1270 if (surface_queue->impl && surface_queue->impl->reset)
1271 surface_queue->impl->reset(surface_queue);
1273 pthread_mutex_unlock(&surface_queue->lock);
1274 pthread_cond_signal(&surface_queue->free_cond);
1276 _tbm_surf_queue_mutex_unlock();
1278 _notify_emit(surface_queue, &surface_queue->reset_noti);
1280 return TBM_SURFACE_QUEUE_ERROR_NONE;
1283 tbm_surface_queue_error_e
1284 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1286 queue_node *node = NULL, *tmp = NULL;
1288 _tbm_surf_queue_mutex_lock();
1290 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1291 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1293 pthread_mutex_lock(&surface_queue->lock);
1295 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1297 /* Destory surface and Push to free_queue */
1298 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1299 _queue_delete_node(surface_queue, node);
1303 _queue_init(&surface_queue->free_queue);
1304 _queue_init(&surface_queue->dirty_queue);
1305 LIST_INITHEAD(&surface_queue->list);
1307 if (surface_queue->impl && surface_queue->impl->reset)
1308 surface_queue->impl->reset(surface_queue);
1310 pthread_mutex_unlock(&surface_queue->lock);
1311 pthread_cond_signal(&surface_queue->free_cond);
1313 _tbm_surf_queue_mutex_unlock();
1315 _notify_emit(surface_queue, &surface_queue->reset_noti);
1317 return TBM_SURFACE_QUEUE_ERROR_NONE;
1320 tbm_surface_queue_error_e
1321 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1322 tbm_surface_h *surfaces, int *num)
1324 queue_node *node = NULL;
1325 queue_node *tmp = NULL;
1327 _tbm_surf_queue_mutex_lock();
1329 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1330 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1331 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1332 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1334 pthread_mutex_lock(&surface_queue->lock);
1337 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1339 surfaces[*num] = node->surface;
1344 pthread_mutex_unlock(&surface_queue->lock);
1346 _tbm_surf_queue_mutex_unlock();
1348 return TBM_SURFACE_QUEUE_ERROR_NONE;
1355 } tbm_queue_default;
1358 __tbm_queue_default_init(tbm_surface_queue_h surface_queue)
1360 tbm_queue_default *data = surface_queue->impl_data;
1362 data->num_attached = 0;
1366 __tbm_queue_default_reset(tbm_surface_queue_h surface_queue)
1368 tbm_queue_default *data = surface_queue->impl_data;
1370 data->num_attached = 0;
1374 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1376 free(surface_queue->impl_data);
1380 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1382 tbm_queue_default *data = surface_queue->impl_data;
1383 tbm_surface_h surface;
1385 if (data->queue_size == data->num_attached)
1388 if (surface_queue->alloc_cb) {
1389 _tbm_surf_queue_mutex_unlock();
1390 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1391 _tbm_surf_queue_mutex_lock();
1396 tbm_surface_internal_ref(surface);
1398 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1399 surface_queue->height,
1400 surface_queue->format,
1402 TBM_RETURN_IF_FAIL(surface != NULL);
1405 _tbm_surface_queue_attach(surface_queue, surface);
1406 tbm_surface_internal_unref(surface);
1407 data->num_attached++;
1410 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1411 __tbm_queue_default_init,
1412 __tbm_queue_default_reset,
1413 __tbm_queue_default_destroy,
1414 __tbm_queue_default_need_attach,
1415 NULL, /*__tbm_queue_default_enqueue*/
1416 NULL, /*__tbm_queue_default_release*/
1417 NULL, /*__tbm_queue_default_dequeue*/
1418 NULL, /*__tbm_queue_default_acquire*/
1422 tbm_surface_queue_create(int queue_size, int width,
1423 int height, int format, int flags)
1425 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1426 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1427 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1428 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1430 _tbm_surf_queue_mutex_lock();
1432 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1433 sizeof(struct _tbm_surface_queue));
1434 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1436 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1438 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1439 sizeof(tbm_queue_default));
1441 free(surface_queue);
1442 _tbm_surf_queue_mutex_unlock();
1446 data->queue_size = queue_size;
1447 data->flags = flags;
1448 _tbm_surface_queue_init(surface_queue,
1450 width, height, format,
1451 &tbm_queue_default_impl, data);
1453 _tbm_surf_queue_mutex_unlock();
1455 return surface_queue;
1463 } tbm_queue_sequence;
1466 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1468 tbm_queue_sequence *data = surface_queue->impl_data;
1470 data->num_attached = 0;
1471 _queue_init(&data->dequeue_list);
1475 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1477 tbm_queue_sequence *data = surface_queue->impl_data;
1479 data->num_attached = 0;
1480 _queue_init(&data->dequeue_list);
1484 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1486 free(surface_queue->impl_data);
1490 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1492 tbm_queue_sequence *data = surface_queue->impl_data;
1493 tbm_surface_h surface;
1495 if (data->queue_size == data->num_attached)
1498 if (surface_queue->alloc_cb) {
1499 _tbm_surf_queue_mutex_unlock();
1500 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1501 _tbm_surf_queue_mutex_lock();
1506 tbm_surface_internal_ref(surface);
1508 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1509 surface_queue->height,
1510 surface_queue->format,
1512 TBM_RETURN_IF_FAIL(surface != NULL);
1515 _tbm_surface_queue_attach(surface_queue, surface);
1516 tbm_surface_internal_unref(surface);
1517 data->num_attached++;
1521 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1524 tbm_queue_sequence *data = surface_queue->impl_data;
1525 queue_node *next = NULL;
1526 queue_node *tmp = NULL;
1528 node->priv_flags = 0;
1530 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1531 if (next->priv_flags)
1533 _queue_node_pop(&data->dequeue_list, next);
1534 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1539 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1542 tbm_queue_sequence *data = surface_queue->impl_data;
1543 queue_node *node = NULL;
1545 node = _tbm_surface_queue_dequeue(surface_queue);
1547 _queue_node_push_back(&data->dequeue_list, node);
1548 node->priv_flags = 1;
1554 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1555 __tbm_queue_sequence_init,
1556 __tbm_queue_sequence_reset,
1557 __tbm_queue_sequence_destroy,
1558 __tbm_queue_sequence_need_attach,
1559 __tbm_queue_sequence_enqueue,
1560 NULL, /*__tbm_queue_sequence_release*/
1561 __tbm_queue_sequence_dequeue,
1562 NULL, /*__tbm_queue_sequence_acquire*/
1566 tbm_surface_queue_sequence_create(int queue_size, int width,
1567 int height, int format, int flags)
1569 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1570 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1571 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1572 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1574 _tbm_surf_queue_mutex_lock();
1576 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1577 sizeof(struct _tbm_surface_queue));
1578 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1580 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1582 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1583 sizeof(tbm_queue_sequence));
1585 free(surface_queue);
1589 data->queue_size = queue_size;
1590 data->flags = flags;
1591 _tbm_surface_queue_init(surface_queue,
1593 width, height, format,
1594 &tbm_queue_sequence_impl, data);
1596 _tbm_surf_queue_mutex_unlock();
1598 return surface_queue;
1600 /* LCOV_EXCL_STOP */