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 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1134 if (ret == TBM_SURFACE_ERROR_NONE)
1135 tbm_surface_unmap(surface);
1138 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1140 pthread_mutex_unlock(&surface_queue->lock);
1141 pthread_cond_signal(&surface_queue->dirty_cond);
1143 _tbm_surf_queue_mutex_unlock();
1145 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1147 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1149 return TBM_SURFACE_QUEUE_ERROR_NONE;
1152 tbm_surface_queue_error_e
1153 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1154 surface_queue, tbm_surface_h surface)
1159 _tbm_surf_queue_mutex_lock();
1161 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1162 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1163 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1164 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1166 pthread_mutex_lock(&surface_queue->lock);
1168 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1170 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1171 if (node == NULL || queue_type != NODE_LIST) {
1172 TBM_LOG_E("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1174 pthread_mutex_unlock(&surface_queue->lock);
1176 _tbm_surf_queue_mutex_unlock();
1177 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1180 if (node->delete_pending) {
1181 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1183 _queue_delete_node(surface_queue, node);
1185 pthread_mutex_unlock(&surface_queue->lock);
1187 _tbm_surf_queue_mutex_unlock();
1189 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1191 return TBM_SURFACE_QUEUE_ERROR_NONE;
1194 if (surface_queue->queue_size < surface_queue->num_attached) {
1195 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1197 if (surface_queue->impl && surface_queue->impl->need_detach)
1198 surface_queue->impl->need_detach(surface_queue, node);
1200 _tbm_surface_queue_detach(surface_queue, surface);
1202 pthread_mutex_unlock(&surface_queue->lock);
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 if (surface_queue->impl && surface_queue->impl->release)
1212 surface_queue->impl->release(surface_queue, node);
1214 _tbm_surface_queue_release(surface_queue, node, 1);
1216 if (_queue_is_empty(&surface_queue->free_queue)) {
1217 pthread_mutex_unlock(&surface_queue->lock);
1219 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1220 _tbm_surf_queue_mutex_unlock();
1221 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1224 node->type = QUEUE_NODE_TYPE_RELEASE;
1226 pthread_mutex_unlock(&surface_queue->lock);
1227 pthread_cond_signal(&surface_queue->free_cond);
1229 _tbm_surf_queue_mutex_unlock();
1231 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1233 return TBM_SURFACE_QUEUE_ERROR_NONE;
1236 tbm_surface_queue_error_e
1237 tbm_surface_queue_dequeue(tbm_surface_queue_h
1238 surface_queue, tbm_surface_h *surface)
1242 _tbm_surf_queue_mutex_lock();
1244 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1245 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1246 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1247 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1251 pthread_mutex_lock(&surface_queue->lock);
1253 if (_queue_is_empty(&surface_queue->free_queue)) {
1254 if (surface_queue->impl && surface_queue->impl->need_attach)
1255 surface_queue->impl->need_attach(surface_queue);
1257 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1258 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1259 pthread_mutex_unlock(&surface_queue->lock);
1260 _tbm_surf_queue_mutex_unlock();
1261 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1265 if (surface_queue->impl && surface_queue->impl->dequeue)
1266 node = surface_queue->impl->dequeue(surface_queue);
1268 node = _tbm_surface_queue_dequeue(surface_queue);
1270 if (node == NULL || node->surface == NULL) {
1271 TBM_LOG_E("_queue_node_pop_front failed\n");
1272 pthread_mutex_unlock(&surface_queue->lock);
1274 _tbm_surf_queue_mutex_unlock();
1275 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1278 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1279 *surface = node->surface;
1281 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1283 pthread_mutex_unlock(&surface_queue->lock);
1285 _tbm_surf_queue_mutex_unlock();
1287 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1289 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1291 return TBM_SURFACE_QUEUE_ERROR_NONE;
1295 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1297 _tbm_surf_queue_mutex_lock();
1299 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1301 _tbm_surf_queue_mutex_unlock();
1303 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1305 _tbm_surf_queue_mutex_lock();
1307 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1309 pthread_mutex_lock(&surface_queue->lock);
1311 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1313 if (_queue_is_empty(&surface_queue->free_queue)) {
1314 if (surface_queue->impl && surface_queue->impl->need_attach)
1315 surface_queue->impl->need_attach(surface_queue);
1317 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1318 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1319 pthread_mutex_unlock(&surface_queue->lock);
1320 _tbm_surf_queue_mutex_unlock();
1325 if (!_queue_is_empty(&surface_queue->free_queue)) {
1326 pthread_mutex_unlock(&surface_queue->lock);
1327 _tbm_surf_queue_mutex_unlock();
1331 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1332 QUEUE_NODE_TYPE_ACQUIRE)) {
1333 _tbm_surf_queue_mutex_unlock();
1334 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1335 pthread_mutex_unlock(&surface_queue->lock);
1339 pthread_mutex_unlock(&surface_queue->lock);
1340 _tbm_surf_queue_mutex_unlock();
1344 tbm_surface_queue_error_e
1345 tbm_surface_queue_release(tbm_surface_queue_h
1346 surface_queue, tbm_surface_h surface)
1351 _tbm_surf_queue_mutex_lock();
1353 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1354 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1355 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1356 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1358 pthread_mutex_lock(&surface_queue->lock);
1360 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1362 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1363 if (node == NULL || queue_type != NODE_LIST) {
1364 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1366 pthread_mutex_unlock(&surface_queue->lock);
1368 _tbm_surf_queue_mutex_unlock();
1371 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1373 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1376 if (node->delete_pending) {
1377 TBM_QUEUE_TRACE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1379 _queue_delete_node(surface_queue, node);
1381 pthread_mutex_unlock(&surface_queue->lock);
1383 _tbm_surf_queue_mutex_unlock();
1385 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1387 return TBM_SURFACE_QUEUE_ERROR_NONE;
1390 if (surface_queue->queue_size < surface_queue->num_attached) {
1391 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1393 if (surface_queue->impl && surface_queue->impl->need_detach)
1394 surface_queue->impl->need_detach(surface_queue, node);
1396 _tbm_surface_queue_detach(surface_queue, surface);
1398 pthread_mutex_unlock(&surface_queue->lock);
1400 _tbm_surf_queue_mutex_unlock();
1402 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1404 return TBM_SURFACE_QUEUE_ERROR_NONE;
1407 if (surface_queue->impl && surface_queue->impl->release)
1408 surface_queue->impl->release(surface_queue, node);
1410 _tbm_surface_queue_release(surface_queue, node, 1);
1412 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1413 TBM_LOG_E("release surface(%p) but surface isn't present in the free_queue\n", surface);
1414 pthread_mutex_unlock(&surface_queue->lock);
1416 _tbm_surf_queue_mutex_unlock();
1417 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1420 node->type = QUEUE_NODE_TYPE_RELEASE;
1422 pthread_mutex_unlock(&surface_queue->lock);
1423 pthread_cond_signal(&surface_queue->free_cond);
1425 _tbm_surf_queue_mutex_unlock();
1427 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1429 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1431 return TBM_SURFACE_QUEUE_ERROR_NONE;
1434 tbm_surface_queue_error_e
1435 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1436 surface_queue, tbm_surface_h surface)
1441 _tbm_surf_queue_mutex_lock();
1443 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1444 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1445 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1446 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1448 pthread_mutex_lock(&surface_queue->lock);
1450 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1452 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1453 if (node == NULL || queue_type != NODE_LIST) {
1454 TBM_LOG_E("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1456 pthread_mutex_unlock(&surface_queue->lock);
1458 _tbm_surf_queue_mutex_unlock();
1459 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1462 if (surface_queue->impl && surface_queue->impl->enqueue)
1463 surface_queue->impl->enqueue(surface_queue, node);
1465 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1467 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1468 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1469 pthread_mutex_unlock(&surface_queue->lock);
1471 _tbm_surf_queue_mutex_unlock();
1472 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1475 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1477 pthread_mutex_unlock(&surface_queue->lock);
1478 pthread_cond_signal(&surface_queue->dirty_cond);
1480 _tbm_surf_queue_mutex_unlock();
1482 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1484 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1486 return TBM_SURFACE_QUEUE_ERROR_NONE;
1489 tbm_surface_queue_error_e
1490 tbm_surface_queue_acquire(tbm_surface_queue_h
1491 surface_queue, tbm_surface_h *surface)
1495 _tbm_surf_queue_mutex_lock();
1499 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1500 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1501 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1502 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1504 pthread_mutex_lock(&surface_queue->lock);
1506 if (surface_queue->impl && surface_queue->impl->acquire)
1507 node = surface_queue->impl->acquire(surface_queue);
1509 node = _tbm_surface_queue_acquire(surface_queue);
1511 if (node == NULL || node->surface == NULL) {
1512 TBM_LOG_E("_queue_node_pop_front failed\n");
1513 pthread_mutex_unlock(&surface_queue->lock);
1515 _tbm_surf_queue_mutex_unlock();
1516 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1519 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1521 *surface = node->surface;
1523 if (surface_queue->acquire_sync_count == 1) {
1524 tbm_surface_info_s info;
1527 TBM_LOG_E("start map surface:%p", *surface);
1528 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1529 TBM_LOG_E("end map surface:%p", *surface);
1530 if (ret == TBM_SURFACE_ERROR_NONE)
1531 tbm_surface_unmap(*surface);
1534 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1536 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1538 pthread_mutex_unlock(&surface_queue->lock);
1540 _tbm_surf_queue_mutex_unlock();
1543 tbm_surface_internal_dump_buffer(*surface, "acquire");
1545 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1547 return TBM_SURFACE_QUEUE_ERROR_NONE;
1551 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1553 _tbm_surf_queue_mutex_lock();
1555 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1557 pthread_mutex_lock(&surface_queue->lock);
1559 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1561 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1562 pthread_mutex_unlock(&surface_queue->lock);
1563 _tbm_surf_queue_mutex_unlock();
1567 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1568 QUEUE_NODE_TYPE_DEQUEUE)) {
1569 _tbm_surf_queue_mutex_unlock();
1570 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1571 pthread_mutex_unlock(&surface_queue->lock);
1575 pthread_mutex_unlock(&surface_queue->lock);
1576 _tbm_surf_queue_mutex_unlock();
1581 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1583 queue_node *node = NULL, *tmp;
1585 _tbm_surf_queue_mutex_lock();
1587 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1589 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1591 LIST_DEL(&surface_queue->item_link);
1593 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1594 _queue_delete_node(surface_queue, node);
1596 if (surface_queue->impl && surface_queue->impl->destroy)
1597 surface_queue->impl->destroy(surface_queue);
1599 _notify_emit(surface_queue, &surface_queue->destory_noti);
1601 _notify_remove_all(&surface_queue->destory_noti);
1602 _notify_remove_all(&surface_queue->dequeuable_noti);
1603 _notify_remove_all(&surface_queue->dequeue_noti);
1604 _notify_remove_all(&surface_queue->can_dequeue_noti);
1605 _notify_remove_all(&surface_queue->acquirable_noti);
1606 _notify_remove_all(&surface_queue->reset_noti);
1607 _trace_remove_all(&surface_queue->trace_noti);
1609 pthread_mutex_destroy(&surface_queue->lock);
1611 free(surface_queue);
1613 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1614 _deinit_tbm_surf_queue_bufmgr();
1616 _tbm_surf_queue_mutex_unlock();
1619 tbm_surface_queue_error_e
1620 tbm_surface_queue_reset(tbm_surface_queue_h
1621 surface_queue, int width, int height, int format)
1623 queue_node *node = NULL, *tmp;
1625 _tbm_surf_queue_mutex_lock();
1627 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1628 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1630 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1632 if (width == surface_queue->width && height == surface_queue->height &&
1633 format == surface_queue->format) {
1634 _tbm_surf_queue_mutex_unlock();
1635 return TBM_SURFACE_QUEUE_ERROR_NONE;
1638 pthread_mutex_lock(&surface_queue->lock);
1640 surface_queue->width = width;
1641 surface_queue->height = height;
1642 surface_queue->format = format;
1644 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1645 /* Destory surface and Push to free_queue */
1646 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1647 _queue_delete_node(surface_queue, node);
1649 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1650 node->delete_pending = 1;
1652 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1653 _queue_delete_node(surface_queue, node);
1655 _queue_init(&surface_queue->dirty_queue);
1656 LIST_INITHEAD(&surface_queue->list);
1660 _queue_init(&surface_queue->free_queue);
1662 surface_queue->num_attached = 0;
1664 if (surface_queue->impl && surface_queue->impl->reset)
1665 surface_queue->impl->reset(surface_queue);
1667 pthread_mutex_unlock(&surface_queue->lock);
1668 pthread_cond_signal(&surface_queue->free_cond);
1670 _tbm_surf_queue_mutex_unlock();
1672 _notify_emit(surface_queue, &surface_queue->reset_noti);
1674 return TBM_SURFACE_QUEUE_ERROR_NONE;
1677 tbm_surface_queue_error_e
1678 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
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);
1685 _tbm_surf_queue_mutex_unlock();
1687 _notify_emit(surface_queue, &surface_queue->reset_noti);
1689 return TBM_SURFACE_QUEUE_ERROR_NONE;
1692 tbm_surface_queue_error_e
1693 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1695 _tbm_surf_queue_mutex_lock();
1697 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1698 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1700 _tbm_surf_queue_mutex_unlock();
1702 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1704 return TBM_SURFACE_QUEUE_ERROR_NONE;
1707 tbm_surface_queue_error_e
1708 tbm_surface_queue_set_size(tbm_surface_queue_h
1709 surface_queue, int queue_size, int flush)
1711 queue_node *node = NULL, *tmp;
1713 _tbm_surf_queue_mutex_lock();
1715 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1716 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1717 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1718 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1720 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1722 if ((surface_queue->queue_size == queue_size) && !flush) {
1723 _tbm_surf_queue_mutex_unlock();
1724 return TBM_SURFACE_QUEUE_ERROR_NONE;
1727 pthread_mutex_lock(&surface_queue->lock);
1730 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1731 /* Destory surface and Push to free_queue */
1732 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1733 _queue_delete_node(surface_queue, node);
1735 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1736 node->delete_pending = 1;
1738 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1739 _queue_delete_node(surface_queue, node);
1741 _queue_init(&surface_queue->dirty_queue);
1742 LIST_INITHEAD(&surface_queue->list);
1746 _queue_init(&surface_queue->free_queue);
1748 surface_queue->num_attached = 0;
1749 surface_queue->queue_size = queue_size;
1751 if (surface_queue->impl && surface_queue->impl->reset)
1752 surface_queue->impl->reset(surface_queue);
1754 pthread_mutex_unlock(&surface_queue->lock);
1755 pthread_cond_signal(&surface_queue->free_cond);
1757 _tbm_surf_queue_mutex_unlock();
1759 _notify_emit(surface_queue, &surface_queue->reset_noti);
1761 return TBM_SURFACE_QUEUE_ERROR_NONE;
1763 if (surface_queue->queue_size > queue_size) {
1764 int need_del = surface_queue->queue_size - queue_size;
1766 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1767 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1769 if (surface_queue->impl && surface_queue->impl->need_detach)
1770 surface_queue->impl->need_detach(surface_queue, node);
1772 _tbm_surface_queue_detach(surface_queue, node->surface);
1780 surface_queue->queue_size = queue_size;
1782 pthread_mutex_unlock(&surface_queue->lock);
1784 _tbm_surf_queue_mutex_unlock();
1786 return TBM_SURFACE_QUEUE_ERROR_NONE;
1790 tbm_surface_queue_error_e
1791 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1793 queue_node *node = NULL;
1795 _tbm_surf_queue_mutex_lock();
1797 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1798 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1800 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1802 if (surface_queue->num_attached == 0) {
1803 _tbm_surf_queue_mutex_unlock();
1804 return TBM_SURFACE_QUEUE_ERROR_NONE;
1807 pthread_mutex_lock(&surface_queue->lock);
1809 /* Destory surface in free_queue */
1810 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1811 if (surface_queue->impl && surface_queue->impl->need_detach)
1812 surface_queue->impl->need_detach(surface_queue, node);
1814 _tbm_surface_queue_detach(surface_queue, node->surface);
1818 _queue_init(&surface_queue->free_queue);
1820 pthread_mutex_unlock(&surface_queue->lock);
1821 _tbm_surf_queue_mutex_unlock();
1823 return TBM_SURFACE_QUEUE_ERROR_NONE;
1826 tbm_surface_queue_error_e
1827 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1829 queue_node *node = NULL, *tmp;
1831 _tbm_surf_queue_mutex_lock();
1833 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1834 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1836 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1838 if (surface_queue->num_attached == 0) {
1839 _tbm_surf_queue_mutex_unlock();
1840 return TBM_SURFACE_QUEUE_ERROR_NONE;
1843 pthread_mutex_lock(&surface_queue->lock);
1845 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1846 /* Destory surface and Push to free_queue */
1847 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1848 _queue_delete_node(surface_queue, node);
1850 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1851 node->delete_pending = 1;
1853 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1854 _queue_delete_node(surface_queue, node);
1856 _queue_init(&surface_queue->dirty_queue);
1857 LIST_INITHEAD(&surface_queue->list);
1861 _queue_init(&surface_queue->free_queue);
1863 surface_queue->num_attached = 0;
1865 if (surface_queue->impl && surface_queue->impl->reset)
1866 surface_queue->impl->reset(surface_queue);
1868 pthread_mutex_unlock(&surface_queue->lock);
1869 pthread_cond_signal(&surface_queue->free_cond);
1871 _tbm_surf_queue_mutex_unlock();
1873 _notify_emit(surface_queue, &surface_queue->reset_noti);
1875 return TBM_SURFACE_QUEUE_ERROR_NONE;
1878 tbm_surface_queue_error_e
1879 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1880 tbm_surface_h *surfaces, int *num)
1882 queue_node *node = NULL;
1884 _tbm_surf_queue_mutex_lock();
1886 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1887 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1888 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1889 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1893 pthread_mutex_lock(&surface_queue->lock);
1895 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1897 surfaces[*num] = node->surface;
1902 pthread_mutex_unlock(&surface_queue->lock);
1904 _tbm_surf_queue_mutex_unlock();
1906 return TBM_SURFACE_QUEUE_ERROR_NONE;
1909 tbm_surface_queue_error_e
1910 tbm_surface_queue_get_trace_surface_num(
1911 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1913 _tbm_surf_queue_mutex_lock();
1915 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1916 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1917 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1918 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1922 pthread_mutex_lock(&surface_queue->lock);
1925 case TBM_SURFACE_QUEUE_TRACE_NONE:
1928 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1929 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1931 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1932 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1934 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1935 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1937 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1938 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1944 pthread_mutex_unlock(&surface_queue->lock);
1946 _tbm_surf_queue_mutex_unlock();
1948 return TBM_SURFACE_QUEUE_ERROR_NONE;
1953 } tbm_queue_default;
1956 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1958 free(surface_queue->impl_data);
1962 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1964 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1965 tbm_surface_h surface;
1967 if (surface_queue->queue_size == surface_queue->num_attached)
1970 if (surface_queue->alloc_cb) {
1971 pthread_mutex_unlock(&surface_queue->lock);
1972 _tbm_surf_queue_mutex_unlock();
1973 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1974 _tbm_surf_queue_mutex_lock();
1975 pthread_mutex_lock(&surface_queue->lock);
1981 tbm_surface_internal_ref(surface);
1983 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1984 surface_queue->height,
1985 surface_queue->format,
1987 TBM_RETURN_IF_FAIL(surface != NULL);
1990 _tbm_surface_queue_attach(surface_queue, surface);
1991 tbm_surface_internal_unref(surface);
1994 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1995 NULL, /*__tbm_queue_default_init*/
1996 NULL, /*__tbm_queue_default_reset*/
1997 __tbm_queue_default_destroy,
1998 __tbm_queue_default_need_attach,
1999 NULL, /*__tbm_queue_default_enqueue*/
2000 NULL, /*__tbm_queue_default_release*/
2001 NULL, /*__tbm_queue_default_dequeue*/
2002 NULL, /*__tbm_queue_default_acquire*/
2003 NULL, /*__tbm_queue_default_need_detach*/
2007 tbm_surface_queue_create(int queue_size, int width,
2008 int height, int format, int flags)
2010 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2011 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2012 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2013 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2015 _tbm_surf_queue_mutex_lock();
2017 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2018 sizeof(struct _tbm_surface_queue));
2019 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2021 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2023 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2024 sizeof(tbm_queue_default));
2026 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
2027 free(surface_queue);
2028 _tbm_surf_queue_mutex_unlock();
2032 data->flags = flags;
2033 _tbm_surface_queue_init(surface_queue,
2035 width, height, format,
2036 &tbm_queue_default_impl, data);
2038 _tbm_surf_queue_mutex_unlock();
2040 return surface_queue;
2046 } tbm_queue_sequence;
2049 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2051 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2053 _queue_init(&data->dequeue_list);
2057 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2059 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2061 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2064 _queue_init(&data->dequeue_list);
2068 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2070 free(surface_queue->impl_data);
2074 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2076 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2077 tbm_surface_h surface;
2079 if (surface_queue->queue_size == surface_queue->num_attached)
2082 if (surface_queue->alloc_cb) {
2083 pthread_mutex_unlock(&surface_queue->lock);
2084 _tbm_surf_queue_mutex_unlock();
2085 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2086 _tbm_surf_queue_mutex_lock();
2087 pthread_mutex_lock(&surface_queue->lock);
2093 tbm_surface_internal_ref(surface);
2095 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2096 surface_queue->height,
2097 surface_queue->format,
2099 TBM_RETURN_IF_FAIL(surface != NULL);
2102 _tbm_surface_queue_attach(surface_queue, surface);
2103 tbm_surface_internal_unref(surface);
2107 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2110 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2111 queue_node *first = NULL;
2113 first = container_of(data->dequeue_list.head.next, first, item_link);
2114 if (first != node) {
2118 node->priv_flags = 0;
2120 _queue_node_pop(&data->dequeue_list, node);
2121 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2125 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2128 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2130 if (node->priv_flags) {
2131 node->priv_flags = 0;
2132 _queue_node_pop(&data->dequeue_list, node);
2135 _tbm_surface_queue_release(surface_queue, node, 1);
2139 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2142 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2145 node = _tbm_surface_queue_dequeue(surface_queue);
2147 _queue_node_push_back(&data->dequeue_list, node);
2148 node->priv_flags = 1;
2154 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2155 __tbm_queue_sequence_init,
2156 __tbm_queue_sequence_reset,
2157 __tbm_queue_sequence_destroy,
2158 __tbm_queue_sequence_need_attach,
2159 __tbm_queue_sequence_enqueue,
2160 __tbm_queue_sequence_release,
2161 __tbm_queue_sequence_dequeue,
2162 NULL, /*__tbm_queue_sequence_acquire*/
2163 NULL, /*__tbm_queue_sequence_need_dettach*/
2167 tbm_surface_queue_sequence_create(int queue_size, int width,
2168 int height, int format, int flags)
2170 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2171 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2172 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2173 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2175 _tbm_surf_queue_mutex_lock();
2177 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2178 sizeof(struct _tbm_surface_queue));
2179 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2181 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
2183 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2184 sizeof(tbm_queue_sequence));
2186 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
2187 free(surface_queue);
2188 _tbm_surf_queue_mutex_unlock();
2192 data->flags = flags;
2193 _tbm_surface_queue_init(surface_queue,
2195 width, height, format,
2196 &tbm_queue_sequence_impl, data);
2198 _tbm_surf_queue_mutex_unlock();
2200 return surface_queue;
2203 tbm_surface_queue_error_e
2204 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2207 _tbm_surf_queue_mutex_lock();
2209 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2210 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2212 pthread_mutex_lock(&surface_queue->lock);
2214 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2215 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2217 surface_queue->modes |= modes;
2219 pthread_mutex_unlock(&surface_queue->lock);
2221 _tbm_surf_queue_mutex_unlock();
2223 return TBM_SURFACE_QUEUE_ERROR_NONE;
2226 tbm_surface_queue_error_e
2227 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2228 unsigned int sync_count)
2230 int dequeue_num, enqueue_num;
2232 _tbm_surf_queue_mutex_lock();
2234 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2235 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2237 pthread_mutex_lock(&surface_queue->lock);
2239 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2240 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2242 if (dequeue_num + sync_count == 0)
2243 surface_queue->acquire_sync_count = enqueue_num;
2245 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2247 TBM_QUEUE_TRACE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2248 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2250 pthread_mutex_unlock(&surface_queue->lock);
2252 _tbm_surf_queue_mutex_unlock();
2254 return TBM_SURFACE_QUEUE_ERROR_NONE;