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 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
120 } tbm_surface_queue_interface;
122 struct _tbm_surface_queue {
131 struct list_head list;
133 struct list_head destory_noti;
134 struct list_head dequeuable_noti;
135 struct list_head dequeue_noti;
136 struct list_head can_dequeue_noti;
137 struct list_head acquirable_noti;
138 struct list_head reset_noti;
140 pthread_mutex_t lock;
141 pthread_cond_t free_cond;
142 pthread_cond_t dirty_cond;
144 const tbm_surface_queue_interface *impl;
147 //For external buffer allocation
148 tbm_surface_alloc_cb alloc_cb;
149 tbm_surface_free_cb free_cb;
152 struct list_head item_link; /* link of surface queue */
155 /* LCOV_EXCL_START */
158 _tbm_surf_queue_mutex_init(void)
160 static bool tbm_surf_queue_mutex_init = false;
162 if (tbm_surf_queue_mutex_init)
165 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
166 TBM_LOG_E("fail: tbm_surf_queue mutex init\n");
170 tbm_surf_queue_mutex_init = true;
176 _tbm_surf_queue_mutex_lock(void)
178 if (!_tbm_surf_queue_mutex_init())
181 pthread_mutex_lock(&tbm_surf_queue_lock);
185 _tbm_surf_queue_mutex_unlock(void)
187 pthread_mutex_unlock(&tbm_surf_queue_lock);
191 _init_tbm_surf_queue_bufmgr(void)
193 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
197 _deinit_tbm_surf_queue_bufmgr(void)
199 if (!g_surf_queue_bufmgr)
202 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
203 g_surf_queue_bufmgr = NULL;
207 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
209 tbm_surface_queue_h old_data = NULL;
211 if (surface_queue == NULL || g_surf_queue_bufmgr == NULL) {
212 TBM_TRACE("error: surface_queue is NULL or not initialized\n");
216 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
217 TBM_TRACE("error: surf_queue_list is empty\n");
221 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
223 if (old_data == surface_queue) {
224 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
229 TBM_TRACE("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
234 _queue_node_create(void)
236 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
238 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
244 _queue_node_delete(queue_node *node)
246 LIST_DEL(&node->item_link);
247 LIST_DEL(&node->link);
252 _queue_is_empty(queue *queue)
254 if (LIST_IS_EMPTY(&queue->head))
261 _queue_node_push_back(queue *queue, queue_node *node)
263 LIST_ADDTAIL(&node->item_link, &queue->head);
268 _queue_node_push_front(queue *queue, queue_node *node)
270 LIST_ADD(&node->item_link, &queue->head);
275 _queue_node_pop_front(queue *queue)
279 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
281 LIST_DEL(&node->item_link);
288 _queue_node_pop(queue *queue, queue_node *node)
290 LIST_DEL(&node->item_link);
297 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
298 tbm_surface_h surface, int *out_type)
300 queue_node *node = NULL;
303 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
307 if (type & FREE_QUEUE) {
308 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
310 if (node->surface == surface) {
312 *out_type = FREE_QUEUE;
319 if (type & DIRTY_QUEUE) {
320 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
322 if (node->surface == surface) {
324 *out_type = DIRTY_QUEUE;
331 if (type & NODE_LIST) {
332 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
333 if (node->surface == surface) {
335 *out_type = NODE_LIST;
346 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
349 if (surface_queue->free_cb) {
350 surface_queue->free_cb(surface_queue,
351 surface_queue->alloc_cb_data,
355 tbm_surface_destroy(node->surface);
358 _queue_node_delete(node);
362 _queue_init(queue *queue)
364 LIST_INITHEAD(&queue->head);
370 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
373 TBM_RETURN_IF_FAIL(cb != NULL);
375 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
377 TBM_RETURN_IF_FAIL(item != NULL);
379 LIST_INITHEAD(&item->link);
383 LIST_ADDTAIL(&item->link, list);
387 _notify_remove(struct list_head *list,
388 tbm_surface_queue_notify_cb cb, void *data)
390 queue_notify *item = NULL, *tmp;
392 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
393 if (item->cb == cb && item->data == data) {
394 LIST_DEL(&item->link);
400 TBM_LOG_E("Cannot find notifiy\n");
404 _notify_remove_all(struct list_head *list)
406 queue_notify *item = NULL, *tmp;
408 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
409 LIST_DEL(&item->link);
415 _notify_emit(tbm_surface_queue_h surface_queue,
416 struct list_head *list)
418 queue_notify *item = NULL, *tmp;;
421 The item->cb is the outside function of the libtbm.
422 The tbm user may/can remove the item of the list,
423 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
425 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
426 item->cb(surface_queue, item->data);
430 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
432 queue_node *node = NULL;
435 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
436 if (node->type == type)
444 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
445 tbm_surface_h surface)
449 node = _queue_node_create();
450 TBM_RETURN_IF_FAIL(node != NULL);
452 tbm_surface_internal_ref(surface);
453 node->surface = surface;
455 LIST_ADDTAIL(&node->link, &surface_queue->list);
456 surface_queue->num_attached++;
457 _queue_node_push_back(&surface_queue->free_queue, node);
461 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
462 tbm_surface_h surface)
467 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
469 _queue_delete_node(surface_queue, node);
470 surface_queue->num_attached--;
475 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
476 queue_node *node, int push_back)
479 _queue_node_push_back(&surface_queue->dirty_queue, node);
481 _queue_node_push_front(&surface_queue->dirty_queue, node);
485 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
489 if (_queue_is_empty(&surface_queue->free_queue)) {
490 if (surface_queue->impl && surface_queue->impl->need_attach)
491 surface_queue->impl->need_attach(surface_queue);
493 if (_queue_is_empty(&surface_queue->free_queue))
497 node = _queue_node_pop_front(&surface_queue->free_queue);
503 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
507 if (_queue_is_empty(&surface_queue->dirty_queue))
510 node = _queue_node_pop_front(&surface_queue->dirty_queue);
516 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
517 queue_node *node, int push_back)
520 _queue_node_push_back(&surface_queue->free_queue, node);
522 _queue_node_push_front(&surface_queue->free_queue, node);
526 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
528 int width, int height, int format,
529 const tbm_surface_queue_interface *impl, void *data)
531 TBM_RETURN_IF_FAIL(surface_queue != NULL);
532 TBM_RETURN_IF_FAIL(impl != NULL);
534 if (!g_surf_queue_bufmgr)
535 _init_tbm_surf_queue_bufmgr();
537 pthread_mutex_init(&surface_queue->lock, NULL);
538 pthread_cond_init(&surface_queue->free_cond, NULL);
539 pthread_cond_init(&surface_queue->dirty_cond, NULL);
541 surface_queue->queue_size = queue_size;
542 surface_queue->width = width;
543 surface_queue->height = height;
544 surface_queue->format = format;
545 surface_queue->impl = impl;
546 surface_queue->impl_data = data;
548 _queue_init(&surface_queue->free_queue);
549 _queue_init(&surface_queue->dirty_queue);
550 LIST_INITHEAD(&surface_queue->list);
552 LIST_INITHEAD(&surface_queue->destory_noti);
553 LIST_INITHEAD(&surface_queue->dequeuable_noti);
554 LIST_INITHEAD(&surface_queue->dequeue_noti);
555 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
556 LIST_INITHEAD(&surface_queue->acquirable_noti);
557 LIST_INITHEAD(&surface_queue->reset_noti);
559 if (surface_queue->impl && surface_queue->impl->init)
560 surface_queue->impl->init(surface_queue);
562 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
565 tbm_surface_queue_error_e
566 tbm_surface_queue_add_destroy_cb(
567 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
570 _tbm_surf_queue_mutex_lock();
572 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
573 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
575 pthread_mutex_lock(&surface_queue->lock);
577 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
579 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
581 pthread_mutex_unlock(&surface_queue->lock);
583 _tbm_surf_queue_mutex_unlock();
585 return TBM_SURFACE_QUEUE_ERROR_NONE;
588 tbm_surface_queue_error_e
589 tbm_surface_queue_remove_destroy_cb(
590 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
593 _tbm_surf_queue_mutex_lock();
595 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
596 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
598 pthread_mutex_lock(&surface_queue->lock);
600 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
602 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
604 pthread_mutex_unlock(&surface_queue->lock);
606 _tbm_surf_queue_mutex_unlock();
608 return TBM_SURFACE_QUEUE_ERROR_NONE;
611 tbm_surface_queue_error_e
612 tbm_surface_queue_add_dequeuable_cb(
613 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
616 _tbm_surf_queue_mutex_lock();
618 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
619 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
621 pthread_mutex_lock(&surface_queue->lock);
623 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
625 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
627 pthread_mutex_unlock(&surface_queue->lock);
629 _tbm_surf_queue_mutex_unlock();
631 return TBM_SURFACE_QUEUE_ERROR_NONE;
634 tbm_surface_queue_error_e
635 tbm_surface_queue_remove_dequeuable_cb(
636 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
639 _tbm_surf_queue_mutex_lock();
641 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
642 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
644 pthread_mutex_lock(&surface_queue->lock);
646 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
648 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
650 pthread_mutex_unlock(&surface_queue->lock);
652 _tbm_surf_queue_mutex_unlock();
654 return TBM_SURFACE_QUEUE_ERROR_NONE;
657 tbm_surface_queue_error_e
658 tbm_surface_queue_add_dequeue_cb(
659 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
662 _tbm_surf_queue_mutex_lock();
664 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
665 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
667 pthread_mutex_lock(&surface_queue->lock);
669 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
671 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
673 pthread_mutex_unlock(&surface_queue->lock);
675 _tbm_surf_queue_mutex_unlock();
677 return TBM_SURFACE_QUEUE_ERROR_NONE;
680 tbm_surface_queue_error_e
681 tbm_surface_queue_remove_dequeue_cb(
682 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
685 _tbm_surf_queue_mutex_lock();
687 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
688 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
690 pthread_mutex_lock(&surface_queue->lock);
692 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
694 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
696 pthread_mutex_unlock(&surface_queue->lock);
698 _tbm_surf_queue_mutex_unlock();
700 return TBM_SURFACE_QUEUE_ERROR_NONE;
703 tbm_surface_queue_error_e
704 tbm_surface_queue_add_can_dequeue_cb(
705 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
708 _tbm_surf_queue_mutex_lock();
710 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
711 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
713 pthread_mutex_lock(&surface_queue->lock);
715 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
717 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
719 pthread_mutex_unlock(&surface_queue->lock);
721 _tbm_surf_queue_mutex_unlock();
723 return TBM_SURFACE_QUEUE_ERROR_NONE;
726 tbm_surface_queue_error_e
727 tbm_surface_queue_remove_can_dequeue_cb(
728 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
731 _tbm_surf_queue_mutex_lock();
733 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
734 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
736 pthread_mutex_lock(&surface_queue->lock);
738 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
740 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
742 pthread_mutex_unlock(&surface_queue->lock);
744 _tbm_surf_queue_mutex_unlock();
746 return TBM_SURFACE_QUEUE_ERROR_NONE;
749 tbm_surface_queue_error_e
750 tbm_surface_queue_add_acquirable_cb(
751 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
754 _tbm_surf_queue_mutex_lock();
756 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
757 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
759 pthread_mutex_lock(&surface_queue->lock);
761 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
763 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
765 pthread_mutex_unlock(&surface_queue->lock);
767 _tbm_surf_queue_mutex_unlock();
769 return TBM_SURFACE_QUEUE_ERROR_NONE;
772 tbm_surface_queue_error_e
773 tbm_surface_queue_remove_acquirable_cb(
774 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
777 _tbm_surf_queue_mutex_lock();
779 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
780 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
782 pthread_mutex_lock(&surface_queue->lock);
784 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
786 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
788 pthread_mutex_unlock(&surface_queue->lock);
790 _tbm_surf_queue_mutex_unlock();
792 return TBM_SURFACE_QUEUE_ERROR_NONE;
795 tbm_surface_queue_error_e
796 tbm_surface_queue_set_alloc_cb(
797 tbm_surface_queue_h surface_queue,
798 tbm_surface_alloc_cb alloc_cb,
799 tbm_surface_free_cb free_cb,
802 _tbm_surf_queue_mutex_lock();
804 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
805 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
807 pthread_mutex_lock(&surface_queue->lock);
809 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
811 surface_queue->alloc_cb = alloc_cb;
812 surface_queue->free_cb = free_cb;
813 surface_queue->alloc_cb_data = data;
815 pthread_mutex_unlock(&surface_queue->lock);
817 _tbm_surf_queue_mutex_unlock();
819 return TBM_SURFACE_QUEUE_ERROR_NONE;
823 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
827 _tbm_surf_queue_mutex_lock();
829 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
831 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
833 width = surface_queue->width;
835 _tbm_surf_queue_mutex_unlock();
841 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
845 _tbm_surf_queue_mutex_lock();
847 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
849 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
851 height = surface_queue->height;
853 _tbm_surf_queue_mutex_unlock();
859 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
863 _tbm_surf_queue_mutex_lock();
865 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
867 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
869 format = surface_queue->format;
871 _tbm_surf_queue_mutex_unlock();
877 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
881 _tbm_surf_queue_mutex_lock();
883 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
885 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
887 queue_size = surface_queue->queue_size;
889 _tbm_surf_queue_mutex_unlock();
894 tbm_surface_queue_error_e
895 tbm_surface_queue_add_reset_cb(
896 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
899 _tbm_surf_queue_mutex_lock();
901 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
902 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
904 pthread_mutex_lock(&surface_queue->lock);
906 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
908 _notify_add(&surface_queue->reset_noti, reset_cb, data);
910 pthread_mutex_unlock(&surface_queue->lock);
912 _tbm_surf_queue_mutex_unlock();
914 return TBM_SURFACE_QUEUE_ERROR_NONE;
917 tbm_surface_queue_error_e
918 tbm_surface_queue_remove_reset_cb(
919 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
922 _tbm_surf_queue_mutex_lock();
924 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
925 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
927 pthread_mutex_lock(&surface_queue->lock);
929 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
931 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
933 pthread_mutex_unlock(&surface_queue->lock);
935 _tbm_surf_queue_mutex_unlock();
937 return TBM_SURFACE_QUEUE_ERROR_NONE;
940 tbm_surface_queue_error_e
941 tbm_surface_queue_enqueue(tbm_surface_queue_h
942 surface_queue, tbm_surface_h surface)
947 _tbm_surf_queue_mutex_lock();
949 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
950 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
951 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
952 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
955 tbm_surface_internal_dump_buffer(surface, "enqueue");
957 pthread_mutex_lock(&surface_queue->lock);
959 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
961 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
962 if (node == NULL || queue_type != NODE_LIST) {
963 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
965 pthread_mutex_unlock(&surface_queue->lock);
967 _tbm_surf_queue_mutex_unlock();
968 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
971 if (surface_queue->impl && surface_queue->impl->enqueue)
972 surface_queue->impl->enqueue(surface_queue, node);
974 _tbm_surface_queue_enqueue(surface_queue, node, 1);
976 if (_queue_is_empty(&surface_queue->dirty_queue)) {
977 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
978 pthread_mutex_unlock(&surface_queue->lock);
980 _tbm_surf_queue_mutex_unlock();
981 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
984 node->type = QUEUE_NODE_TYPE_ENQUEUE;
986 pthread_mutex_unlock(&surface_queue->lock);
987 pthread_cond_signal(&surface_queue->dirty_cond);
989 _tbm_surf_queue_mutex_unlock();
991 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
993 return TBM_SURFACE_QUEUE_ERROR_NONE;
996 tbm_surface_queue_error_e
997 tbm_surface_queue_dequeue(tbm_surface_queue_h
998 surface_queue, tbm_surface_h *surface)
1002 _tbm_surf_queue_mutex_lock();
1006 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1007 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1008 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1009 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1011 pthread_mutex_lock(&surface_queue->lock);
1013 if (surface_queue->impl && surface_queue->impl->dequeue)
1014 node = surface_queue->impl->dequeue(surface_queue);
1016 node = _tbm_surface_queue_dequeue(surface_queue);
1018 if (node == NULL || node->surface == NULL) {
1019 TBM_LOG_E("_queue_node_pop_front failed\n");
1020 pthread_mutex_unlock(&surface_queue->lock);
1022 _tbm_surf_queue_mutex_unlock();
1023 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1026 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1027 *surface = node->surface;
1029 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1031 pthread_mutex_unlock(&surface_queue->lock);
1033 _tbm_surf_queue_mutex_unlock();
1035 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1037 return TBM_SURFACE_QUEUE_ERROR_NONE;
1041 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1043 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue, 0);
1045 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1047 _tbm_surf_queue_mutex_lock();
1049 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1051 pthread_mutex_lock(&surface_queue->lock);
1053 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1055 if (_queue_is_empty(&surface_queue->free_queue)) {
1056 if (surface_queue->impl && surface_queue->impl->need_attach)
1057 surface_queue->impl->need_attach(surface_queue);
1059 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1060 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1061 _tbm_surf_queue_mutex_unlock();
1066 if (!_queue_is_empty(&surface_queue->free_queue)) {
1067 pthread_mutex_unlock(&surface_queue->lock);
1068 _tbm_surf_queue_mutex_unlock();
1072 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1073 QUEUE_NODE_TYPE_ACQUIRE)) {
1074 _tbm_surf_queue_mutex_unlock();
1075 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1076 _tbm_surf_queue_mutex_lock();
1078 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1079 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1080 pthread_mutex_unlock(&surface_queue->lock);
1081 _tbm_surf_queue_mutex_unlock();
1085 pthread_mutex_unlock(&surface_queue->lock);
1086 _tbm_surf_queue_mutex_unlock();
1090 pthread_mutex_unlock(&surface_queue->lock);
1091 _tbm_surf_queue_mutex_unlock();
1095 tbm_surface_queue_error_e
1096 tbm_surface_queue_release(tbm_surface_queue_h
1097 surface_queue, tbm_surface_h surface)
1102 _tbm_surf_queue_mutex_lock();
1104 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1105 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1106 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1107 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1109 pthread_mutex_lock(&surface_queue->lock);
1111 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1113 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1114 if (node == NULL || queue_type != NODE_LIST) {
1115 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1117 pthread_mutex_unlock(&surface_queue->lock);
1119 _tbm_surf_queue_mutex_unlock();
1120 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1123 if (surface_queue->queue_size < surface_queue->num_attached) {
1124 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1126 if (surface_queue->impl && surface_queue->impl->need_detach)
1127 surface_queue->impl->need_detach(surface_queue, node);
1129 _tbm_surface_queue_detach(surface_queue, surface);
1131 pthread_mutex_unlock(&surface_queue->lock);
1133 _tbm_surf_queue_mutex_unlock();
1134 return TBM_SURFACE_QUEUE_ERROR_NONE;
1137 if (surface_queue->impl && surface_queue->impl->release)
1138 surface_queue->impl->release(surface_queue, node);
1140 _tbm_surface_queue_release(surface_queue, node, 1);
1142 if (_queue_is_empty(&surface_queue->free_queue)) {
1143 pthread_mutex_unlock(&surface_queue->lock);
1145 _tbm_surf_queue_mutex_unlock();
1146 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1149 node->type = QUEUE_NODE_TYPE_RELEASE;
1151 pthread_mutex_unlock(&surface_queue->lock);
1152 pthread_cond_signal(&surface_queue->free_cond);
1154 _tbm_surf_queue_mutex_unlock();
1156 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1158 return TBM_SURFACE_QUEUE_ERROR_NONE;
1161 tbm_surface_queue_error_e
1162 tbm_surface_queue_acquire(tbm_surface_queue_h
1163 surface_queue, tbm_surface_h *surface)
1167 _tbm_surf_queue_mutex_lock();
1171 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1172 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1173 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1174 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1176 pthread_mutex_lock(&surface_queue->lock);
1178 if (surface_queue->impl && surface_queue->impl->acquire)
1179 node = surface_queue->impl->acquire(surface_queue);
1181 node = _tbm_surface_queue_acquire(surface_queue);
1183 if (node == NULL || node->surface == NULL) {
1184 TBM_LOG_E("_queue_node_pop_front failed\n");
1185 pthread_mutex_unlock(&surface_queue->lock);
1187 _tbm_surf_queue_mutex_unlock();
1188 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1191 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1193 *surface = node->surface;
1195 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1197 pthread_mutex_unlock(&surface_queue->lock);
1199 _tbm_surf_queue_mutex_unlock();
1202 tbm_surface_internal_dump_buffer(*surface, "acquire");
1204 return TBM_SURFACE_QUEUE_ERROR_NONE;
1208 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1210 _tbm_surf_queue_mutex_lock();
1212 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1214 pthread_mutex_lock(&surface_queue->lock);
1216 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1218 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1219 pthread_mutex_unlock(&surface_queue->lock);
1220 _tbm_surf_queue_mutex_unlock();
1224 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1225 QUEUE_NODE_TYPE_DEQUEUE)) {
1226 _tbm_surf_queue_mutex_unlock();
1227 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1228 _tbm_surf_queue_mutex_lock();
1230 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1231 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1232 pthread_mutex_unlock(&surface_queue->lock);
1233 _tbm_surf_queue_mutex_unlock();
1237 pthread_mutex_unlock(&surface_queue->lock);
1238 _tbm_surf_queue_mutex_unlock();
1242 pthread_mutex_unlock(&surface_queue->lock);
1243 _tbm_surf_queue_mutex_unlock();
1248 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1250 queue_node *node = NULL, *tmp;
1252 _tbm_surf_queue_mutex_lock();
1254 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1256 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1258 LIST_DEL(&surface_queue->item_link);
1260 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1261 _queue_delete_node(surface_queue, node);
1263 if (surface_queue->impl && surface_queue->impl->destroy)
1264 surface_queue->impl->destroy(surface_queue);
1266 _notify_emit(surface_queue, &surface_queue->destory_noti);
1268 _notify_remove_all(&surface_queue->destory_noti);
1269 _notify_remove_all(&surface_queue->dequeuable_noti);
1270 _notify_remove_all(&surface_queue->dequeue_noti);
1271 _notify_remove_all(&surface_queue->can_dequeue_noti);
1272 _notify_remove_all(&surface_queue->acquirable_noti);
1273 _notify_remove_all(&surface_queue->reset_noti);
1275 pthread_mutex_destroy(&surface_queue->lock);
1277 free(surface_queue);
1279 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1280 _deinit_tbm_surf_queue_bufmgr();
1282 _tbm_surf_queue_mutex_unlock();
1285 tbm_surface_queue_error_e
1286 tbm_surface_queue_reset(tbm_surface_queue_h
1287 surface_queue, int width, int height, int format)
1289 queue_node *node = NULL, *tmp;
1291 _tbm_surf_queue_mutex_lock();
1293 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1294 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1296 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1298 if (width == surface_queue->width && height == surface_queue->height &&
1299 format == surface_queue->format) {
1300 _tbm_surf_queue_mutex_unlock();
1301 return TBM_SURFACE_QUEUE_ERROR_NONE;
1304 pthread_mutex_lock(&surface_queue->lock);
1306 surface_queue->width = width;
1307 surface_queue->height = height;
1308 surface_queue->format = format;
1310 /* Destory surface and Push to free_queue */
1311 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1312 _queue_delete_node(surface_queue, node);
1315 _queue_init(&surface_queue->free_queue);
1316 _queue_init(&surface_queue->dirty_queue);
1317 LIST_INITHEAD(&surface_queue->list);
1319 surface_queue->num_attached = 0;
1321 if (surface_queue->impl && surface_queue->impl->reset)
1322 surface_queue->impl->reset(surface_queue);
1324 pthread_mutex_unlock(&surface_queue->lock);
1325 pthread_cond_signal(&surface_queue->free_cond);
1327 _tbm_surf_queue_mutex_unlock();
1329 _notify_emit(surface_queue, &surface_queue->reset_noti);
1331 return TBM_SURFACE_QUEUE_ERROR_NONE;
1334 tbm_surface_queue_error_e
1335 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1337 _tbm_surf_queue_mutex_lock();
1339 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1340 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1342 _tbm_surf_queue_mutex_unlock();
1344 _notify_emit(surface_queue, &surface_queue->reset_noti);
1346 return TBM_SURFACE_QUEUE_ERROR_NONE;
1349 tbm_surface_queue_error_e
1350 tbm_surface_queue_set_size(tbm_surface_queue_h
1351 surface_queue, int queue_size, int flush)
1353 queue_node *node = NULL, *tmp;
1355 _tbm_surf_queue_mutex_lock();
1357 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1358 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1359 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1360 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1362 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1364 if ((surface_queue->queue_size == queue_size) && !flush) {
1365 _tbm_surf_queue_mutex_unlock();
1366 return TBM_SURFACE_QUEUE_ERROR_NONE;
1369 pthread_mutex_lock(&surface_queue->lock);
1372 /* Destory surface and Push to free_queue */
1373 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1374 _queue_delete_node(surface_queue, node);
1377 _queue_init(&surface_queue->free_queue);
1378 _queue_init(&surface_queue->dirty_queue);
1379 LIST_INITHEAD(&surface_queue->list);
1381 surface_queue->num_attached = 0;
1382 surface_queue->queue_size = queue_size;
1384 if (surface_queue->impl && surface_queue->impl->reset)
1385 surface_queue->impl->reset(surface_queue);
1387 pthread_mutex_unlock(&surface_queue->lock);
1388 pthread_cond_signal(&surface_queue->free_cond);
1390 _tbm_surf_queue_mutex_unlock();
1392 _notify_emit(surface_queue, &surface_queue->reset_noti);
1394 return TBM_SURFACE_QUEUE_ERROR_NONE;
1396 if (surface_queue->queue_size > queue_size) {
1397 int need_del = surface_queue->queue_size - queue_size;
1399 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1400 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1402 if (surface_queue->impl && surface_queue->impl->need_detach)
1403 surface_queue->impl->need_detach(surface_queue, node);
1405 _tbm_surface_queue_detach(surface_queue, node->surface);
1413 surface_queue->queue_size = queue_size;
1415 pthread_mutex_unlock(&surface_queue->lock);
1417 _tbm_surf_queue_mutex_unlock();
1419 return TBM_SURFACE_QUEUE_ERROR_NONE;
1423 tbm_surface_queue_error_e
1424 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1426 queue_node *node = NULL, *tmp;
1428 _tbm_surf_queue_mutex_lock();
1430 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1431 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1433 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1435 if (surface_queue->num_attached == 0) {
1436 _tbm_surf_queue_mutex_unlock();
1437 return TBM_SURFACE_QUEUE_ERROR_NONE;
1440 pthread_mutex_lock(&surface_queue->lock);
1442 /* Destory surface and Push to free_queue */
1443 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1444 _queue_delete_node(surface_queue, node);
1447 _queue_init(&surface_queue->free_queue);
1448 _queue_init(&surface_queue->dirty_queue);
1449 LIST_INITHEAD(&surface_queue->list);
1451 surface_queue->num_attached = 0;
1453 if (surface_queue->impl && surface_queue->impl->reset)
1454 surface_queue->impl->reset(surface_queue);
1456 pthread_mutex_unlock(&surface_queue->lock);
1457 pthread_cond_signal(&surface_queue->free_cond);
1459 _tbm_surf_queue_mutex_unlock();
1461 _notify_emit(surface_queue, &surface_queue->reset_noti);
1463 return TBM_SURFACE_QUEUE_ERROR_NONE;
1466 tbm_surface_queue_error_e
1467 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1468 tbm_surface_h *surfaces, int *num)
1470 queue_node *node = NULL;
1472 _tbm_surf_queue_mutex_lock();
1476 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1477 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1478 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1479 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1481 pthread_mutex_lock(&surface_queue->lock);
1483 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1485 surfaces[*num] = node->surface;
1490 pthread_mutex_unlock(&surface_queue->lock);
1492 _tbm_surf_queue_mutex_unlock();
1494 return TBM_SURFACE_QUEUE_ERROR_NONE;
1499 } tbm_queue_default;
1502 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1504 free(surface_queue->impl_data);
1508 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1510 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1511 tbm_surface_h surface;
1513 if (surface_queue->queue_size == surface_queue->num_attached)
1516 if (surface_queue->alloc_cb) {
1517 pthread_mutex_unlock(&surface_queue->lock);
1518 _tbm_surf_queue_mutex_unlock();
1519 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1520 _tbm_surf_queue_mutex_lock();
1521 pthread_mutex_lock(&surface_queue->lock);
1526 tbm_surface_internal_ref(surface);
1528 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1529 surface_queue->height,
1530 surface_queue->format,
1532 TBM_RETURN_IF_FAIL(surface != NULL);
1535 _tbm_surface_queue_attach(surface_queue, surface);
1536 tbm_surface_internal_unref(surface);
1539 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1540 NULL, /*__tbm_queue_default_init*/
1541 NULL, /*__tbm_queue_default_reset*/
1542 __tbm_queue_default_destroy,
1543 __tbm_queue_default_need_attach,
1544 NULL, /*__tbm_queue_default_enqueue*/
1545 NULL, /*__tbm_queue_default_release*/
1546 NULL, /*__tbm_queue_default_dequeue*/
1547 NULL, /*__tbm_queue_default_acquire*/
1548 NULL, /*__tbm_queue_default_need_detach*/
1552 tbm_surface_queue_create(int queue_size, int width,
1553 int height, int format, int flags)
1555 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1556 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1557 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1558 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1560 _tbm_surf_queue_mutex_lock();
1562 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1563 sizeof(struct _tbm_surface_queue));
1564 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1566 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1568 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1569 sizeof(tbm_queue_default));
1571 free(surface_queue);
1572 _tbm_surf_queue_mutex_unlock();
1576 data->flags = flags;
1577 _tbm_surface_queue_init(surface_queue,
1579 width, height, format,
1580 &tbm_queue_default_impl, data);
1582 _tbm_surf_queue_mutex_unlock();
1584 return surface_queue;
1590 } tbm_queue_sequence;
1593 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1595 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1597 _queue_init(&data->dequeue_list);
1601 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1603 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1605 _queue_init(&data->dequeue_list);
1609 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1611 free(surface_queue->impl_data);
1615 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1617 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1618 tbm_surface_h surface;
1620 if (surface_queue->queue_size == surface_queue->num_attached)
1623 if (surface_queue->alloc_cb) {
1624 pthread_mutex_unlock(&surface_queue->lock);
1625 _tbm_surf_queue_mutex_unlock();
1626 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1627 _tbm_surf_queue_mutex_lock();
1628 pthread_mutex_lock(&surface_queue->lock);
1633 tbm_surface_internal_ref(surface);
1635 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1636 surface_queue->height,
1637 surface_queue->format,
1639 TBM_RETURN_IF_FAIL(surface != NULL);
1642 _tbm_surface_queue_attach(surface_queue, surface);
1643 tbm_surface_internal_unref(surface);
1647 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1650 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1651 queue_node *next = NULL, *tmp;
1653 node->priv_flags = 0;
1655 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1656 if (next->priv_flags)
1658 _queue_node_pop(&data->dequeue_list, next);
1659 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1664 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1667 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1670 node = _tbm_surface_queue_dequeue(surface_queue);
1672 _queue_node_push_back(&data->dequeue_list, node);
1673 node->priv_flags = 1;
1679 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1680 __tbm_queue_sequence_init,
1681 __tbm_queue_sequence_reset,
1682 __tbm_queue_sequence_destroy,
1683 __tbm_queue_sequence_need_attach,
1684 __tbm_queue_sequence_enqueue,
1685 NULL, /*__tbm_queue_sequence_release*/
1686 __tbm_queue_sequence_dequeue,
1687 NULL, /*__tbm_queue_sequence_acquire*/
1688 NULL, /*__tbm_queue_sequence_need_dettach*/
1692 tbm_surface_queue_sequence_create(int queue_size, int width,
1693 int height, int format, int flags)
1695 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1696 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1697 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1698 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1700 _tbm_surf_queue_mutex_lock();
1702 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1703 sizeof(struct _tbm_surface_queue));
1704 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1706 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1708 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1709 sizeof(tbm_queue_sequence));
1711 free(surface_queue);
1712 _tbm_surf_queue_mutex_unlock();
1716 data->flags = flags;
1717 _tbm_surface_queue_init(surface_queue,
1719 width, height, format,
1720 &tbm_queue_sequence_impl, data);
1722 _tbm_surf_queue_mutex_unlock();
1724 return surface_queue;
1726 /* LCOV_EXCL_STOP */