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_cancel_dequeue(tbm_surface_queue_h
1124 surface_queue, tbm_surface_h surface)
1129 _tbm_surf_queue_mutex_lock();
1131 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1132 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1133 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1134 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1136 pthread_mutex_lock(&surface_queue->lock);
1138 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1140 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1141 if (node == NULL || queue_type != NODE_LIST) {
1142 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1144 pthread_mutex_unlock(&surface_queue->lock);
1146 _tbm_surf_queue_mutex_unlock();
1147 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1150 if (surface_queue->queue_size < surface_queue->num_attached) {
1151 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1153 if (surface_queue->impl && surface_queue->impl->need_detach)
1154 surface_queue->impl->need_detach(surface_queue, node);
1156 _tbm_surface_queue_detach(surface_queue, surface);
1158 pthread_mutex_unlock(&surface_queue->lock);
1160 _tbm_surf_queue_mutex_unlock();
1162 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1164 return TBM_SURFACE_QUEUE_ERROR_NONE;
1167 if (surface_queue->impl && surface_queue->impl->release)
1168 surface_queue->impl->release(surface_queue, node);
1170 _tbm_surface_queue_release(surface_queue, node, 1);
1172 if (_queue_is_empty(&surface_queue->free_queue)) {
1173 pthread_mutex_unlock(&surface_queue->lock);
1175 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1176 _tbm_surf_queue_mutex_unlock();
1177 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1180 node->type = QUEUE_NODE_TYPE_RELEASE;
1182 pthread_mutex_unlock(&surface_queue->lock);
1183 pthread_cond_signal(&surface_queue->free_cond);
1185 _tbm_surf_queue_mutex_unlock();
1187 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1189 return TBM_SURFACE_QUEUE_ERROR_NONE;
1192 tbm_surface_queue_error_e
1193 tbm_surface_queue_dequeue(tbm_surface_queue_h
1194 surface_queue, tbm_surface_h *surface)
1198 _tbm_surf_queue_mutex_lock();
1202 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1203 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1204 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1205 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1207 pthread_mutex_lock(&surface_queue->lock);
1209 if (_queue_is_empty(&surface_queue->free_queue)) {
1210 if (surface_queue->impl && surface_queue->impl->need_attach)
1211 surface_queue->impl->need_attach(surface_queue);
1213 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1214 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1215 pthread_mutex_unlock(&surface_queue->lock);
1216 _tbm_surf_queue_mutex_unlock();
1217 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1221 if (surface_queue->impl && surface_queue->impl->dequeue)
1222 node = surface_queue->impl->dequeue(surface_queue);
1224 node = _tbm_surface_queue_dequeue(surface_queue);
1226 if (node == NULL || node->surface == NULL) {
1227 TBM_LOG_E("_queue_node_pop_front failed\n");
1228 pthread_mutex_unlock(&surface_queue->lock);
1230 _tbm_surf_queue_mutex_unlock();
1231 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1234 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1235 *surface = node->surface;
1237 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1239 pthread_mutex_unlock(&surface_queue->lock);
1241 _tbm_surf_queue_mutex_unlock();
1243 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1245 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1247 return TBM_SURFACE_QUEUE_ERROR_NONE;
1251 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1253 _tbm_surf_queue_mutex_lock();
1255 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1257 _tbm_surf_queue_mutex_unlock();
1259 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1261 _tbm_surf_queue_mutex_lock();
1263 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1265 pthread_mutex_lock(&surface_queue->lock);
1267 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1269 if (_queue_is_empty(&surface_queue->free_queue)) {
1270 if (surface_queue->impl && surface_queue->impl->need_attach)
1271 surface_queue->impl->need_attach(surface_queue);
1273 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1274 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1275 pthread_mutex_unlock(&surface_queue->lock);
1276 _tbm_surf_queue_mutex_unlock();
1281 if (!_queue_is_empty(&surface_queue->free_queue)) {
1282 pthread_mutex_unlock(&surface_queue->lock);
1283 _tbm_surf_queue_mutex_unlock();
1287 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1288 QUEUE_NODE_TYPE_ACQUIRE)) {
1289 _tbm_surf_queue_mutex_unlock();
1290 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1291 _tbm_surf_queue_mutex_lock();
1293 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1294 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1295 pthread_mutex_unlock(&surface_queue->lock);
1296 _tbm_surf_queue_mutex_unlock();
1300 pthread_mutex_unlock(&surface_queue->lock);
1301 _tbm_surf_queue_mutex_unlock();
1305 pthread_mutex_unlock(&surface_queue->lock);
1306 _tbm_surf_queue_mutex_unlock();
1310 tbm_surface_queue_error_e
1311 tbm_surface_queue_release(tbm_surface_queue_h
1312 surface_queue, tbm_surface_h surface)
1317 _tbm_surf_queue_mutex_lock();
1319 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1320 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1321 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1322 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1324 pthread_mutex_lock(&surface_queue->lock);
1326 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1328 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1329 if (node == NULL || queue_type != NODE_LIST) {
1330 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1332 pthread_mutex_unlock(&surface_queue->lock);
1334 _tbm_surf_queue_mutex_unlock();
1337 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1339 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1342 if (surface_queue->queue_size < surface_queue->num_attached) {
1343 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1345 if (surface_queue->impl && surface_queue->impl->need_detach)
1346 surface_queue->impl->need_detach(surface_queue, node);
1348 _tbm_surface_queue_detach(surface_queue, surface);
1350 pthread_mutex_unlock(&surface_queue->lock);
1352 _tbm_surf_queue_mutex_unlock();
1353 return TBM_SURFACE_QUEUE_ERROR_NONE;
1356 if (surface_queue->impl && surface_queue->impl->release)
1357 surface_queue->impl->release(surface_queue, node);
1359 _tbm_surface_queue_release(surface_queue, node, 1);
1361 if (_queue_is_empty(&surface_queue->free_queue)) {
1362 pthread_mutex_unlock(&surface_queue->lock);
1364 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1365 _tbm_surf_queue_mutex_unlock();
1366 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1369 node->type = QUEUE_NODE_TYPE_RELEASE;
1371 pthread_mutex_unlock(&surface_queue->lock);
1372 pthread_cond_signal(&surface_queue->free_cond);
1374 _tbm_surf_queue_mutex_unlock();
1376 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1378 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1380 return TBM_SURFACE_QUEUE_ERROR_NONE;
1383 tbm_surface_queue_error_e
1384 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1385 surface_queue, tbm_surface_h surface)
1390 _tbm_surf_queue_mutex_lock();
1392 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1393 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1394 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1395 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1397 pthread_mutex_lock(&surface_queue->lock);
1399 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1401 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1402 if (node == NULL || queue_type != NODE_LIST) {
1403 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1405 pthread_mutex_unlock(&surface_queue->lock);
1407 _tbm_surf_queue_mutex_unlock();
1408 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1411 if (surface_queue->impl && surface_queue->impl->enqueue)
1412 surface_queue->impl->enqueue(surface_queue, node);
1414 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1416 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1417 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1418 pthread_mutex_unlock(&surface_queue->lock);
1420 _tbm_surf_queue_mutex_unlock();
1421 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1424 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1426 pthread_mutex_unlock(&surface_queue->lock);
1427 pthread_cond_signal(&surface_queue->dirty_cond);
1429 _tbm_surf_queue_mutex_unlock();
1431 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1433 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1435 return TBM_SURFACE_QUEUE_ERROR_NONE;
1438 tbm_surface_queue_error_e
1439 tbm_surface_queue_acquire(tbm_surface_queue_h
1440 surface_queue, tbm_surface_h *surface)
1444 _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);
1450 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1451 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1453 pthread_mutex_lock(&surface_queue->lock);
1455 if (surface_queue->impl && surface_queue->impl->acquire)
1456 node = surface_queue->impl->acquire(surface_queue);
1458 node = _tbm_surface_queue_acquire(surface_queue);
1460 if (node == NULL || node->surface == NULL) {
1461 TBM_LOG_E("_queue_node_pop_front failed\n");
1462 pthread_mutex_unlock(&surface_queue->lock);
1464 _tbm_surf_queue_mutex_unlock();
1465 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1468 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1470 *surface = node->surface;
1472 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1474 pthread_mutex_unlock(&surface_queue->lock);
1476 _tbm_surf_queue_mutex_unlock();
1479 tbm_surface_internal_dump_buffer(*surface, "acquire");
1481 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1483 return TBM_SURFACE_QUEUE_ERROR_NONE;
1487 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1489 _tbm_surf_queue_mutex_lock();
1491 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1493 pthread_mutex_lock(&surface_queue->lock);
1495 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1497 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1498 pthread_mutex_unlock(&surface_queue->lock);
1499 _tbm_surf_queue_mutex_unlock();
1503 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1504 QUEUE_NODE_TYPE_DEQUEUE)) {
1505 _tbm_surf_queue_mutex_unlock();
1506 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1507 _tbm_surf_queue_mutex_lock();
1509 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1510 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1511 pthread_mutex_unlock(&surface_queue->lock);
1512 _tbm_surf_queue_mutex_unlock();
1516 pthread_mutex_unlock(&surface_queue->lock);
1517 _tbm_surf_queue_mutex_unlock();
1521 pthread_mutex_unlock(&surface_queue->lock);
1522 _tbm_surf_queue_mutex_unlock();
1527 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1529 queue_node *node = NULL, *tmp;
1531 _tbm_surf_queue_mutex_lock();
1533 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1535 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1537 LIST_DEL(&surface_queue->item_link);
1539 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1540 _queue_delete_node(surface_queue, node);
1542 if (surface_queue->impl && surface_queue->impl->destroy)
1543 surface_queue->impl->destroy(surface_queue);
1545 _notify_emit(surface_queue, &surface_queue->destory_noti);
1547 _notify_remove_all(&surface_queue->destory_noti);
1548 _notify_remove_all(&surface_queue->dequeuable_noti);
1549 _notify_remove_all(&surface_queue->dequeue_noti);
1550 _notify_remove_all(&surface_queue->can_dequeue_noti);
1551 _notify_remove_all(&surface_queue->acquirable_noti);
1552 _notify_remove_all(&surface_queue->reset_noti);
1553 _trace_remove_all(&surface_queue->trace_noti);
1555 pthread_mutex_destroy(&surface_queue->lock);
1557 free(surface_queue);
1559 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1560 _deinit_tbm_surf_queue_bufmgr();
1562 _tbm_surf_queue_mutex_unlock();
1565 tbm_surface_queue_error_e
1566 tbm_surface_queue_reset(tbm_surface_queue_h
1567 surface_queue, int width, int height, int format)
1569 queue_node *node = NULL, *tmp;
1571 _tbm_surf_queue_mutex_lock();
1573 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1574 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1576 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1578 if (width == surface_queue->width && height == surface_queue->height &&
1579 format == surface_queue->format) {
1580 _tbm_surf_queue_mutex_unlock();
1581 return TBM_SURFACE_QUEUE_ERROR_NONE;
1584 pthread_mutex_lock(&surface_queue->lock);
1586 surface_queue->width = width;
1587 surface_queue->height = height;
1588 surface_queue->format = format;
1590 /* Destory surface and Push to free_queue */
1591 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1592 _queue_delete_node(surface_queue, node);
1595 _queue_init(&surface_queue->free_queue);
1596 _queue_init(&surface_queue->dirty_queue);
1597 LIST_INITHEAD(&surface_queue->list);
1599 surface_queue->num_attached = 0;
1601 if (surface_queue->impl && surface_queue->impl->reset)
1602 surface_queue->impl->reset(surface_queue);
1604 pthread_mutex_unlock(&surface_queue->lock);
1605 pthread_cond_signal(&surface_queue->free_cond);
1607 _tbm_surf_queue_mutex_unlock();
1609 _notify_emit(surface_queue, &surface_queue->reset_noti);
1611 return TBM_SURFACE_QUEUE_ERROR_NONE;
1614 tbm_surface_queue_error_e
1615 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1617 _tbm_surf_queue_mutex_lock();
1619 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1620 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1622 _tbm_surf_queue_mutex_unlock();
1624 _notify_emit(surface_queue, &surface_queue->reset_noti);
1626 return TBM_SURFACE_QUEUE_ERROR_NONE;
1629 tbm_surface_queue_error_e
1630 tbm_surface_queue_set_size(tbm_surface_queue_h
1631 surface_queue, int queue_size, int flush)
1633 queue_node *node = NULL, *tmp;
1635 _tbm_surf_queue_mutex_lock();
1637 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1638 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1639 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1640 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1642 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1644 if ((surface_queue->queue_size == queue_size) && !flush) {
1645 _tbm_surf_queue_mutex_unlock();
1646 return TBM_SURFACE_QUEUE_ERROR_NONE;
1649 pthread_mutex_lock(&surface_queue->lock);
1652 /* Destory surface and Push to free_queue */
1653 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1654 _queue_delete_node(surface_queue, node);
1657 _queue_init(&surface_queue->free_queue);
1658 _queue_init(&surface_queue->dirty_queue);
1659 LIST_INITHEAD(&surface_queue->list);
1661 surface_queue->num_attached = 0;
1662 surface_queue->queue_size = queue_size;
1664 if (surface_queue->impl && surface_queue->impl->reset)
1665 surface_queue->impl->reset(surface_queue);
1667 pthread_mutex_unlock(&surface_queue->lock);
1668 pthread_cond_signal(&surface_queue->free_cond);
1670 _tbm_surf_queue_mutex_unlock();
1672 _notify_emit(surface_queue, &surface_queue->reset_noti);
1674 return TBM_SURFACE_QUEUE_ERROR_NONE;
1676 if (surface_queue->queue_size > queue_size) {
1677 int need_del = surface_queue->queue_size - queue_size;
1679 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1680 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1682 if (surface_queue->impl && surface_queue->impl->need_detach)
1683 surface_queue->impl->need_detach(surface_queue, node);
1685 _tbm_surface_queue_detach(surface_queue, node->surface);
1693 surface_queue->queue_size = queue_size;
1695 pthread_mutex_unlock(&surface_queue->lock);
1697 _tbm_surf_queue_mutex_unlock();
1699 return TBM_SURFACE_QUEUE_ERROR_NONE;
1703 tbm_surface_queue_error_e
1704 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1706 queue_node *node = NULL;
1708 _tbm_surf_queue_mutex_lock();
1710 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1711 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1713 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1715 if (surface_queue->num_attached == 0) {
1716 _tbm_surf_queue_mutex_unlock();
1717 return TBM_SURFACE_QUEUE_ERROR_NONE;
1720 pthread_mutex_lock(&surface_queue->lock);
1722 /* Destory surface in free_queue */
1723 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1724 if (surface_queue->impl && surface_queue->impl->need_detach)
1725 surface_queue->impl->need_detach(surface_queue, node);
1727 _tbm_surface_queue_detach(surface_queue, node->surface);
1731 _queue_init(&surface_queue->free_queue);
1733 pthread_mutex_unlock(&surface_queue->lock);
1734 _tbm_surf_queue_mutex_unlock();
1736 return TBM_SURFACE_QUEUE_ERROR_NONE;
1739 tbm_surface_queue_error_e
1740 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1742 queue_node *node = NULL, *tmp;
1744 _tbm_surf_queue_mutex_lock();
1746 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1747 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1749 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1751 if (surface_queue->num_attached == 0) {
1752 _tbm_surf_queue_mutex_unlock();
1753 return TBM_SURFACE_QUEUE_ERROR_NONE;
1756 pthread_mutex_lock(&surface_queue->lock);
1758 /* Destory surface and Push to free_queue */
1759 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1760 _queue_delete_node(surface_queue, node);
1763 _queue_init(&surface_queue->free_queue);
1764 _queue_init(&surface_queue->dirty_queue);
1765 LIST_INITHEAD(&surface_queue->list);
1767 surface_queue->num_attached = 0;
1769 if (surface_queue->impl && surface_queue->impl->reset)
1770 surface_queue->impl->reset(surface_queue);
1772 pthread_mutex_unlock(&surface_queue->lock);
1773 pthread_cond_signal(&surface_queue->free_cond);
1775 _tbm_surf_queue_mutex_unlock();
1777 _notify_emit(surface_queue, &surface_queue->reset_noti);
1779 return TBM_SURFACE_QUEUE_ERROR_NONE;
1782 tbm_surface_queue_error_e
1783 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1784 tbm_surface_h *surfaces, int *num)
1786 queue_node *node = NULL;
1788 _tbm_surf_queue_mutex_lock();
1792 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1793 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1794 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1795 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1797 pthread_mutex_lock(&surface_queue->lock);
1799 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1801 surfaces[*num] = node->surface;
1806 pthread_mutex_unlock(&surface_queue->lock);
1808 _tbm_surf_queue_mutex_unlock();
1810 return TBM_SURFACE_QUEUE_ERROR_NONE;
1813 tbm_surface_queue_error_e
1814 tbm_surface_queue_get_trace_surface_num(
1815 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1817 _tbm_surf_queue_mutex_lock();
1821 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1822 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1823 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1824 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1826 pthread_mutex_lock(&surface_queue->lock);
1829 case TBM_SURFACE_QUEUE_TRACE_NONE:
1832 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1833 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1835 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1836 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1838 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1839 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1841 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1842 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1848 pthread_mutex_unlock(&surface_queue->lock);
1850 _tbm_surf_queue_mutex_unlock();
1852 return TBM_SURFACE_QUEUE_ERROR_NONE;
1857 } tbm_queue_default;
1860 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1862 free(surface_queue->impl_data);
1866 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1868 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1869 tbm_surface_h surface;
1871 if (surface_queue->queue_size == surface_queue->num_attached)
1874 if (surface_queue->alloc_cb) {
1875 pthread_mutex_unlock(&surface_queue->lock);
1876 _tbm_surf_queue_mutex_unlock();
1877 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1878 _tbm_surf_queue_mutex_lock();
1879 pthread_mutex_lock(&surface_queue->lock);
1885 tbm_surface_internal_ref(surface);
1887 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1888 surface_queue->height,
1889 surface_queue->format,
1891 TBM_RETURN_IF_FAIL(surface != NULL);
1894 _tbm_surface_queue_attach(surface_queue, surface);
1895 tbm_surface_internal_unref(surface);
1898 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1899 NULL, /*__tbm_queue_default_init*/
1900 NULL, /*__tbm_queue_default_reset*/
1901 __tbm_queue_default_destroy,
1902 __tbm_queue_default_need_attach,
1903 NULL, /*__tbm_queue_default_enqueue*/
1904 NULL, /*__tbm_queue_default_release*/
1905 NULL, /*__tbm_queue_default_dequeue*/
1906 NULL, /*__tbm_queue_default_acquire*/
1907 NULL, /*__tbm_queue_default_need_detach*/
1911 tbm_surface_queue_create(int queue_size, int width,
1912 int height, int format, int flags)
1914 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1915 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1916 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1917 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1919 _tbm_surf_queue_mutex_lock();
1921 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1922 sizeof(struct _tbm_surface_queue));
1923 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1925 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1927 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1928 sizeof(tbm_queue_default));
1930 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
1931 free(surface_queue);
1932 _tbm_surf_queue_mutex_unlock();
1936 data->flags = flags;
1937 _tbm_surface_queue_init(surface_queue,
1939 width, height, format,
1940 &tbm_queue_default_impl, data);
1942 _tbm_surf_queue_mutex_unlock();
1944 return surface_queue;
1950 } tbm_queue_sequence;
1953 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1955 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1957 _queue_init(&data->dequeue_list);
1961 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1963 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1965 _queue_init(&data->dequeue_list);
1969 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1971 free(surface_queue->impl_data);
1975 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1977 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1978 tbm_surface_h surface;
1980 if (surface_queue->queue_size == surface_queue->num_attached)
1983 if (surface_queue->alloc_cb) {
1984 pthread_mutex_unlock(&surface_queue->lock);
1985 _tbm_surf_queue_mutex_unlock();
1986 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1987 _tbm_surf_queue_mutex_lock();
1988 pthread_mutex_lock(&surface_queue->lock);
1994 tbm_surface_internal_ref(surface);
1996 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1997 surface_queue->height,
1998 surface_queue->format,
2000 TBM_RETURN_IF_FAIL(surface != NULL);
2003 _tbm_surface_queue_attach(surface_queue, surface);
2004 tbm_surface_internal_unref(surface);
2008 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2011 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2012 queue_node *next = NULL, *tmp;
2014 node->priv_flags = 0;
2016 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
2017 if (next->priv_flags)
2019 _queue_node_pop(&data->dequeue_list, next);
2020 _tbm_surface_queue_enqueue(surface_queue, next, 1);
2025 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2028 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2030 if (node->priv_flags) {
2031 node->priv_flags = 0;
2032 _queue_node_pop(&data->dequeue_list, node);
2035 _tbm_surface_queue_release(surface_queue, node, 1);
2039 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2042 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2045 node = _tbm_surface_queue_dequeue(surface_queue);
2047 _queue_node_push_back(&data->dequeue_list, node);
2048 node->priv_flags = 1;
2054 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2055 __tbm_queue_sequence_init,
2056 __tbm_queue_sequence_reset,
2057 __tbm_queue_sequence_destroy,
2058 __tbm_queue_sequence_need_attach,
2059 __tbm_queue_sequence_enqueue,
2060 __tbm_queue_sequence_release,
2061 __tbm_queue_sequence_dequeue,
2062 NULL, /*__tbm_queue_sequence_acquire*/
2063 NULL, /*__tbm_queue_sequence_need_dettach*/
2067 tbm_surface_queue_sequence_create(int queue_size, int width,
2068 int height, int format, int flags)
2070 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2071 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2072 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2073 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2075 _tbm_surf_queue_mutex_lock();
2077 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2078 sizeof(struct _tbm_surface_queue));
2079 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2081 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2083 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2084 sizeof(tbm_queue_sequence));
2086 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
2087 free(surface_queue);
2088 _tbm_surf_queue_mutex_unlock();
2092 data->flags = flags;
2093 _tbm_surface_queue_init(surface_queue,
2095 width, height, format,
2096 &tbm_queue_sequence_impl, data);
2098 _tbm_surf_queue_mutex_unlock();
2100 return surface_queue;
2102 /* LCOV_EXCL_STOP */