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 */
167 /* LCOV_EXCL_START */
170 _tbm_surf_queue_mutex_init(void)
172 static bool tbm_surf_queue_mutex_init = false;
174 if (tbm_surf_queue_mutex_init)
177 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
178 TBM_LOG_E("fail: pthread_mutex_init\n");
182 tbm_surf_queue_mutex_init = true;
188 _tbm_surf_queue_mutex_lock(void)
190 if (!_tbm_surf_queue_mutex_init()) {
191 TBM_LOG_E("fail: _tbm_surf_queue_mutex_init\n");
195 pthread_mutex_lock(&tbm_surf_queue_lock);
199 _tbm_surf_queue_mutex_unlock(void)
201 pthread_mutex_unlock(&tbm_surf_queue_lock);
205 _init_tbm_surf_queue_bufmgr(void)
207 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
211 _deinit_tbm_surf_queue_bufmgr(void)
213 if (!g_surf_queue_bufmgr)
216 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
217 g_surf_queue_bufmgr = NULL;
221 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
223 tbm_surface_queue_h old_data = NULL;
225 if (surface_queue == NULL) {
226 TBM_LOG_E("error: surface_queue is NULL.\n");
230 if (g_surf_queue_bufmgr == NULL) {
231 TBM_LOG_E("error: g_surf_queue_bufmgr is NULL.\n");
235 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
236 TBM_LOG_E("error: surf_queue_list is empty\n");
240 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
242 if (old_data == surface_queue) {
243 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
248 TBM_LOG_E("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
254 _queue_node_create(void)
256 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
258 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
264 _queue_node_delete(queue_node *node)
266 LIST_DEL(&node->item_link);
267 LIST_DEL(&node->link);
272 _queue_is_empty(queue *queue)
274 if (LIST_IS_EMPTY(&queue->head))
281 _queue_node_push_back(queue *queue, queue_node *node)
283 LIST_ADDTAIL(&node->item_link, &queue->head);
288 _queue_node_push_front(queue *queue, queue_node *node)
290 LIST_ADD(&node->item_link, &queue->head);
295 _queue_node_pop_front(queue *queue)
299 if (!queue->head.next) return NULL;
300 if (!queue->count) return NULL;
302 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
304 LIST_DELINIT(&node->item_link);
311 _queue_node_pop(queue *queue, queue_node *node)
313 LIST_DELINIT(&node->item_link);
320 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
321 tbm_surface_h surface, int *out_type)
323 queue_node *node = NULL;
326 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
330 if (type & FREE_QUEUE) {
331 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
333 if (node->surface == surface) {
335 *out_type = FREE_QUEUE;
342 if (type & DIRTY_QUEUE) {
343 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
345 if (node->surface == surface) {
347 *out_type = DIRTY_QUEUE;
354 if (type & NODE_LIST) {
355 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
356 if (node->surface == surface) {
358 *out_type = NODE_LIST;
365 TBM_LOG_E("fail to get the queue_node.\n");
371 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
374 if (surface_queue->free_cb) {
375 surface_queue->free_cb(surface_queue,
376 surface_queue->alloc_cb_data,
380 tbm_surface_destroy(node->surface);
383 _queue_node_delete(node);
387 _queue_init(queue *queue)
389 LIST_INITHEAD(&queue->head);
395 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
398 TBM_RETURN_IF_FAIL(cb != NULL);
400 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
402 TBM_RETURN_IF_FAIL(item != NULL);
404 LIST_INITHEAD(&item->link);
408 LIST_ADDTAIL(&item->link, list);
412 _notify_remove(struct list_head *list,
413 tbm_surface_queue_notify_cb cb, void *data)
415 queue_notify *item = NULL, *tmp;
417 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
418 if (item->cb == cb && item->data == data) {
419 LIST_DEL(&item->link);
425 TBM_LOG_E("Cannot find notifiy\n");
429 _notify_remove_all(struct list_head *list)
431 queue_notify *item = NULL, *tmp;
433 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
434 LIST_DEL(&item->link);
440 _notify_emit(tbm_surface_queue_h surface_queue,
441 struct list_head *list)
443 queue_notify *item = NULL, *tmp;;
446 The item->cb is the outside function of the libtbm.
447 The tbm user may/can remove the item of the list,
448 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
450 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
451 item->cb(surface_queue, item->data);
455 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
458 TBM_RETURN_IF_FAIL(cb != NULL);
460 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
462 TBM_RETURN_IF_FAIL(item != NULL);
464 LIST_INITHEAD(&item->link);
468 LIST_ADDTAIL(&item->link, list);
472 _trace_remove(struct list_head *list,
473 tbm_surface_queue_trace_cb cb, void *data)
475 queue_trace *item = NULL, *tmp;
477 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
478 if (item->cb == cb && item->data == data) {
479 LIST_DEL(&item->link);
485 TBM_LOG_E("Cannot find notifiy\n");
489 _trace_remove_all(struct list_head *list)
491 queue_trace *item = NULL, *tmp;
493 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
494 LIST_DEL(&item->link);
500 _trace_emit(tbm_surface_queue_h surface_queue,
501 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
503 queue_trace *item = NULL, *tmp;;
506 The item->cb is the outside function of the libtbm.
507 The tbm user may/can remove the item of the list,
508 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
510 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
511 item->cb(surface_queue, surface, trace, item->data);
515 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
517 queue_node *node = NULL;
520 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
521 if (node->type == type)
529 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
530 tbm_surface_h surface)
534 node = _queue_node_create();
535 TBM_RETURN_IF_FAIL(node != NULL);
537 tbm_surface_internal_ref(surface);
538 node->surface = surface;
540 LIST_ADDTAIL(&node->link, &surface_queue->list);
541 surface_queue->num_attached++;
542 _queue_node_push_back(&surface_queue->free_queue, node);
546 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
547 tbm_surface_h surface)
552 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
554 _queue_delete_node(surface_queue, node);
555 surface_queue->num_attached--;
560 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
561 queue_node *node, int push_back)
564 _queue_node_push_back(&surface_queue->dirty_queue, node);
566 _queue_node_push_front(&surface_queue->dirty_queue, node);
570 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
574 node = _queue_node_pop_front(&surface_queue->free_queue);
580 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
584 if (_queue_is_empty(&surface_queue->dirty_queue))
587 node = _queue_node_pop_front(&surface_queue->dirty_queue);
593 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
594 queue_node *node, int push_back)
597 _queue_node_push_back(&surface_queue->free_queue, node);
599 _queue_node_push_front(&surface_queue->free_queue, node);
603 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
605 int width, int height, int format,
606 const tbm_surface_queue_interface *impl, void *data)
608 TBM_RETURN_IF_FAIL(surface_queue != NULL);
609 TBM_RETURN_IF_FAIL(impl != NULL);
611 if (!g_surf_queue_bufmgr)
612 _init_tbm_surf_queue_bufmgr();
614 pthread_mutex_init(&surface_queue->lock, NULL);
615 pthread_cond_init(&surface_queue->free_cond, NULL);
616 pthread_cond_init(&surface_queue->dirty_cond, NULL);
618 surface_queue->queue_size = queue_size;
619 surface_queue->width = width;
620 surface_queue->height = height;
621 surface_queue->format = format;
622 surface_queue->impl = impl;
623 surface_queue->impl_data = data;
624 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
626 _queue_init(&surface_queue->free_queue);
627 _queue_init(&surface_queue->dirty_queue);
628 LIST_INITHEAD(&surface_queue->list);
630 LIST_INITHEAD(&surface_queue->destory_noti);
631 LIST_INITHEAD(&surface_queue->dequeuable_noti);
632 LIST_INITHEAD(&surface_queue->dequeue_noti);
633 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
634 LIST_INITHEAD(&surface_queue->acquirable_noti);
635 LIST_INITHEAD(&surface_queue->reset_noti);
636 LIST_INITHEAD(&surface_queue->trace_noti);
638 if (surface_queue->impl && surface_queue->impl->init)
639 surface_queue->impl->init(surface_queue);
641 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
644 tbm_surface_queue_error_e
645 tbm_surface_queue_add_destroy_cb(
646 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
649 _tbm_surf_queue_mutex_lock();
651 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
652 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
654 pthread_mutex_lock(&surface_queue->lock);
656 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
658 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
660 pthread_mutex_unlock(&surface_queue->lock);
662 _tbm_surf_queue_mutex_unlock();
664 return TBM_SURFACE_QUEUE_ERROR_NONE;
667 tbm_surface_queue_error_e
668 tbm_surface_queue_remove_destroy_cb(
669 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
672 _tbm_surf_queue_mutex_lock();
674 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
675 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
677 pthread_mutex_lock(&surface_queue->lock);
679 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
681 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
683 pthread_mutex_unlock(&surface_queue->lock);
685 _tbm_surf_queue_mutex_unlock();
687 return TBM_SURFACE_QUEUE_ERROR_NONE;
690 tbm_surface_queue_error_e
691 tbm_surface_queue_add_dequeuable_cb(
692 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
695 _tbm_surf_queue_mutex_lock();
697 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
698 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
700 pthread_mutex_lock(&surface_queue->lock);
702 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
704 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
706 pthread_mutex_unlock(&surface_queue->lock);
708 _tbm_surf_queue_mutex_unlock();
710 return TBM_SURFACE_QUEUE_ERROR_NONE;
713 tbm_surface_queue_error_e
714 tbm_surface_queue_remove_dequeuable_cb(
715 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
718 _tbm_surf_queue_mutex_lock();
720 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
721 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
723 pthread_mutex_lock(&surface_queue->lock);
725 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
727 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
729 pthread_mutex_unlock(&surface_queue->lock);
731 _tbm_surf_queue_mutex_unlock();
733 return TBM_SURFACE_QUEUE_ERROR_NONE;
736 tbm_surface_queue_error_e
737 tbm_surface_queue_add_dequeue_cb(
738 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
741 _tbm_surf_queue_mutex_lock();
743 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
744 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
746 pthread_mutex_lock(&surface_queue->lock);
748 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
750 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
752 pthread_mutex_unlock(&surface_queue->lock);
754 _tbm_surf_queue_mutex_unlock();
756 return TBM_SURFACE_QUEUE_ERROR_NONE;
759 tbm_surface_queue_error_e
760 tbm_surface_queue_remove_dequeue_cb(
761 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
764 _tbm_surf_queue_mutex_lock();
766 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
767 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
769 pthread_mutex_lock(&surface_queue->lock);
771 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
773 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
775 pthread_mutex_unlock(&surface_queue->lock);
777 _tbm_surf_queue_mutex_unlock();
779 return TBM_SURFACE_QUEUE_ERROR_NONE;
782 tbm_surface_queue_error_e
783 tbm_surface_queue_add_can_dequeue_cb(
784 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
787 _tbm_surf_queue_mutex_lock();
789 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
790 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
792 pthread_mutex_lock(&surface_queue->lock);
794 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
796 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
798 pthread_mutex_unlock(&surface_queue->lock);
800 _tbm_surf_queue_mutex_unlock();
802 return TBM_SURFACE_QUEUE_ERROR_NONE;
805 tbm_surface_queue_error_e
806 tbm_surface_queue_remove_can_dequeue_cb(
807 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
810 _tbm_surf_queue_mutex_lock();
812 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
813 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
815 pthread_mutex_lock(&surface_queue->lock);
817 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
819 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
821 pthread_mutex_unlock(&surface_queue->lock);
823 _tbm_surf_queue_mutex_unlock();
825 return TBM_SURFACE_QUEUE_ERROR_NONE;
828 tbm_surface_queue_error_e
829 tbm_surface_queue_add_acquirable_cb(
830 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
833 _tbm_surf_queue_mutex_lock();
835 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
836 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
838 pthread_mutex_lock(&surface_queue->lock);
840 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
842 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
844 pthread_mutex_unlock(&surface_queue->lock);
846 _tbm_surf_queue_mutex_unlock();
848 return TBM_SURFACE_QUEUE_ERROR_NONE;
851 tbm_surface_queue_error_e
852 tbm_surface_queue_remove_acquirable_cb(
853 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
856 _tbm_surf_queue_mutex_lock();
858 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
859 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
861 pthread_mutex_lock(&surface_queue->lock);
863 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
865 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
867 pthread_mutex_unlock(&surface_queue->lock);
869 _tbm_surf_queue_mutex_unlock();
871 return TBM_SURFACE_QUEUE_ERROR_NONE;
874 tbm_surface_queue_error_e
875 tbm_surface_queue_add_trace_cb(
876 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
879 _tbm_surf_queue_mutex_lock();
881 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
882 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
884 pthread_mutex_lock(&surface_queue->lock);
886 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
888 _trace_add(&surface_queue->trace_noti, trace_cb, data);
890 pthread_mutex_unlock(&surface_queue->lock);
892 _tbm_surf_queue_mutex_unlock();
894 return TBM_SURFACE_QUEUE_ERROR_NONE;
897 tbm_surface_queue_error_e
898 tbm_surface_queue_remove_trace_cb(
899 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
902 _tbm_surf_queue_mutex_lock();
904 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
905 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
907 pthread_mutex_lock(&surface_queue->lock);
909 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
911 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
913 pthread_mutex_unlock(&surface_queue->lock);
915 _tbm_surf_queue_mutex_unlock();
917 return TBM_SURFACE_QUEUE_ERROR_NONE;
920 tbm_surface_queue_error_e
921 tbm_surface_queue_set_alloc_cb(
922 tbm_surface_queue_h surface_queue,
923 tbm_surface_alloc_cb alloc_cb,
924 tbm_surface_free_cb free_cb,
927 _tbm_surf_queue_mutex_lock();
929 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
930 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
932 pthread_mutex_lock(&surface_queue->lock);
934 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
936 surface_queue->alloc_cb = alloc_cb;
937 surface_queue->free_cb = free_cb;
938 surface_queue->alloc_cb_data = data;
940 pthread_mutex_unlock(&surface_queue->lock);
942 _tbm_surf_queue_mutex_unlock();
944 return TBM_SURFACE_QUEUE_ERROR_NONE;
948 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
952 _tbm_surf_queue_mutex_lock();
954 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
956 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
958 width = surface_queue->width;
960 _tbm_surf_queue_mutex_unlock();
966 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
970 _tbm_surf_queue_mutex_lock();
972 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
974 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
976 height = surface_queue->height;
978 _tbm_surf_queue_mutex_unlock();
984 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
988 _tbm_surf_queue_mutex_lock();
990 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
992 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
994 format = surface_queue->format;
996 _tbm_surf_queue_mutex_unlock();
1002 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1006 _tbm_surf_queue_mutex_lock();
1008 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1010 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1012 queue_size = surface_queue->queue_size;
1014 _tbm_surf_queue_mutex_unlock();
1019 tbm_surface_queue_error_e
1020 tbm_surface_queue_add_reset_cb(
1021 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1024 _tbm_surf_queue_mutex_lock();
1026 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1027 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1029 pthread_mutex_lock(&surface_queue->lock);
1031 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1033 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1035 pthread_mutex_unlock(&surface_queue->lock);
1037 _tbm_surf_queue_mutex_unlock();
1039 return TBM_SURFACE_QUEUE_ERROR_NONE;
1042 tbm_surface_queue_error_e
1043 tbm_surface_queue_remove_reset_cb(
1044 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1047 _tbm_surf_queue_mutex_lock();
1049 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1050 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1052 pthread_mutex_lock(&surface_queue->lock);
1054 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1056 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1058 pthread_mutex_unlock(&surface_queue->lock);
1060 _tbm_surf_queue_mutex_unlock();
1062 return TBM_SURFACE_QUEUE_ERROR_NONE;
1065 tbm_surface_queue_error_e
1066 tbm_surface_queue_enqueue(tbm_surface_queue_h
1067 surface_queue, tbm_surface_h surface)
1072 _tbm_surf_queue_mutex_lock();
1074 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1075 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1076 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1077 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1080 tbm_surface_internal_dump_buffer(surface, "enqueue");
1082 pthread_mutex_lock(&surface_queue->lock);
1084 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1086 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1087 if (node == NULL || queue_type != NODE_LIST) {
1088 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1090 pthread_mutex_unlock(&surface_queue->lock);
1092 _tbm_surf_queue_mutex_unlock();
1095 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1097 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1100 if (surface_queue->impl && surface_queue->impl->enqueue)
1101 surface_queue->impl->enqueue(surface_queue, node);
1103 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1105 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1106 TBM_LOG_E("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1107 pthread_mutex_unlock(&surface_queue->lock);
1109 _tbm_surf_queue_mutex_unlock();
1110 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1113 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1115 pthread_mutex_unlock(&surface_queue->lock);
1116 pthread_cond_signal(&surface_queue->dirty_cond);
1118 _tbm_surf_queue_mutex_unlock();
1120 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1122 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1124 return TBM_SURFACE_QUEUE_ERROR_NONE;
1127 tbm_surface_queue_error_e
1128 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1129 surface_queue, tbm_surface_h surface)
1134 _tbm_surf_queue_mutex_lock();
1136 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1137 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1138 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1139 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1141 pthread_mutex_lock(&surface_queue->lock);
1143 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1145 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1146 if (node == NULL || queue_type != NODE_LIST) {
1147 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1149 pthread_mutex_unlock(&surface_queue->lock);
1151 _tbm_surf_queue_mutex_unlock();
1152 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1155 if (node->delete_pending) {
1156 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1158 _queue_delete_node(surface_queue, node);
1160 pthread_mutex_unlock(&surface_queue->lock);
1162 _tbm_surf_queue_mutex_unlock();
1164 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1166 return TBM_SURFACE_QUEUE_ERROR_NONE;
1169 if (surface_queue->queue_size < surface_queue->num_attached) {
1170 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1172 if (surface_queue->impl && surface_queue->impl->need_detach)
1173 surface_queue->impl->need_detach(surface_queue, node);
1175 _tbm_surface_queue_detach(surface_queue, surface);
1177 pthread_mutex_unlock(&surface_queue->lock);
1179 _tbm_surf_queue_mutex_unlock();
1181 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1183 return TBM_SURFACE_QUEUE_ERROR_NONE;
1186 if (surface_queue->impl && surface_queue->impl->release)
1187 surface_queue->impl->release(surface_queue, node);
1189 _tbm_surface_queue_release(surface_queue, node, 1);
1191 if (_queue_is_empty(&surface_queue->free_queue)) {
1192 pthread_mutex_unlock(&surface_queue->lock);
1194 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1195 _tbm_surf_queue_mutex_unlock();
1196 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1199 node->type = QUEUE_NODE_TYPE_RELEASE;
1201 pthread_mutex_unlock(&surface_queue->lock);
1202 pthread_cond_signal(&surface_queue->free_cond);
1204 _tbm_surf_queue_mutex_unlock();
1206 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1208 return TBM_SURFACE_QUEUE_ERROR_NONE;
1211 tbm_surface_queue_error_e
1212 tbm_surface_queue_dequeue(tbm_surface_queue_h
1213 surface_queue, tbm_surface_h *surface)
1217 _tbm_surf_queue_mutex_lock();
1221 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1222 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1223 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1224 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1226 pthread_mutex_lock(&surface_queue->lock);
1228 if (_queue_is_empty(&surface_queue->free_queue)) {
1229 if (surface_queue->impl && surface_queue->impl->need_attach)
1230 surface_queue->impl->need_attach(surface_queue);
1232 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1233 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1234 pthread_mutex_unlock(&surface_queue->lock);
1235 _tbm_surf_queue_mutex_unlock();
1236 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1240 if (surface_queue->impl && surface_queue->impl->dequeue)
1241 node = surface_queue->impl->dequeue(surface_queue);
1243 node = _tbm_surface_queue_dequeue(surface_queue);
1245 if (node == NULL || node->surface == NULL) {
1246 TBM_LOG_E("_queue_node_pop_front failed\n");
1247 pthread_mutex_unlock(&surface_queue->lock);
1249 _tbm_surf_queue_mutex_unlock();
1250 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1253 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1254 *surface = node->surface;
1256 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1258 pthread_mutex_unlock(&surface_queue->lock);
1260 _tbm_surf_queue_mutex_unlock();
1262 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1264 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1266 return TBM_SURFACE_QUEUE_ERROR_NONE;
1270 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1272 _tbm_surf_queue_mutex_lock();
1274 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1276 _tbm_surf_queue_mutex_unlock();
1278 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1280 _tbm_surf_queue_mutex_lock();
1282 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1284 pthread_mutex_lock(&surface_queue->lock);
1286 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1288 if (_queue_is_empty(&surface_queue->free_queue)) {
1289 if (surface_queue->impl && surface_queue->impl->need_attach)
1290 surface_queue->impl->need_attach(surface_queue);
1292 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1293 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1294 pthread_mutex_unlock(&surface_queue->lock);
1295 _tbm_surf_queue_mutex_unlock();
1300 if (!_queue_is_empty(&surface_queue->free_queue)) {
1301 pthread_mutex_unlock(&surface_queue->lock);
1302 _tbm_surf_queue_mutex_unlock();
1306 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1307 QUEUE_NODE_TYPE_ACQUIRE)) {
1308 _tbm_surf_queue_mutex_unlock();
1309 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1310 _tbm_surf_queue_mutex_lock();
1312 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1313 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1314 pthread_mutex_unlock(&surface_queue->lock);
1315 _tbm_surf_queue_mutex_unlock();
1319 pthread_mutex_unlock(&surface_queue->lock);
1320 _tbm_surf_queue_mutex_unlock();
1324 pthread_mutex_unlock(&surface_queue->lock);
1325 _tbm_surf_queue_mutex_unlock();
1329 tbm_surface_queue_error_e
1330 tbm_surface_queue_release(tbm_surface_queue_h
1331 surface_queue, tbm_surface_h surface)
1336 _tbm_surf_queue_mutex_lock();
1338 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1339 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1340 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1341 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1343 pthread_mutex_lock(&surface_queue->lock);
1345 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1347 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1348 if (node == NULL || queue_type != NODE_LIST) {
1349 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1351 pthread_mutex_unlock(&surface_queue->lock);
1353 _tbm_surf_queue_mutex_unlock();
1356 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1358 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1361 if (node->delete_pending) {
1362 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1364 _queue_delete_node(surface_queue, node);
1366 pthread_mutex_unlock(&surface_queue->lock);
1368 _tbm_surf_queue_mutex_unlock();
1370 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1372 return TBM_SURFACE_QUEUE_ERROR_NONE;
1375 if (surface_queue->queue_size < surface_queue->num_attached) {
1376 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1378 if (surface_queue->impl && surface_queue->impl->need_detach)
1379 surface_queue->impl->need_detach(surface_queue, node);
1381 _tbm_surface_queue_detach(surface_queue, surface);
1383 pthread_mutex_unlock(&surface_queue->lock);
1385 _tbm_surf_queue_mutex_unlock();
1387 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1389 return TBM_SURFACE_QUEUE_ERROR_NONE;
1392 if (surface_queue->impl && surface_queue->impl->release)
1393 surface_queue->impl->release(surface_queue, node);
1395 _tbm_surface_queue_release(surface_queue, node, 1);
1397 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1398 TBM_LOG_E("release surface(%p) but surface isn't present in the free_queue\n", surface);
1399 pthread_mutex_unlock(&surface_queue->lock);
1401 _tbm_surf_queue_mutex_unlock();
1402 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1405 node->type = QUEUE_NODE_TYPE_RELEASE;
1407 pthread_mutex_unlock(&surface_queue->lock);
1408 pthread_cond_signal(&surface_queue->free_cond);
1410 _tbm_surf_queue_mutex_unlock();
1412 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1414 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1416 return TBM_SURFACE_QUEUE_ERROR_NONE;
1419 tbm_surface_queue_error_e
1420 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1421 surface_queue, tbm_surface_h surface)
1426 _tbm_surf_queue_mutex_lock();
1428 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1429 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1430 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1431 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1433 pthread_mutex_lock(&surface_queue->lock);
1435 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1437 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1438 if (node == NULL || queue_type != NODE_LIST) {
1439 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1441 pthread_mutex_unlock(&surface_queue->lock);
1443 _tbm_surf_queue_mutex_unlock();
1444 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1447 if (surface_queue->impl && surface_queue->impl->enqueue)
1448 surface_queue->impl->enqueue(surface_queue, node);
1450 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1452 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1453 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1454 pthread_mutex_unlock(&surface_queue->lock);
1456 _tbm_surf_queue_mutex_unlock();
1457 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1460 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1462 pthread_mutex_unlock(&surface_queue->lock);
1463 pthread_cond_signal(&surface_queue->dirty_cond);
1465 _tbm_surf_queue_mutex_unlock();
1467 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1469 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1471 return TBM_SURFACE_QUEUE_ERROR_NONE;
1474 tbm_surface_queue_error_e
1475 tbm_surface_queue_acquire(tbm_surface_queue_h
1476 surface_queue, tbm_surface_h *surface)
1480 _tbm_surf_queue_mutex_lock();
1484 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1485 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1486 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1487 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1489 pthread_mutex_lock(&surface_queue->lock);
1491 if (surface_queue->impl && surface_queue->impl->acquire)
1492 node = surface_queue->impl->acquire(surface_queue);
1494 node = _tbm_surface_queue_acquire(surface_queue);
1496 if (node == NULL || node->surface == NULL) {
1497 TBM_LOG_E("_queue_node_pop_front failed\n");
1498 pthread_mutex_unlock(&surface_queue->lock);
1500 _tbm_surf_queue_mutex_unlock();
1501 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1504 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1506 *surface = node->surface;
1508 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1510 pthread_mutex_unlock(&surface_queue->lock);
1512 _tbm_surf_queue_mutex_unlock();
1515 tbm_surface_internal_dump_buffer(*surface, "acquire");
1517 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1519 return TBM_SURFACE_QUEUE_ERROR_NONE;
1523 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1525 _tbm_surf_queue_mutex_lock();
1527 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1529 pthread_mutex_lock(&surface_queue->lock);
1531 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1533 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1534 pthread_mutex_unlock(&surface_queue->lock);
1535 _tbm_surf_queue_mutex_unlock();
1539 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1540 QUEUE_NODE_TYPE_DEQUEUE)) {
1541 _tbm_surf_queue_mutex_unlock();
1542 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1543 _tbm_surf_queue_mutex_lock();
1545 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1546 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1547 pthread_mutex_unlock(&surface_queue->lock);
1548 _tbm_surf_queue_mutex_unlock();
1552 pthread_mutex_unlock(&surface_queue->lock);
1553 _tbm_surf_queue_mutex_unlock();
1557 pthread_mutex_unlock(&surface_queue->lock);
1558 _tbm_surf_queue_mutex_unlock();
1563 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1565 queue_node *node = NULL, *tmp;
1567 _tbm_surf_queue_mutex_lock();
1569 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1571 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1573 LIST_DEL(&surface_queue->item_link);
1575 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1576 _queue_delete_node(surface_queue, node);
1578 if (surface_queue->impl && surface_queue->impl->destroy)
1579 surface_queue->impl->destroy(surface_queue);
1581 _notify_emit(surface_queue, &surface_queue->destory_noti);
1583 _notify_remove_all(&surface_queue->destory_noti);
1584 _notify_remove_all(&surface_queue->dequeuable_noti);
1585 _notify_remove_all(&surface_queue->dequeue_noti);
1586 _notify_remove_all(&surface_queue->can_dequeue_noti);
1587 _notify_remove_all(&surface_queue->acquirable_noti);
1588 _notify_remove_all(&surface_queue->reset_noti);
1589 _trace_remove_all(&surface_queue->trace_noti);
1591 pthread_mutex_destroy(&surface_queue->lock);
1593 free(surface_queue);
1595 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1596 _deinit_tbm_surf_queue_bufmgr();
1598 _tbm_surf_queue_mutex_unlock();
1601 tbm_surface_queue_error_e
1602 tbm_surface_queue_reset(tbm_surface_queue_h
1603 surface_queue, int width, int height, int format)
1605 queue_node *node = NULL, *tmp;
1607 _tbm_surf_queue_mutex_lock();
1609 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1610 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1612 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1614 if (width == surface_queue->width && height == surface_queue->height &&
1615 format == surface_queue->format) {
1616 _tbm_surf_queue_mutex_unlock();
1617 return TBM_SURFACE_QUEUE_ERROR_NONE;
1620 pthread_mutex_lock(&surface_queue->lock);
1622 surface_queue->width = width;
1623 surface_queue->height = height;
1624 surface_queue->format = format;
1626 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1627 /* Destory surface and Push to free_queue */
1628 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1629 _queue_delete_node(surface_queue, node);
1631 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1632 node->delete_pending = 1;
1634 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1635 _queue_delete_node(surface_queue, node);
1637 _queue_init(&surface_queue->dirty_queue);
1638 LIST_INITHEAD(&surface_queue->list);
1642 _queue_init(&surface_queue->free_queue);
1644 surface_queue->num_attached = 0;
1646 if (surface_queue->impl && surface_queue->impl->reset)
1647 surface_queue->impl->reset(surface_queue);
1649 pthread_mutex_unlock(&surface_queue->lock);
1650 pthread_cond_signal(&surface_queue->free_cond);
1652 _tbm_surf_queue_mutex_unlock();
1654 _notify_emit(surface_queue, &surface_queue->reset_noti);
1656 return TBM_SURFACE_QUEUE_ERROR_NONE;
1659 tbm_surface_queue_error_e
1660 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1662 _tbm_surf_queue_mutex_lock();
1664 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1665 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1667 _tbm_surf_queue_mutex_unlock();
1669 _notify_emit(surface_queue, &surface_queue->reset_noti);
1671 return TBM_SURFACE_QUEUE_ERROR_NONE;
1674 tbm_surface_queue_error_e
1675 tbm_surface_queue_set_size(tbm_surface_queue_h
1676 surface_queue, int queue_size, int flush)
1678 queue_node *node = NULL, *tmp;
1680 _tbm_surf_queue_mutex_lock();
1682 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1683 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1684 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1685 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1687 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1689 if ((surface_queue->queue_size == queue_size) && !flush) {
1690 _tbm_surf_queue_mutex_unlock();
1691 return TBM_SURFACE_QUEUE_ERROR_NONE;
1694 pthread_mutex_lock(&surface_queue->lock);
1697 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1698 /* Destory surface and Push to free_queue */
1699 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1700 _queue_delete_node(surface_queue, node);
1702 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1703 node->delete_pending = 1;
1705 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1706 _queue_delete_node(surface_queue, node);
1708 _queue_init(&surface_queue->dirty_queue);
1709 LIST_INITHEAD(&surface_queue->list);
1713 _queue_init(&surface_queue->free_queue);
1715 surface_queue->num_attached = 0;
1716 surface_queue->queue_size = queue_size;
1718 if (surface_queue->impl && surface_queue->impl->reset)
1719 surface_queue->impl->reset(surface_queue);
1721 pthread_mutex_unlock(&surface_queue->lock);
1722 pthread_cond_signal(&surface_queue->free_cond);
1724 _tbm_surf_queue_mutex_unlock();
1726 _notify_emit(surface_queue, &surface_queue->reset_noti);
1728 return TBM_SURFACE_QUEUE_ERROR_NONE;
1730 if (surface_queue->queue_size > queue_size) {
1731 int need_del = surface_queue->queue_size - queue_size;
1733 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1734 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1736 if (surface_queue->impl && surface_queue->impl->need_detach)
1737 surface_queue->impl->need_detach(surface_queue, node);
1739 _tbm_surface_queue_detach(surface_queue, node->surface);
1747 surface_queue->queue_size = queue_size;
1749 pthread_mutex_unlock(&surface_queue->lock);
1751 _tbm_surf_queue_mutex_unlock();
1753 return TBM_SURFACE_QUEUE_ERROR_NONE;
1757 tbm_surface_queue_error_e
1758 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1760 queue_node *node = NULL;
1762 _tbm_surf_queue_mutex_lock();
1764 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1765 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1767 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1769 if (surface_queue->num_attached == 0) {
1770 _tbm_surf_queue_mutex_unlock();
1771 return TBM_SURFACE_QUEUE_ERROR_NONE;
1774 pthread_mutex_lock(&surface_queue->lock);
1776 /* Destory surface in free_queue */
1777 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1778 if (surface_queue->impl && surface_queue->impl->need_detach)
1779 surface_queue->impl->need_detach(surface_queue, node);
1781 _tbm_surface_queue_detach(surface_queue, node->surface);
1785 _queue_init(&surface_queue->free_queue);
1787 pthread_mutex_unlock(&surface_queue->lock);
1788 _tbm_surf_queue_mutex_unlock();
1790 return TBM_SURFACE_QUEUE_ERROR_NONE;
1793 tbm_surface_queue_error_e
1794 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1796 queue_node *node = NULL, *tmp;
1798 _tbm_surf_queue_mutex_lock();
1800 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1801 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1803 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1805 if (surface_queue->num_attached == 0) {
1806 _tbm_surf_queue_mutex_unlock();
1807 return TBM_SURFACE_QUEUE_ERROR_NONE;
1810 pthread_mutex_lock(&surface_queue->lock);
1812 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1813 /* Destory surface and Push to free_queue */
1814 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1815 _queue_delete_node(surface_queue, node);
1817 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1818 node->delete_pending = 1;
1820 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1821 _queue_delete_node(surface_queue, node);
1823 _queue_init(&surface_queue->dirty_queue);
1824 LIST_INITHEAD(&surface_queue->list);
1828 _queue_init(&surface_queue->free_queue);
1830 surface_queue->num_attached = 0;
1832 if (surface_queue->impl && surface_queue->impl->reset)
1833 surface_queue->impl->reset(surface_queue);
1835 pthread_mutex_unlock(&surface_queue->lock);
1836 pthread_cond_signal(&surface_queue->free_cond);
1838 _tbm_surf_queue_mutex_unlock();
1840 _notify_emit(surface_queue, &surface_queue->reset_noti);
1842 return TBM_SURFACE_QUEUE_ERROR_NONE;
1845 tbm_surface_queue_error_e
1846 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1847 tbm_surface_h *surfaces, int *num)
1849 queue_node *node = NULL;
1851 _tbm_surf_queue_mutex_lock();
1855 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1856 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1857 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1858 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1860 pthread_mutex_lock(&surface_queue->lock);
1862 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1864 surfaces[*num] = node->surface;
1869 pthread_mutex_unlock(&surface_queue->lock);
1871 _tbm_surf_queue_mutex_unlock();
1873 return TBM_SURFACE_QUEUE_ERROR_NONE;
1876 tbm_surface_queue_error_e
1877 tbm_surface_queue_get_trace_surface_num(
1878 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1880 _tbm_surf_queue_mutex_lock();
1884 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1885 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1886 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1887 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1889 pthread_mutex_lock(&surface_queue->lock);
1892 case TBM_SURFACE_QUEUE_TRACE_NONE:
1895 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1896 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1898 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1899 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1901 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1902 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1904 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1905 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1911 pthread_mutex_unlock(&surface_queue->lock);
1913 _tbm_surf_queue_mutex_unlock();
1915 return TBM_SURFACE_QUEUE_ERROR_NONE;
1920 } tbm_queue_default;
1923 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1925 free(surface_queue->impl_data);
1929 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1931 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1932 tbm_surface_h surface;
1934 if (surface_queue->queue_size == surface_queue->num_attached)
1937 if (surface_queue->alloc_cb) {
1938 pthread_mutex_unlock(&surface_queue->lock);
1939 _tbm_surf_queue_mutex_unlock();
1940 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1941 _tbm_surf_queue_mutex_lock();
1942 pthread_mutex_lock(&surface_queue->lock);
1948 tbm_surface_internal_ref(surface);
1950 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1951 surface_queue->height,
1952 surface_queue->format,
1954 TBM_RETURN_IF_FAIL(surface != NULL);
1957 _tbm_surface_queue_attach(surface_queue, surface);
1958 tbm_surface_internal_unref(surface);
1961 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1962 NULL, /*__tbm_queue_default_init*/
1963 NULL, /*__tbm_queue_default_reset*/
1964 __tbm_queue_default_destroy,
1965 __tbm_queue_default_need_attach,
1966 NULL, /*__tbm_queue_default_enqueue*/
1967 NULL, /*__tbm_queue_default_release*/
1968 NULL, /*__tbm_queue_default_dequeue*/
1969 NULL, /*__tbm_queue_default_acquire*/
1970 NULL, /*__tbm_queue_default_need_detach*/
1974 tbm_surface_queue_create(int queue_size, int width,
1975 int height, int format, int flags)
1977 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1978 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1979 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1980 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1982 _tbm_surf_queue_mutex_lock();
1984 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1985 sizeof(struct _tbm_surface_queue));
1986 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1988 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1990 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1991 sizeof(tbm_queue_default));
1993 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
1994 free(surface_queue);
1995 _tbm_surf_queue_mutex_unlock();
1999 data->flags = flags;
2000 _tbm_surface_queue_init(surface_queue,
2002 width, height, format,
2003 &tbm_queue_default_impl, data);
2005 _tbm_surf_queue_mutex_unlock();
2007 return surface_queue;
2013 } tbm_queue_sequence;
2016 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2018 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2020 _queue_init(&data->dequeue_list);
2024 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2026 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2028 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2031 _queue_init(&data->dequeue_list);
2035 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2037 free(surface_queue->impl_data);
2041 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2043 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2044 tbm_surface_h surface;
2046 if (surface_queue->queue_size == surface_queue->num_attached)
2049 if (surface_queue->alloc_cb) {
2050 pthread_mutex_unlock(&surface_queue->lock);
2051 _tbm_surf_queue_mutex_unlock();
2052 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2053 _tbm_surf_queue_mutex_lock();
2054 pthread_mutex_lock(&surface_queue->lock);
2060 tbm_surface_internal_ref(surface);
2062 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2063 surface_queue->height,
2064 surface_queue->format,
2066 TBM_RETURN_IF_FAIL(surface != NULL);
2069 _tbm_surface_queue_attach(surface_queue, surface);
2070 tbm_surface_internal_unref(surface);
2074 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2077 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2078 queue_node *next = NULL, *tmp;
2080 node->priv_flags = 0;
2082 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
2083 if (next->priv_flags)
2085 _queue_node_pop(&data->dequeue_list, next);
2086 _tbm_surface_queue_enqueue(surface_queue, next, 1);
2091 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2094 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2096 if (node->priv_flags) {
2097 node->priv_flags = 0;
2098 _queue_node_pop(&data->dequeue_list, node);
2101 _tbm_surface_queue_release(surface_queue, node, 1);
2105 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2108 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2111 node = _tbm_surface_queue_dequeue(surface_queue);
2113 _queue_node_push_back(&data->dequeue_list, node);
2114 node->priv_flags = 1;
2120 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2121 __tbm_queue_sequence_init,
2122 __tbm_queue_sequence_reset,
2123 __tbm_queue_sequence_destroy,
2124 __tbm_queue_sequence_need_attach,
2125 __tbm_queue_sequence_enqueue,
2126 __tbm_queue_sequence_release,
2127 __tbm_queue_sequence_dequeue,
2128 NULL, /*__tbm_queue_sequence_acquire*/
2129 NULL, /*__tbm_queue_sequence_need_dettach*/
2133 tbm_surface_queue_sequence_create(int queue_size, int width,
2134 int height, int format, int flags)
2136 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2137 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2138 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2139 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2141 _tbm_surf_queue_mutex_lock();
2143 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2144 sizeof(struct _tbm_surface_queue));
2145 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2147 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2149 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2150 sizeof(tbm_queue_sequence));
2152 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
2153 free(surface_queue);
2154 _tbm_surf_queue_mutex_unlock();
2158 data->flags = flags;
2159 _tbm_surface_queue_init(surface_queue,
2161 width, height, format,
2162 &tbm_queue_sequence_impl, data);
2164 _tbm_surf_queue_mutex_unlock();
2166 return surface_queue;
2169 tbm_surface_queue_error_e
2170 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2173 _tbm_surf_queue_mutex_lock();
2175 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2176 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2178 pthread_mutex_lock(&surface_queue->lock);
2180 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2181 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2183 surface_queue->modes |= modes;
2185 pthread_mutex_unlock(&surface_queue->lock);
2187 _tbm_surf_queue_mutex_unlock();
2189 return TBM_SURFACE_QUEUE_ERROR_NONE;
2191 /* LCOV_EXCL_STOP */