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_mutex_lock();
1045 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1047 _tbm_surf_queue_mutex_unlock();
1049 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1051 _tbm_surf_queue_mutex_lock();
1053 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1055 pthread_mutex_lock(&surface_queue->lock);
1057 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1059 if (_queue_is_empty(&surface_queue->free_queue)) {
1060 if (surface_queue->impl && surface_queue->impl->need_attach)
1061 surface_queue->impl->need_attach(surface_queue);
1063 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1064 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1065 _tbm_surf_queue_mutex_unlock();
1070 if (!_queue_is_empty(&surface_queue->free_queue)) {
1071 pthread_mutex_unlock(&surface_queue->lock);
1072 _tbm_surf_queue_mutex_unlock();
1076 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1077 QUEUE_NODE_TYPE_ACQUIRE)) {
1078 _tbm_surf_queue_mutex_unlock();
1079 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1080 _tbm_surf_queue_mutex_lock();
1082 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1083 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1084 pthread_mutex_unlock(&surface_queue->lock);
1085 _tbm_surf_queue_mutex_unlock();
1089 pthread_mutex_unlock(&surface_queue->lock);
1090 _tbm_surf_queue_mutex_unlock();
1094 pthread_mutex_unlock(&surface_queue->lock);
1095 _tbm_surf_queue_mutex_unlock();
1099 tbm_surface_queue_error_e
1100 tbm_surface_queue_release(tbm_surface_queue_h
1101 surface_queue, tbm_surface_h surface)
1106 _tbm_surf_queue_mutex_lock();
1108 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1109 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1110 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1111 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1113 pthread_mutex_lock(&surface_queue->lock);
1115 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1117 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1118 if (node == NULL || queue_type != NODE_LIST) {
1119 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1121 pthread_mutex_unlock(&surface_queue->lock);
1123 _tbm_surf_queue_mutex_unlock();
1124 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1127 if (surface_queue->queue_size < surface_queue->num_attached) {
1128 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1130 if (surface_queue->impl && surface_queue->impl->need_detach)
1131 surface_queue->impl->need_detach(surface_queue, node);
1133 _tbm_surface_queue_detach(surface_queue, surface);
1135 pthread_mutex_unlock(&surface_queue->lock);
1137 _tbm_surf_queue_mutex_unlock();
1138 return TBM_SURFACE_QUEUE_ERROR_NONE;
1141 if (surface_queue->impl && surface_queue->impl->release)
1142 surface_queue->impl->release(surface_queue, node);
1144 _tbm_surface_queue_release(surface_queue, node, 1);
1146 if (_queue_is_empty(&surface_queue->free_queue)) {
1147 pthread_mutex_unlock(&surface_queue->lock);
1149 _tbm_surf_queue_mutex_unlock();
1150 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1153 node->type = QUEUE_NODE_TYPE_RELEASE;
1155 pthread_mutex_unlock(&surface_queue->lock);
1156 pthread_cond_signal(&surface_queue->free_cond);
1158 _tbm_surf_queue_mutex_unlock();
1160 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1162 return TBM_SURFACE_QUEUE_ERROR_NONE;
1165 tbm_surface_queue_error_e
1166 tbm_surface_queue_acquire(tbm_surface_queue_h
1167 surface_queue, tbm_surface_h *surface)
1171 _tbm_surf_queue_mutex_lock();
1175 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1176 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1177 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1178 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1180 pthread_mutex_lock(&surface_queue->lock);
1182 if (surface_queue->impl && surface_queue->impl->acquire)
1183 node = surface_queue->impl->acquire(surface_queue);
1185 node = _tbm_surface_queue_acquire(surface_queue);
1187 if (node == NULL || node->surface == NULL) {
1188 TBM_LOG_E("_queue_node_pop_front failed\n");
1189 pthread_mutex_unlock(&surface_queue->lock);
1191 _tbm_surf_queue_mutex_unlock();
1192 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1195 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1197 *surface = node->surface;
1199 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1201 pthread_mutex_unlock(&surface_queue->lock);
1203 _tbm_surf_queue_mutex_unlock();
1206 tbm_surface_internal_dump_buffer(*surface, "acquire");
1208 return TBM_SURFACE_QUEUE_ERROR_NONE;
1212 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1214 _tbm_surf_queue_mutex_lock();
1216 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1218 pthread_mutex_lock(&surface_queue->lock);
1220 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1222 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1223 pthread_mutex_unlock(&surface_queue->lock);
1224 _tbm_surf_queue_mutex_unlock();
1228 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1229 QUEUE_NODE_TYPE_DEQUEUE)) {
1230 _tbm_surf_queue_mutex_unlock();
1231 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1232 _tbm_surf_queue_mutex_lock();
1234 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1235 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1236 pthread_mutex_unlock(&surface_queue->lock);
1237 _tbm_surf_queue_mutex_unlock();
1241 pthread_mutex_unlock(&surface_queue->lock);
1242 _tbm_surf_queue_mutex_unlock();
1246 pthread_mutex_unlock(&surface_queue->lock);
1247 _tbm_surf_queue_mutex_unlock();
1252 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1254 queue_node *node = NULL, *tmp;
1256 _tbm_surf_queue_mutex_lock();
1258 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1260 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1262 LIST_DEL(&surface_queue->item_link);
1264 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1265 _queue_delete_node(surface_queue, node);
1267 if (surface_queue->impl && surface_queue->impl->destroy)
1268 surface_queue->impl->destroy(surface_queue);
1270 _notify_emit(surface_queue, &surface_queue->destory_noti);
1272 _notify_remove_all(&surface_queue->destory_noti);
1273 _notify_remove_all(&surface_queue->dequeuable_noti);
1274 _notify_remove_all(&surface_queue->dequeue_noti);
1275 _notify_remove_all(&surface_queue->can_dequeue_noti);
1276 _notify_remove_all(&surface_queue->acquirable_noti);
1277 _notify_remove_all(&surface_queue->reset_noti);
1279 pthread_mutex_destroy(&surface_queue->lock);
1281 free(surface_queue);
1283 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1284 _deinit_tbm_surf_queue_bufmgr();
1286 _tbm_surf_queue_mutex_unlock();
1289 tbm_surface_queue_error_e
1290 tbm_surface_queue_reset(tbm_surface_queue_h
1291 surface_queue, int width, int height, int format)
1293 queue_node *node = NULL, *tmp;
1295 _tbm_surf_queue_mutex_lock();
1297 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1298 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1300 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1302 if (width == surface_queue->width && height == surface_queue->height &&
1303 format == surface_queue->format) {
1304 _tbm_surf_queue_mutex_unlock();
1305 return TBM_SURFACE_QUEUE_ERROR_NONE;
1308 pthread_mutex_lock(&surface_queue->lock);
1310 surface_queue->width = width;
1311 surface_queue->height = height;
1312 surface_queue->format = format;
1314 /* Destory surface and Push to free_queue */
1315 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1316 _queue_delete_node(surface_queue, node);
1319 _queue_init(&surface_queue->free_queue);
1320 _queue_init(&surface_queue->dirty_queue);
1321 LIST_INITHEAD(&surface_queue->list);
1323 surface_queue->num_attached = 0;
1325 if (surface_queue->impl && surface_queue->impl->reset)
1326 surface_queue->impl->reset(surface_queue);
1328 pthread_mutex_unlock(&surface_queue->lock);
1329 pthread_cond_signal(&surface_queue->free_cond);
1331 _tbm_surf_queue_mutex_unlock();
1333 _notify_emit(surface_queue, &surface_queue->reset_noti);
1335 return TBM_SURFACE_QUEUE_ERROR_NONE;
1338 tbm_surface_queue_error_e
1339 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1341 _tbm_surf_queue_mutex_lock();
1343 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1344 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1346 _tbm_surf_queue_mutex_unlock();
1348 _notify_emit(surface_queue, &surface_queue->reset_noti);
1350 return TBM_SURFACE_QUEUE_ERROR_NONE;
1353 tbm_surface_queue_error_e
1354 tbm_surface_queue_set_size(tbm_surface_queue_h
1355 surface_queue, int queue_size, int flush)
1357 queue_node *node = NULL, *tmp;
1359 _tbm_surf_queue_mutex_lock();
1361 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1362 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1363 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1364 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1366 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1368 if ((surface_queue->queue_size == queue_size) && !flush) {
1369 _tbm_surf_queue_mutex_unlock();
1370 return TBM_SURFACE_QUEUE_ERROR_NONE;
1373 pthread_mutex_lock(&surface_queue->lock);
1376 /* Destory surface and Push to free_queue */
1377 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1378 _queue_delete_node(surface_queue, node);
1381 _queue_init(&surface_queue->free_queue);
1382 _queue_init(&surface_queue->dirty_queue);
1383 LIST_INITHEAD(&surface_queue->list);
1385 surface_queue->num_attached = 0;
1386 surface_queue->queue_size = queue_size;
1388 if (surface_queue->impl && surface_queue->impl->reset)
1389 surface_queue->impl->reset(surface_queue);
1391 pthread_mutex_unlock(&surface_queue->lock);
1392 pthread_cond_signal(&surface_queue->free_cond);
1394 _tbm_surf_queue_mutex_unlock();
1396 _notify_emit(surface_queue, &surface_queue->reset_noti);
1398 return TBM_SURFACE_QUEUE_ERROR_NONE;
1400 if (surface_queue->queue_size > queue_size) {
1401 int need_del = surface_queue->queue_size - queue_size;
1403 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1404 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1406 if (surface_queue->impl && surface_queue->impl->need_detach)
1407 surface_queue->impl->need_detach(surface_queue, node);
1409 _tbm_surface_queue_detach(surface_queue, node->surface);
1417 surface_queue->queue_size = queue_size;
1419 pthread_mutex_unlock(&surface_queue->lock);
1421 _tbm_surf_queue_mutex_unlock();
1423 return TBM_SURFACE_QUEUE_ERROR_NONE;
1427 tbm_surface_queue_error_e
1428 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1430 queue_node *node = NULL, *tmp;
1432 _tbm_surf_queue_mutex_lock();
1434 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1435 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1437 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1439 if (surface_queue->num_attached == 0) {
1440 _tbm_surf_queue_mutex_unlock();
1441 return TBM_SURFACE_QUEUE_ERROR_NONE;
1444 pthread_mutex_lock(&surface_queue->lock);
1446 /* Destory surface and Push to free_queue */
1447 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1448 _queue_delete_node(surface_queue, node);
1451 _queue_init(&surface_queue->free_queue);
1452 _queue_init(&surface_queue->dirty_queue);
1453 LIST_INITHEAD(&surface_queue->list);
1455 surface_queue->num_attached = 0;
1457 if (surface_queue->impl && surface_queue->impl->reset)
1458 surface_queue->impl->reset(surface_queue);
1460 pthread_mutex_unlock(&surface_queue->lock);
1461 pthread_cond_signal(&surface_queue->free_cond);
1463 _tbm_surf_queue_mutex_unlock();
1465 _notify_emit(surface_queue, &surface_queue->reset_noti);
1467 return TBM_SURFACE_QUEUE_ERROR_NONE;
1470 tbm_surface_queue_error_e
1471 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1472 tbm_surface_h *surfaces, int *num)
1474 queue_node *node = NULL;
1476 _tbm_surf_queue_mutex_lock();
1480 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1481 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1482 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1483 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1485 pthread_mutex_lock(&surface_queue->lock);
1487 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1489 surfaces[*num] = node->surface;
1494 pthread_mutex_unlock(&surface_queue->lock);
1496 _tbm_surf_queue_mutex_unlock();
1498 return TBM_SURFACE_QUEUE_ERROR_NONE;
1503 } tbm_queue_default;
1506 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1508 free(surface_queue->impl_data);
1512 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1514 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1515 tbm_surface_h surface;
1517 if (surface_queue->queue_size == surface_queue->num_attached)
1520 if (surface_queue->alloc_cb) {
1521 pthread_mutex_unlock(&surface_queue->lock);
1522 _tbm_surf_queue_mutex_unlock();
1523 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1524 _tbm_surf_queue_mutex_lock();
1525 pthread_mutex_lock(&surface_queue->lock);
1530 tbm_surface_internal_ref(surface);
1532 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1533 surface_queue->height,
1534 surface_queue->format,
1536 TBM_RETURN_IF_FAIL(surface != NULL);
1539 _tbm_surface_queue_attach(surface_queue, surface);
1540 tbm_surface_internal_unref(surface);
1543 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1544 NULL, /*__tbm_queue_default_init*/
1545 NULL, /*__tbm_queue_default_reset*/
1546 __tbm_queue_default_destroy,
1547 __tbm_queue_default_need_attach,
1548 NULL, /*__tbm_queue_default_enqueue*/
1549 NULL, /*__tbm_queue_default_release*/
1550 NULL, /*__tbm_queue_default_dequeue*/
1551 NULL, /*__tbm_queue_default_acquire*/
1552 NULL, /*__tbm_queue_default_need_detach*/
1556 tbm_surface_queue_create(int queue_size, int width,
1557 int height, int format, int flags)
1559 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1560 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1561 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1562 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1564 _tbm_surf_queue_mutex_lock();
1566 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1567 sizeof(struct _tbm_surface_queue));
1568 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1570 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1572 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1573 sizeof(tbm_queue_default));
1575 free(surface_queue);
1576 _tbm_surf_queue_mutex_unlock();
1580 data->flags = flags;
1581 _tbm_surface_queue_init(surface_queue,
1583 width, height, format,
1584 &tbm_queue_default_impl, data);
1586 _tbm_surf_queue_mutex_unlock();
1588 return surface_queue;
1594 } tbm_queue_sequence;
1597 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1599 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1601 _queue_init(&data->dequeue_list);
1605 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1607 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1609 _queue_init(&data->dequeue_list);
1613 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1615 free(surface_queue->impl_data);
1619 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1621 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1622 tbm_surface_h surface;
1624 if (surface_queue->queue_size == surface_queue->num_attached)
1627 if (surface_queue->alloc_cb) {
1628 pthread_mutex_unlock(&surface_queue->lock);
1629 _tbm_surf_queue_mutex_unlock();
1630 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1631 _tbm_surf_queue_mutex_lock();
1632 pthread_mutex_lock(&surface_queue->lock);
1637 tbm_surface_internal_ref(surface);
1639 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1640 surface_queue->height,
1641 surface_queue->format,
1643 TBM_RETURN_IF_FAIL(surface != NULL);
1646 _tbm_surface_queue_attach(surface_queue, surface);
1647 tbm_surface_internal_unref(surface);
1651 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1654 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1655 queue_node *next = NULL, *tmp;
1657 node->priv_flags = 0;
1659 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1660 if (next->priv_flags)
1662 _queue_node_pop(&data->dequeue_list, next);
1663 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1668 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1671 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1674 node = _tbm_surface_queue_dequeue(surface_queue);
1676 _queue_node_push_back(&data->dequeue_list, node);
1677 node->priv_flags = 1;
1683 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1684 __tbm_queue_sequence_init,
1685 __tbm_queue_sequence_reset,
1686 __tbm_queue_sequence_destroy,
1687 __tbm_queue_sequence_need_attach,
1688 __tbm_queue_sequence_enqueue,
1689 NULL, /*__tbm_queue_sequence_release*/
1690 __tbm_queue_sequence_dequeue,
1691 NULL, /*__tbm_queue_sequence_acquire*/
1692 NULL, /*__tbm_queue_sequence_need_dettach*/
1696 tbm_surface_queue_sequence_create(int queue_size, int width,
1697 int height, int format, int flags)
1699 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1700 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1701 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1702 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1704 _tbm_surf_queue_mutex_lock();
1706 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1707 sizeof(struct _tbm_surface_queue));
1708 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1710 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1712 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1713 sizeof(tbm_queue_sequence));
1715 free(surface_queue);
1716 _tbm_surf_queue_mutex_unlock();
1720 data->flags = flags;
1721 _tbm_surface_queue_init(surface_queue,
1723 width, height, format,
1724 &tbm_queue_sequence_impl, data);
1726 _tbm_surf_queue_mutex_unlock();
1728 return surface_queue;
1730 /* LCOV_EXCL_STOP */