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;
110 struct list_head link;
112 tbm_surface_queue_trace_cb cb;
116 typedef struct _tbm_surface_queue_interface {
117 void (*init)(tbm_surface_queue_h queue);
118 void (*reset)(tbm_surface_queue_h queue);
119 void (*destroy)(tbm_surface_queue_h queue);
120 void (*need_attach)(tbm_surface_queue_h queue);
122 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
123 void (*release)(tbm_surface_queue_h queue, queue_node *node);
124 queue_node *(*dequeue)(tbm_surface_queue_h queue);
125 queue_node *(*acquire)(tbm_surface_queue_h queue);
126 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
127 } tbm_surface_queue_interface;
129 struct _tbm_surface_queue {
138 struct list_head list;
140 struct list_head destory_noti;
141 struct list_head dequeuable_noti;
142 struct list_head dequeue_noti;
143 struct list_head can_dequeue_noti;
144 struct list_head acquirable_noti;
145 struct list_head reset_noti;
146 struct list_head trace_noti;
148 pthread_mutex_t lock;
149 pthread_cond_t free_cond;
150 pthread_cond_t dirty_cond;
152 const tbm_surface_queue_interface *impl;
155 //For external buffer allocation
156 tbm_surface_alloc_cb alloc_cb;
157 tbm_surface_free_cb free_cb;
160 struct list_head item_link; /* link of surface queue */
163 /* LCOV_EXCL_START */
166 _tbm_surf_queue_mutex_init(void)
168 static bool tbm_surf_queue_mutex_init = false;
170 if (tbm_surf_queue_mutex_init)
173 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
174 TBM_LOG_E("fail: pthread_mutex_init\n");
178 tbm_surf_queue_mutex_init = true;
184 _tbm_surf_queue_mutex_lock(void)
186 if (!_tbm_surf_queue_mutex_init()) {
187 TBM_LOG_E("fail: _tbm_surf_queue_mutex_init\n");
191 pthread_mutex_lock(&tbm_surf_queue_lock);
195 _tbm_surf_queue_mutex_unlock(void)
197 pthread_mutex_unlock(&tbm_surf_queue_lock);
201 _init_tbm_surf_queue_bufmgr(void)
203 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
207 _deinit_tbm_surf_queue_bufmgr(void)
209 if (!g_surf_queue_bufmgr)
212 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
213 g_surf_queue_bufmgr = NULL;
217 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
219 tbm_surface_queue_h old_data = NULL;
221 if (surface_queue == NULL) {
222 TBM_LOG_E("error: surface_queue is NULL.\n");
226 if (g_surf_queue_bufmgr == NULL) {
227 TBM_LOG_E("error: g_surf_queue_bufmgr is NULL.\n");
231 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
232 TBM_LOG_E("error: surf_queue_list is empty\n");
236 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
238 if (old_data == surface_queue) {
239 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
244 TBM_LOG_E("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
250 _queue_node_create(void)
252 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
254 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
260 _queue_node_delete(queue_node *node)
262 LIST_DEL(&node->item_link);
263 LIST_DEL(&node->link);
268 _queue_is_empty(queue *queue)
270 if (LIST_IS_EMPTY(&queue->head))
277 _queue_node_push_back(queue *queue, queue_node *node)
279 LIST_ADDTAIL(&node->item_link, &queue->head);
284 _queue_node_push_front(queue *queue, queue_node *node)
286 LIST_ADD(&node->item_link, &queue->head);
291 _queue_node_pop_front(queue *queue)
295 if (!queue->head.next) return NULL;
296 if (!queue->count) return NULL;
298 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
300 LIST_DELINIT(&node->item_link);
307 _queue_node_pop(queue *queue, queue_node *node)
309 LIST_DELINIT(&node->item_link);
316 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
317 tbm_surface_h surface, int *out_type)
319 queue_node *node = NULL;
322 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
326 if (type & FREE_QUEUE) {
327 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
329 if (node->surface == surface) {
331 *out_type = FREE_QUEUE;
338 if (type & DIRTY_QUEUE) {
339 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
341 if (node->surface == surface) {
343 *out_type = DIRTY_QUEUE;
350 if (type & NODE_LIST) {
351 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
352 if (node->surface == surface) {
354 *out_type = NODE_LIST;
361 TBM_LOG_E("fail to get the queue_node.\n");
367 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
370 if (surface_queue->free_cb) {
371 surface_queue->free_cb(surface_queue,
372 surface_queue->alloc_cb_data,
376 tbm_surface_destroy(node->surface);
379 _queue_node_delete(node);
383 _queue_init(queue *queue)
385 LIST_INITHEAD(&queue->head);
391 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
394 TBM_RETURN_IF_FAIL(cb != NULL);
396 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
398 TBM_RETURN_IF_FAIL(item != NULL);
400 LIST_INITHEAD(&item->link);
404 LIST_ADDTAIL(&item->link, list);
408 _notify_remove(struct list_head *list,
409 tbm_surface_queue_notify_cb cb, void *data)
411 queue_notify *item = NULL, *tmp;
413 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
414 if (item->cb == cb && item->data == data) {
415 LIST_DEL(&item->link);
421 TBM_LOG_E("Cannot find notifiy\n");
425 _notify_remove_all(struct list_head *list)
427 queue_notify *item = NULL, *tmp;
429 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
430 LIST_DEL(&item->link);
436 _notify_emit(tbm_surface_queue_h surface_queue,
437 struct list_head *list)
439 queue_notify *item = NULL, *tmp;;
442 The item->cb is the outside function of the libtbm.
443 The tbm user may/can remove the item of the list,
444 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
446 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
447 item->cb(surface_queue, item->data);
451 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
454 TBM_RETURN_IF_FAIL(cb != NULL);
456 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
458 TBM_RETURN_IF_FAIL(item != NULL);
460 LIST_INITHEAD(&item->link);
464 LIST_ADDTAIL(&item->link, list);
468 _trace_remove(struct list_head *list,
469 tbm_surface_queue_trace_cb cb, void *data)
471 queue_trace *item = NULL, *tmp;
473 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
474 if (item->cb == cb && item->data == data) {
475 LIST_DEL(&item->link);
481 TBM_LOG_E("Cannot find notifiy\n");
485 _trace_remove_all(struct list_head *list)
487 queue_trace *item = NULL, *tmp;
489 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
490 LIST_DEL(&item->link);
496 _trace_emit(tbm_surface_queue_h surface_queue,
497 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
499 queue_trace *item = NULL, *tmp;;
502 The item->cb is the outside function of the libtbm.
503 The tbm user may/can remove the item of the list,
504 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
506 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
507 item->cb(surface_queue, surface, trace, item->data);
511 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
513 queue_node *node = NULL;
516 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
517 if (node->type == type)
525 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
526 tbm_surface_h surface)
530 node = _queue_node_create();
531 TBM_RETURN_IF_FAIL(node != NULL);
533 tbm_surface_internal_ref(surface);
534 node->surface = surface;
536 LIST_ADDTAIL(&node->link, &surface_queue->list);
537 surface_queue->num_attached++;
538 _queue_node_push_back(&surface_queue->free_queue, node);
542 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
543 tbm_surface_h surface)
548 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
550 _queue_delete_node(surface_queue, node);
551 surface_queue->num_attached--;
556 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
557 queue_node *node, int push_back)
560 _queue_node_push_back(&surface_queue->dirty_queue, node);
562 _queue_node_push_front(&surface_queue->dirty_queue, node);
566 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
570 node = _queue_node_pop_front(&surface_queue->free_queue);
576 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
580 if (_queue_is_empty(&surface_queue->dirty_queue))
583 node = _queue_node_pop_front(&surface_queue->dirty_queue);
589 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
590 queue_node *node, int push_back)
593 _queue_node_push_back(&surface_queue->free_queue, node);
595 _queue_node_push_front(&surface_queue->free_queue, node);
599 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
601 int width, int height, int format,
602 const tbm_surface_queue_interface *impl, void *data)
604 TBM_RETURN_IF_FAIL(surface_queue != NULL);
605 TBM_RETURN_IF_FAIL(impl != NULL);
607 if (!g_surf_queue_bufmgr)
608 _init_tbm_surf_queue_bufmgr();
610 pthread_mutex_init(&surface_queue->lock, NULL);
611 pthread_cond_init(&surface_queue->free_cond, NULL);
612 pthread_cond_init(&surface_queue->dirty_cond, NULL);
614 surface_queue->queue_size = queue_size;
615 surface_queue->width = width;
616 surface_queue->height = height;
617 surface_queue->format = format;
618 surface_queue->impl = impl;
619 surface_queue->impl_data = data;
621 _queue_init(&surface_queue->free_queue);
622 _queue_init(&surface_queue->dirty_queue);
623 LIST_INITHEAD(&surface_queue->list);
625 LIST_INITHEAD(&surface_queue->destory_noti);
626 LIST_INITHEAD(&surface_queue->dequeuable_noti);
627 LIST_INITHEAD(&surface_queue->dequeue_noti);
628 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
629 LIST_INITHEAD(&surface_queue->acquirable_noti);
630 LIST_INITHEAD(&surface_queue->reset_noti);
631 LIST_INITHEAD(&surface_queue->trace_noti);
633 if (surface_queue->impl && surface_queue->impl->init)
634 surface_queue->impl->init(surface_queue);
636 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
639 tbm_surface_queue_error_e
640 tbm_surface_queue_add_destroy_cb(
641 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
644 _tbm_surf_queue_mutex_lock();
646 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
647 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
649 pthread_mutex_lock(&surface_queue->lock);
651 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
653 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
655 pthread_mutex_unlock(&surface_queue->lock);
657 _tbm_surf_queue_mutex_unlock();
659 return TBM_SURFACE_QUEUE_ERROR_NONE;
662 tbm_surface_queue_error_e
663 tbm_surface_queue_remove_destroy_cb(
664 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
667 _tbm_surf_queue_mutex_lock();
669 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
670 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
672 pthread_mutex_lock(&surface_queue->lock);
674 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
676 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
678 pthread_mutex_unlock(&surface_queue->lock);
680 _tbm_surf_queue_mutex_unlock();
682 return TBM_SURFACE_QUEUE_ERROR_NONE;
685 tbm_surface_queue_error_e
686 tbm_surface_queue_add_dequeuable_cb(
687 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
690 _tbm_surf_queue_mutex_lock();
692 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
693 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
695 pthread_mutex_lock(&surface_queue->lock);
697 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
699 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
701 pthread_mutex_unlock(&surface_queue->lock);
703 _tbm_surf_queue_mutex_unlock();
705 return TBM_SURFACE_QUEUE_ERROR_NONE;
708 tbm_surface_queue_error_e
709 tbm_surface_queue_remove_dequeuable_cb(
710 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
713 _tbm_surf_queue_mutex_lock();
715 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
716 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
718 pthread_mutex_lock(&surface_queue->lock);
720 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
722 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
724 pthread_mutex_unlock(&surface_queue->lock);
726 _tbm_surf_queue_mutex_unlock();
728 return TBM_SURFACE_QUEUE_ERROR_NONE;
731 tbm_surface_queue_error_e
732 tbm_surface_queue_add_dequeue_cb(
733 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
736 _tbm_surf_queue_mutex_lock();
738 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
739 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
741 pthread_mutex_lock(&surface_queue->lock);
743 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
745 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
747 pthread_mutex_unlock(&surface_queue->lock);
749 _tbm_surf_queue_mutex_unlock();
751 return TBM_SURFACE_QUEUE_ERROR_NONE;
754 tbm_surface_queue_error_e
755 tbm_surface_queue_remove_dequeue_cb(
756 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
759 _tbm_surf_queue_mutex_lock();
761 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
762 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
764 pthread_mutex_lock(&surface_queue->lock);
766 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
768 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
770 pthread_mutex_unlock(&surface_queue->lock);
772 _tbm_surf_queue_mutex_unlock();
774 return TBM_SURFACE_QUEUE_ERROR_NONE;
777 tbm_surface_queue_error_e
778 tbm_surface_queue_add_can_dequeue_cb(
779 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
782 _tbm_surf_queue_mutex_lock();
784 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
785 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
787 pthread_mutex_lock(&surface_queue->lock);
789 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
791 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
793 pthread_mutex_unlock(&surface_queue->lock);
795 _tbm_surf_queue_mutex_unlock();
797 return TBM_SURFACE_QUEUE_ERROR_NONE;
800 tbm_surface_queue_error_e
801 tbm_surface_queue_remove_can_dequeue_cb(
802 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
805 _tbm_surf_queue_mutex_lock();
807 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
808 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
810 pthread_mutex_lock(&surface_queue->lock);
812 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
814 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
816 pthread_mutex_unlock(&surface_queue->lock);
818 _tbm_surf_queue_mutex_unlock();
820 return TBM_SURFACE_QUEUE_ERROR_NONE;
823 tbm_surface_queue_error_e
824 tbm_surface_queue_add_acquirable_cb(
825 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
828 _tbm_surf_queue_mutex_lock();
830 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
831 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
833 pthread_mutex_lock(&surface_queue->lock);
835 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
837 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
839 pthread_mutex_unlock(&surface_queue->lock);
841 _tbm_surf_queue_mutex_unlock();
843 return TBM_SURFACE_QUEUE_ERROR_NONE;
846 tbm_surface_queue_error_e
847 tbm_surface_queue_remove_acquirable_cb(
848 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
851 _tbm_surf_queue_mutex_lock();
853 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
854 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
856 pthread_mutex_lock(&surface_queue->lock);
858 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
860 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
862 pthread_mutex_unlock(&surface_queue->lock);
864 _tbm_surf_queue_mutex_unlock();
866 return TBM_SURFACE_QUEUE_ERROR_NONE;
869 tbm_surface_queue_error_e
870 tbm_surface_queue_add_trace_cb(
871 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
874 _tbm_surf_queue_mutex_lock();
876 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
877 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
879 pthread_mutex_lock(&surface_queue->lock);
881 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
883 _trace_add(&surface_queue->trace_noti, trace_cb, data);
885 pthread_mutex_unlock(&surface_queue->lock);
887 _tbm_surf_queue_mutex_unlock();
889 return TBM_SURFACE_QUEUE_ERROR_NONE;
892 tbm_surface_queue_error_e
893 tbm_surface_queue_remove_trace_cb(
894 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
897 _tbm_surf_queue_mutex_lock();
899 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
900 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
902 pthread_mutex_lock(&surface_queue->lock);
904 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
906 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
908 pthread_mutex_unlock(&surface_queue->lock);
910 _tbm_surf_queue_mutex_unlock();
912 return TBM_SURFACE_QUEUE_ERROR_NONE;
915 tbm_surface_queue_error_e
916 tbm_surface_queue_set_alloc_cb(
917 tbm_surface_queue_h surface_queue,
918 tbm_surface_alloc_cb alloc_cb,
919 tbm_surface_free_cb free_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 surface_queue->alloc_cb = alloc_cb;
932 surface_queue->free_cb = free_cb;
933 surface_queue->alloc_cb_data = data;
935 pthread_mutex_unlock(&surface_queue->lock);
937 _tbm_surf_queue_mutex_unlock();
939 return TBM_SURFACE_QUEUE_ERROR_NONE;
943 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
947 _tbm_surf_queue_mutex_lock();
949 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
951 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
953 width = surface_queue->width;
955 _tbm_surf_queue_mutex_unlock();
961 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
965 _tbm_surf_queue_mutex_lock();
967 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
969 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
971 height = surface_queue->height;
973 _tbm_surf_queue_mutex_unlock();
979 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
983 _tbm_surf_queue_mutex_lock();
985 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
987 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
989 format = surface_queue->format;
991 _tbm_surf_queue_mutex_unlock();
997 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1001 _tbm_surf_queue_mutex_lock();
1003 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1005 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1007 queue_size = surface_queue->queue_size;
1009 _tbm_surf_queue_mutex_unlock();
1014 tbm_surface_queue_error_e
1015 tbm_surface_queue_add_reset_cb(
1016 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1019 _tbm_surf_queue_mutex_lock();
1021 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1022 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1024 pthread_mutex_lock(&surface_queue->lock);
1026 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1028 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1030 pthread_mutex_unlock(&surface_queue->lock);
1032 _tbm_surf_queue_mutex_unlock();
1034 return TBM_SURFACE_QUEUE_ERROR_NONE;
1037 tbm_surface_queue_error_e
1038 tbm_surface_queue_remove_reset_cb(
1039 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1042 _tbm_surf_queue_mutex_lock();
1044 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1045 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1047 pthread_mutex_lock(&surface_queue->lock);
1049 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1051 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1053 pthread_mutex_unlock(&surface_queue->lock);
1055 _tbm_surf_queue_mutex_unlock();
1057 return TBM_SURFACE_QUEUE_ERROR_NONE;
1060 tbm_surface_queue_error_e
1061 tbm_surface_queue_enqueue(tbm_surface_queue_h
1062 surface_queue, tbm_surface_h surface)
1067 _tbm_surf_queue_mutex_lock();
1069 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1070 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1071 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1072 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1075 tbm_surface_internal_dump_buffer(surface, "enqueue");
1077 pthread_mutex_lock(&surface_queue->lock);
1079 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1081 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1082 if (node == NULL || queue_type != NODE_LIST) {
1083 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1085 pthread_mutex_unlock(&surface_queue->lock);
1087 _tbm_surf_queue_mutex_unlock();
1090 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1092 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1095 if (surface_queue->impl && surface_queue->impl->enqueue)
1096 surface_queue->impl->enqueue(surface_queue, node);
1098 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1100 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1101 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1102 pthread_mutex_unlock(&surface_queue->lock);
1104 _tbm_surf_queue_mutex_unlock();
1105 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1108 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1110 pthread_mutex_unlock(&surface_queue->lock);
1111 pthread_cond_signal(&surface_queue->dirty_cond);
1113 _tbm_surf_queue_mutex_unlock();
1115 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1117 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1119 return TBM_SURFACE_QUEUE_ERROR_NONE;
1122 tbm_surface_queue_error_e
1123 tbm_surface_queue_dequeue(tbm_surface_queue_h
1124 surface_queue, tbm_surface_h *surface)
1128 _tbm_surf_queue_mutex_lock();
1132 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1133 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1134 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1135 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1137 pthread_mutex_lock(&surface_queue->lock);
1139 if (_queue_is_empty(&surface_queue->free_queue)) {
1140 if (surface_queue->impl && surface_queue->impl->need_attach)
1141 surface_queue->impl->need_attach(surface_queue);
1143 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1144 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1145 pthread_mutex_unlock(&surface_queue->lock);
1146 _tbm_surf_queue_mutex_unlock();
1147 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1151 if (surface_queue->impl && surface_queue->impl->dequeue)
1152 node = surface_queue->impl->dequeue(surface_queue);
1154 node = _tbm_surface_queue_dequeue(surface_queue);
1156 if (node == NULL || node->surface == NULL) {
1157 TBM_LOG_E("_queue_node_pop_front failed\n");
1158 pthread_mutex_unlock(&surface_queue->lock);
1160 _tbm_surf_queue_mutex_unlock();
1161 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1164 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1165 *surface = node->surface;
1167 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1169 pthread_mutex_unlock(&surface_queue->lock);
1171 _tbm_surf_queue_mutex_unlock();
1173 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1175 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1177 return TBM_SURFACE_QUEUE_ERROR_NONE;
1181 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1183 _tbm_surf_queue_mutex_lock();
1185 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1187 _tbm_surf_queue_mutex_unlock();
1189 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1191 _tbm_surf_queue_mutex_lock();
1193 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1195 pthread_mutex_lock(&surface_queue->lock);
1197 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1199 if (_queue_is_empty(&surface_queue->free_queue)) {
1200 if (surface_queue->impl && surface_queue->impl->need_attach)
1201 surface_queue->impl->need_attach(surface_queue);
1203 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1204 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1205 pthread_mutex_unlock(&surface_queue->lock);
1206 _tbm_surf_queue_mutex_unlock();
1211 if (!_queue_is_empty(&surface_queue->free_queue)) {
1212 pthread_mutex_unlock(&surface_queue->lock);
1213 _tbm_surf_queue_mutex_unlock();
1217 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1218 QUEUE_NODE_TYPE_ACQUIRE)) {
1219 _tbm_surf_queue_mutex_unlock();
1220 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1221 _tbm_surf_queue_mutex_lock();
1223 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1224 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1225 pthread_mutex_unlock(&surface_queue->lock);
1226 _tbm_surf_queue_mutex_unlock();
1230 pthread_mutex_unlock(&surface_queue->lock);
1231 _tbm_surf_queue_mutex_unlock();
1235 pthread_mutex_unlock(&surface_queue->lock);
1236 _tbm_surf_queue_mutex_unlock();
1240 tbm_surface_queue_error_e
1241 tbm_surface_queue_release(tbm_surface_queue_h
1242 surface_queue, tbm_surface_h surface)
1247 _tbm_surf_queue_mutex_lock();
1249 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1250 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1251 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1252 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1254 pthread_mutex_lock(&surface_queue->lock);
1256 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1258 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1259 if (node == NULL || queue_type != NODE_LIST) {
1260 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1262 pthread_mutex_unlock(&surface_queue->lock);
1264 _tbm_surf_queue_mutex_unlock();
1267 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1269 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1272 if (surface_queue->queue_size < surface_queue->num_attached) {
1273 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1275 if (surface_queue->impl && surface_queue->impl->need_detach)
1276 surface_queue->impl->need_detach(surface_queue, node);
1278 _tbm_surface_queue_detach(surface_queue, surface);
1280 pthread_mutex_unlock(&surface_queue->lock);
1282 _tbm_surf_queue_mutex_unlock();
1283 return TBM_SURFACE_QUEUE_ERROR_NONE;
1286 if (surface_queue->impl && surface_queue->impl->release)
1287 surface_queue->impl->release(surface_queue, node);
1289 _tbm_surface_queue_release(surface_queue, node, 1);
1291 if (_queue_is_empty(&surface_queue->free_queue)) {
1292 pthread_mutex_unlock(&surface_queue->lock);
1294 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1295 _tbm_surf_queue_mutex_unlock();
1296 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1299 node->type = QUEUE_NODE_TYPE_RELEASE;
1301 pthread_mutex_unlock(&surface_queue->lock);
1302 pthread_cond_signal(&surface_queue->free_cond);
1304 _tbm_surf_queue_mutex_unlock();
1306 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1308 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1310 return TBM_SURFACE_QUEUE_ERROR_NONE;
1313 tbm_surface_queue_error_e
1314 tbm_surface_queue_acquire(tbm_surface_queue_h
1315 surface_queue, tbm_surface_h *surface)
1319 _tbm_surf_queue_mutex_lock();
1323 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1324 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1325 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1326 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1328 pthread_mutex_lock(&surface_queue->lock);
1330 if (surface_queue->impl && surface_queue->impl->acquire)
1331 node = surface_queue->impl->acquire(surface_queue);
1333 node = _tbm_surface_queue_acquire(surface_queue);
1335 if (node == NULL || node->surface == NULL) {
1336 TBM_LOG_E("_queue_node_pop_front failed\n");
1337 pthread_mutex_unlock(&surface_queue->lock);
1339 _tbm_surf_queue_mutex_unlock();
1340 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1343 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1345 *surface = node->surface;
1347 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1349 pthread_mutex_unlock(&surface_queue->lock);
1351 _tbm_surf_queue_mutex_unlock();
1354 tbm_surface_internal_dump_buffer(*surface, "acquire");
1356 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1358 return TBM_SURFACE_QUEUE_ERROR_NONE;
1362 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1364 _tbm_surf_queue_mutex_lock();
1366 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1368 pthread_mutex_lock(&surface_queue->lock);
1370 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1372 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1373 pthread_mutex_unlock(&surface_queue->lock);
1374 _tbm_surf_queue_mutex_unlock();
1378 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1379 QUEUE_NODE_TYPE_DEQUEUE)) {
1380 _tbm_surf_queue_mutex_unlock();
1381 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1382 _tbm_surf_queue_mutex_lock();
1384 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1385 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1386 pthread_mutex_unlock(&surface_queue->lock);
1387 _tbm_surf_queue_mutex_unlock();
1391 pthread_mutex_unlock(&surface_queue->lock);
1392 _tbm_surf_queue_mutex_unlock();
1396 pthread_mutex_unlock(&surface_queue->lock);
1397 _tbm_surf_queue_mutex_unlock();
1402 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1404 queue_node *node = NULL, *tmp;
1406 _tbm_surf_queue_mutex_lock();
1408 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1410 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1412 LIST_DEL(&surface_queue->item_link);
1414 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1415 _queue_delete_node(surface_queue, node);
1417 if (surface_queue->impl && surface_queue->impl->destroy)
1418 surface_queue->impl->destroy(surface_queue);
1420 _notify_emit(surface_queue, &surface_queue->destory_noti);
1422 _notify_remove_all(&surface_queue->destory_noti);
1423 _notify_remove_all(&surface_queue->dequeuable_noti);
1424 _notify_remove_all(&surface_queue->dequeue_noti);
1425 _notify_remove_all(&surface_queue->can_dequeue_noti);
1426 _notify_remove_all(&surface_queue->acquirable_noti);
1427 _notify_remove_all(&surface_queue->reset_noti);
1428 _trace_remove_all(&surface_queue->trace_noti);
1430 pthread_mutex_destroy(&surface_queue->lock);
1432 free(surface_queue);
1434 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1435 _deinit_tbm_surf_queue_bufmgr();
1437 _tbm_surf_queue_mutex_unlock();
1440 tbm_surface_queue_error_e
1441 tbm_surface_queue_reset(tbm_surface_queue_h
1442 surface_queue, int width, int height, int format)
1444 queue_node *node = NULL, *tmp;
1446 _tbm_surf_queue_mutex_lock();
1448 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1449 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1451 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1453 if (width == surface_queue->width && height == surface_queue->height &&
1454 format == surface_queue->format) {
1455 _tbm_surf_queue_mutex_unlock();
1456 return TBM_SURFACE_QUEUE_ERROR_NONE;
1459 pthread_mutex_lock(&surface_queue->lock);
1461 surface_queue->width = width;
1462 surface_queue->height = height;
1463 surface_queue->format = format;
1465 /* Destory surface and Push to free_queue */
1466 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1467 _queue_delete_node(surface_queue, node);
1470 _queue_init(&surface_queue->free_queue);
1471 _queue_init(&surface_queue->dirty_queue);
1472 LIST_INITHEAD(&surface_queue->list);
1474 surface_queue->num_attached = 0;
1476 if (surface_queue->impl && surface_queue->impl->reset)
1477 surface_queue->impl->reset(surface_queue);
1479 pthread_mutex_unlock(&surface_queue->lock);
1480 pthread_cond_signal(&surface_queue->free_cond);
1482 _tbm_surf_queue_mutex_unlock();
1484 _notify_emit(surface_queue, &surface_queue->reset_noti);
1486 return TBM_SURFACE_QUEUE_ERROR_NONE;
1489 tbm_surface_queue_error_e
1490 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1492 _tbm_surf_queue_mutex_lock();
1494 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1495 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1497 _tbm_surf_queue_mutex_unlock();
1499 _notify_emit(surface_queue, &surface_queue->reset_noti);
1501 return TBM_SURFACE_QUEUE_ERROR_NONE;
1504 tbm_surface_queue_error_e
1505 tbm_surface_queue_set_size(tbm_surface_queue_h
1506 surface_queue, int queue_size, int flush)
1508 queue_node *node = NULL, *tmp;
1510 _tbm_surf_queue_mutex_lock();
1512 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1513 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1514 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1515 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1517 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1519 if ((surface_queue->queue_size == queue_size) && !flush) {
1520 _tbm_surf_queue_mutex_unlock();
1521 return TBM_SURFACE_QUEUE_ERROR_NONE;
1524 pthread_mutex_lock(&surface_queue->lock);
1527 /* Destory surface and Push to free_queue */
1528 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1529 _queue_delete_node(surface_queue, node);
1532 _queue_init(&surface_queue->free_queue);
1533 _queue_init(&surface_queue->dirty_queue);
1534 LIST_INITHEAD(&surface_queue->list);
1536 surface_queue->num_attached = 0;
1537 surface_queue->queue_size = queue_size;
1539 if (surface_queue->impl && surface_queue->impl->reset)
1540 surface_queue->impl->reset(surface_queue);
1542 pthread_mutex_unlock(&surface_queue->lock);
1543 pthread_cond_signal(&surface_queue->free_cond);
1545 _tbm_surf_queue_mutex_unlock();
1547 _notify_emit(surface_queue, &surface_queue->reset_noti);
1549 return TBM_SURFACE_QUEUE_ERROR_NONE;
1551 if (surface_queue->queue_size > queue_size) {
1552 int need_del = surface_queue->queue_size - queue_size;
1554 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1555 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1557 if (surface_queue->impl && surface_queue->impl->need_detach)
1558 surface_queue->impl->need_detach(surface_queue, node);
1560 _tbm_surface_queue_detach(surface_queue, node->surface);
1568 surface_queue->queue_size = queue_size;
1570 pthread_mutex_unlock(&surface_queue->lock);
1572 _tbm_surf_queue_mutex_unlock();
1574 return TBM_SURFACE_QUEUE_ERROR_NONE;
1578 tbm_surface_queue_error_e
1579 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1581 queue_node *node = NULL;
1583 _tbm_surf_queue_mutex_lock();
1585 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1586 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1588 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1590 if (surface_queue->num_attached == 0) {
1591 _tbm_surf_queue_mutex_unlock();
1592 return TBM_SURFACE_QUEUE_ERROR_NONE;
1595 pthread_mutex_lock(&surface_queue->lock);
1597 /* Destory surface in free_queue */
1598 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1599 if (surface_queue->impl && surface_queue->impl->need_detach)
1600 surface_queue->impl->need_detach(surface_queue, node);
1602 _tbm_surface_queue_detach(surface_queue, node->surface);
1606 _queue_init(&surface_queue->free_queue);
1608 pthread_mutex_unlock(&surface_queue->lock);
1609 _tbm_surf_queue_mutex_unlock();
1611 return TBM_SURFACE_QUEUE_ERROR_NONE;
1614 tbm_surface_queue_error_e
1615 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1617 queue_node *node = NULL, *tmp;
1619 _tbm_surf_queue_mutex_lock();
1621 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1622 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1624 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1626 if (surface_queue->num_attached == 0) {
1627 _tbm_surf_queue_mutex_unlock();
1628 return TBM_SURFACE_QUEUE_ERROR_NONE;
1631 pthread_mutex_lock(&surface_queue->lock);
1633 /* Destory surface and Push to free_queue */
1634 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1635 _queue_delete_node(surface_queue, node);
1638 _queue_init(&surface_queue->free_queue);
1639 _queue_init(&surface_queue->dirty_queue);
1640 LIST_INITHEAD(&surface_queue->list);
1642 surface_queue->num_attached = 0;
1644 if (surface_queue->impl && surface_queue->impl->reset)
1645 surface_queue->impl->reset(surface_queue);
1647 pthread_mutex_unlock(&surface_queue->lock);
1648 pthread_cond_signal(&surface_queue->free_cond);
1650 _tbm_surf_queue_mutex_unlock();
1652 _notify_emit(surface_queue, &surface_queue->reset_noti);
1654 return TBM_SURFACE_QUEUE_ERROR_NONE;
1657 tbm_surface_queue_error_e
1658 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1659 tbm_surface_h *surfaces, int *num)
1661 queue_node *node = NULL;
1663 _tbm_surf_queue_mutex_lock();
1667 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1668 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1669 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1670 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1672 pthread_mutex_lock(&surface_queue->lock);
1674 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1676 surfaces[*num] = node->surface;
1681 pthread_mutex_unlock(&surface_queue->lock);
1683 _tbm_surf_queue_mutex_unlock();
1685 return TBM_SURFACE_QUEUE_ERROR_NONE;
1688 tbm_surface_queue_error_e
1689 tbm_surface_queue_get_trace_surface_num(
1690 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1692 _tbm_surf_queue_mutex_lock();
1696 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1697 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1698 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1699 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1701 pthread_mutex_lock(&surface_queue->lock);
1704 case TBM_SURFACE_QUEUE_TRACE_NONE:
1707 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1708 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1710 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1711 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1713 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1714 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1716 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1717 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1721 pthread_mutex_unlock(&surface_queue->lock);
1723 _tbm_surf_queue_mutex_unlock();
1725 return TBM_SURFACE_QUEUE_ERROR_NONE;
1730 } tbm_queue_default;
1733 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1735 free(surface_queue->impl_data);
1739 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1741 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1742 tbm_surface_h surface;
1744 if (surface_queue->queue_size == surface_queue->num_attached)
1747 if (surface_queue->alloc_cb) {
1748 pthread_mutex_unlock(&surface_queue->lock);
1749 _tbm_surf_queue_mutex_unlock();
1750 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1751 _tbm_surf_queue_mutex_lock();
1752 pthread_mutex_lock(&surface_queue->lock);
1758 tbm_surface_internal_ref(surface);
1760 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1761 surface_queue->height,
1762 surface_queue->format,
1764 TBM_RETURN_IF_FAIL(surface != NULL);
1767 _tbm_surface_queue_attach(surface_queue, surface);
1768 tbm_surface_internal_unref(surface);
1771 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1772 NULL, /*__tbm_queue_default_init*/
1773 NULL, /*__tbm_queue_default_reset*/
1774 __tbm_queue_default_destroy,
1775 __tbm_queue_default_need_attach,
1776 NULL, /*__tbm_queue_default_enqueue*/
1777 NULL, /*__tbm_queue_default_release*/
1778 NULL, /*__tbm_queue_default_dequeue*/
1779 NULL, /*__tbm_queue_default_acquire*/
1780 NULL, /*__tbm_queue_default_need_detach*/
1784 tbm_surface_queue_create(int queue_size, int width,
1785 int height, int format, int flags)
1787 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1788 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1789 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1790 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1792 _tbm_surf_queue_mutex_lock();
1794 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1795 sizeof(struct _tbm_surface_queue));
1796 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1798 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1800 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1801 sizeof(tbm_queue_default));
1803 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
1804 free(surface_queue);
1805 _tbm_surf_queue_mutex_unlock();
1809 data->flags = flags;
1810 _tbm_surface_queue_init(surface_queue,
1812 width, height, format,
1813 &tbm_queue_default_impl, data);
1815 _tbm_surf_queue_mutex_unlock();
1817 return surface_queue;
1823 } tbm_queue_sequence;
1826 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1828 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1830 _queue_init(&data->dequeue_list);
1834 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1836 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1838 _queue_init(&data->dequeue_list);
1842 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1844 free(surface_queue->impl_data);
1848 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1850 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1851 tbm_surface_h surface;
1853 if (surface_queue->queue_size == surface_queue->num_attached)
1856 if (surface_queue->alloc_cb) {
1857 pthread_mutex_unlock(&surface_queue->lock);
1858 _tbm_surf_queue_mutex_unlock();
1859 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1860 _tbm_surf_queue_mutex_lock();
1861 pthread_mutex_lock(&surface_queue->lock);
1867 tbm_surface_internal_ref(surface);
1869 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1870 surface_queue->height,
1871 surface_queue->format,
1873 TBM_RETURN_IF_FAIL(surface != NULL);
1876 _tbm_surface_queue_attach(surface_queue, surface);
1877 tbm_surface_internal_unref(surface);
1881 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1884 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1885 queue_node *next = NULL, *tmp;
1887 node->priv_flags = 0;
1889 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1890 if (next->priv_flags)
1892 _queue_node_pop(&data->dequeue_list, next);
1893 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1898 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1901 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1904 node = _tbm_surface_queue_dequeue(surface_queue);
1906 _queue_node_push_back(&data->dequeue_list, node);
1907 node->priv_flags = 1;
1913 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1914 __tbm_queue_sequence_init,
1915 __tbm_queue_sequence_reset,
1916 __tbm_queue_sequence_destroy,
1917 __tbm_queue_sequence_need_attach,
1918 __tbm_queue_sequence_enqueue,
1919 NULL, /*__tbm_queue_sequence_release*/
1920 __tbm_queue_sequence_dequeue,
1921 NULL, /*__tbm_queue_sequence_acquire*/
1922 NULL, /*__tbm_queue_sequence_need_dettach*/
1926 tbm_surface_queue_sequence_create(int queue_size, int width,
1927 int height, int format, int flags)
1929 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1930 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1931 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1932 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1934 _tbm_surf_queue_mutex_lock();
1936 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1937 sizeof(struct _tbm_surface_queue));
1938 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1940 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1942 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1943 sizeof(tbm_queue_sequence));
1945 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
1946 free(surface_queue);
1947 _tbm_surf_queue_mutex_unlock();
1951 data->flags = flags;
1952 _tbm_surface_queue_init(surface_queue,
1954 width, height, format,
1955 &tbm_queue_sequence_impl, data);
1957 _tbm_surf_queue_mutex_unlock();
1959 return surface_queue;
1961 /* LCOV_EXCL_STOP */