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*/
105 struct list_head link;
107 tbm_surface_queue_notify_cb cb;
112 struct list_head link;
114 tbm_surface_queue_trace_cb cb;
118 typedef struct _tbm_surface_queue_interface {
119 void (*init)(tbm_surface_queue_h queue);
120 void (*reset)(tbm_surface_queue_h queue);
121 void (*destroy)(tbm_surface_queue_h queue);
122 void (*need_attach)(tbm_surface_queue_h queue);
124 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
125 void (*release)(tbm_surface_queue_h queue, queue_node *node);
126 queue_node *(*dequeue)(tbm_surface_queue_h queue);
127 queue_node *(*acquire)(tbm_surface_queue_h queue);
128 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
129 } tbm_surface_queue_interface;
131 struct _tbm_surface_queue {
140 struct list_head list;
142 struct list_head destory_noti;
143 struct list_head dequeuable_noti;
144 struct list_head dequeue_noti;
145 struct list_head can_dequeue_noti;
146 struct list_head acquirable_noti;
147 struct list_head reset_noti;
148 struct list_head trace_noti;
150 pthread_mutex_t lock;
151 pthread_cond_t free_cond;
152 pthread_cond_t dirty_cond;
154 const tbm_surface_queue_interface *impl;
157 //For external buffer allocation
158 tbm_surface_alloc_cb alloc_cb;
159 tbm_surface_free_cb free_cb;
162 struct list_head item_link; /* link of surface queue */
165 /* LCOV_EXCL_START */
168 _tbm_surf_queue_mutex_init(void)
170 static bool tbm_surf_queue_mutex_init = false;
172 if (tbm_surf_queue_mutex_init)
175 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
176 TBM_LOG_E("fail: pthread_mutex_init\n");
180 tbm_surf_queue_mutex_init = true;
186 _tbm_surf_queue_mutex_lock(void)
188 if (!_tbm_surf_queue_mutex_init()) {
189 TBM_LOG_E("fail: _tbm_surf_queue_mutex_init\n");
193 pthread_mutex_lock(&tbm_surf_queue_lock);
197 _tbm_surf_queue_mutex_unlock(void)
199 pthread_mutex_unlock(&tbm_surf_queue_lock);
203 _init_tbm_surf_queue_bufmgr(void)
205 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
209 _deinit_tbm_surf_queue_bufmgr(void)
211 if (!g_surf_queue_bufmgr)
214 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
215 g_surf_queue_bufmgr = NULL;
219 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
221 tbm_surface_queue_h old_data = NULL;
223 if (surface_queue == NULL) {
224 TBM_LOG_E("error: surface_queue is NULL.\n");
228 if (g_surf_queue_bufmgr == NULL) {
229 TBM_LOG_E("error: g_surf_queue_bufmgr is NULL.\n");
233 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
234 TBM_LOG_E("error: surf_queue_list is empty\n");
238 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
240 if (old_data == surface_queue) {
241 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
246 TBM_LOG_E("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
252 _queue_node_create(void)
254 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
256 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
262 _queue_node_delete(queue_node *node)
264 LIST_DEL(&node->item_link);
265 LIST_DEL(&node->link);
270 _queue_is_empty(queue *queue)
272 if (LIST_IS_EMPTY(&queue->head))
279 _queue_node_push_back(queue *queue, queue_node *node)
281 LIST_ADDTAIL(&node->item_link, &queue->head);
286 _queue_node_push_front(queue *queue, queue_node *node)
288 LIST_ADD(&node->item_link, &queue->head);
293 _queue_node_pop_front(queue *queue)
297 if (!queue->head.next) return NULL;
298 if (!queue->count) return NULL;
300 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
302 LIST_DELINIT(&node->item_link);
309 _queue_node_pop(queue *queue, queue_node *node)
311 LIST_DELINIT(&node->item_link);
318 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
319 tbm_surface_h surface, int *out_type)
321 queue_node *node = NULL;
324 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
328 if (type & FREE_QUEUE) {
329 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
331 if (node->surface == surface) {
333 *out_type = FREE_QUEUE;
340 if (type & DIRTY_QUEUE) {
341 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
343 if (node->surface == surface) {
345 *out_type = DIRTY_QUEUE;
352 if (type & NODE_LIST) {
353 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
354 if (node->surface == surface) {
356 *out_type = NODE_LIST;
363 TBM_LOG_E("fail to get the queue_node.\n");
369 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
372 if (surface_queue->free_cb) {
373 surface_queue->free_cb(surface_queue,
374 surface_queue->alloc_cb_data,
378 tbm_surface_destroy(node->surface);
381 _queue_node_delete(node);
385 _queue_init(queue *queue)
387 LIST_INITHEAD(&queue->head);
393 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
396 TBM_RETURN_IF_FAIL(cb != NULL);
398 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
400 TBM_RETURN_IF_FAIL(item != NULL);
402 LIST_INITHEAD(&item->link);
406 LIST_ADDTAIL(&item->link, list);
410 _notify_remove(struct list_head *list,
411 tbm_surface_queue_notify_cb cb, void *data)
413 queue_notify *item = NULL, *tmp;
415 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
416 if (item->cb == cb && item->data == data) {
417 LIST_DEL(&item->link);
423 TBM_LOG_E("Cannot find notifiy\n");
427 _notify_remove_all(struct list_head *list)
429 queue_notify *item = NULL, *tmp;
431 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
432 LIST_DEL(&item->link);
438 _notify_emit(tbm_surface_queue_h surface_queue,
439 struct list_head *list)
441 queue_notify *item = NULL, *tmp;;
444 The item->cb is the outside function of the libtbm.
445 The tbm user may/can remove the item of the list,
446 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
448 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
449 item->cb(surface_queue, item->data);
453 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
456 TBM_RETURN_IF_FAIL(cb != NULL);
458 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
460 TBM_RETURN_IF_FAIL(item != NULL);
462 LIST_INITHEAD(&item->link);
466 LIST_ADDTAIL(&item->link, list);
470 _trace_remove(struct list_head *list,
471 tbm_surface_queue_trace_cb cb, void *data)
473 queue_trace *item = NULL, *tmp;
475 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
476 if (item->cb == cb && item->data == data) {
477 LIST_DEL(&item->link);
483 TBM_LOG_E("Cannot find notifiy\n");
487 _trace_remove_all(struct list_head *list)
489 queue_trace *item = NULL, *tmp;
491 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
492 LIST_DEL(&item->link);
498 _trace_emit(tbm_surface_queue_h surface_queue,
499 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
501 queue_trace *item = NULL, *tmp;;
504 The item->cb is the outside function of the libtbm.
505 The tbm user may/can remove the item of the list,
506 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
508 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
509 item->cb(surface_queue, surface, trace, item->data);
513 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
515 queue_node *node = NULL;
518 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
519 if (node->type == type)
527 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
528 tbm_surface_h surface)
532 node = _queue_node_create();
533 TBM_RETURN_IF_FAIL(node != NULL);
535 tbm_surface_internal_ref(surface);
536 node->surface = surface;
538 LIST_ADDTAIL(&node->link, &surface_queue->list);
539 surface_queue->num_attached++;
540 _queue_node_push_back(&surface_queue->free_queue, node);
544 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
545 tbm_surface_h surface)
550 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
552 _queue_delete_node(surface_queue, node);
553 surface_queue->num_attached--;
558 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
559 queue_node *node, int push_back)
562 _queue_node_push_back(&surface_queue->dirty_queue, node);
564 _queue_node_push_front(&surface_queue->dirty_queue, node);
568 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
572 node = _queue_node_pop_front(&surface_queue->free_queue);
578 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
582 if (_queue_is_empty(&surface_queue->dirty_queue))
585 node = _queue_node_pop_front(&surface_queue->dirty_queue);
591 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
592 queue_node *node, int push_back)
595 _queue_node_push_back(&surface_queue->free_queue, node);
597 _queue_node_push_front(&surface_queue->free_queue, node);
601 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
603 int width, int height, int format,
604 const tbm_surface_queue_interface *impl, void *data)
606 TBM_RETURN_IF_FAIL(surface_queue != NULL);
607 TBM_RETURN_IF_FAIL(impl != NULL);
609 if (!g_surf_queue_bufmgr)
610 _init_tbm_surf_queue_bufmgr();
612 pthread_mutex_init(&surface_queue->lock, NULL);
613 pthread_cond_init(&surface_queue->free_cond, NULL);
614 pthread_cond_init(&surface_queue->dirty_cond, NULL);
616 surface_queue->queue_size = queue_size;
617 surface_queue->width = width;
618 surface_queue->height = height;
619 surface_queue->format = format;
620 surface_queue->impl = impl;
621 surface_queue->impl_data = data;
623 _queue_init(&surface_queue->free_queue);
624 _queue_init(&surface_queue->dirty_queue);
625 LIST_INITHEAD(&surface_queue->list);
627 LIST_INITHEAD(&surface_queue->destory_noti);
628 LIST_INITHEAD(&surface_queue->dequeuable_noti);
629 LIST_INITHEAD(&surface_queue->dequeue_noti);
630 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
631 LIST_INITHEAD(&surface_queue->acquirable_noti);
632 LIST_INITHEAD(&surface_queue->reset_noti);
633 LIST_INITHEAD(&surface_queue->trace_noti);
635 if (surface_queue->impl && surface_queue->impl->init)
636 surface_queue->impl->init(surface_queue);
638 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
641 tbm_surface_queue_error_e
642 tbm_surface_queue_add_destroy_cb(
643 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
646 _tbm_surf_queue_mutex_lock();
648 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
649 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
651 pthread_mutex_lock(&surface_queue->lock);
653 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
655 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
657 pthread_mutex_unlock(&surface_queue->lock);
659 _tbm_surf_queue_mutex_unlock();
661 return TBM_SURFACE_QUEUE_ERROR_NONE;
664 tbm_surface_queue_error_e
665 tbm_surface_queue_remove_destroy_cb(
666 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
669 _tbm_surf_queue_mutex_lock();
671 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
672 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
674 pthread_mutex_lock(&surface_queue->lock);
676 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
678 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
680 pthread_mutex_unlock(&surface_queue->lock);
682 _tbm_surf_queue_mutex_unlock();
684 return TBM_SURFACE_QUEUE_ERROR_NONE;
687 tbm_surface_queue_error_e
688 tbm_surface_queue_add_dequeuable_cb(
689 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
692 _tbm_surf_queue_mutex_lock();
694 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
695 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
697 pthread_mutex_lock(&surface_queue->lock);
699 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
701 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
703 pthread_mutex_unlock(&surface_queue->lock);
705 _tbm_surf_queue_mutex_unlock();
707 return TBM_SURFACE_QUEUE_ERROR_NONE;
710 tbm_surface_queue_error_e
711 tbm_surface_queue_remove_dequeuable_cb(
712 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
715 _tbm_surf_queue_mutex_lock();
717 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
718 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
720 pthread_mutex_lock(&surface_queue->lock);
722 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
724 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
726 pthread_mutex_unlock(&surface_queue->lock);
728 _tbm_surf_queue_mutex_unlock();
730 return TBM_SURFACE_QUEUE_ERROR_NONE;
733 tbm_surface_queue_error_e
734 tbm_surface_queue_add_dequeue_cb(
735 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
738 _tbm_surf_queue_mutex_lock();
740 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
741 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
743 pthread_mutex_lock(&surface_queue->lock);
745 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
747 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
749 pthread_mutex_unlock(&surface_queue->lock);
751 _tbm_surf_queue_mutex_unlock();
753 return TBM_SURFACE_QUEUE_ERROR_NONE;
756 tbm_surface_queue_error_e
757 tbm_surface_queue_remove_dequeue_cb(
758 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
761 _tbm_surf_queue_mutex_lock();
763 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
764 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
766 pthread_mutex_lock(&surface_queue->lock);
768 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
770 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
772 pthread_mutex_unlock(&surface_queue->lock);
774 _tbm_surf_queue_mutex_unlock();
776 return TBM_SURFACE_QUEUE_ERROR_NONE;
779 tbm_surface_queue_error_e
780 tbm_surface_queue_add_can_dequeue_cb(
781 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
784 _tbm_surf_queue_mutex_lock();
786 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
787 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
789 pthread_mutex_lock(&surface_queue->lock);
791 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
793 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
795 pthread_mutex_unlock(&surface_queue->lock);
797 _tbm_surf_queue_mutex_unlock();
799 return TBM_SURFACE_QUEUE_ERROR_NONE;
802 tbm_surface_queue_error_e
803 tbm_surface_queue_remove_can_dequeue_cb(
804 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
807 _tbm_surf_queue_mutex_lock();
809 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
810 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
812 pthread_mutex_lock(&surface_queue->lock);
814 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
816 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
818 pthread_mutex_unlock(&surface_queue->lock);
820 _tbm_surf_queue_mutex_unlock();
822 return TBM_SURFACE_QUEUE_ERROR_NONE;
825 tbm_surface_queue_error_e
826 tbm_surface_queue_add_acquirable_cb(
827 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
830 _tbm_surf_queue_mutex_lock();
832 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
833 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
835 pthread_mutex_lock(&surface_queue->lock);
837 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
839 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
841 pthread_mutex_unlock(&surface_queue->lock);
843 _tbm_surf_queue_mutex_unlock();
845 return TBM_SURFACE_QUEUE_ERROR_NONE;
848 tbm_surface_queue_error_e
849 tbm_surface_queue_remove_acquirable_cb(
850 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
853 _tbm_surf_queue_mutex_lock();
855 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
856 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
858 pthread_mutex_lock(&surface_queue->lock);
860 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
862 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
864 pthread_mutex_unlock(&surface_queue->lock);
866 _tbm_surf_queue_mutex_unlock();
868 return TBM_SURFACE_QUEUE_ERROR_NONE;
871 tbm_surface_queue_error_e
872 tbm_surface_queue_add_trace_cb(
873 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
876 _tbm_surf_queue_mutex_lock();
878 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
879 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
881 pthread_mutex_lock(&surface_queue->lock);
883 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
885 _trace_add(&surface_queue->trace_noti, trace_cb, data);
887 pthread_mutex_unlock(&surface_queue->lock);
889 _tbm_surf_queue_mutex_unlock();
891 return TBM_SURFACE_QUEUE_ERROR_NONE;
894 tbm_surface_queue_error_e
895 tbm_surface_queue_remove_trace_cb(
896 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_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 _trace_remove(&surface_queue->trace_noti, trace_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_set_alloc_cb(
919 tbm_surface_queue_h surface_queue,
920 tbm_surface_alloc_cb alloc_cb,
921 tbm_surface_free_cb free_cb,
924 _tbm_surf_queue_mutex_lock();
926 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
927 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
929 pthread_mutex_lock(&surface_queue->lock);
931 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
933 surface_queue->alloc_cb = alloc_cb;
934 surface_queue->free_cb = free_cb;
935 surface_queue->alloc_cb_data = data;
937 pthread_mutex_unlock(&surface_queue->lock);
939 _tbm_surf_queue_mutex_unlock();
941 return TBM_SURFACE_QUEUE_ERROR_NONE;
945 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
949 _tbm_surf_queue_mutex_lock();
951 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
953 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
955 width = surface_queue->width;
957 _tbm_surf_queue_mutex_unlock();
963 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
967 _tbm_surf_queue_mutex_lock();
969 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
971 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
973 height = surface_queue->height;
975 _tbm_surf_queue_mutex_unlock();
981 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
985 _tbm_surf_queue_mutex_lock();
987 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
989 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
991 format = surface_queue->format;
993 _tbm_surf_queue_mutex_unlock();
999 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1003 _tbm_surf_queue_mutex_lock();
1005 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1007 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1009 queue_size = surface_queue->queue_size;
1011 _tbm_surf_queue_mutex_unlock();
1016 tbm_surface_queue_error_e
1017 tbm_surface_queue_add_reset_cb(
1018 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1021 _tbm_surf_queue_mutex_lock();
1023 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1024 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1026 pthread_mutex_lock(&surface_queue->lock);
1028 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1030 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1032 pthread_mutex_unlock(&surface_queue->lock);
1034 _tbm_surf_queue_mutex_unlock();
1036 return TBM_SURFACE_QUEUE_ERROR_NONE;
1039 tbm_surface_queue_error_e
1040 tbm_surface_queue_remove_reset_cb(
1041 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1044 _tbm_surf_queue_mutex_lock();
1046 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1047 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1049 pthread_mutex_lock(&surface_queue->lock);
1051 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1053 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1055 pthread_mutex_unlock(&surface_queue->lock);
1057 _tbm_surf_queue_mutex_unlock();
1059 return TBM_SURFACE_QUEUE_ERROR_NONE;
1062 tbm_surface_queue_error_e
1063 tbm_surface_queue_enqueue(tbm_surface_queue_h
1064 surface_queue, tbm_surface_h surface)
1069 _tbm_surf_queue_mutex_lock();
1071 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1072 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1073 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1074 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1077 tbm_surface_internal_dump_buffer(surface, "enqueue");
1079 pthread_mutex_lock(&surface_queue->lock);
1081 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1083 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1084 if (node == NULL || queue_type != NODE_LIST) {
1085 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1087 pthread_mutex_unlock(&surface_queue->lock);
1089 _tbm_surf_queue_mutex_unlock();
1092 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1094 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1097 if (surface_queue->impl && surface_queue->impl->enqueue)
1098 surface_queue->impl->enqueue(surface_queue, node);
1100 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1102 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1103 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1104 pthread_mutex_unlock(&surface_queue->lock);
1106 _tbm_surf_queue_mutex_unlock();
1107 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1110 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1112 pthread_mutex_unlock(&surface_queue->lock);
1113 pthread_cond_signal(&surface_queue->dirty_cond);
1115 _tbm_surf_queue_mutex_unlock();
1117 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1119 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1121 return TBM_SURFACE_QUEUE_ERROR_NONE;
1124 tbm_surface_queue_error_e
1125 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1126 surface_queue, tbm_surface_h surface)
1131 _tbm_surf_queue_mutex_lock();
1133 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1134 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1135 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1136 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1138 pthread_mutex_lock(&surface_queue->lock);
1140 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1142 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1143 if (node == NULL || queue_type != NODE_LIST) {
1144 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1146 pthread_mutex_unlock(&surface_queue->lock);
1148 _tbm_surf_queue_mutex_unlock();
1149 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1152 if (node->delete_pending) {
1153 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1155 _queue_delete_node(surface_queue, node);
1157 pthread_mutex_unlock(&surface_queue->lock);
1159 _tbm_surf_queue_mutex_unlock();
1161 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1163 return TBM_SURFACE_QUEUE_ERROR_NONE;
1166 if (surface_queue->queue_size < surface_queue->num_attached) {
1167 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1169 if (surface_queue->impl && surface_queue->impl->need_detach)
1170 surface_queue->impl->need_detach(surface_queue, node);
1172 _tbm_surface_queue_detach(surface_queue, surface);
1174 pthread_mutex_unlock(&surface_queue->lock);
1176 _tbm_surf_queue_mutex_unlock();
1178 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1180 return TBM_SURFACE_QUEUE_ERROR_NONE;
1183 if (surface_queue->impl && surface_queue->impl->release)
1184 surface_queue->impl->release(surface_queue, node);
1186 _tbm_surface_queue_release(surface_queue, node, 1);
1188 if (_queue_is_empty(&surface_queue->free_queue)) {
1189 pthread_mutex_unlock(&surface_queue->lock);
1191 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1192 _tbm_surf_queue_mutex_unlock();
1193 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1196 node->type = QUEUE_NODE_TYPE_RELEASE;
1198 pthread_mutex_unlock(&surface_queue->lock);
1199 pthread_cond_signal(&surface_queue->free_cond);
1201 _tbm_surf_queue_mutex_unlock();
1203 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1205 return TBM_SURFACE_QUEUE_ERROR_NONE;
1208 tbm_surface_queue_error_e
1209 tbm_surface_queue_dequeue(tbm_surface_queue_h
1210 surface_queue, tbm_surface_h *surface)
1214 _tbm_surf_queue_mutex_lock();
1218 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1219 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1220 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1221 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1223 pthread_mutex_lock(&surface_queue->lock);
1225 if (_queue_is_empty(&surface_queue->free_queue)) {
1226 if (surface_queue->impl && surface_queue->impl->need_attach)
1227 surface_queue->impl->need_attach(surface_queue);
1229 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1230 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1231 pthread_mutex_unlock(&surface_queue->lock);
1232 _tbm_surf_queue_mutex_unlock();
1233 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1237 if (surface_queue->impl && surface_queue->impl->dequeue)
1238 node = surface_queue->impl->dequeue(surface_queue);
1240 node = _tbm_surface_queue_dequeue(surface_queue);
1242 if (node == NULL || node->surface == NULL) {
1243 TBM_LOG_E("_queue_node_pop_front failed\n");
1244 pthread_mutex_unlock(&surface_queue->lock);
1246 _tbm_surf_queue_mutex_unlock();
1247 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1250 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1251 *surface = node->surface;
1253 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1255 pthread_mutex_unlock(&surface_queue->lock);
1257 _tbm_surf_queue_mutex_unlock();
1259 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1261 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1263 return TBM_SURFACE_QUEUE_ERROR_NONE;
1267 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1269 _tbm_surf_queue_mutex_lock();
1271 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1273 _tbm_surf_queue_mutex_unlock();
1275 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1277 _tbm_surf_queue_mutex_lock();
1279 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1281 pthread_mutex_lock(&surface_queue->lock);
1283 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1285 if (_queue_is_empty(&surface_queue->free_queue)) {
1286 if (surface_queue->impl && surface_queue->impl->need_attach)
1287 surface_queue->impl->need_attach(surface_queue);
1289 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1290 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1291 pthread_mutex_unlock(&surface_queue->lock);
1292 _tbm_surf_queue_mutex_unlock();
1297 if (!_queue_is_empty(&surface_queue->free_queue)) {
1298 pthread_mutex_unlock(&surface_queue->lock);
1299 _tbm_surf_queue_mutex_unlock();
1303 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1304 QUEUE_NODE_TYPE_ACQUIRE)) {
1305 _tbm_surf_queue_mutex_unlock();
1306 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1307 _tbm_surf_queue_mutex_lock();
1309 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1310 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1311 pthread_mutex_unlock(&surface_queue->lock);
1312 _tbm_surf_queue_mutex_unlock();
1316 pthread_mutex_unlock(&surface_queue->lock);
1317 _tbm_surf_queue_mutex_unlock();
1321 pthread_mutex_unlock(&surface_queue->lock);
1322 _tbm_surf_queue_mutex_unlock();
1326 tbm_surface_queue_error_e
1327 tbm_surface_queue_release(tbm_surface_queue_h
1328 surface_queue, tbm_surface_h surface)
1333 _tbm_surf_queue_mutex_lock();
1335 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1336 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1337 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1338 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1340 pthread_mutex_lock(&surface_queue->lock);
1342 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1344 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1345 if (node == NULL || queue_type != NODE_LIST) {
1346 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1348 pthread_mutex_unlock(&surface_queue->lock);
1350 _tbm_surf_queue_mutex_unlock();
1353 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1355 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1358 if (node->delete_pending) {
1359 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1361 _queue_delete_node(surface_queue, node);
1363 pthread_mutex_unlock(&surface_queue->lock);
1365 _tbm_surf_queue_mutex_unlock();
1367 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1369 return TBM_SURFACE_QUEUE_ERROR_NONE;
1372 if (surface_queue->queue_size < surface_queue->num_attached) {
1373 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1375 if (surface_queue->impl && surface_queue->impl->need_detach)
1376 surface_queue->impl->need_detach(surface_queue, node);
1378 _tbm_surface_queue_detach(surface_queue, surface);
1380 pthread_mutex_unlock(&surface_queue->lock);
1382 _tbm_surf_queue_mutex_unlock();
1384 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1386 return TBM_SURFACE_QUEUE_ERROR_NONE;
1389 if (surface_queue->impl && surface_queue->impl->release)
1390 surface_queue->impl->release(surface_queue, node);
1392 _tbm_surface_queue_release(surface_queue, node, 1);
1394 if (_queue_is_empty(&surface_queue->free_queue)) {
1395 pthread_mutex_unlock(&surface_queue->lock);
1397 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1398 _tbm_surf_queue_mutex_unlock();
1399 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1402 node->type = QUEUE_NODE_TYPE_RELEASE;
1404 pthread_mutex_unlock(&surface_queue->lock);
1405 pthread_cond_signal(&surface_queue->free_cond);
1407 _tbm_surf_queue_mutex_unlock();
1409 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1411 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1413 return TBM_SURFACE_QUEUE_ERROR_NONE;
1416 tbm_surface_queue_error_e
1417 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1418 surface_queue, tbm_surface_h surface)
1423 _tbm_surf_queue_mutex_lock();
1425 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1426 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1427 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1428 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1430 pthread_mutex_lock(&surface_queue->lock);
1432 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1434 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1435 if (node == NULL || queue_type != NODE_LIST) {
1436 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1438 pthread_mutex_unlock(&surface_queue->lock);
1440 _tbm_surf_queue_mutex_unlock();
1441 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1444 if (surface_queue->impl && surface_queue->impl->enqueue)
1445 surface_queue->impl->enqueue(surface_queue, node);
1447 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1449 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1450 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1451 pthread_mutex_unlock(&surface_queue->lock);
1453 _tbm_surf_queue_mutex_unlock();
1454 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1457 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1459 pthread_mutex_unlock(&surface_queue->lock);
1460 pthread_cond_signal(&surface_queue->dirty_cond);
1462 _tbm_surf_queue_mutex_unlock();
1464 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1466 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1468 return TBM_SURFACE_QUEUE_ERROR_NONE;
1471 tbm_surface_queue_error_e
1472 tbm_surface_queue_acquire(tbm_surface_queue_h
1473 surface_queue, tbm_surface_h *surface)
1477 _tbm_surf_queue_mutex_lock();
1481 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1482 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1483 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1484 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1486 pthread_mutex_lock(&surface_queue->lock);
1488 if (surface_queue->impl && surface_queue->impl->acquire)
1489 node = surface_queue->impl->acquire(surface_queue);
1491 node = _tbm_surface_queue_acquire(surface_queue);
1493 if (node == NULL || node->surface == NULL) {
1494 TBM_LOG_E("_queue_node_pop_front failed\n");
1495 pthread_mutex_unlock(&surface_queue->lock);
1497 _tbm_surf_queue_mutex_unlock();
1498 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1501 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1503 *surface = node->surface;
1505 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1507 pthread_mutex_unlock(&surface_queue->lock);
1509 _tbm_surf_queue_mutex_unlock();
1512 tbm_surface_internal_dump_buffer(*surface, "acquire");
1514 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1516 return TBM_SURFACE_QUEUE_ERROR_NONE;
1520 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1522 _tbm_surf_queue_mutex_lock();
1524 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1526 pthread_mutex_lock(&surface_queue->lock);
1528 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1530 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1531 pthread_mutex_unlock(&surface_queue->lock);
1532 _tbm_surf_queue_mutex_unlock();
1536 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1537 QUEUE_NODE_TYPE_DEQUEUE)) {
1538 _tbm_surf_queue_mutex_unlock();
1539 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1540 _tbm_surf_queue_mutex_lock();
1542 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1543 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1544 pthread_mutex_unlock(&surface_queue->lock);
1545 _tbm_surf_queue_mutex_unlock();
1549 pthread_mutex_unlock(&surface_queue->lock);
1550 _tbm_surf_queue_mutex_unlock();
1554 pthread_mutex_unlock(&surface_queue->lock);
1555 _tbm_surf_queue_mutex_unlock();
1560 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1562 queue_node *node = NULL, *tmp;
1564 _tbm_surf_queue_mutex_lock();
1566 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1568 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1570 LIST_DEL(&surface_queue->item_link);
1572 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1573 _queue_delete_node(surface_queue, node);
1575 if (surface_queue->impl && surface_queue->impl->destroy)
1576 surface_queue->impl->destroy(surface_queue);
1578 _notify_emit(surface_queue, &surface_queue->destory_noti);
1580 _notify_remove_all(&surface_queue->destory_noti);
1581 _notify_remove_all(&surface_queue->dequeuable_noti);
1582 _notify_remove_all(&surface_queue->dequeue_noti);
1583 _notify_remove_all(&surface_queue->can_dequeue_noti);
1584 _notify_remove_all(&surface_queue->acquirable_noti);
1585 _notify_remove_all(&surface_queue->reset_noti);
1586 _trace_remove_all(&surface_queue->trace_noti);
1588 pthread_mutex_destroy(&surface_queue->lock);
1590 free(surface_queue);
1592 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1593 _deinit_tbm_surf_queue_bufmgr();
1595 _tbm_surf_queue_mutex_unlock();
1598 tbm_surface_queue_error_e
1599 tbm_surface_queue_reset(tbm_surface_queue_h
1600 surface_queue, int width, int height, int format)
1602 queue_node *node = NULL, *tmp;
1604 _tbm_surf_queue_mutex_lock();
1606 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1607 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1609 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1611 if (width == surface_queue->width && height == surface_queue->height &&
1612 format == surface_queue->format) {
1613 _tbm_surf_queue_mutex_unlock();
1614 return TBM_SURFACE_QUEUE_ERROR_NONE;
1617 pthread_mutex_lock(&surface_queue->lock);
1619 surface_queue->width = width;
1620 surface_queue->height = height;
1621 surface_queue->format = format;
1623 /* Destory surface and Push to free_queue */
1624 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, link)
1625 _queue_delete_node(surface_queue, node);
1627 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1628 node->delete_pending = 1;
1631 _queue_init(&surface_queue->free_queue);
1633 surface_queue->num_attached = 0;
1635 if (surface_queue->impl && surface_queue->impl->reset)
1636 surface_queue->impl->reset(surface_queue);
1638 pthread_mutex_unlock(&surface_queue->lock);
1639 pthread_cond_signal(&surface_queue->free_cond);
1641 _tbm_surf_queue_mutex_unlock();
1643 _notify_emit(surface_queue, &surface_queue->reset_noti);
1645 return TBM_SURFACE_QUEUE_ERROR_NONE;
1648 tbm_surface_queue_error_e
1649 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1651 _tbm_surf_queue_mutex_lock();
1653 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1654 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1656 _tbm_surf_queue_mutex_unlock();
1658 _notify_emit(surface_queue, &surface_queue->reset_noti);
1660 return TBM_SURFACE_QUEUE_ERROR_NONE;
1663 tbm_surface_queue_error_e
1664 tbm_surface_queue_set_size(tbm_surface_queue_h
1665 surface_queue, int queue_size, int flush)
1667 queue_node *node = NULL, *tmp;
1669 _tbm_surf_queue_mutex_lock();
1671 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1672 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1673 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1674 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1676 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1678 if ((surface_queue->queue_size == queue_size) && !flush) {
1679 _tbm_surf_queue_mutex_unlock();
1680 return TBM_SURFACE_QUEUE_ERROR_NONE;
1683 pthread_mutex_lock(&surface_queue->lock);
1686 /* Destory surface and Push to free_queue */
1687 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1688 _queue_delete_node(surface_queue, node);
1690 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1691 node->delete_pending = 1;
1694 _queue_init(&surface_queue->free_queue);
1696 surface_queue->num_attached = 0;
1697 surface_queue->queue_size = queue_size;
1699 if (surface_queue->impl && surface_queue->impl->reset)
1700 surface_queue->impl->reset(surface_queue);
1702 pthread_mutex_unlock(&surface_queue->lock);
1703 pthread_cond_signal(&surface_queue->free_cond);
1705 _tbm_surf_queue_mutex_unlock();
1707 _notify_emit(surface_queue, &surface_queue->reset_noti);
1709 return TBM_SURFACE_QUEUE_ERROR_NONE;
1711 if (surface_queue->queue_size > queue_size) {
1712 int need_del = surface_queue->queue_size - queue_size;
1714 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1715 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1717 if (surface_queue->impl && surface_queue->impl->need_detach)
1718 surface_queue->impl->need_detach(surface_queue, node);
1720 _tbm_surface_queue_detach(surface_queue, node->surface);
1728 surface_queue->queue_size = queue_size;
1730 pthread_mutex_unlock(&surface_queue->lock);
1732 _tbm_surf_queue_mutex_unlock();
1734 return TBM_SURFACE_QUEUE_ERROR_NONE;
1738 tbm_surface_queue_error_e
1739 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1741 queue_node *node = NULL;
1743 _tbm_surf_queue_mutex_lock();
1745 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1746 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1748 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1750 if (surface_queue->num_attached == 0) {
1751 _tbm_surf_queue_mutex_unlock();
1752 return TBM_SURFACE_QUEUE_ERROR_NONE;
1755 pthread_mutex_lock(&surface_queue->lock);
1757 /* Destory surface in free_queue */
1758 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1759 if (surface_queue->impl && surface_queue->impl->need_detach)
1760 surface_queue->impl->need_detach(surface_queue, node);
1762 _tbm_surface_queue_detach(surface_queue, node->surface);
1766 _queue_init(&surface_queue->free_queue);
1768 pthread_mutex_unlock(&surface_queue->lock);
1769 _tbm_surf_queue_mutex_unlock();
1771 return TBM_SURFACE_QUEUE_ERROR_NONE;
1774 tbm_surface_queue_error_e
1775 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1777 queue_node *node = NULL, *tmp;
1779 _tbm_surf_queue_mutex_lock();
1781 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1782 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1784 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1786 if (surface_queue->num_attached == 0) {
1787 _tbm_surf_queue_mutex_unlock();
1788 return TBM_SURFACE_QUEUE_ERROR_NONE;
1791 pthread_mutex_lock(&surface_queue->lock);
1793 /* Destory surface and Push to free_queue */
1794 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1795 _queue_delete_node(surface_queue, node);
1797 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1798 node->delete_pending = 1;
1801 _queue_init(&surface_queue->free_queue);
1803 surface_queue->num_attached = 0;
1805 if (surface_queue->impl && surface_queue->impl->reset)
1806 surface_queue->impl->reset(surface_queue);
1808 pthread_mutex_unlock(&surface_queue->lock);
1809 pthread_cond_signal(&surface_queue->free_cond);
1811 _tbm_surf_queue_mutex_unlock();
1813 _notify_emit(surface_queue, &surface_queue->reset_noti);
1815 return TBM_SURFACE_QUEUE_ERROR_NONE;
1818 tbm_surface_queue_error_e
1819 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1820 tbm_surface_h *surfaces, int *num)
1822 queue_node *node = NULL;
1824 _tbm_surf_queue_mutex_lock();
1828 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1829 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1830 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1831 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1833 pthread_mutex_lock(&surface_queue->lock);
1835 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1837 surfaces[*num] = node->surface;
1842 pthread_mutex_unlock(&surface_queue->lock);
1844 _tbm_surf_queue_mutex_unlock();
1846 return TBM_SURFACE_QUEUE_ERROR_NONE;
1849 tbm_surface_queue_error_e
1850 tbm_surface_queue_get_trace_surface_num(
1851 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1853 _tbm_surf_queue_mutex_lock();
1857 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1858 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1859 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1860 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1862 pthread_mutex_lock(&surface_queue->lock);
1865 case TBM_SURFACE_QUEUE_TRACE_NONE:
1868 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1869 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1871 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1872 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1874 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1875 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1877 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1878 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1884 pthread_mutex_unlock(&surface_queue->lock);
1886 _tbm_surf_queue_mutex_unlock();
1888 return TBM_SURFACE_QUEUE_ERROR_NONE;
1893 } tbm_queue_default;
1896 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1898 free(surface_queue->impl_data);
1902 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1904 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1905 tbm_surface_h surface;
1907 if (surface_queue->queue_size == surface_queue->num_attached)
1910 if (surface_queue->alloc_cb) {
1911 pthread_mutex_unlock(&surface_queue->lock);
1912 _tbm_surf_queue_mutex_unlock();
1913 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1914 _tbm_surf_queue_mutex_lock();
1915 pthread_mutex_lock(&surface_queue->lock);
1921 tbm_surface_internal_ref(surface);
1923 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1924 surface_queue->height,
1925 surface_queue->format,
1927 TBM_RETURN_IF_FAIL(surface != NULL);
1930 _tbm_surface_queue_attach(surface_queue, surface);
1931 tbm_surface_internal_unref(surface);
1934 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1935 NULL, /*__tbm_queue_default_init*/
1936 NULL, /*__tbm_queue_default_reset*/
1937 __tbm_queue_default_destroy,
1938 __tbm_queue_default_need_attach,
1939 NULL, /*__tbm_queue_default_enqueue*/
1940 NULL, /*__tbm_queue_default_release*/
1941 NULL, /*__tbm_queue_default_dequeue*/
1942 NULL, /*__tbm_queue_default_acquire*/
1943 NULL, /*__tbm_queue_default_need_detach*/
1947 tbm_surface_queue_create(int queue_size, int width,
1948 int height, int format, int flags)
1950 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1951 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1952 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1953 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1955 _tbm_surf_queue_mutex_lock();
1957 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1958 sizeof(struct _tbm_surface_queue));
1959 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1961 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1963 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1964 sizeof(tbm_queue_default));
1966 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
1967 free(surface_queue);
1968 _tbm_surf_queue_mutex_unlock();
1972 data->flags = flags;
1973 _tbm_surface_queue_init(surface_queue,
1975 width, height, format,
1976 &tbm_queue_default_impl, data);
1978 _tbm_surf_queue_mutex_unlock();
1980 return surface_queue;
1986 } tbm_queue_sequence;
1989 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1991 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1993 _queue_init(&data->dequeue_list);
1997 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1999 free(surface_queue->impl_data);
2003 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2005 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2006 tbm_surface_h surface;
2008 if (surface_queue->queue_size == surface_queue->num_attached)
2011 if (surface_queue->alloc_cb) {
2012 pthread_mutex_unlock(&surface_queue->lock);
2013 _tbm_surf_queue_mutex_unlock();
2014 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2015 _tbm_surf_queue_mutex_lock();
2016 pthread_mutex_lock(&surface_queue->lock);
2022 tbm_surface_internal_ref(surface);
2024 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2025 surface_queue->height,
2026 surface_queue->format,
2028 TBM_RETURN_IF_FAIL(surface != NULL);
2031 _tbm_surface_queue_attach(surface_queue, surface);
2032 tbm_surface_internal_unref(surface);
2036 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2039 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2040 queue_node *next = NULL, *tmp;
2042 node->priv_flags = 0;
2044 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
2045 if (next->priv_flags)
2047 _queue_node_pop(&data->dequeue_list, next);
2048 _tbm_surface_queue_enqueue(surface_queue, next, 1);
2053 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2056 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2058 if (node->priv_flags) {
2059 node->priv_flags = 0;
2060 _queue_node_pop(&data->dequeue_list, node);
2063 _tbm_surface_queue_release(surface_queue, node, 1);
2067 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2070 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2073 node = _tbm_surface_queue_dequeue(surface_queue);
2075 _queue_node_push_back(&data->dequeue_list, node);
2076 node->priv_flags = 1;
2082 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2083 __tbm_queue_sequence_init,
2085 __tbm_queue_sequence_destroy,
2086 __tbm_queue_sequence_need_attach,
2087 __tbm_queue_sequence_enqueue,
2088 __tbm_queue_sequence_release,
2089 __tbm_queue_sequence_dequeue,
2090 NULL, /*__tbm_queue_sequence_acquire*/
2091 NULL, /*__tbm_queue_sequence_need_dettach*/
2095 tbm_surface_queue_sequence_create(int queue_size, int width,
2096 int height, int format, int flags)
2098 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2099 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2100 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2101 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2103 _tbm_surf_queue_mutex_lock();
2105 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2106 sizeof(struct _tbm_surface_queue));
2107 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2109 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2111 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2112 sizeof(tbm_queue_sequence));
2114 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
2115 free(surface_queue);
2116 _tbm_surf_queue_mutex_unlock();
2120 data->flags = flags;
2121 _tbm_surface_queue_init(surface_queue,
2123 width, height, format,
2124 &tbm_queue_sequence_impl, data);
2126 _tbm_surf_queue_mutex_unlock();
2128 return surface_queue;
2130 /* LCOV_EXCL_STOP */