1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 #include "tbm_bufmgr_int.h"
41 #define TBM_QUEUE_DEBUG 0
44 #define TBM_QUEUE_TRACE(fmt, ...) { if (bTrace&0x1) fprintf(stderr, "[TBM:TRACE(%d)(%s:%d)] " fmt, getpid(), __func__, __LINE__, ##__VA_ARGS__); }
46 #define TBM_QUEUE_TRACE(fmt, ...)
50 #define TBM_LOCK() TBM_LOG_D("[LOCK] %s:%d surface:%p\n", __func__, __LINE__, surface_queue)
51 #define TBM_UNLOCK() TBM_LOG_D("[UNLOCK] %s:%d surface:%p\n", __func__, __LINE__, surface_queue)
57 static tbm_bufmgr g_surf_queue_bufmgr;
58 static pthread_mutex_t tbm_surf_queue_lock;
59 void _tbm_surface_queue_mutex_unlock(void);
62 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
64 TBM_LOG_E("'%s' failed.\n", #cond);\
65 _tbm_surf_queue_mutex_unlock();\
70 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
72 TBM_LOG_E("'%s' failed.\n", #cond);\
73 _tbm_surf_queue_mutex_unlock();\
78 typedef enum _queue_node_type {
80 QUEUE_NODE_TYPE_DEQUEUE,
81 QUEUE_NODE_TYPE_ENQUEUE,
82 QUEUE_NODE_TYPE_ACQUIRE,
83 QUEUE_NODE_TYPE_RELEASE
87 struct list_head head;
92 tbm_surface_h surface;
94 struct list_head item_link;
95 struct list_head link;
99 unsigned int priv_flags; /*for each queue*/
105 struct list_head link;
107 tbm_surface_queue_notify_cb cb;
112 struct list_head link;
114 tbm_surface_queue_trace_cb cb;
118 typedef struct _tbm_surface_queue_interface {
119 void (*init)(tbm_surface_queue_h queue);
120 void (*reset)(tbm_surface_queue_h queue);
121 void (*destroy)(tbm_surface_queue_h queue);
122 void (*need_attach)(tbm_surface_queue_h queue);
124 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
125 void (*release)(tbm_surface_queue_h queue, queue_node *node);
126 queue_node *(*dequeue)(tbm_surface_queue_h queue);
127 queue_node *(*acquire)(tbm_surface_queue_h queue);
128 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
129 } tbm_surface_queue_interface;
131 struct _tbm_surface_queue {
140 struct list_head list;
142 struct list_head destory_noti;
143 struct list_head dequeuable_noti;
144 struct list_head dequeue_noti;
145 struct list_head can_dequeue_noti;
146 struct list_head acquirable_noti;
147 struct list_head reset_noti;
148 struct list_head trace_noti;
150 pthread_mutex_t lock;
151 pthread_cond_t free_cond;
152 pthread_cond_t dirty_cond;
154 const tbm_surface_queue_interface *impl;
157 //For external buffer allocation
158 tbm_surface_alloc_cb alloc_cb;
159 tbm_surface_free_cb free_cb;
162 struct list_head item_link; /* link of surface queue */
165 unsigned int enqueue_sync_count;
166 unsigned int acquire_sync_count;
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);
653 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
654 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
656 pthread_mutex_lock(&surface_queue->lock);
658 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
660 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
662 pthread_mutex_unlock(&surface_queue->lock);
664 _tbm_surf_queue_mutex_unlock();
666 return TBM_SURFACE_QUEUE_ERROR_NONE;
669 tbm_surface_queue_error_e
670 tbm_surface_queue_remove_destroy_cb(
671 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
674 _tbm_surf_queue_mutex_lock();
676 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
677 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
679 pthread_mutex_lock(&surface_queue->lock);
681 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
683 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
685 pthread_mutex_unlock(&surface_queue->lock);
687 _tbm_surf_queue_mutex_unlock();
689 return TBM_SURFACE_QUEUE_ERROR_NONE;
692 tbm_surface_queue_error_e
693 tbm_surface_queue_add_dequeuable_cb(
694 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
697 _tbm_surf_queue_mutex_lock();
699 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
700 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
701 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
702 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
704 pthread_mutex_lock(&surface_queue->lock);
706 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
708 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
710 pthread_mutex_unlock(&surface_queue->lock);
712 _tbm_surf_queue_mutex_unlock();
714 return TBM_SURFACE_QUEUE_ERROR_NONE;
717 tbm_surface_queue_error_e
718 tbm_surface_queue_remove_dequeuable_cb(
719 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
722 _tbm_surf_queue_mutex_lock();
724 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
725 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
727 pthread_mutex_lock(&surface_queue->lock);
729 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
731 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
733 pthread_mutex_unlock(&surface_queue->lock);
735 _tbm_surf_queue_mutex_unlock();
737 return TBM_SURFACE_QUEUE_ERROR_NONE;
740 tbm_surface_queue_error_e
741 tbm_surface_queue_add_dequeue_cb(
742 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
745 _tbm_surf_queue_mutex_lock();
747 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
748 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
749 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
750 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
752 pthread_mutex_lock(&surface_queue->lock);
754 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
756 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
758 pthread_mutex_unlock(&surface_queue->lock);
760 _tbm_surf_queue_mutex_unlock();
762 return TBM_SURFACE_QUEUE_ERROR_NONE;
765 tbm_surface_queue_error_e
766 tbm_surface_queue_remove_dequeue_cb(
767 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
770 _tbm_surf_queue_mutex_lock();
772 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
773 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
775 pthread_mutex_lock(&surface_queue->lock);
777 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
779 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
781 pthread_mutex_unlock(&surface_queue->lock);
783 _tbm_surf_queue_mutex_unlock();
785 return TBM_SURFACE_QUEUE_ERROR_NONE;
788 tbm_surface_queue_error_e
789 tbm_surface_queue_add_can_dequeue_cb(
790 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
793 _tbm_surf_queue_mutex_lock();
795 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
796 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
797 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
798 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
800 pthread_mutex_lock(&surface_queue->lock);
802 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
804 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
806 pthread_mutex_unlock(&surface_queue->lock);
808 _tbm_surf_queue_mutex_unlock();
810 return TBM_SURFACE_QUEUE_ERROR_NONE;
813 tbm_surface_queue_error_e
814 tbm_surface_queue_remove_can_dequeue_cb(
815 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
818 _tbm_surf_queue_mutex_lock();
820 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
821 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
823 pthread_mutex_lock(&surface_queue->lock);
825 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
827 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
829 pthread_mutex_unlock(&surface_queue->lock);
831 _tbm_surf_queue_mutex_unlock();
833 return TBM_SURFACE_QUEUE_ERROR_NONE;
836 tbm_surface_queue_error_e
837 tbm_surface_queue_add_acquirable_cb(
838 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
841 _tbm_surf_queue_mutex_lock();
843 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
844 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
845 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
846 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
848 pthread_mutex_lock(&surface_queue->lock);
850 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
852 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
854 pthread_mutex_unlock(&surface_queue->lock);
856 _tbm_surf_queue_mutex_unlock();
858 return TBM_SURFACE_QUEUE_ERROR_NONE;
861 tbm_surface_queue_error_e
862 tbm_surface_queue_remove_acquirable_cb(
863 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
866 _tbm_surf_queue_mutex_lock();
868 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
869 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
871 pthread_mutex_lock(&surface_queue->lock);
873 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
875 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
877 pthread_mutex_unlock(&surface_queue->lock);
879 _tbm_surf_queue_mutex_unlock();
881 return TBM_SURFACE_QUEUE_ERROR_NONE;
884 tbm_surface_queue_error_e
885 tbm_surface_queue_add_trace_cb(
886 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
889 _tbm_surf_queue_mutex_lock();
891 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
892 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
893 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
894 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
896 pthread_mutex_lock(&surface_queue->lock);
898 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
900 _trace_add(&surface_queue->trace_noti, trace_cb, data);
902 pthread_mutex_unlock(&surface_queue->lock);
904 _tbm_surf_queue_mutex_unlock();
906 return TBM_SURFACE_QUEUE_ERROR_NONE;
909 tbm_surface_queue_error_e
910 tbm_surface_queue_remove_trace_cb(
911 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
914 _tbm_surf_queue_mutex_lock();
916 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
917 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
919 pthread_mutex_lock(&surface_queue->lock);
921 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
923 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
925 pthread_mutex_unlock(&surface_queue->lock);
927 _tbm_surf_queue_mutex_unlock();
929 return TBM_SURFACE_QUEUE_ERROR_NONE;
932 tbm_surface_queue_error_e
933 tbm_surface_queue_set_alloc_cb(
934 tbm_surface_queue_h surface_queue,
935 tbm_surface_alloc_cb alloc_cb,
936 tbm_surface_free_cb free_cb,
939 _tbm_surf_queue_mutex_lock();
941 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
942 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
944 pthread_mutex_lock(&surface_queue->lock);
946 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
948 surface_queue->alloc_cb = alloc_cb;
949 surface_queue->free_cb = free_cb;
950 surface_queue->alloc_cb_data = data;
952 pthread_mutex_unlock(&surface_queue->lock);
954 _tbm_surf_queue_mutex_unlock();
956 return TBM_SURFACE_QUEUE_ERROR_NONE;
960 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
964 _tbm_surf_queue_mutex_lock();
966 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
968 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
970 width = surface_queue->width;
972 _tbm_surf_queue_mutex_unlock();
978 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
982 _tbm_surf_queue_mutex_lock();
984 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
986 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
988 height = surface_queue->height;
990 _tbm_surf_queue_mutex_unlock();
996 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1000 _tbm_surf_queue_mutex_lock();
1002 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1004 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1006 format = surface_queue->format;
1008 _tbm_surf_queue_mutex_unlock();
1014 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1018 _tbm_surf_queue_mutex_lock();
1020 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1022 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1024 queue_size = surface_queue->queue_size;
1026 _tbm_surf_queue_mutex_unlock();
1031 tbm_surface_queue_error_e
1032 tbm_surface_queue_add_reset_cb(
1033 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1036 _tbm_surf_queue_mutex_lock();
1038 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1039 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1040 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1041 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1043 pthread_mutex_lock(&surface_queue->lock);
1045 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1047 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1049 pthread_mutex_unlock(&surface_queue->lock);
1051 _tbm_surf_queue_mutex_unlock();
1053 return TBM_SURFACE_QUEUE_ERROR_NONE;
1056 tbm_surface_queue_error_e
1057 tbm_surface_queue_remove_reset_cb(
1058 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1061 _tbm_surf_queue_mutex_lock();
1063 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1064 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1066 pthread_mutex_lock(&surface_queue->lock);
1068 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1070 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1072 pthread_mutex_unlock(&surface_queue->lock);
1074 _tbm_surf_queue_mutex_unlock();
1076 return TBM_SURFACE_QUEUE_ERROR_NONE;
1079 tbm_surface_queue_error_e
1080 tbm_surface_queue_enqueue(tbm_surface_queue_h
1081 surface_queue, tbm_surface_h surface)
1086 _tbm_surf_queue_mutex_lock();
1088 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1089 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1090 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1091 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1094 tbm_surface_internal_dump_buffer(surface, "enqueue");
1096 pthread_mutex_lock(&surface_queue->lock);
1098 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1100 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1101 if (node == NULL || queue_type != NODE_LIST) {
1102 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1104 pthread_mutex_unlock(&surface_queue->lock);
1106 _tbm_surf_queue_mutex_unlock();
1109 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1111 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1114 if (surface_queue->impl && surface_queue->impl->enqueue)
1115 surface_queue->impl->enqueue(surface_queue, node);
1117 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1119 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1120 TBM_LOG_E("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1121 pthread_mutex_unlock(&surface_queue->lock);
1123 _tbm_surf_queue_mutex_unlock();
1124 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1127 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1129 if (surface_queue->enqueue_sync_count == 1) {
1130 tbm_surface_info_s info;
1133 TBM_LOG_E("start map surface:%p", surface);
1134 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1135 TBM_LOG_E("end map surface:%p", surface);
1136 if (ret == TBM_SURFACE_ERROR_NONE)
1137 tbm_surface_unmap(surface);
1140 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1142 pthread_mutex_unlock(&surface_queue->lock);
1143 pthread_cond_signal(&surface_queue->dirty_cond);
1145 _tbm_surf_queue_mutex_unlock();
1147 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1149 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1151 return TBM_SURFACE_QUEUE_ERROR_NONE;
1154 tbm_surface_queue_error_e
1155 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1156 surface_queue, tbm_surface_h surface)
1161 _tbm_surf_queue_mutex_lock();
1163 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1164 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1165 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1166 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1168 pthread_mutex_lock(&surface_queue->lock);
1170 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1172 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1173 if (node == NULL || queue_type != NODE_LIST) {
1174 TBM_LOG_E("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1176 pthread_mutex_unlock(&surface_queue->lock);
1178 _tbm_surf_queue_mutex_unlock();
1179 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1182 if (node->delete_pending) {
1183 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1185 _queue_delete_node(surface_queue, node);
1187 pthread_mutex_unlock(&surface_queue->lock);
1189 _tbm_surf_queue_mutex_unlock();
1191 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1193 return TBM_SURFACE_QUEUE_ERROR_NONE;
1196 if (surface_queue->queue_size < surface_queue->num_attached) {
1197 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1199 if (surface_queue->impl && surface_queue->impl->need_detach)
1200 surface_queue->impl->need_detach(surface_queue, node);
1202 _tbm_surface_queue_detach(surface_queue, surface);
1204 pthread_mutex_unlock(&surface_queue->lock);
1206 _tbm_surf_queue_mutex_unlock();
1208 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1210 return TBM_SURFACE_QUEUE_ERROR_NONE;
1213 if (surface_queue->impl && surface_queue->impl->release)
1214 surface_queue->impl->release(surface_queue, node);
1216 _tbm_surface_queue_release(surface_queue, node, 1);
1218 if (_queue_is_empty(&surface_queue->free_queue)) {
1219 pthread_mutex_unlock(&surface_queue->lock);
1221 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1222 _tbm_surf_queue_mutex_unlock();
1223 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1226 node->type = QUEUE_NODE_TYPE_RELEASE;
1228 pthread_mutex_unlock(&surface_queue->lock);
1229 pthread_cond_signal(&surface_queue->free_cond);
1231 _tbm_surf_queue_mutex_unlock();
1233 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1235 return TBM_SURFACE_QUEUE_ERROR_NONE;
1238 tbm_surface_queue_error_e
1239 tbm_surface_queue_dequeue(tbm_surface_queue_h
1240 surface_queue, tbm_surface_h *surface)
1244 _tbm_surf_queue_mutex_lock();
1246 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1247 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1248 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1249 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1253 pthread_mutex_lock(&surface_queue->lock);
1255 if (_queue_is_empty(&surface_queue->free_queue)) {
1256 if (surface_queue->impl && surface_queue->impl->need_attach)
1257 surface_queue->impl->need_attach(surface_queue);
1259 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1260 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1261 pthread_mutex_unlock(&surface_queue->lock);
1262 _tbm_surf_queue_mutex_unlock();
1263 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1267 if (surface_queue->impl && surface_queue->impl->dequeue)
1268 node = surface_queue->impl->dequeue(surface_queue);
1270 node = _tbm_surface_queue_dequeue(surface_queue);
1272 if (node == NULL || node->surface == NULL) {
1273 TBM_LOG_E("_queue_node_pop_front failed\n");
1274 pthread_mutex_unlock(&surface_queue->lock);
1276 _tbm_surf_queue_mutex_unlock();
1277 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1280 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1281 *surface = node->surface;
1283 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1285 pthread_mutex_unlock(&surface_queue->lock);
1287 _tbm_surf_queue_mutex_unlock();
1289 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1291 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1293 return TBM_SURFACE_QUEUE_ERROR_NONE;
1297 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1299 _tbm_surf_queue_mutex_lock();
1301 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1303 _tbm_surf_queue_mutex_unlock();
1305 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1307 _tbm_surf_queue_mutex_lock();
1309 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1311 pthread_mutex_lock(&surface_queue->lock);
1313 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1315 if (_queue_is_empty(&surface_queue->free_queue)) {
1316 if (surface_queue->impl && surface_queue->impl->need_attach)
1317 surface_queue->impl->need_attach(surface_queue);
1319 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1320 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1321 pthread_mutex_unlock(&surface_queue->lock);
1322 _tbm_surf_queue_mutex_unlock();
1327 if (!_queue_is_empty(&surface_queue->free_queue)) {
1328 pthread_mutex_unlock(&surface_queue->lock);
1329 _tbm_surf_queue_mutex_unlock();
1333 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1334 QUEUE_NODE_TYPE_ACQUIRE)) {
1335 _tbm_surf_queue_mutex_unlock();
1336 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1337 pthread_mutex_unlock(&surface_queue->lock);
1341 pthread_mutex_unlock(&surface_queue->lock);
1342 _tbm_surf_queue_mutex_unlock();
1346 tbm_surface_queue_error_e
1347 tbm_surface_queue_release(tbm_surface_queue_h
1348 surface_queue, tbm_surface_h surface)
1353 _tbm_surf_queue_mutex_lock();
1355 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1356 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1357 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1358 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1360 pthread_mutex_lock(&surface_queue->lock);
1362 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1364 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1365 if (node == NULL || queue_type != NODE_LIST) {
1366 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1368 pthread_mutex_unlock(&surface_queue->lock);
1370 _tbm_surf_queue_mutex_unlock();
1373 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1375 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1378 if (node->delete_pending) {
1379 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1381 _queue_delete_node(surface_queue, node);
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->queue_size < surface_queue->num_attached) {
1393 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1395 if (surface_queue->impl && surface_queue->impl->need_detach)
1396 surface_queue->impl->need_detach(surface_queue, node);
1398 _tbm_surface_queue_detach(surface_queue, surface);
1400 pthread_mutex_unlock(&surface_queue->lock);
1402 _tbm_surf_queue_mutex_unlock();
1404 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1406 return TBM_SURFACE_QUEUE_ERROR_NONE;
1409 if (surface_queue->impl && surface_queue->impl->release)
1410 surface_queue->impl->release(surface_queue, node);
1412 _tbm_surface_queue_release(surface_queue, node, 1);
1414 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1415 TBM_LOG_E("release surface(%p) but surface isn't present in the free_queue\n", surface);
1416 pthread_mutex_unlock(&surface_queue->lock);
1418 _tbm_surf_queue_mutex_unlock();
1419 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1422 node->type = QUEUE_NODE_TYPE_RELEASE;
1424 pthread_mutex_unlock(&surface_queue->lock);
1425 pthread_cond_signal(&surface_queue->free_cond);
1427 _tbm_surf_queue_mutex_unlock();
1429 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1431 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1433 return TBM_SURFACE_QUEUE_ERROR_NONE;
1436 tbm_surface_queue_error_e
1437 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1438 surface_queue, tbm_surface_h surface)
1443 _tbm_surf_queue_mutex_lock();
1445 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1446 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1447 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1448 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1450 pthread_mutex_lock(&surface_queue->lock);
1452 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1454 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1455 if (node == NULL || queue_type != NODE_LIST) {
1456 TBM_LOG_E("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1458 pthread_mutex_unlock(&surface_queue->lock);
1460 _tbm_surf_queue_mutex_unlock();
1461 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1464 if (surface_queue->impl && surface_queue->impl->enqueue)
1465 surface_queue->impl->enqueue(surface_queue, node);
1467 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1469 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1470 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1471 pthread_mutex_unlock(&surface_queue->lock);
1473 _tbm_surf_queue_mutex_unlock();
1474 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1477 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1479 pthread_mutex_unlock(&surface_queue->lock);
1480 pthread_cond_signal(&surface_queue->dirty_cond);
1482 _tbm_surf_queue_mutex_unlock();
1484 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1486 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1488 return TBM_SURFACE_QUEUE_ERROR_NONE;
1491 tbm_surface_queue_error_e
1492 tbm_surface_queue_acquire(tbm_surface_queue_h
1493 surface_queue, tbm_surface_h *surface)
1497 _tbm_surf_queue_mutex_lock();
1501 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1502 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1503 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1504 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1506 pthread_mutex_lock(&surface_queue->lock);
1508 if (surface_queue->impl && surface_queue->impl->acquire)
1509 node = surface_queue->impl->acquire(surface_queue);
1511 node = _tbm_surface_queue_acquire(surface_queue);
1513 if (node == NULL || node->surface == NULL) {
1514 TBM_LOG_E("_queue_node_pop_front failed\n");
1515 pthread_mutex_unlock(&surface_queue->lock);
1517 _tbm_surf_queue_mutex_unlock();
1518 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1521 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1523 *surface = node->surface;
1525 if (surface_queue->acquire_sync_count == 1) {
1526 tbm_surface_info_s info;
1529 TBM_LOG_E("start map surface:%p", *surface);
1530 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1531 TBM_LOG_E("end map surface:%p", *surface);
1532 if (ret == TBM_SURFACE_ERROR_NONE)
1533 tbm_surface_unmap(*surface);
1536 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1538 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1540 pthread_mutex_unlock(&surface_queue->lock);
1542 _tbm_surf_queue_mutex_unlock();
1545 tbm_surface_internal_dump_buffer(*surface, "acquire");
1547 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1549 return TBM_SURFACE_QUEUE_ERROR_NONE;
1553 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1555 _tbm_surf_queue_mutex_lock();
1557 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1559 pthread_mutex_lock(&surface_queue->lock);
1561 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1563 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1564 pthread_mutex_unlock(&surface_queue->lock);
1565 _tbm_surf_queue_mutex_unlock();
1569 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1570 QUEUE_NODE_TYPE_DEQUEUE)) {
1571 _tbm_surf_queue_mutex_unlock();
1572 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1573 pthread_mutex_unlock(&surface_queue->lock);
1577 pthread_mutex_unlock(&surface_queue->lock);
1578 _tbm_surf_queue_mutex_unlock();
1583 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1585 queue_node *node = NULL, *tmp;
1587 _tbm_surf_queue_mutex_lock();
1589 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1591 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1593 LIST_DEL(&surface_queue->item_link);
1595 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1596 _queue_delete_node(surface_queue, node);
1598 if (surface_queue->impl && surface_queue->impl->destroy)
1599 surface_queue->impl->destroy(surface_queue);
1601 _notify_emit(surface_queue, &surface_queue->destory_noti);
1603 _notify_remove_all(&surface_queue->destory_noti);
1604 _notify_remove_all(&surface_queue->dequeuable_noti);
1605 _notify_remove_all(&surface_queue->dequeue_noti);
1606 _notify_remove_all(&surface_queue->can_dequeue_noti);
1607 _notify_remove_all(&surface_queue->acquirable_noti);
1608 _notify_remove_all(&surface_queue->reset_noti);
1609 _trace_remove_all(&surface_queue->trace_noti);
1611 pthread_mutex_destroy(&surface_queue->lock);
1613 free(surface_queue);
1615 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1616 _deinit_tbm_surf_queue_bufmgr();
1618 _tbm_surf_queue_mutex_unlock();
1621 tbm_surface_queue_error_e
1622 tbm_surface_queue_reset(tbm_surface_queue_h
1623 surface_queue, int width, int height, int format)
1625 queue_node *node = NULL, *tmp;
1627 _tbm_surf_queue_mutex_lock();
1629 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1630 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1632 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1634 if (width == surface_queue->width && height == surface_queue->height &&
1635 format == surface_queue->format) {
1636 _tbm_surf_queue_mutex_unlock();
1637 return TBM_SURFACE_QUEUE_ERROR_NONE;
1640 pthread_mutex_lock(&surface_queue->lock);
1642 surface_queue->width = width;
1643 surface_queue->height = height;
1644 surface_queue->format = format;
1646 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1647 /* Destory surface and Push to free_queue */
1648 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1649 _queue_delete_node(surface_queue, node);
1651 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1652 node->delete_pending = 1;
1654 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1655 _queue_delete_node(surface_queue, node);
1657 _queue_init(&surface_queue->dirty_queue);
1658 LIST_INITHEAD(&surface_queue->list);
1662 _queue_init(&surface_queue->free_queue);
1664 surface_queue->num_attached = 0;
1666 if (surface_queue->impl && surface_queue->impl->reset)
1667 surface_queue->impl->reset(surface_queue);
1669 pthread_mutex_unlock(&surface_queue->lock);
1670 pthread_cond_signal(&surface_queue->free_cond);
1672 _tbm_surf_queue_mutex_unlock();
1674 _notify_emit(surface_queue, &surface_queue->reset_noti);
1676 return TBM_SURFACE_QUEUE_ERROR_NONE;
1679 tbm_surface_queue_error_e
1680 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1682 _tbm_surf_queue_mutex_lock();
1684 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1685 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1687 _tbm_surf_queue_mutex_unlock();
1689 _notify_emit(surface_queue, &surface_queue->reset_noti);
1691 return TBM_SURFACE_QUEUE_ERROR_NONE;
1694 tbm_surface_queue_error_e
1695 tbm_surface_queue_set_size(tbm_surface_queue_h
1696 surface_queue, int queue_size, int flush)
1698 queue_node *node = NULL, *tmp;
1700 _tbm_surf_queue_mutex_lock();
1702 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1703 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1704 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1705 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1707 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1709 if ((surface_queue->queue_size == queue_size) && !flush) {
1710 _tbm_surf_queue_mutex_unlock();
1711 return TBM_SURFACE_QUEUE_ERROR_NONE;
1714 pthread_mutex_lock(&surface_queue->lock);
1717 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1718 /* Destory surface and Push to free_queue */
1719 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1720 _queue_delete_node(surface_queue, node);
1722 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1723 node->delete_pending = 1;
1725 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1726 _queue_delete_node(surface_queue, node);
1728 _queue_init(&surface_queue->dirty_queue);
1729 LIST_INITHEAD(&surface_queue->list);
1733 _queue_init(&surface_queue->free_queue);
1735 surface_queue->num_attached = 0;
1736 surface_queue->queue_size = queue_size;
1738 if (surface_queue->impl && surface_queue->impl->reset)
1739 surface_queue->impl->reset(surface_queue);
1741 pthread_mutex_unlock(&surface_queue->lock);
1742 pthread_cond_signal(&surface_queue->free_cond);
1744 _tbm_surf_queue_mutex_unlock();
1746 _notify_emit(surface_queue, &surface_queue->reset_noti);
1748 return TBM_SURFACE_QUEUE_ERROR_NONE;
1750 if (surface_queue->queue_size > queue_size) {
1751 int need_del = surface_queue->queue_size - queue_size;
1753 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1754 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1756 if (surface_queue->impl && surface_queue->impl->need_detach)
1757 surface_queue->impl->need_detach(surface_queue, node);
1759 _tbm_surface_queue_detach(surface_queue, node->surface);
1767 surface_queue->queue_size = queue_size;
1769 pthread_mutex_unlock(&surface_queue->lock);
1771 _tbm_surf_queue_mutex_unlock();
1773 return TBM_SURFACE_QUEUE_ERROR_NONE;
1777 tbm_surface_queue_error_e
1778 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1780 queue_node *node = NULL;
1782 _tbm_surf_queue_mutex_lock();
1784 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1785 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1787 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1789 if (surface_queue->num_attached == 0) {
1790 _tbm_surf_queue_mutex_unlock();
1791 return TBM_SURFACE_QUEUE_ERROR_NONE;
1794 pthread_mutex_lock(&surface_queue->lock);
1796 /* Destory surface in free_queue */
1797 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1798 if (surface_queue->impl && surface_queue->impl->need_detach)
1799 surface_queue->impl->need_detach(surface_queue, node);
1801 _tbm_surface_queue_detach(surface_queue, node->surface);
1805 _queue_init(&surface_queue->free_queue);
1807 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_flush(tbm_surface_queue_h surface_queue)
1816 queue_node *node = NULL, *tmp;
1818 _tbm_surf_queue_mutex_lock();
1820 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1821 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1823 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1825 if (surface_queue->num_attached == 0) {
1826 _tbm_surf_queue_mutex_unlock();
1827 return TBM_SURFACE_QUEUE_ERROR_NONE;
1830 pthread_mutex_lock(&surface_queue->lock);
1832 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1833 /* Destory surface and Push to free_queue */
1834 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1835 _queue_delete_node(surface_queue, node);
1837 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1838 node->delete_pending = 1;
1840 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1841 _queue_delete_node(surface_queue, node);
1843 _queue_init(&surface_queue->dirty_queue);
1844 LIST_INITHEAD(&surface_queue->list);
1848 _queue_init(&surface_queue->free_queue);
1850 surface_queue->num_attached = 0;
1852 if (surface_queue->impl && surface_queue->impl->reset)
1853 surface_queue->impl->reset(surface_queue);
1855 pthread_mutex_unlock(&surface_queue->lock);
1856 pthread_cond_signal(&surface_queue->free_cond);
1858 _tbm_surf_queue_mutex_unlock();
1860 _notify_emit(surface_queue, &surface_queue->reset_noti);
1862 return TBM_SURFACE_QUEUE_ERROR_NONE;
1865 tbm_surface_queue_error_e
1866 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1867 tbm_surface_h *surfaces, int *num)
1869 queue_node *node = NULL;
1871 _tbm_surf_queue_mutex_lock();
1873 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1874 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1875 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1876 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1880 pthread_mutex_lock(&surface_queue->lock);
1882 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1884 surfaces[*num] = node->surface;
1889 pthread_mutex_unlock(&surface_queue->lock);
1891 _tbm_surf_queue_mutex_unlock();
1893 return TBM_SURFACE_QUEUE_ERROR_NONE;
1896 tbm_surface_queue_error_e
1897 tbm_surface_queue_get_trace_surface_num(
1898 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1900 _tbm_surf_queue_mutex_lock();
1902 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1903 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1904 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1905 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1909 pthread_mutex_lock(&surface_queue->lock);
1912 case TBM_SURFACE_QUEUE_TRACE_NONE:
1915 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1916 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1918 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1919 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1921 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1922 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1924 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1925 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1931 pthread_mutex_unlock(&surface_queue->lock);
1933 _tbm_surf_queue_mutex_unlock();
1935 return TBM_SURFACE_QUEUE_ERROR_NONE;
1940 } tbm_queue_default;
1943 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1945 free(surface_queue->impl_data);
1949 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1951 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1952 tbm_surface_h surface;
1954 if (surface_queue->queue_size == surface_queue->num_attached)
1957 if (surface_queue->alloc_cb) {
1958 pthread_mutex_unlock(&surface_queue->lock);
1959 _tbm_surf_queue_mutex_unlock();
1960 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1961 _tbm_surf_queue_mutex_lock();
1962 pthread_mutex_lock(&surface_queue->lock);
1968 tbm_surface_internal_ref(surface);
1970 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1971 surface_queue->height,
1972 surface_queue->format,
1974 TBM_RETURN_IF_FAIL(surface != NULL);
1977 _tbm_surface_queue_attach(surface_queue, surface);
1978 tbm_surface_internal_unref(surface);
1981 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1982 NULL, /*__tbm_queue_default_init*/
1983 NULL, /*__tbm_queue_default_reset*/
1984 __tbm_queue_default_destroy,
1985 __tbm_queue_default_need_attach,
1986 NULL, /*__tbm_queue_default_enqueue*/
1987 NULL, /*__tbm_queue_default_release*/
1988 NULL, /*__tbm_queue_default_dequeue*/
1989 NULL, /*__tbm_queue_default_acquire*/
1990 NULL, /*__tbm_queue_default_need_detach*/
1994 tbm_surface_queue_create(int queue_size, int width,
1995 int height, int format, int flags)
1997 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1998 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1999 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2000 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2002 _tbm_surf_queue_mutex_lock();
2004 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2005 sizeof(struct _tbm_surface_queue));
2006 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2008 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2010 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2011 sizeof(tbm_queue_default));
2013 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
2014 free(surface_queue);
2015 _tbm_surf_queue_mutex_unlock();
2019 data->flags = flags;
2020 _tbm_surface_queue_init(surface_queue,
2022 width, height, format,
2023 &tbm_queue_default_impl, data);
2025 _tbm_surf_queue_mutex_unlock();
2027 return surface_queue;
2033 } tbm_queue_sequence;
2036 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2038 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2040 _queue_init(&data->dequeue_list);
2044 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2046 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2048 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2051 _queue_init(&data->dequeue_list);
2055 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2057 free(surface_queue->impl_data);
2061 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2063 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2064 tbm_surface_h surface;
2066 if (surface_queue->queue_size == surface_queue->num_attached)
2069 if (surface_queue->alloc_cb) {
2070 pthread_mutex_unlock(&surface_queue->lock);
2071 _tbm_surf_queue_mutex_unlock();
2072 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2073 _tbm_surf_queue_mutex_lock();
2074 pthread_mutex_lock(&surface_queue->lock);
2080 tbm_surface_internal_ref(surface);
2082 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2083 surface_queue->height,
2084 surface_queue->format,
2086 TBM_RETURN_IF_FAIL(surface != NULL);
2089 _tbm_surface_queue_attach(surface_queue, surface);
2090 tbm_surface_internal_unref(surface);
2094 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2097 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2098 queue_node *first = NULL;
2100 first = container_of(data->dequeue_list.head.next, first, item_link);
2101 if (first != node) {
2105 node->priv_flags = 0;
2107 _queue_node_pop(&data->dequeue_list, node);
2108 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2112 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2115 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2117 if (node->priv_flags) {
2118 node->priv_flags = 0;
2119 _queue_node_pop(&data->dequeue_list, node);
2122 _tbm_surface_queue_release(surface_queue, node, 1);
2126 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2129 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2132 node = _tbm_surface_queue_dequeue(surface_queue);
2134 _queue_node_push_back(&data->dequeue_list, node);
2135 node->priv_flags = 1;
2141 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2142 __tbm_queue_sequence_init,
2143 __tbm_queue_sequence_reset,
2144 __tbm_queue_sequence_destroy,
2145 __tbm_queue_sequence_need_attach,
2146 __tbm_queue_sequence_enqueue,
2147 __tbm_queue_sequence_release,
2148 __tbm_queue_sequence_dequeue,
2149 NULL, /*__tbm_queue_sequence_acquire*/
2150 NULL, /*__tbm_queue_sequence_need_dettach*/
2154 tbm_surface_queue_sequence_create(int queue_size, int width,
2155 int height, int format, int flags)
2157 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2158 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2159 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2160 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2162 _tbm_surf_queue_mutex_lock();
2164 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2165 sizeof(struct _tbm_surface_queue));
2166 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2168 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2170 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2171 sizeof(tbm_queue_sequence));
2173 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
2174 free(surface_queue);
2175 _tbm_surf_queue_mutex_unlock();
2179 data->flags = flags;
2180 _tbm_surface_queue_init(surface_queue,
2182 width, height, format,
2183 &tbm_queue_sequence_impl, data);
2185 _tbm_surf_queue_mutex_unlock();
2187 return surface_queue;
2190 tbm_surface_queue_error_e
2191 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2194 _tbm_surf_queue_mutex_lock();
2196 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2197 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2199 pthread_mutex_lock(&surface_queue->lock);
2201 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2202 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2204 surface_queue->modes |= modes;
2206 pthread_mutex_unlock(&surface_queue->lock);
2208 _tbm_surf_queue_mutex_unlock();
2210 return TBM_SURFACE_QUEUE_ERROR_NONE;
2213 tbm_surface_queue_error_e
2214 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2215 unsigned int sync_count)
2217 int dequeue_num, enqueue_num;
2219 _tbm_surf_queue_mutex_lock();
2221 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2222 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2224 pthread_mutex_lock(&surface_queue->lock);
2226 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2227 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2229 if (dequeue_num + sync_count == 0)
2230 surface_queue->acquire_sync_count = enqueue_num;
2232 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2234 TBM_QUEUE_TRACE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2235 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2237 pthread_mutex_unlock(&surface_queue->lock);
2239 _tbm_surf_queue_mutex_unlock();
2241 return TBM_SURFACE_QUEUE_ERROR_NONE;