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"
42 static tbm_bufmgr g_surf_queue_bufmgr;
43 static pthread_mutex_t tbm_surf_queue_lock;
44 void _tbm_surface_queue_mutex_unlock(void);
47 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
49 TBM_ERR("'%s' failed.\n", #cond);\
50 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
51 _tbm_surf_queue_mutex_unlock();\
56 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
58 TBM_ERR("'%s' failed.\n", #cond);\
59 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
60 _tbm_surf_queue_mutex_unlock();\
65 typedef enum _queue_node_type {
67 QUEUE_NODE_TYPE_DEQUEUE,
68 QUEUE_NODE_TYPE_ENQUEUE,
69 QUEUE_NODE_TYPE_ACQUIRE,
70 QUEUE_NODE_TYPE_RELEASE
74 struct list_head head;
79 tbm_surface_h surface;
81 struct list_head item_link;
82 struct list_head link;
86 unsigned int priv_flags; /*for each queue*/
92 struct list_head link;
94 tbm_surface_queue_notify_cb cb;
99 struct list_head link;
101 tbm_surface_queue_trace_cb cb;
105 typedef struct _tbm_surface_queue_interface {
106 void (*init)(tbm_surface_queue_h queue);
107 void (*reset)(tbm_surface_queue_h queue);
108 void (*destroy)(tbm_surface_queue_h queue);
109 void (*need_attach)(tbm_surface_queue_h queue);
111 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
112 void (*release)(tbm_surface_queue_h queue, queue_node *node);
113 queue_node *(*dequeue)(tbm_surface_queue_h queue);
114 queue_node *(*acquire)(tbm_surface_queue_h queue);
115 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
116 } tbm_surface_queue_interface;
118 struct _tbm_surface_queue {
127 struct list_head list;
129 struct list_head destory_noti;
130 struct list_head dequeuable_noti;
131 struct list_head dequeue_noti;
132 struct list_head can_dequeue_noti;
133 struct list_head acquirable_noti;
134 struct list_head reset_noti;
135 struct list_head trace_noti;
137 pthread_mutex_t lock;
138 pthread_cond_t free_cond;
139 pthread_cond_t dirty_cond;
141 const tbm_surface_queue_interface *impl;
144 //For external buffer allocation
145 tbm_surface_alloc_cb alloc_cb;
146 tbm_surface_free_cb free_cb;
149 struct list_head item_link; /* link of surface queue */
152 unsigned int enqueue_sync_count;
153 unsigned int acquire_sync_count;
157 _tbm_surf_queue_mutex_init(void)
159 static bool tbm_surf_queue_mutex_init = false;
161 if (tbm_surf_queue_mutex_init)
164 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
165 TBM_ERR("fail: pthread_mutex_init\n");
169 tbm_surf_queue_mutex_init = true;
175 _tbm_surf_queue_mutex_lock(void)
177 if (!_tbm_surf_queue_mutex_init()) {
178 TBM_ERR("fail: _tbm_surf_queue_mutex_init\n");
182 pthread_mutex_lock(&tbm_surf_queue_lock);
186 _tbm_surf_queue_mutex_unlock(void)
188 pthread_mutex_unlock(&tbm_surf_queue_lock);
192 _init_tbm_surf_queue_bufmgr(void)
194 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
198 _deinit_tbm_surf_queue_bufmgr(void)
200 if (!g_surf_queue_bufmgr)
203 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
204 g_surf_queue_bufmgr = NULL;
208 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
210 tbm_surface_queue_h old_data = NULL;
212 if (surface_queue == NULL) {
213 TBM_ERR("error: surface_queue is NULL.\n");
217 if (g_surf_queue_bufmgr == NULL) {
218 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
222 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
223 TBM_ERR("error: surf_queue_list is empty\n");
227 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
229 if (old_data == surface_queue) {
230 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
235 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
241 _queue_node_create(void)
243 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
245 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
251 _queue_node_delete(queue_node *node)
253 LIST_DEL(&node->item_link);
254 LIST_DEL(&node->link);
259 _queue_is_empty(queue *queue)
261 if (LIST_IS_EMPTY(&queue->head))
268 _queue_node_push_back(queue *queue, queue_node *node)
270 LIST_ADDTAIL(&node->item_link, &queue->head);
275 _queue_node_push_front(queue *queue, queue_node *node)
277 LIST_ADD(&node->item_link, &queue->head);
282 _queue_node_pop_front(queue *queue)
286 if (!queue->head.next) return NULL;
287 if (!queue->count) return NULL;
289 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
291 LIST_DELINIT(&node->item_link);
298 _queue_node_pop(queue *queue, queue_node *node)
300 LIST_DELINIT(&node->item_link);
307 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
308 tbm_surface_h surface, int *out_type)
310 queue_node *node = NULL;
313 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
317 if (type & FREE_QUEUE) {
318 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
320 if (node->surface == surface) {
322 *out_type = FREE_QUEUE;
329 if (type & DIRTY_QUEUE) {
330 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
332 if (node->surface == surface) {
334 *out_type = DIRTY_QUEUE;
341 if (type & NODE_LIST) {
342 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
343 if (node->surface == surface) {
345 *out_type = NODE_LIST;
352 TBM_ERR("fail to get the queue_node.\n");
358 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
361 if (surface_queue->free_cb) {
362 surface_queue->free_cb(surface_queue,
363 surface_queue->alloc_cb_data,
367 tbm_surface_destroy(node->surface);
370 _queue_node_delete(node);
374 _queue_init(queue *queue)
376 LIST_INITHEAD(&queue->head);
382 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
385 TBM_RETURN_IF_FAIL(cb != NULL);
387 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
389 TBM_RETURN_IF_FAIL(item != NULL);
391 LIST_INITHEAD(&item->link);
395 LIST_ADDTAIL(&item->link, list);
399 _notify_remove(struct list_head *list,
400 tbm_surface_queue_notify_cb cb, void *data)
402 queue_notify *item = NULL, *tmp;
404 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
405 if (item->cb == cb && item->data == data) {
406 LIST_DEL(&item->link);
412 TBM_ERR("Cannot find notifiy\n");
416 _notify_remove_all(struct list_head *list)
418 queue_notify *item = NULL, *tmp;
420 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
421 LIST_DEL(&item->link);
427 _notify_emit(tbm_surface_queue_h surface_queue,
428 struct list_head *list)
430 queue_notify *item = NULL, *tmp;;
433 The item->cb is the outside function of the libtbm.
434 The tbm user may/can remove the item of the list,
435 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
437 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
438 item->cb(surface_queue, item->data);
442 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
445 TBM_RETURN_IF_FAIL(cb != NULL);
447 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
449 TBM_RETURN_IF_FAIL(item != NULL);
451 LIST_INITHEAD(&item->link);
455 LIST_ADDTAIL(&item->link, list);
459 _trace_remove(struct list_head *list,
460 tbm_surface_queue_trace_cb cb, void *data)
462 queue_trace *item = NULL, *tmp;
464 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
465 if (item->cb == cb && item->data == data) {
466 LIST_DEL(&item->link);
472 TBM_ERR("Cannot find notifiy\n");
476 _trace_remove_all(struct list_head *list)
478 queue_trace *item = NULL, *tmp;
480 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
481 LIST_DEL(&item->link);
487 _trace_emit(tbm_surface_queue_h surface_queue,
488 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
490 queue_trace *item = NULL, *tmp;;
493 The item->cb is the outside function of the libtbm.
494 The tbm user may/can remove the item of the list,
495 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
497 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
498 item->cb(surface_queue, surface, trace, item->data);
502 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
504 queue_node *node = NULL;
507 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
508 if (node->type == type)
516 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
517 tbm_surface_h surface)
521 node = _queue_node_create();
522 TBM_RETURN_IF_FAIL(node != NULL);
524 tbm_surface_internal_ref(surface);
525 node->surface = surface;
527 LIST_ADDTAIL(&node->link, &surface_queue->list);
528 surface_queue->num_attached++;
529 _queue_node_push_back(&surface_queue->free_queue, node);
533 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
534 tbm_surface_h surface)
539 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
541 _queue_delete_node(surface_queue, node);
542 surface_queue->num_attached--;
547 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
548 queue_node *node, int push_back)
551 _queue_node_push_back(&surface_queue->dirty_queue, node);
553 _queue_node_push_front(&surface_queue->dirty_queue, node);
557 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
561 node = _queue_node_pop_front(&surface_queue->free_queue);
567 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
571 if (_queue_is_empty(&surface_queue->dirty_queue))
574 node = _queue_node_pop_front(&surface_queue->dirty_queue);
580 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
581 queue_node *node, int push_back)
584 _queue_node_push_back(&surface_queue->free_queue, node);
586 _queue_node_push_front(&surface_queue->free_queue, node);
590 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
592 int width, int height, int format,
593 const tbm_surface_queue_interface *impl, void *data)
595 pthread_condattr_t attr;
597 TBM_RETURN_IF_FAIL(surface_queue != NULL);
598 TBM_RETURN_IF_FAIL(impl != NULL);
600 if (!g_surf_queue_bufmgr)
601 _init_tbm_surf_queue_bufmgr();
603 pthread_mutex_init(&surface_queue->lock, NULL);
605 pthread_condattr_init(&attr);
606 pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
607 pthread_cond_init(&surface_queue->free_cond, &attr);
608 pthread_cond_init(&surface_queue->dirty_cond, &attr);
609 pthread_condattr_destroy(&attr);
611 surface_queue->queue_size = queue_size;
612 surface_queue->width = width;
613 surface_queue->height = height;
614 surface_queue->format = format;
615 surface_queue->impl = impl;
616 surface_queue->impl_data = data;
617 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
619 _queue_init(&surface_queue->free_queue);
620 _queue_init(&surface_queue->dirty_queue);
621 LIST_INITHEAD(&surface_queue->list);
623 LIST_INITHEAD(&surface_queue->destory_noti);
624 LIST_INITHEAD(&surface_queue->dequeuable_noti);
625 LIST_INITHEAD(&surface_queue->dequeue_noti);
626 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
627 LIST_INITHEAD(&surface_queue->acquirable_noti);
628 LIST_INITHEAD(&surface_queue->reset_noti);
629 LIST_INITHEAD(&surface_queue->trace_noti);
631 if (surface_queue->impl && surface_queue->impl->init)
632 surface_queue->impl->init(surface_queue);
634 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
637 tbm_surface_queue_error_e
638 tbm_surface_queue_add_destroy_cb(
639 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
642 _tbm_surf_queue_mutex_lock();
643 _tbm_set_last_result(TBM_ERROR_NONE);
645 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
646 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
647 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
648 TBM_ERROR_INVALID_PARAMETER);
650 pthread_mutex_lock(&surface_queue->lock);
652 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
654 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
656 pthread_mutex_unlock(&surface_queue->lock);
658 _tbm_surf_queue_mutex_unlock();
660 return TBM_SURFACE_QUEUE_ERROR_NONE;
663 tbm_surface_queue_error_e
664 tbm_surface_queue_remove_destroy_cb(
665 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
668 _tbm_surf_queue_mutex_lock();
669 _tbm_set_last_result(TBM_ERROR_NONE);
671 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
672 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
674 pthread_mutex_lock(&surface_queue->lock);
676 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
678 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
680 pthread_mutex_unlock(&surface_queue->lock);
682 _tbm_surf_queue_mutex_unlock();
684 return TBM_SURFACE_QUEUE_ERROR_NONE;
687 tbm_surface_queue_error_e
688 tbm_surface_queue_add_dequeuable_cb(
689 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
692 _tbm_surf_queue_mutex_lock();
693 _tbm_set_last_result(TBM_ERROR_NONE);
695 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
696 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
697 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
698 TBM_ERROR_INVALID_PARAMETER);
700 pthread_mutex_lock(&surface_queue->lock);
702 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
704 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
706 pthread_mutex_unlock(&surface_queue->lock);
708 _tbm_surf_queue_mutex_unlock();
710 return TBM_SURFACE_QUEUE_ERROR_NONE;
713 tbm_surface_queue_error_e
714 tbm_surface_queue_remove_dequeuable_cb(
715 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
718 _tbm_surf_queue_mutex_lock();
719 _tbm_set_last_result(TBM_ERROR_NONE);
721 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
722 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
724 pthread_mutex_lock(&surface_queue->lock);
726 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
728 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
730 pthread_mutex_unlock(&surface_queue->lock);
732 _tbm_surf_queue_mutex_unlock();
734 return TBM_SURFACE_QUEUE_ERROR_NONE;
737 tbm_surface_queue_error_e
738 tbm_surface_queue_add_dequeue_cb(
739 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
742 _tbm_surf_queue_mutex_lock();
743 _tbm_set_last_result(TBM_ERROR_NONE);
745 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
746 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
747 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
748 TBM_ERROR_INVALID_PARAMETER);
750 pthread_mutex_lock(&surface_queue->lock);
752 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
754 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
756 pthread_mutex_unlock(&surface_queue->lock);
758 _tbm_surf_queue_mutex_unlock();
760 return TBM_SURFACE_QUEUE_ERROR_NONE;
763 tbm_surface_queue_error_e
764 tbm_surface_queue_remove_dequeue_cb(
765 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
768 _tbm_surf_queue_mutex_lock();
769 _tbm_set_last_result(TBM_ERROR_NONE);
771 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
772 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
774 pthread_mutex_lock(&surface_queue->lock);
776 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
778 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
780 pthread_mutex_unlock(&surface_queue->lock);
782 _tbm_surf_queue_mutex_unlock();
784 return TBM_SURFACE_QUEUE_ERROR_NONE;
787 tbm_surface_queue_error_e
788 tbm_surface_queue_add_can_dequeue_cb(
789 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
792 _tbm_surf_queue_mutex_lock();
793 _tbm_set_last_result(TBM_ERROR_NONE);
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_ERROR_INVALID_PARAMETER);
800 pthread_mutex_lock(&surface_queue->lock);
802 TBM_TRACE_SURFACE_QUEUE("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();
819 _tbm_set_last_result(TBM_ERROR_NONE);
821 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
822 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
824 pthread_mutex_lock(&surface_queue->lock);
826 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
828 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
830 pthread_mutex_unlock(&surface_queue->lock);
832 _tbm_surf_queue_mutex_unlock();
834 return TBM_SURFACE_QUEUE_ERROR_NONE;
837 tbm_surface_queue_error_e
838 tbm_surface_queue_add_acquirable_cb(
839 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
842 _tbm_surf_queue_mutex_lock();
843 _tbm_set_last_result(TBM_ERROR_NONE);
845 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
846 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
847 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
848 TBM_ERROR_INVALID_PARAMETER);
850 pthread_mutex_lock(&surface_queue->lock);
852 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
854 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
856 pthread_mutex_unlock(&surface_queue->lock);
858 _tbm_surf_queue_mutex_unlock();
860 return TBM_SURFACE_QUEUE_ERROR_NONE;
863 tbm_surface_queue_error_e
864 tbm_surface_queue_remove_acquirable_cb(
865 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
868 _tbm_surf_queue_mutex_lock();
869 _tbm_set_last_result(TBM_ERROR_NONE);
871 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
872 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
874 pthread_mutex_lock(&surface_queue->lock);
876 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
878 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
880 pthread_mutex_unlock(&surface_queue->lock);
882 _tbm_surf_queue_mutex_unlock();
884 return TBM_SURFACE_QUEUE_ERROR_NONE;
887 tbm_surface_queue_error_e
888 tbm_surface_queue_add_trace_cb(
889 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
892 _tbm_surf_queue_mutex_lock();
893 _tbm_set_last_result(TBM_ERROR_NONE);
895 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
896 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
897 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
898 TBM_ERROR_INVALID_PARAMETER);
900 pthread_mutex_lock(&surface_queue->lock);
902 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
904 _trace_add(&surface_queue->trace_noti, trace_cb, data);
906 pthread_mutex_unlock(&surface_queue->lock);
908 _tbm_surf_queue_mutex_unlock();
910 return TBM_SURFACE_QUEUE_ERROR_NONE;
913 tbm_surface_queue_error_e
914 tbm_surface_queue_remove_trace_cb(
915 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
918 _tbm_surf_queue_mutex_lock();
919 _tbm_set_last_result(TBM_ERROR_NONE);
921 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
922 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
924 pthread_mutex_lock(&surface_queue->lock);
926 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
928 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
930 pthread_mutex_unlock(&surface_queue->lock);
932 _tbm_surf_queue_mutex_unlock();
934 return TBM_SURFACE_QUEUE_ERROR_NONE;
937 tbm_surface_queue_error_e
938 tbm_surface_queue_set_alloc_cb(
939 tbm_surface_queue_h surface_queue,
940 tbm_surface_alloc_cb alloc_cb,
941 tbm_surface_free_cb free_cb,
944 _tbm_surf_queue_mutex_lock();
945 _tbm_set_last_result(TBM_ERROR_NONE);
947 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
948 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
950 pthread_mutex_lock(&surface_queue->lock);
952 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
954 surface_queue->alloc_cb = alloc_cb;
955 surface_queue->free_cb = free_cb;
956 surface_queue->alloc_cb_data = data;
958 pthread_mutex_unlock(&surface_queue->lock);
960 _tbm_surf_queue_mutex_unlock();
962 return TBM_SURFACE_QUEUE_ERROR_NONE;
966 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
970 _tbm_surf_queue_mutex_lock();
971 _tbm_set_last_result(TBM_ERROR_NONE);
973 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
975 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
977 width = surface_queue->width;
979 _tbm_surf_queue_mutex_unlock();
985 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
989 _tbm_surf_queue_mutex_lock();
990 _tbm_set_last_result(TBM_ERROR_NONE);
992 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
994 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
996 height = surface_queue->height;
998 _tbm_surf_queue_mutex_unlock();
1004 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1008 _tbm_surf_queue_mutex_lock();
1009 _tbm_set_last_result(TBM_ERROR_NONE);
1011 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1013 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1015 format = surface_queue->format;
1017 _tbm_surf_queue_mutex_unlock();
1023 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1027 _tbm_surf_queue_mutex_lock();
1028 _tbm_set_last_result(TBM_ERROR_NONE);
1030 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1032 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1034 queue_size = surface_queue->queue_size;
1036 _tbm_surf_queue_mutex_unlock();
1041 tbm_surface_queue_error_e
1042 tbm_surface_queue_add_reset_cb(
1043 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1046 _tbm_surf_queue_mutex_lock();
1047 _tbm_set_last_result(TBM_ERROR_NONE);
1049 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1050 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1051 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1052 TBM_ERROR_INVALID_PARAMETER);
1054 pthread_mutex_lock(&surface_queue->lock);
1056 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1058 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1060 pthread_mutex_unlock(&surface_queue->lock);
1062 _tbm_surf_queue_mutex_unlock();
1064 return TBM_SURFACE_QUEUE_ERROR_NONE;
1067 tbm_surface_queue_error_e
1068 tbm_surface_queue_remove_reset_cb(
1069 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1072 _tbm_surf_queue_mutex_lock();
1073 _tbm_set_last_result(TBM_ERROR_NONE);
1075 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1076 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1078 pthread_mutex_lock(&surface_queue->lock);
1080 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1082 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1084 pthread_mutex_unlock(&surface_queue->lock);
1086 _tbm_surf_queue_mutex_unlock();
1088 return TBM_SURFACE_QUEUE_ERROR_NONE;
1091 tbm_surface_queue_error_e
1092 tbm_surface_queue_enqueue(tbm_surface_queue_h
1093 surface_queue, tbm_surface_h surface)
1098 _tbm_surf_queue_mutex_lock();
1099 _tbm_set_last_result(TBM_ERROR_NONE);
1101 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1102 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1103 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1104 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1107 tbm_surface_internal_dump_buffer(surface, "enqueue");
1109 pthread_mutex_lock(&surface_queue->lock);
1111 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1113 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1114 if (node == NULL || queue_type != NODE_LIST) {
1115 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1117 pthread_mutex_unlock(&surface_queue->lock);
1119 _tbm_surf_queue_mutex_unlock();
1122 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1123 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1125 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1126 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1130 if (surface_queue->impl && surface_queue->impl->enqueue)
1131 surface_queue->impl->enqueue(surface_queue, node);
1133 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1135 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1136 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1137 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1138 pthread_mutex_unlock(&surface_queue->lock);
1140 _tbm_surf_queue_mutex_unlock();
1141 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1144 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1146 if (surface_queue->enqueue_sync_count == 1) {
1147 tbm_surface_info_s info;
1150 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1151 if (ret == TBM_SURFACE_ERROR_NONE)
1152 tbm_surface_unmap(surface);
1155 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1157 pthread_mutex_unlock(&surface_queue->lock);
1158 pthread_cond_signal(&surface_queue->dirty_cond);
1160 _tbm_surf_queue_mutex_unlock();
1162 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1164 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1166 return TBM_SURFACE_QUEUE_ERROR_NONE;
1169 tbm_surface_queue_error_e
1170 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1171 surface_queue, tbm_surface_h surface)
1176 _tbm_surf_queue_mutex_lock();
1177 _tbm_set_last_result(TBM_ERROR_NONE);
1179 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1180 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1181 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1182 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1184 pthread_mutex_lock(&surface_queue->lock);
1186 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1188 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1189 if (node == NULL || queue_type != NODE_LIST) {
1190 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1192 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1193 pthread_mutex_unlock(&surface_queue->lock);
1195 _tbm_surf_queue_mutex_unlock();
1196 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1199 if (node->delete_pending) {
1200 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1202 _queue_delete_node(surface_queue, node);
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->queue_size < surface_queue->num_attached) {
1214 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1216 if (surface_queue->impl && surface_queue->impl->need_detach)
1217 surface_queue->impl->need_detach(surface_queue, node);
1219 _tbm_surface_queue_detach(surface_queue, surface);
1221 pthread_mutex_unlock(&surface_queue->lock);
1223 _tbm_surf_queue_mutex_unlock();
1225 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1227 return TBM_SURFACE_QUEUE_ERROR_NONE;
1230 if (surface_queue->impl && surface_queue->impl->release)
1231 surface_queue->impl->release(surface_queue, node);
1233 _tbm_surface_queue_release(surface_queue, node, 1);
1235 if (_queue_is_empty(&surface_queue->free_queue)) {
1236 TBM_ERR("surface_queue->free_queue is empty.\n");
1237 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1238 pthread_mutex_unlock(&surface_queue->lock);
1240 _tbm_surf_queue_mutex_unlock();
1241 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1244 node->type = QUEUE_NODE_TYPE_RELEASE;
1246 pthread_mutex_unlock(&surface_queue->lock);
1247 pthread_cond_signal(&surface_queue->free_cond);
1249 _tbm_surf_queue_mutex_unlock();
1251 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1253 return TBM_SURFACE_QUEUE_ERROR_NONE;
1256 tbm_surface_queue_error_e
1257 tbm_surface_queue_dequeue(tbm_surface_queue_h
1258 surface_queue, tbm_surface_h *surface)
1262 _tbm_surf_queue_mutex_lock();
1263 _tbm_set_last_result(TBM_ERROR_NONE);
1265 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1266 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1267 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1268 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1272 pthread_mutex_lock(&surface_queue->lock);
1274 if (_queue_is_empty(&surface_queue->free_queue)) {
1275 if (surface_queue->impl && surface_queue->impl->need_attach)
1276 surface_queue->impl->need_attach(surface_queue);
1278 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1279 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1280 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1281 pthread_mutex_unlock(&surface_queue->lock);
1282 _tbm_surf_queue_mutex_unlock();
1283 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1287 if (surface_queue->impl && surface_queue->impl->dequeue)
1288 node = surface_queue->impl->dequeue(surface_queue);
1290 node = _tbm_surface_queue_dequeue(surface_queue);
1292 if (node == NULL || node->surface == NULL) {
1293 TBM_ERR("_queue_node_pop_front failed\n");
1294 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1295 pthread_mutex_unlock(&surface_queue->lock);
1297 _tbm_surf_queue_mutex_unlock();
1298 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1301 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1302 *surface = node->surface;
1304 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1306 pthread_mutex_unlock(&surface_queue->lock);
1308 _tbm_surf_queue_mutex_unlock();
1310 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1312 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1314 return TBM_SURFACE_QUEUE_ERROR_NONE;
1317 tbm_surface_queue_error_e
1318 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1323 _tbm_surf_queue_mutex_lock();
1324 _tbm_set_last_result(TBM_ERROR_NONE);
1326 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1327 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1329 _tbm_surf_queue_mutex_unlock();
1331 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1333 _tbm_surf_queue_mutex_lock();
1335 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1336 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1338 pthread_mutex_lock(&surface_queue->lock);
1340 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1342 if (_queue_is_empty(&surface_queue->free_queue)) {
1343 if (surface_queue->impl && surface_queue->impl->need_attach)
1344 surface_queue->impl->need_attach(surface_queue);
1346 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1347 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1348 pthread_mutex_unlock(&surface_queue->lock);
1349 _tbm_surf_queue_mutex_unlock();
1350 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1354 if (!_queue_is_empty(&surface_queue->free_queue)) {
1355 pthread_mutex_unlock(&surface_queue->lock);
1356 _tbm_surf_queue_mutex_unlock();
1357 return TBM_SURFACE_QUEUE_ERROR_NONE;
1360 _tbm_surf_queue_mutex_unlock();
1363 clock_gettime(CLOCK_MONOTONIC, &tp);
1365 if (ms_timeout > 1000)
1366 tp.tv_sec += ms_timeout / 1000;
1368 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1370 if (tp.tv_nsec > 1000000000L) {
1372 tp.tv_nsec -= 1000000000L;
1375 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1377 if (ret == ETIMEDOUT) {
1378 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1379 pthread_mutex_unlock(&surface_queue->lock);
1380 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1382 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1385 pthread_mutex_unlock(&surface_queue->lock);
1386 return TBM_SURFACE_QUEUE_ERROR_NONE;
1392 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1394 _tbm_surf_queue_mutex_lock();
1395 _tbm_set_last_result(TBM_ERROR_NONE);
1397 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1399 _tbm_surf_queue_mutex_unlock();
1401 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1403 _tbm_surf_queue_mutex_lock();
1405 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1407 pthread_mutex_lock(&surface_queue->lock);
1409 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1411 if (_queue_is_empty(&surface_queue->free_queue)) {
1412 if (surface_queue->impl && surface_queue->impl->need_attach)
1413 surface_queue->impl->need_attach(surface_queue);
1415 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1416 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1417 pthread_mutex_unlock(&surface_queue->lock);
1418 _tbm_surf_queue_mutex_unlock();
1423 if (!_queue_is_empty(&surface_queue->free_queue)) {
1424 pthread_mutex_unlock(&surface_queue->lock);
1425 _tbm_surf_queue_mutex_unlock();
1430 _tbm_surf_queue_mutex_unlock();
1431 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1432 pthread_mutex_unlock(&surface_queue->lock);
1436 pthread_mutex_unlock(&surface_queue->lock);
1437 _tbm_surf_queue_mutex_unlock();
1441 tbm_surface_queue_error_e
1442 tbm_surface_queue_release(tbm_surface_queue_h
1443 surface_queue, tbm_surface_h surface)
1448 _tbm_surf_queue_mutex_lock();
1449 _tbm_set_last_result(TBM_ERROR_NONE);
1451 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1452 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1453 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1454 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1456 pthread_mutex_lock(&surface_queue->lock);
1458 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1460 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1461 if (node == NULL || queue_type != NODE_LIST) {
1462 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1464 pthread_mutex_unlock(&surface_queue->lock);
1466 _tbm_surf_queue_mutex_unlock();
1469 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1470 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1472 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1473 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1477 if (node->delete_pending) {
1478 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1480 _queue_delete_node(surface_queue, node);
1482 pthread_mutex_unlock(&surface_queue->lock);
1484 _tbm_surf_queue_mutex_unlock();
1486 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1488 return TBM_SURFACE_QUEUE_ERROR_NONE;
1491 if (surface_queue->queue_size < surface_queue->num_attached) {
1492 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1494 if (surface_queue->impl && surface_queue->impl->need_detach)
1495 surface_queue->impl->need_detach(surface_queue, node);
1497 _tbm_surface_queue_detach(surface_queue, surface);
1499 pthread_mutex_unlock(&surface_queue->lock);
1501 _tbm_surf_queue_mutex_unlock();
1503 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1505 return TBM_SURFACE_QUEUE_ERROR_NONE;
1508 if (surface_queue->impl && surface_queue->impl->release)
1509 surface_queue->impl->release(surface_queue, node);
1511 _tbm_surface_queue_release(surface_queue, node, 1);
1513 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1514 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1515 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1516 pthread_mutex_unlock(&surface_queue->lock);
1518 _tbm_surf_queue_mutex_unlock();
1519 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1522 node->type = QUEUE_NODE_TYPE_RELEASE;
1524 pthread_mutex_unlock(&surface_queue->lock);
1525 pthread_cond_signal(&surface_queue->free_cond);
1527 _tbm_surf_queue_mutex_unlock();
1529 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1531 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1533 return TBM_SURFACE_QUEUE_ERROR_NONE;
1536 tbm_surface_queue_error_e
1537 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1538 surface_queue, tbm_surface_h surface)
1543 _tbm_surf_queue_mutex_lock();
1544 _tbm_set_last_result(TBM_ERROR_NONE);
1546 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1547 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1548 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1549 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1551 pthread_mutex_lock(&surface_queue->lock);
1553 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1555 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1556 if (node == NULL || queue_type != NODE_LIST) {
1557 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1559 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1560 pthread_mutex_unlock(&surface_queue->lock);
1562 _tbm_surf_queue_mutex_unlock();
1563 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1566 if (surface_queue->impl && surface_queue->impl->enqueue)
1567 surface_queue->impl->enqueue(surface_queue, node);
1569 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1571 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1572 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1573 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1574 pthread_mutex_unlock(&surface_queue->lock);
1576 _tbm_surf_queue_mutex_unlock();
1577 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1580 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1582 pthread_mutex_unlock(&surface_queue->lock);
1583 pthread_cond_signal(&surface_queue->dirty_cond);
1585 _tbm_surf_queue_mutex_unlock();
1587 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1589 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1591 return TBM_SURFACE_QUEUE_ERROR_NONE;
1594 tbm_surface_queue_error_e
1595 tbm_surface_queue_acquire(tbm_surface_queue_h
1596 surface_queue, tbm_surface_h *surface)
1600 _tbm_surf_queue_mutex_lock();
1601 _tbm_set_last_result(TBM_ERROR_NONE);
1605 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1606 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1607 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1608 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1610 pthread_mutex_lock(&surface_queue->lock);
1612 if (surface_queue->impl && surface_queue->impl->acquire)
1613 node = surface_queue->impl->acquire(surface_queue);
1615 node = _tbm_surface_queue_acquire(surface_queue);
1617 if (node == NULL || node->surface == NULL) {
1618 TBM_ERR("_queue_node_pop_front failed\n");
1619 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1620 pthread_mutex_unlock(&surface_queue->lock);
1622 _tbm_surf_queue_mutex_unlock();
1623 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1626 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1628 *surface = node->surface;
1630 if (surface_queue->acquire_sync_count == 1) {
1631 tbm_surface_info_s info;
1634 TBM_ERR("start map surface:%p", *surface);
1635 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1636 TBM_ERR("end map surface:%p", *surface);
1637 if (ret == TBM_SURFACE_ERROR_NONE)
1638 tbm_surface_unmap(*surface);
1641 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1643 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1645 pthread_mutex_unlock(&surface_queue->lock);
1647 _tbm_surf_queue_mutex_unlock();
1650 tbm_surface_internal_dump_buffer(*surface, "acquire");
1652 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1654 return TBM_SURFACE_QUEUE_ERROR_NONE;
1658 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1660 _tbm_surf_queue_mutex_lock();
1661 _tbm_set_last_result(TBM_ERROR_NONE);
1663 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1665 pthread_mutex_lock(&surface_queue->lock);
1667 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1669 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1670 pthread_mutex_unlock(&surface_queue->lock);
1671 _tbm_surf_queue_mutex_unlock();
1675 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1676 QUEUE_NODE_TYPE_DEQUEUE)) {
1677 _tbm_surf_queue_mutex_unlock();
1678 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1679 pthread_mutex_unlock(&surface_queue->lock);
1683 pthread_mutex_unlock(&surface_queue->lock);
1684 _tbm_surf_queue_mutex_unlock();
1689 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1691 queue_node *node = NULL, *tmp;
1693 _tbm_surf_queue_mutex_lock();
1694 _tbm_set_last_result(TBM_ERROR_NONE);
1696 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1698 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1700 LIST_DEL(&surface_queue->item_link);
1702 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1703 _queue_delete_node(surface_queue, node);
1705 if (surface_queue->impl && surface_queue->impl->destroy)
1706 surface_queue->impl->destroy(surface_queue);
1708 _notify_emit(surface_queue, &surface_queue->destory_noti);
1710 _notify_remove_all(&surface_queue->destory_noti);
1711 _notify_remove_all(&surface_queue->dequeuable_noti);
1712 _notify_remove_all(&surface_queue->dequeue_noti);
1713 _notify_remove_all(&surface_queue->can_dequeue_noti);
1714 _notify_remove_all(&surface_queue->acquirable_noti);
1715 _notify_remove_all(&surface_queue->reset_noti);
1716 _trace_remove_all(&surface_queue->trace_noti);
1718 pthread_mutex_destroy(&surface_queue->lock);
1720 free(surface_queue);
1722 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1723 _deinit_tbm_surf_queue_bufmgr();
1725 _tbm_surf_queue_mutex_unlock();
1728 tbm_surface_queue_error_e
1729 tbm_surface_queue_reset(tbm_surface_queue_h
1730 surface_queue, int width, int height, int format)
1732 queue_node *node = NULL, *tmp;
1734 _tbm_surf_queue_mutex_lock();
1735 _tbm_set_last_result(TBM_ERROR_NONE);
1737 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1738 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1740 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1742 if (width == surface_queue->width && height == surface_queue->height &&
1743 format == surface_queue->format) {
1744 _tbm_surf_queue_mutex_unlock();
1745 return TBM_SURFACE_QUEUE_ERROR_NONE;
1748 pthread_mutex_lock(&surface_queue->lock);
1750 surface_queue->width = width;
1751 surface_queue->height = height;
1752 surface_queue->format = format;
1754 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1755 /* Destory surface and Push to free_queue */
1756 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1757 _queue_delete_node(surface_queue, node);
1759 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1760 node->delete_pending = 1;
1762 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1763 _queue_delete_node(surface_queue, node);
1765 _queue_init(&surface_queue->dirty_queue);
1766 LIST_INITHEAD(&surface_queue->list);
1770 _queue_init(&surface_queue->free_queue);
1772 surface_queue->num_attached = 0;
1774 if (surface_queue->impl && surface_queue->impl->reset)
1775 surface_queue->impl->reset(surface_queue);
1777 pthread_mutex_unlock(&surface_queue->lock);
1778 pthread_cond_signal(&surface_queue->free_cond);
1780 _tbm_surf_queue_mutex_unlock();
1782 _notify_emit(surface_queue, &surface_queue->reset_noti);
1784 return TBM_SURFACE_QUEUE_ERROR_NONE;
1787 tbm_surface_queue_error_e
1788 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1790 _tbm_surf_queue_mutex_lock();
1791 _tbm_set_last_result(TBM_ERROR_NONE);
1793 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1794 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1796 _tbm_surf_queue_mutex_unlock();
1798 _notify_emit(surface_queue, &surface_queue->reset_noti);
1800 return TBM_SURFACE_QUEUE_ERROR_NONE;
1803 tbm_surface_queue_error_e
1804 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1806 _tbm_surf_queue_mutex_lock();
1807 _tbm_set_last_result(TBM_ERROR_NONE);
1809 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1810 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1812 pthread_mutex_lock(&surface_queue->lock);
1813 pthread_mutex_unlock(&surface_queue->lock);
1814 pthread_cond_signal(&surface_queue->free_cond);
1816 _tbm_surf_queue_mutex_unlock();
1818 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1820 return TBM_SURFACE_QUEUE_ERROR_NONE;
1823 tbm_surface_queue_error_e
1824 tbm_surface_queue_set_size(tbm_surface_queue_h
1825 surface_queue, int queue_size, int flush)
1827 queue_node *node = NULL, *tmp;
1829 _tbm_surf_queue_mutex_lock();
1830 _tbm_set_last_result(TBM_ERROR_NONE);
1832 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1833 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1834 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1835 TBM_ERROR_INVALID_PARAMETER);
1837 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1839 if ((surface_queue->queue_size == queue_size) && !flush) {
1840 _tbm_surf_queue_mutex_unlock();
1841 return TBM_SURFACE_QUEUE_ERROR_NONE;
1844 pthread_mutex_lock(&surface_queue->lock);
1847 surface_queue->queue_size = queue_size;
1849 if (surface_queue->num_attached == 0) {
1850 pthread_mutex_unlock(&surface_queue->lock);
1851 _tbm_surf_queue_mutex_unlock();
1852 return TBM_SURFACE_QUEUE_ERROR_NONE;
1855 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1856 /* Destory surface and Push to free_queue */
1857 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1858 _queue_delete_node(surface_queue, node);
1860 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1861 node->delete_pending = 1;
1863 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1864 _queue_delete_node(surface_queue, node);
1866 _queue_init(&surface_queue->dirty_queue);
1867 LIST_INITHEAD(&surface_queue->list);
1871 _queue_init(&surface_queue->free_queue);
1873 surface_queue->num_attached = 0;
1875 if (surface_queue->impl && surface_queue->impl->reset)
1876 surface_queue->impl->reset(surface_queue);
1878 pthread_mutex_unlock(&surface_queue->lock);
1879 pthread_cond_signal(&surface_queue->free_cond);
1881 _tbm_surf_queue_mutex_unlock();
1883 _notify_emit(surface_queue, &surface_queue->reset_noti);
1885 return TBM_SURFACE_QUEUE_ERROR_NONE;
1887 if (surface_queue->queue_size > queue_size) {
1888 int need_del = surface_queue->queue_size - queue_size;
1890 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1891 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1893 if (surface_queue->impl && surface_queue->impl->need_detach)
1894 surface_queue->impl->need_detach(surface_queue, node);
1896 _tbm_surface_queue_detach(surface_queue, node->surface);
1904 surface_queue->queue_size = queue_size;
1906 pthread_mutex_unlock(&surface_queue->lock);
1908 _tbm_surf_queue_mutex_unlock();
1910 return TBM_SURFACE_QUEUE_ERROR_NONE;
1914 tbm_surface_queue_error_e
1915 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1917 queue_node *node = NULL;
1919 _tbm_surf_queue_mutex_lock();
1920 _tbm_set_last_result(TBM_ERROR_NONE);
1922 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1923 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1925 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1927 if (surface_queue->num_attached == 0) {
1928 _tbm_surf_queue_mutex_unlock();
1929 return TBM_SURFACE_QUEUE_ERROR_NONE;
1932 pthread_mutex_lock(&surface_queue->lock);
1934 /* Destory surface in free_queue */
1935 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1936 if (surface_queue->impl && surface_queue->impl->need_detach)
1937 surface_queue->impl->need_detach(surface_queue, node);
1939 _tbm_surface_queue_detach(surface_queue, node->surface);
1943 _queue_init(&surface_queue->free_queue);
1945 pthread_mutex_unlock(&surface_queue->lock);
1946 _tbm_surf_queue_mutex_unlock();
1948 return TBM_SURFACE_QUEUE_ERROR_NONE;
1951 tbm_surface_queue_error_e
1952 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1954 queue_node *node = NULL, *tmp;
1956 _tbm_surf_queue_mutex_lock();
1957 _tbm_set_last_result(TBM_ERROR_NONE);
1959 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1960 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1962 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1964 if (surface_queue->num_attached == 0) {
1965 _tbm_surf_queue_mutex_unlock();
1966 return TBM_SURFACE_QUEUE_ERROR_NONE;
1969 pthread_mutex_lock(&surface_queue->lock);
1971 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1972 /* Destory surface and Push to free_queue */
1973 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1974 _queue_delete_node(surface_queue, node);
1976 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1977 node->delete_pending = 1;
1979 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1980 _queue_delete_node(surface_queue, node);
1982 _queue_init(&surface_queue->dirty_queue);
1983 LIST_INITHEAD(&surface_queue->list);
1987 _queue_init(&surface_queue->free_queue);
1989 surface_queue->num_attached = 0;
1991 if (surface_queue->impl && surface_queue->impl->reset)
1992 surface_queue->impl->reset(surface_queue);
1994 pthread_mutex_unlock(&surface_queue->lock);
1995 pthread_cond_signal(&surface_queue->free_cond);
1997 _tbm_surf_queue_mutex_unlock();
1999 _notify_emit(surface_queue, &surface_queue->reset_noti);
2001 return TBM_SURFACE_QUEUE_ERROR_NONE;
2004 tbm_surface_queue_error_e
2005 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
2006 tbm_surface_h *surfaces, int *num)
2008 queue_node *node = NULL;
2010 _tbm_surf_queue_mutex_lock();
2011 _tbm_set_last_result(TBM_ERROR_NONE);
2013 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2014 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2015 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2016 TBM_ERROR_INVALID_PARAMETER);
2020 pthread_mutex_lock(&surface_queue->lock);
2022 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2023 if (node->delete_pending) continue;
2026 surfaces[*num] = node->surface;
2031 pthread_mutex_unlock(&surface_queue->lock);
2033 _tbm_surf_queue_mutex_unlock();
2035 return TBM_SURFACE_QUEUE_ERROR_NONE;
2038 tbm_surface_queue_error_e
2039 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2040 tbm_surface_h *surfaces, int *num)
2042 queue_node *node = NULL;
2044 _tbm_surf_queue_mutex_lock();
2048 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2049 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2050 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2051 TBM_ERROR_INVALID_PARAMETER);
2053 pthread_mutex_lock(&surface_queue->lock);
2055 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2057 surfaces[*num] = node->surface;
2062 pthread_mutex_unlock(&surface_queue->lock);
2064 _tbm_surf_queue_mutex_unlock();
2066 return TBM_SURFACE_QUEUE_ERROR_NONE;
2069 tbm_surface_queue_error_e
2070 tbm_surface_queue_get_trace_surface_num(
2071 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2073 _tbm_surf_queue_mutex_lock();
2074 _tbm_set_last_result(TBM_ERROR_NONE);
2076 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2077 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2078 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2079 TBM_ERROR_INVALID_PARAMETER);
2083 pthread_mutex_lock(&surface_queue->lock);
2086 case TBM_SURFACE_QUEUE_TRACE_NONE:
2089 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2090 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2092 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2093 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2095 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2096 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2098 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2099 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2105 pthread_mutex_unlock(&surface_queue->lock);
2107 _tbm_surf_queue_mutex_unlock();
2109 return TBM_SURFACE_QUEUE_ERROR_NONE;
2114 } tbm_queue_default;
2117 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
2119 free(surface_queue->impl_data);
2123 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
2125 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
2126 tbm_surface_h surface;
2128 if (surface_queue->queue_size == surface_queue->num_attached)
2131 if (surface_queue->alloc_cb) {
2132 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2138 tbm_surface_internal_ref(surface);
2140 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2141 surface_queue->height,
2142 surface_queue->format,
2144 TBM_RETURN_IF_FAIL(surface != NULL);
2147 _tbm_surface_queue_attach(surface_queue, surface);
2148 tbm_surface_internal_unref(surface);
2151 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2152 NULL, /*__tbm_queue_default_init*/
2153 NULL, /*__tbm_queue_default_reset*/
2154 __tbm_queue_default_destroy,
2155 __tbm_queue_default_need_attach,
2156 NULL, /*__tbm_queue_default_enqueue*/
2157 NULL, /*__tbm_queue_default_release*/
2158 NULL, /*__tbm_queue_default_dequeue*/
2159 NULL, /*__tbm_queue_default_acquire*/
2160 NULL, /*__tbm_queue_default_need_detach*/
2164 tbm_surface_queue_create(int queue_size, int width,
2165 int height, int format, int flags)
2167 _tbm_surf_queue_mutex_lock();
2168 _tbm_set_last_result(TBM_ERROR_NONE);
2170 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2171 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2172 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2173 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2175 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2176 sizeof(struct _tbm_surface_queue));
2177 if (!surface_queue) {
2178 TBM_ERR("cannot allocate the surface_queue.\n");
2179 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2180 _tbm_surf_queue_mutex_unlock();
2184 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2186 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2187 sizeof(tbm_queue_default));
2189 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2190 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2191 free(surface_queue);
2192 _tbm_surf_queue_mutex_unlock();
2196 data->flags = flags;
2197 _tbm_surface_queue_init(surface_queue,
2199 width, height, format,
2200 &tbm_queue_default_impl, data);
2202 _tbm_surf_queue_mutex_unlock();
2204 return surface_queue;
2210 } tbm_queue_sequence;
2213 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2215 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2217 _queue_init(&data->dequeue_list);
2221 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2223 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2225 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2228 _queue_init(&data->dequeue_list);
2232 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2234 free(surface_queue->impl_data);
2238 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2240 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2241 tbm_surface_h surface;
2243 if (surface_queue->queue_size == surface_queue->num_attached)
2246 if (surface_queue->alloc_cb) {
2247 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2253 tbm_surface_internal_ref(surface);
2255 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2256 surface_queue->height,
2257 surface_queue->format,
2259 TBM_RETURN_IF_FAIL(surface != NULL);
2262 _tbm_surface_queue_attach(surface_queue, surface);
2263 tbm_surface_internal_unref(surface);
2267 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2270 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2271 queue_node *first = NULL;
2273 first = container_of(data->dequeue_list.head.next, first, item_link);
2274 if (first != node) {
2278 node->priv_flags = 0;
2280 _queue_node_pop(&data->dequeue_list, node);
2281 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2285 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2288 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2290 if (node->priv_flags) {
2291 node->priv_flags = 0;
2292 _queue_node_pop(&data->dequeue_list, node);
2295 _tbm_surface_queue_release(surface_queue, node, 1);
2299 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2302 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2305 node = _tbm_surface_queue_dequeue(surface_queue);
2307 _queue_node_push_back(&data->dequeue_list, node);
2308 node->priv_flags = 1;
2314 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2315 __tbm_queue_sequence_init,
2316 __tbm_queue_sequence_reset,
2317 __tbm_queue_sequence_destroy,
2318 __tbm_queue_sequence_need_attach,
2319 __tbm_queue_sequence_enqueue,
2320 __tbm_queue_sequence_release,
2321 __tbm_queue_sequence_dequeue,
2322 NULL, /*__tbm_queue_sequence_acquire*/
2323 NULL, /*__tbm_queue_sequence_need_dettach*/
2327 tbm_surface_queue_sequence_create(int queue_size, int width,
2328 int height, int format, int flags)
2330 _tbm_surf_queue_mutex_lock();
2331 _tbm_set_last_result(TBM_ERROR_NONE);
2333 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2334 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2335 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2336 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2338 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2339 sizeof(struct _tbm_surface_queue));
2340 if (surface_queue == NULL) {
2341 TBM_ERR("cannot allocate the surface_queue.\n");
2342 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2343 _tbm_surf_queue_mutex_unlock();
2347 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2349 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2350 sizeof(tbm_queue_sequence));
2352 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2353 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2354 free(surface_queue);
2355 _tbm_surf_queue_mutex_unlock();
2359 data->flags = flags;
2360 _tbm_surface_queue_init(surface_queue,
2362 width, height, format,
2363 &tbm_queue_sequence_impl, data);
2365 _tbm_surf_queue_mutex_unlock();
2367 return surface_queue;
2370 tbm_surface_queue_error_e
2371 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2374 _tbm_surf_queue_mutex_lock();
2375 _tbm_set_last_result(TBM_ERROR_NONE);
2377 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2378 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2380 pthread_mutex_lock(&surface_queue->lock);
2382 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2383 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2385 surface_queue->modes |= modes;
2387 pthread_mutex_unlock(&surface_queue->lock);
2389 _tbm_surf_queue_mutex_unlock();
2391 return TBM_SURFACE_QUEUE_ERROR_NONE;
2394 tbm_surface_queue_error_e
2395 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2396 unsigned int sync_count)
2398 int dequeue_num, enqueue_num;
2400 _tbm_surf_queue_mutex_lock();
2401 _tbm_set_last_result(TBM_ERROR_NONE);
2403 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2404 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2406 pthread_mutex_lock(&surface_queue->lock);
2408 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2409 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2411 if (dequeue_num + sync_count == 0)
2412 surface_queue->acquire_sync_count = enqueue_num;
2414 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2416 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2417 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2419 pthread_mutex_unlock(&surface_queue->lock);
2421 _tbm_surf_queue_mutex_unlock();
2423 return TBM_SURFACE_QUEUE_ERROR_NONE;