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 = PTHREAD_MUTEX_INITIALIZER;
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 {
128 struct list_head list;
130 struct list_head destory_noti;
131 struct list_head dequeuable_noti;
132 struct list_head dequeue_noti;
133 struct list_head can_dequeue_noti;
134 struct list_head acquirable_noti;
135 struct list_head reset_noti;
136 struct list_head trace_noti;
138 pthread_mutex_t lock;
139 pthread_cond_t free_cond;
140 pthread_cond_t dirty_cond;
142 const tbm_surface_queue_interface *impl;
145 //For external buffer allocation
146 tbm_surface_alloc_cb alloc_cb;
147 tbm_surface_free_cb free_cb;
150 struct list_head item_link; /* link of surface queue */
153 unsigned int enqueue_sync_count;
154 unsigned int acquire_sync_count;
158 _tbm_surf_queue_mutex_lock(void)
160 pthread_mutex_lock(&tbm_surf_queue_lock);
164 _tbm_surf_queue_mutex_unlock(void)
166 pthread_mutex_unlock(&tbm_surf_queue_lock);
170 _init_tbm_surf_queue_bufmgr(void)
172 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
176 _deinit_tbm_surf_queue_bufmgr(void)
178 if (!g_surf_queue_bufmgr)
181 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
182 g_surf_queue_bufmgr = NULL;
186 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
188 tbm_surface_queue_h old_data = NULL;
190 if (surface_queue == NULL) {
191 TBM_ERR("error: surface_queue is NULL.\n");
195 if (g_surf_queue_bufmgr == NULL) {
196 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
200 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
201 TBM_ERR("error: surf_queue_list is empty\n");
205 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
207 if (old_data == surface_queue)
211 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
217 _queue_node_create(void)
219 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
221 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
227 _queue_node_delete(queue_node *node)
229 LIST_DEL(&node->item_link);
230 LIST_DEL(&node->link);
235 _queue_is_empty(queue *queue)
237 if (LIST_IS_EMPTY(&queue->head))
244 _queue_node_push_back(queue *queue, queue_node *node)
246 LIST_ADDTAIL(&node->item_link, &queue->head);
251 _queue_node_push_front(queue *queue, queue_node *node)
253 LIST_ADD(&node->item_link, &queue->head);
258 _queue_node_pop_front(queue *queue)
262 if (!queue->head.next) return NULL;
263 if (!queue->count) return NULL;
265 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
267 LIST_DELINIT(&node->item_link);
274 _queue_node_pop(queue *queue, queue_node *node)
276 LIST_DELINIT(&node->item_link);
283 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
284 tbm_surface_h surface, int *out_type)
286 queue_node *node = NULL;
289 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
293 if (type & FREE_QUEUE) {
294 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
296 if (node->surface == surface) {
298 *out_type = FREE_QUEUE;
305 if (type & DIRTY_QUEUE) {
306 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
308 if (node->surface == surface) {
310 *out_type = DIRTY_QUEUE;
317 if (type & NODE_LIST) {
318 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
319 if (node->surface == surface) {
321 *out_type = NODE_LIST;
328 TBM_ERR("fail to get the queue_node.\n");
334 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
337 if (surface_queue->free_cb) {
338 surface_queue->free_cb(surface_queue,
339 surface_queue->alloc_cb_data,
343 tbm_surface_destroy(node->surface);
346 _queue_node_delete(node);
350 _queue_init(queue *queue)
352 LIST_INITHEAD(&queue->head);
358 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
361 TBM_RETURN_IF_FAIL(cb != NULL);
363 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
365 TBM_RETURN_IF_FAIL(item != NULL);
367 LIST_INITHEAD(&item->link);
371 LIST_ADDTAIL(&item->link, list);
375 _notify_remove(struct list_head *list,
376 tbm_surface_queue_notify_cb cb, void *data)
378 queue_notify *item = NULL, *tmp;
380 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
381 if (item->cb == cb && item->data == data) {
382 LIST_DEL(&item->link);
388 TBM_ERR("Cannot find notifiy\n");
392 _notify_remove_all(struct list_head *list)
394 queue_notify *item = NULL, *tmp;
396 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
397 LIST_DEL(&item->link);
403 _notify_emit(tbm_surface_queue_h surface_queue,
404 struct list_head *list)
406 queue_notify *item = NULL, *tmp;;
409 The item->cb is the outside function of the libtbm.
410 The tbm user may/can remove the item of the list,
411 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
413 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
414 item->cb(surface_queue, item->data);
418 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
421 TBM_RETURN_IF_FAIL(cb != NULL);
423 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
425 TBM_RETURN_IF_FAIL(item != NULL);
427 LIST_INITHEAD(&item->link);
431 LIST_ADDTAIL(&item->link, list);
435 _trace_remove(struct list_head *list,
436 tbm_surface_queue_trace_cb cb, void *data)
438 queue_trace *item = NULL, *tmp;
440 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
441 if (item->cb == cb && item->data == data) {
442 LIST_DEL(&item->link);
448 TBM_ERR("Cannot find notifiy\n");
452 _trace_remove_all(struct list_head *list)
454 queue_trace *item = NULL, *tmp;
456 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
457 LIST_DEL(&item->link);
463 _trace_emit(tbm_surface_queue_h surface_queue,
464 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
466 queue_trace *item = NULL, *tmp;;
469 The item->cb is the outside function of the libtbm.
470 The tbm user may/can remove the item of the list,
471 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
473 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
474 item->cb(surface_queue, surface, trace, item->data);
478 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
480 queue_node *node = NULL;
483 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
484 if (node->type == type)
492 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
493 tbm_surface_h surface)
497 node = _queue_node_create();
498 TBM_RETURN_IF_FAIL(node != NULL);
500 tbm_surface_internal_ref(surface);
501 node->surface = surface;
503 LIST_ADDTAIL(&node->link, &surface_queue->list);
504 surface_queue->num_attached++;
505 _queue_node_push_back(&surface_queue->free_queue, node);
509 _tbm_surface_queue_need_attach(tbm_surface_queue_h surface_queue)
511 tbm_surface_h surface;
513 if (surface_queue->queue_size == surface_queue->num_attached)
516 if (surface_queue->alloc_cb) {
517 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
523 tbm_surface_internal_ref(surface);
525 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
526 surface_queue->height,
527 surface_queue->format,
528 surface_queue->flags);
529 TBM_RETURN_IF_FAIL(surface != NULL);
532 _tbm_surface_queue_attach(surface_queue, surface);
533 tbm_surface_internal_unref(surface);
537 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
538 tbm_surface_h surface)
543 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
545 _queue_delete_node(surface_queue, node);
546 surface_queue->num_attached--;
551 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
552 queue_node *node, int push_back)
555 _queue_node_push_back(&surface_queue->dirty_queue, node);
557 _queue_node_push_front(&surface_queue->dirty_queue, node);
561 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
565 node = _queue_node_pop_front(&surface_queue->free_queue);
571 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
575 if (_queue_is_empty(&surface_queue->dirty_queue))
578 node = _queue_node_pop_front(&surface_queue->dirty_queue);
584 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
585 queue_node *node, int push_back)
588 _queue_node_push_back(&surface_queue->free_queue, node);
590 _queue_node_push_front(&surface_queue->free_queue, node);
594 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
596 int width, int height, int format, int flags,
597 const tbm_surface_queue_interface *impl, void *data)
599 pthread_condattr_t free_attr, dirty_attr;
601 TBM_RETURN_IF_FAIL(surface_queue != NULL);
602 TBM_RETURN_IF_FAIL(impl != NULL);
604 if (!g_surf_queue_bufmgr)
605 _init_tbm_surf_queue_bufmgr();
607 pthread_mutex_init(&surface_queue->lock, NULL);
609 pthread_condattr_init(&free_attr);
610 pthread_condattr_setclock(&free_attr, CLOCK_MONOTONIC);
611 pthread_cond_init(&surface_queue->free_cond, &free_attr);
612 pthread_condattr_destroy(&free_attr);
614 pthread_condattr_init(&dirty_attr);
615 pthread_condattr_setclock(&dirty_attr, CLOCK_MONOTONIC);
616 pthread_cond_init(&surface_queue->dirty_cond, &dirty_attr);
617 pthread_condattr_destroy(&dirty_attr);
619 surface_queue->queue_size = queue_size;
620 surface_queue->width = width;
621 surface_queue->height = height;
622 surface_queue->format = format;
623 surface_queue->flags = flags;
624 surface_queue->impl = impl;
625 surface_queue->impl_data = data;
626 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
628 _queue_init(&surface_queue->free_queue);
629 _queue_init(&surface_queue->dirty_queue);
630 LIST_INITHEAD(&surface_queue->list);
632 LIST_INITHEAD(&surface_queue->destory_noti);
633 LIST_INITHEAD(&surface_queue->dequeuable_noti);
634 LIST_INITHEAD(&surface_queue->dequeue_noti);
635 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
636 LIST_INITHEAD(&surface_queue->acquirable_noti);
637 LIST_INITHEAD(&surface_queue->reset_noti);
638 LIST_INITHEAD(&surface_queue->trace_noti);
640 if (surface_queue->impl && surface_queue->impl->init)
641 surface_queue->impl->init(surface_queue);
643 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
646 tbm_surface_queue_error_e
647 tbm_surface_queue_add_destroy_cb(
648 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
651 _tbm_surf_queue_mutex_lock();
652 _tbm_set_last_result(TBM_ERROR_NONE);
654 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
655 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
656 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
657 TBM_ERROR_INVALID_PARAMETER);
659 pthread_mutex_lock(&surface_queue->lock);
661 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
663 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
665 pthread_mutex_unlock(&surface_queue->lock);
667 _tbm_surf_queue_mutex_unlock();
669 return TBM_SURFACE_QUEUE_ERROR_NONE;
672 tbm_surface_queue_error_e
673 tbm_surface_queue_remove_destroy_cb(
674 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
677 _tbm_surf_queue_mutex_lock();
678 _tbm_set_last_result(TBM_ERROR_NONE);
680 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
681 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
683 pthread_mutex_lock(&surface_queue->lock);
685 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
687 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
689 pthread_mutex_unlock(&surface_queue->lock);
691 _tbm_surf_queue_mutex_unlock();
693 return TBM_SURFACE_QUEUE_ERROR_NONE;
696 tbm_surface_queue_error_e
697 tbm_surface_queue_add_dequeuable_cb(
698 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
701 _tbm_surf_queue_mutex_lock();
702 _tbm_set_last_result(TBM_ERROR_NONE);
704 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
705 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
706 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
707 TBM_ERROR_INVALID_PARAMETER);
709 pthread_mutex_lock(&surface_queue->lock);
711 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
713 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
715 pthread_mutex_unlock(&surface_queue->lock);
717 _tbm_surf_queue_mutex_unlock();
719 return TBM_SURFACE_QUEUE_ERROR_NONE;
722 tbm_surface_queue_error_e
723 tbm_surface_queue_remove_dequeuable_cb(
724 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
727 _tbm_surf_queue_mutex_lock();
728 _tbm_set_last_result(TBM_ERROR_NONE);
730 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
731 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
733 pthread_mutex_lock(&surface_queue->lock);
735 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
737 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
739 pthread_mutex_unlock(&surface_queue->lock);
741 _tbm_surf_queue_mutex_unlock();
743 return TBM_SURFACE_QUEUE_ERROR_NONE;
746 tbm_surface_queue_error_e
747 tbm_surface_queue_add_dequeue_cb(
748 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
751 _tbm_surf_queue_mutex_lock();
752 _tbm_set_last_result(TBM_ERROR_NONE);
754 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
755 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
756 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
757 TBM_ERROR_INVALID_PARAMETER);
759 pthread_mutex_lock(&surface_queue->lock);
761 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
763 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
765 pthread_mutex_unlock(&surface_queue->lock);
767 _tbm_surf_queue_mutex_unlock();
769 return TBM_SURFACE_QUEUE_ERROR_NONE;
772 tbm_surface_queue_error_e
773 tbm_surface_queue_remove_dequeue_cb(
774 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
777 _tbm_surf_queue_mutex_lock();
778 _tbm_set_last_result(TBM_ERROR_NONE);
780 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
781 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
783 pthread_mutex_lock(&surface_queue->lock);
785 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
787 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
789 pthread_mutex_unlock(&surface_queue->lock);
791 _tbm_surf_queue_mutex_unlock();
793 return TBM_SURFACE_QUEUE_ERROR_NONE;
796 tbm_surface_queue_error_e
797 tbm_surface_queue_add_can_dequeue_cb(
798 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
801 _tbm_surf_queue_mutex_lock();
802 _tbm_set_last_result(TBM_ERROR_NONE);
804 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
805 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
806 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
807 TBM_ERROR_INVALID_PARAMETER);
809 pthread_mutex_lock(&surface_queue->lock);
811 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
813 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
815 pthread_mutex_unlock(&surface_queue->lock);
817 _tbm_surf_queue_mutex_unlock();
819 return TBM_SURFACE_QUEUE_ERROR_NONE;
822 tbm_surface_queue_error_e
823 tbm_surface_queue_remove_can_dequeue_cb(
824 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
827 _tbm_surf_queue_mutex_lock();
828 _tbm_set_last_result(TBM_ERROR_NONE);
830 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
831 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
833 pthread_mutex_lock(&surface_queue->lock);
835 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
837 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
839 pthread_mutex_unlock(&surface_queue->lock);
841 _tbm_surf_queue_mutex_unlock();
843 return TBM_SURFACE_QUEUE_ERROR_NONE;
846 tbm_surface_queue_error_e
847 tbm_surface_queue_add_acquirable_cb(
848 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
851 _tbm_surf_queue_mutex_lock();
852 _tbm_set_last_result(TBM_ERROR_NONE);
854 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
855 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
856 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
857 TBM_ERROR_INVALID_PARAMETER);
859 pthread_mutex_lock(&surface_queue->lock);
861 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
863 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
865 pthread_mutex_unlock(&surface_queue->lock);
867 _tbm_surf_queue_mutex_unlock();
869 return TBM_SURFACE_QUEUE_ERROR_NONE;
872 tbm_surface_queue_error_e
873 tbm_surface_queue_remove_acquirable_cb(
874 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
877 _tbm_surf_queue_mutex_lock();
878 _tbm_set_last_result(TBM_ERROR_NONE);
880 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
881 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
883 pthread_mutex_lock(&surface_queue->lock);
885 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
887 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
889 pthread_mutex_unlock(&surface_queue->lock);
891 _tbm_surf_queue_mutex_unlock();
893 return TBM_SURFACE_QUEUE_ERROR_NONE;
896 tbm_surface_queue_error_e
897 tbm_surface_queue_add_trace_cb(
898 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
901 _tbm_surf_queue_mutex_lock();
902 _tbm_set_last_result(TBM_ERROR_NONE);
904 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
905 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
906 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
907 TBM_ERROR_INVALID_PARAMETER);
909 pthread_mutex_lock(&surface_queue->lock);
911 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
913 _trace_add(&surface_queue->trace_noti, trace_cb, data);
915 pthread_mutex_unlock(&surface_queue->lock);
917 _tbm_surf_queue_mutex_unlock();
919 return TBM_SURFACE_QUEUE_ERROR_NONE;
922 tbm_surface_queue_error_e
923 tbm_surface_queue_remove_trace_cb(
924 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
927 _tbm_surf_queue_mutex_lock();
928 _tbm_set_last_result(TBM_ERROR_NONE);
930 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
931 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
933 pthread_mutex_lock(&surface_queue->lock);
935 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
937 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
939 pthread_mutex_unlock(&surface_queue->lock);
941 _tbm_surf_queue_mutex_unlock();
943 return TBM_SURFACE_QUEUE_ERROR_NONE;
946 tbm_surface_queue_error_e
947 tbm_surface_queue_set_alloc_cb(
948 tbm_surface_queue_h surface_queue,
949 tbm_surface_alloc_cb alloc_cb,
950 tbm_surface_free_cb free_cb,
953 _tbm_surf_queue_mutex_lock();
954 _tbm_set_last_result(TBM_ERROR_NONE);
956 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
957 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
959 pthread_mutex_lock(&surface_queue->lock);
961 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
963 surface_queue->alloc_cb = alloc_cb;
964 surface_queue->free_cb = free_cb;
965 surface_queue->alloc_cb_data = data;
967 pthread_mutex_unlock(&surface_queue->lock);
969 _tbm_surf_queue_mutex_unlock();
971 return TBM_SURFACE_QUEUE_ERROR_NONE;
975 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
979 _tbm_surf_queue_mutex_lock();
980 _tbm_set_last_result(TBM_ERROR_NONE);
982 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
984 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
986 width = surface_queue->width;
988 _tbm_surf_queue_mutex_unlock();
994 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
998 _tbm_surf_queue_mutex_lock();
999 _tbm_set_last_result(TBM_ERROR_NONE);
1001 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1003 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1005 height = surface_queue->height;
1007 _tbm_surf_queue_mutex_unlock();
1013 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1017 _tbm_surf_queue_mutex_lock();
1018 _tbm_set_last_result(TBM_ERROR_NONE);
1020 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1022 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1024 format = surface_queue->format;
1026 _tbm_surf_queue_mutex_unlock();
1032 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1036 _tbm_surf_queue_mutex_lock();
1037 _tbm_set_last_result(TBM_ERROR_NONE);
1039 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1041 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1043 queue_size = surface_queue->queue_size;
1045 _tbm_surf_queue_mutex_unlock();
1050 tbm_surface_queue_error_e
1051 tbm_surface_queue_add_reset_cb(
1052 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1055 _tbm_surf_queue_mutex_lock();
1056 _tbm_set_last_result(TBM_ERROR_NONE);
1058 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1059 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1060 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1061 TBM_ERROR_INVALID_PARAMETER);
1063 pthread_mutex_lock(&surface_queue->lock);
1065 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1067 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1069 pthread_mutex_unlock(&surface_queue->lock);
1071 _tbm_surf_queue_mutex_unlock();
1073 return TBM_SURFACE_QUEUE_ERROR_NONE;
1076 tbm_surface_queue_error_e
1077 tbm_surface_queue_remove_reset_cb(
1078 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1081 _tbm_surf_queue_mutex_lock();
1082 _tbm_set_last_result(TBM_ERROR_NONE);
1084 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1085 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1087 pthread_mutex_lock(&surface_queue->lock);
1089 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1091 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1093 pthread_mutex_unlock(&surface_queue->lock);
1095 _tbm_surf_queue_mutex_unlock();
1097 return TBM_SURFACE_QUEUE_ERROR_NONE;
1100 tbm_surface_queue_error_e
1101 tbm_surface_queue_enqueue(tbm_surface_queue_h
1102 surface_queue, tbm_surface_h surface)
1107 _tbm_surf_queue_mutex_lock();
1108 _tbm_set_last_result(TBM_ERROR_NONE);
1110 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1111 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1112 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1113 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1116 tbm_surface_internal_dump_buffer(surface, "enqueue");
1118 pthread_mutex_lock(&surface_queue->lock);
1120 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1122 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1123 if (node == NULL || queue_type != NODE_LIST) {
1124 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1126 pthread_mutex_unlock(&surface_queue->lock);
1128 _tbm_surf_queue_mutex_unlock();
1131 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1132 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1134 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1135 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1139 if (surface_queue->impl && surface_queue->impl->enqueue)
1140 surface_queue->impl->enqueue(surface_queue, node);
1142 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1144 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1145 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1146 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1147 pthread_mutex_unlock(&surface_queue->lock);
1149 _tbm_surf_queue_mutex_unlock();
1150 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1153 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1155 if (surface_queue->enqueue_sync_count == 1) {
1156 tbm_surface_info_s info;
1159 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1160 if (ret == TBM_SURFACE_ERROR_NONE)
1161 tbm_surface_unmap(surface);
1164 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1166 pthread_mutex_unlock(&surface_queue->lock);
1167 pthread_cond_signal(&surface_queue->dirty_cond);
1169 _tbm_surf_queue_mutex_unlock();
1171 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1173 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1175 return TBM_SURFACE_QUEUE_ERROR_NONE;
1178 tbm_surface_queue_error_e
1179 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1180 surface_queue, tbm_surface_h surface)
1185 _tbm_surf_queue_mutex_lock();
1186 _tbm_set_last_result(TBM_ERROR_NONE);
1188 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1189 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1190 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1191 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1193 pthread_mutex_lock(&surface_queue->lock);
1195 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1197 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1198 if (node == NULL || queue_type != NODE_LIST) {
1199 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1201 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1202 pthread_mutex_unlock(&surface_queue->lock);
1204 _tbm_surf_queue_mutex_unlock();
1205 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1208 if (node->delete_pending) {
1209 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1211 _queue_delete_node(surface_queue, node);
1213 pthread_mutex_unlock(&surface_queue->lock);
1215 _tbm_surf_queue_mutex_unlock();
1217 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1219 return TBM_SURFACE_QUEUE_ERROR_NONE;
1222 if (surface_queue->queue_size < surface_queue->num_attached) {
1223 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1225 if (surface_queue->impl && surface_queue->impl->need_detach)
1226 surface_queue->impl->need_detach(surface_queue, node);
1228 _tbm_surface_queue_detach(surface_queue, surface);
1230 pthread_mutex_unlock(&surface_queue->lock);
1232 _tbm_surf_queue_mutex_unlock();
1234 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1236 return TBM_SURFACE_QUEUE_ERROR_NONE;
1239 if (surface_queue->impl && surface_queue->impl->release)
1240 surface_queue->impl->release(surface_queue, node);
1242 _tbm_surface_queue_release(surface_queue, node, 1);
1244 if (_queue_is_empty(&surface_queue->free_queue)) {
1245 TBM_ERR("surface_queue->free_queue is empty.\n");
1246 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1247 pthread_mutex_unlock(&surface_queue->lock);
1249 _tbm_surf_queue_mutex_unlock();
1250 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1253 node->type = QUEUE_NODE_TYPE_RELEASE;
1255 pthread_mutex_unlock(&surface_queue->lock);
1256 pthread_cond_signal(&surface_queue->free_cond);
1258 _tbm_surf_queue_mutex_unlock();
1260 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1262 return TBM_SURFACE_QUEUE_ERROR_NONE;
1265 tbm_surface_queue_error_e
1266 tbm_surface_queue_dequeue(tbm_surface_queue_h
1267 surface_queue, tbm_surface_h *surface)
1271 _tbm_surf_queue_mutex_lock();
1272 _tbm_set_last_result(TBM_ERROR_NONE);
1274 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1275 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1276 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1277 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1281 pthread_mutex_lock(&surface_queue->lock);
1283 if (_queue_is_empty(&surface_queue->free_queue)) {
1284 if (surface_queue->impl && surface_queue->impl->need_attach)
1285 surface_queue->impl->need_attach(surface_queue);
1287 _tbm_surface_queue_need_attach(surface_queue);
1290 if (surface_queue->impl && surface_queue->impl->dequeue)
1291 node = surface_queue->impl->dequeue(surface_queue);
1293 node = _tbm_surface_queue_dequeue(surface_queue);
1295 if (node == NULL || node->surface == NULL) {
1296 TBM_ERR("_queue_node_pop_front failed\n");
1297 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1298 pthread_mutex_unlock(&surface_queue->lock);
1300 _tbm_surf_queue_mutex_unlock();
1301 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1304 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1305 *surface = node->surface;
1307 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1309 pthread_mutex_unlock(&surface_queue->lock);
1311 _tbm_surf_queue_mutex_unlock();
1313 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1315 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1317 return TBM_SURFACE_QUEUE_ERROR_NONE;
1320 tbm_surface_queue_error_e
1321 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1326 _tbm_surf_queue_mutex_lock();
1327 _tbm_set_last_result(TBM_ERROR_NONE);
1329 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1330 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1332 _tbm_surf_queue_mutex_unlock();
1334 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1336 _tbm_surf_queue_mutex_lock();
1338 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1339 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1341 pthread_mutex_lock(&surface_queue->lock);
1343 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1345 if (_queue_is_empty(&surface_queue->free_queue)) {
1346 if (surface_queue->impl && surface_queue->impl->need_attach)
1347 surface_queue->impl->need_attach(surface_queue);
1349 _tbm_surface_queue_need_attach(surface_queue);
1352 if (!_queue_is_empty(&surface_queue->free_queue)) {
1353 pthread_mutex_unlock(&surface_queue->lock);
1354 _tbm_surf_queue_mutex_unlock();
1355 return TBM_SURFACE_QUEUE_ERROR_NONE;
1358 _tbm_surf_queue_mutex_unlock();
1361 clock_gettime(CLOCK_MONOTONIC, &tp);
1363 if (ms_timeout > 1000)
1364 tp.tv_sec += ms_timeout / 1000;
1366 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1368 if (tp.tv_nsec > 1000000000L) {
1370 tp.tv_nsec -= 1000000000L;
1373 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1375 if (ret == ETIMEDOUT) {
1376 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1377 pthread_mutex_unlock(&surface_queue->lock);
1378 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1380 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1383 if (surface_queue->impl && surface_queue->impl->need_attach)
1384 surface_queue->impl->need_attach(surface_queue);
1386 _tbm_surface_queue_need_attach(surface_queue);
1388 if (!_queue_is_empty(&surface_queue->free_queue)) {
1389 pthread_mutex_unlock(&surface_queue->lock);
1390 return TBM_SURFACE_QUEUE_ERROR_NONE;
1397 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1399 _tbm_surf_queue_mutex_lock();
1400 _tbm_set_last_result(TBM_ERROR_NONE);
1402 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1404 _tbm_surf_queue_mutex_unlock();
1406 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1408 _tbm_surf_queue_mutex_lock();
1410 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1412 pthread_mutex_lock(&surface_queue->lock);
1414 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1416 if (_queue_is_empty(&surface_queue->free_queue)) {
1417 if (surface_queue->impl && surface_queue->impl->need_attach)
1418 surface_queue->impl->need_attach(surface_queue);
1420 _tbm_surface_queue_need_attach(surface_queue);
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();
1432 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1434 if (surface_queue->impl && surface_queue->impl->need_attach)
1435 surface_queue->impl->need_attach(surface_queue);
1437 _tbm_surface_queue_need_attach(surface_queue);
1439 if (!_queue_is_empty(&surface_queue->free_queue)) {
1440 pthread_mutex_unlock(&surface_queue->lock);
1446 pthread_mutex_unlock(&surface_queue->lock);
1447 _tbm_surf_queue_mutex_unlock();
1451 tbm_surface_queue_error_e
1452 tbm_surface_queue_release(tbm_surface_queue_h
1453 surface_queue, tbm_surface_h surface)
1458 _tbm_surf_queue_mutex_lock();
1459 _tbm_set_last_result(TBM_ERROR_NONE);
1461 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1462 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1463 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1464 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1466 pthread_mutex_lock(&surface_queue->lock);
1468 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1470 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1471 if (node == NULL || queue_type != NODE_LIST) {
1472 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1474 pthread_mutex_unlock(&surface_queue->lock);
1476 _tbm_surf_queue_mutex_unlock();
1479 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1480 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1482 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1483 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1487 if (node->delete_pending) {
1488 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1490 _queue_delete_node(surface_queue, node);
1492 pthread_mutex_unlock(&surface_queue->lock);
1494 _tbm_surf_queue_mutex_unlock();
1496 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1498 return TBM_SURFACE_QUEUE_ERROR_NONE;
1501 if (surface_queue->queue_size < surface_queue->num_attached) {
1502 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1504 if (surface_queue->impl && surface_queue->impl->need_detach)
1505 surface_queue->impl->need_detach(surface_queue, node);
1507 _tbm_surface_queue_detach(surface_queue, surface);
1509 pthread_mutex_unlock(&surface_queue->lock);
1511 _tbm_surf_queue_mutex_unlock();
1513 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1515 return TBM_SURFACE_QUEUE_ERROR_NONE;
1518 if (surface_queue->impl && surface_queue->impl->release)
1519 surface_queue->impl->release(surface_queue, node);
1521 _tbm_surface_queue_release(surface_queue, node, 1);
1523 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1524 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1525 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1526 pthread_mutex_unlock(&surface_queue->lock);
1528 _tbm_surf_queue_mutex_unlock();
1529 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1532 node->type = QUEUE_NODE_TYPE_RELEASE;
1534 pthread_mutex_unlock(&surface_queue->lock);
1535 pthread_cond_signal(&surface_queue->free_cond);
1537 _tbm_surf_queue_mutex_unlock();
1539 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1541 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1543 return TBM_SURFACE_QUEUE_ERROR_NONE;
1546 tbm_surface_queue_error_e
1547 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1548 surface_queue, tbm_surface_h surface)
1553 _tbm_surf_queue_mutex_lock();
1554 _tbm_set_last_result(TBM_ERROR_NONE);
1556 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1557 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1558 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1559 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1561 pthread_mutex_lock(&surface_queue->lock);
1563 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1565 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1566 if (node == NULL || queue_type != NODE_LIST) {
1567 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1569 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1570 pthread_mutex_unlock(&surface_queue->lock);
1572 _tbm_surf_queue_mutex_unlock();
1573 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1576 if (surface_queue->impl && surface_queue->impl->enqueue)
1577 surface_queue->impl->enqueue(surface_queue, node);
1579 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1581 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1582 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1583 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1584 pthread_mutex_unlock(&surface_queue->lock);
1586 _tbm_surf_queue_mutex_unlock();
1587 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1590 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1592 pthread_mutex_unlock(&surface_queue->lock);
1593 pthread_cond_signal(&surface_queue->dirty_cond);
1595 _tbm_surf_queue_mutex_unlock();
1597 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1599 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1601 return TBM_SURFACE_QUEUE_ERROR_NONE;
1604 tbm_surface_queue_error_e
1605 tbm_surface_queue_acquire(tbm_surface_queue_h
1606 surface_queue, tbm_surface_h *surface)
1610 _tbm_surf_queue_mutex_lock();
1611 _tbm_set_last_result(TBM_ERROR_NONE);
1615 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1616 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1617 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1618 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1620 pthread_mutex_lock(&surface_queue->lock);
1622 if (surface_queue->impl && surface_queue->impl->acquire)
1623 node = surface_queue->impl->acquire(surface_queue);
1625 node = _tbm_surface_queue_acquire(surface_queue);
1627 if (node == NULL || node->surface == NULL) {
1628 TBM_ERR("_queue_node_pop_front failed\n");
1629 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1630 pthread_mutex_unlock(&surface_queue->lock);
1632 _tbm_surf_queue_mutex_unlock();
1633 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1636 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1638 *surface = node->surface;
1640 if (surface_queue->acquire_sync_count == 1) {
1641 tbm_surface_info_s info;
1644 TBM_ERR("start map surface:%p", *surface);
1645 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1646 TBM_ERR("end map surface:%p", *surface);
1647 if (ret == TBM_SURFACE_ERROR_NONE)
1648 tbm_surface_unmap(*surface);
1651 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1653 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1655 pthread_mutex_unlock(&surface_queue->lock);
1657 _tbm_surf_queue_mutex_unlock();
1660 tbm_surface_internal_dump_buffer(*surface, "acquire");
1662 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1664 return TBM_SURFACE_QUEUE_ERROR_NONE;
1668 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1670 _tbm_surf_queue_mutex_lock();
1671 _tbm_set_last_result(TBM_ERROR_NONE);
1673 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1675 pthread_mutex_lock(&surface_queue->lock);
1677 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1679 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1680 pthread_mutex_unlock(&surface_queue->lock);
1681 _tbm_surf_queue_mutex_unlock();
1685 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1686 QUEUE_NODE_TYPE_DEQUEUE)) {
1687 _tbm_surf_queue_mutex_unlock();
1688 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1689 pthread_mutex_unlock(&surface_queue->lock);
1693 pthread_mutex_unlock(&surface_queue->lock);
1694 _tbm_surf_queue_mutex_unlock();
1699 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1701 queue_node *node = NULL, *tmp;
1703 _tbm_surf_queue_mutex_lock();
1704 _tbm_set_last_result(TBM_ERROR_NONE);
1706 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1708 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1710 LIST_DEL(&surface_queue->item_link);
1712 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1713 _queue_delete_node(surface_queue, node);
1715 if (surface_queue->impl && surface_queue->impl->destroy)
1716 surface_queue->impl->destroy(surface_queue);
1718 _notify_emit(surface_queue, &surface_queue->destory_noti);
1720 _notify_remove_all(&surface_queue->destory_noti);
1721 _notify_remove_all(&surface_queue->dequeuable_noti);
1722 _notify_remove_all(&surface_queue->dequeue_noti);
1723 _notify_remove_all(&surface_queue->can_dequeue_noti);
1724 _notify_remove_all(&surface_queue->acquirable_noti);
1725 _notify_remove_all(&surface_queue->reset_noti);
1726 _trace_remove_all(&surface_queue->trace_noti);
1728 pthread_mutex_destroy(&surface_queue->lock);
1730 free(surface_queue);
1732 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1733 _deinit_tbm_surf_queue_bufmgr();
1735 _tbm_surf_queue_mutex_unlock();
1738 tbm_surface_queue_error_e
1739 tbm_surface_queue_reset(tbm_surface_queue_h
1740 surface_queue, int width, int height, int format)
1742 queue_node *node = NULL, *tmp;
1744 _tbm_surf_queue_mutex_lock();
1745 _tbm_set_last_result(TBM_ERROR_NONE);
1747 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1748 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1750 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1752 if (width == surface_queue->width && height == surface_queue->height &&
1753 format == surface_queue->format) {
1754 _tbm_surf_queue_mutex_unlock();
1755 return TBM_SURFACE_QUEUE_ERROR_NONE;
1758 pthread_mutex_lock(&surface_queue->lock);
1760 surface_queue->width = width;
1761 surface_queue->height = height;
1762 surface_queue->format = format;
1764 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1765 /* Destory surface and Push to free_queue */
1766 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1767 _queue_delete_node(surface_queue, node);
1769 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1770 node->delete_pending = 1;
1772 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1773 _queue_delete_node(surface_queue, node);
1775 _queue_init(&surface_queue->dirty_queue);
1776 LIST_INITHEAD(&surface_queue->list);
1780 _queue_init(&surface_queue->free_queue);
1782 surface_queue->num_attached = 0;
1784 if (surface_queue->impl && surface_queue->impl->reset)
1785 surface_queue->impl->reset(surface_queue);
1787 pthread_mutex_unlock(&surface_queue->lock);
1788 pthread_cond_signal(&surface_queue->free_cond);
1790 _tbm_surf_queue_mutex_unlock();
1792 _notify_emit(surface_queue, &surface_queue->reset_noti);
1794 return TBM_SURFACE_QUEUE_ERROR_NONE;
1797 tbm_surface_queue_error_e
1798 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1800 _tbm_surf_queue_mutex_lock();
1801 _tbm_set_last_result(TBM_ERROR_NONE);
1803 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1804 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1806 _tbm_surf_queue_mutex_unlock();
1808 _notify_emit(surface_queue, &surface_queue->reset_noti);
1810 return TBM_SURFACE_QUEUE_ERROR_NONE;
1813 tbm_surface_queue_error_e
1814 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1816 _tbm_surf_queue_mutex_lock();
1817 _tbm_set_last_result(TBM_ERROR_NONE);
1819 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1820 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1822 pthread_mutex_lock(&surface_queue->lock);
1823 pthread_mutex_unlock(&surface_queue->lock);
1824 pthread_cond_signal(&surface_queue->free_cond);
1826 _tbm_surf_queue_mutex_unlock();
1828 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1830 return TBM_SURFACE_QUEUE_ERROR_NONE;
1833 tbm_surface_queue_error_e
1834 tbm_surface_queue_set_size(tbm_surface_queue_h
1835 surface_queue, int queue_size, int flush)
1837 queue_node *node = NULL, *tmp;
1839 _tbm_surf_queue_mutex_lock();
1840 _tbm_set_last_result(TBM_ERROR_NONE);
1842 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1843 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1844 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1845 TBM_ERROR_INVALID_PARAMETER);
1847 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1849 if ((surface_queue->queue_size == queue_size) && !flush) {
1850 _tbm_surf_queue_mutex_unlock();
1851 return TBM_SURFACE_QUEUE_ERROR_NONE;
1854 pthread_mutex_lock(&surface_queue->lock);
1857 surface_queue->queue_size = queue_size;
1859 if (surface_queue->num_attached == 0) {
1860 pthread_mutex_unlock(&surface_queue->lock);
1861 _tbm_surf_queue_mutex_unlock();
1862 return TBM_SURFACE_QUEUE_ERROR_NONE;
1865 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1866 /* Destory surface and Push to free_queue */
1867 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1868 _queue_delete_node(surface_queue, node);
1870 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1871 node->delete_pending = 1;
1873 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1874 _queue_delete_node(surface_queue, node);
1876 _queue_init(&surface_queue->dirty_queue);
1877 LIST_INITHEAD(&surface_queue->list);
1881 _queue_init(&surface_queue->free_queue);
1883 surface_queue->num_attached = 0;
1885 if (surface_queue->impl && surface_queue->impl->reset)
1886 surface_queue->impl->reset(surface_queue);
1888 pthread_mutex_unlock(&surface_queue->lock);
1889 pthread_cond_signal(&surface_queue->free_cond);
1891 _tbm_surf_queue_mutex_unlock();
1893 _notify_emit(surface_queue, &surface_queue->reset_noti);
1895 return TBM_SURFACE_QUEUE_ERROR_NONE;
1897 if (surface_queue->queue_size > queue_size) {
1898 int need_del = surface_queue->queue_size - queue_size;
1900 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1901 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1903 if (surface_queue->impl && surface_queue->impl->need_detach)
1904 surface_queue->impl->need_detach(surface_queue, node);
1906 _tbm_surface_queue_detach(surface_queue, node->surface);
1914 surface_queue->queue_size = queue_size;
1916 pthread_mutex_unlock(&surface_queue->lock);
1918 _tbm_surf_queue_mutex_unlock();
1920 return TBM_SURFACE_QUEUE_ERROR_NONE;
1924 tbm_surface_queue_error_e
1925 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1927 queue_node *node = NULL;
1929 _tbm_surf_queue_mutex_lock();
1930 _tbm_set_last_result(TBM_ERROR_NONE);
1932 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1933 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1935 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1937 if (surface_queue->num_attached == 0) {
1938 _tbm_surf_queue_mutex_unlock();
1939 return TBM_SURFACE_QUEUE_ERROR_NONE;
1942 pthread_mutex_lock(&surface_queue->lock);
1944 /* Destory surface in free_queue */
1945 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1946 if (surface_queue->impl && surface_queue->impl->need_detach)
1947 surface_queue->impl->need_detach(surface_queue, node);
1949 _tbm_surface_queue_detach(surface_queue, node->surface);
1953 _queue_init(&surface_queue->free_queue);
1955 pthread_mutex_unlock(&surface_queue->lock);
1956 _tbm_surf_queue_mutex_unlock();
1958 return TBM_SURFACE_QUEUE_ERROR_NONE;
1961 tbm_surface_queue_error_e
1962 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1964 queue_node *node = NULL, *tmp;
1966 _tbm_surf_queue_mutex_lock();
1967 _tbm_set_last_result(TBM_ERROR_NONE);
1969 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1970 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1972 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1974 if (surface_queue->num_attached == 0) {
1975 _tbm_surf_queue_mutex_unlock();
1976 return TBM_SURFACE_QUEUE_ERROR_NONE;
1979 pthread_mutex_lock(&surface_queue->lock);
1981 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1982 /* Destory surface and Push to free_queue */
1983 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1984 _queue_delete_node(surface_queue, node);
1986 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1987 node->delete_pending = 1;
1989 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1990 _queue_delete_node(surface_queue, node);
1992 _queue_init(&surface_queue->dirty_queue);
1993 LIST_INITHEAD(&surface_queue->list);
1997 _queue_init(&surface_queue->free_queue);
1999 surface_queue->num_attached = 0;
2001 if (surface_queue->impl && surface_queue->impl->reset)
2002 surface_queue->impl->reset(surface_queue);
2004 pthread_mutex_unlock(&surface_queue->lock);
2005 pthread_cond_signal(&surface_queue->free_cond);
2007 _tbm_surf_queue_mutex_unlock();
2009 _notify_emit(surface_queue, &surface_queue->reset_noti);
2011 return TBM_SURFACE_QUEUE_ERROR_NONE;
2014 tbm_surface_queue_error_e
2015 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
2016 tbm_surface_h *surfaces, int *num)
2018 queue_node *node = NULL;
2020 _tbm_surf_queue_mutex_lock();
2021 _tbm_set_last_result(TBM_ERROR_NONE);
2023 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2024 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2025 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2026 TBM_ERROR_INVALID_PARAMETER);
2030 pthread_mutex_lock(&surface_queue->lock);
2032 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2033 if (node->delete_pending) continue;
2036 surfaces[*num] = node->surface;
2041 pthread_mutex_unlock(&surface_queue->lock);
2043 _tbm_surf_queue_mutex_unlock();
2045 return TBM_SURFACE_QUEUE_ERROR_NONE;
2048 tbm_surface_queue_error_e
2049 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2050 tbm_surface_h *surfaces, int *num)
2052 queue_node *node = NULL;
2054 _tbm_surf_queue_mutex_lock();
2058 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2059 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2060 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2061 TBM_ERROR_INVALID_PARAMETER);
2063 pthread_mutex_lock(&surface_queue->lock);
2065 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2067 surfaces[*num] = node->surface;
2072 pthread_mutex_unlock(&surface_queue->lock);
2074 _tbm_surf_queue_mutex_unlock();
2076 return TBM_SURFACE_QUEUE_ERROR_NONE;
2079 tbm_surface_queue_error_e
2080 tbm_surface_queue_get_trace_surface_num(
2081 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2083 _tbm_surf_queue_mutex_lock();
2084 _tbm_set_last_result(TBM_ERROR_NONE);
2086 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2087 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2088 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2089 TBM_ERROR_INVALID_PARAMETER);
2093 pthread_mutex_lock(&surface_queue->lock);
2096 case TBM_SURFACE_QUEUE_TRACE_NONE:
2099 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2100 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2102 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2103 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2105 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2106 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2108 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2109 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2115 pthread_mutex_unlock(&surface_queue->lock);
2117 _tbm_surf_queue_mutex_unlock();
2119 return TBM_SURFACE_QUEUE_ERROR_NONE;
2122 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2123 NULL, /*__tbm_queue_default_init*/
2124 NULL, /*__tbm_queue_default_reset*/
2125 NULL, /*__tbm_queue_default_destroy*/
2126 NULL, /*__tbm_queue_default_need_attach*/
2127 NULL, /*__tbm_queue_default_enqueue*/
2128 NULL, /*__tbm_queue_default_release*/
2129 NULL, /*__tbm_queue_default_dequeue*/
2130 NULL, /*__tbm_queue_default_acquire*/
2131 NULL, /*__tbm_queue_default_need_detach*/
2135 tbm_surface_queue_create(int queue_size, int width,
2136 int height, int format, int flags)
2138 _tbm_surf_queue_mutex_lock();
2139 _tbm_set_last_result(TBM_ERROR_NONE);
2141 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2142 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2143 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2144 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2146 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2147 sizeof(struct _tbm_surface_queue));
2148 if (!surface_queue) {
2149 TBM_ERR("cannot allocate the surface_queue.\n");
2150 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2151 _tbm_surf_queue_mutex_unlock();
2155 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2157 _tbm_surface_queue_init(surface_queue,
2159 width, height, format, flags,
2160 &tbm_queue_default_impl, NULL);
2162 _tbm_surf_queue_mutex_unlock();
2164 return surface_queue;
2169 } tbm_queue_sequence;
2172 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2174 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2176 _queue_init(&data->dequeue_list);
2180 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2182 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2184 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2187 _queue_init(&data->dequeue_list);
2191 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2193 free(surface_queue->impl_data);
2197 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2200 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2201 queue_node *first = NULL;
2203 first = container_of(data->dequeue_list.head.next, first, item_link);
2204 if (first != node) {
2208 node->priv_flags = 0;
2210 _queue_node_pop(&data->dequeue_list, node);
2211 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2215 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2218 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2220 if (node->priv_flags) {
2221 node->priv_flags = 0;
2222 _queue_node_pop(&data->dequeue_list, node);
2225 _tbm_surface_queue_release(surface_queue, node, 1);
2229 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2232 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2235 node = _tbm_surface_queue_dequeue(surface_queue);
2237 _queue_node_push_back(&data->dequeue_list, node);
2238 node->priv_flags = 1;
2244 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2245 __tbm_queue_sequence_init,
2246 __tbm_queue_sequence_reset,
2247 __tbm_queue_sequence_destroy,
2249 __tbm_queue_sequence_enqueue,
2250 __tbm_queue_sequence_release,
2251 __tbm_queue_sequence_dequeue,
2252 NULL, /*__tbm_queue_sequence_acquire*/
2253 NULL, /*__tbm_queue_sequence_need_dettach*/
2257 tbm_surface_queue_sequence_create(int queue_size, int width,
2258 int height, int format, int flags)
2260 _tbm_surf_queue_mutex_lock();
2261 _tbm_set_last_result(TBM_ERROR_NONE);
2263 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2264 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2265 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2266 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2268 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2269 sizeof(struct _tbm_surface_queue));
2270 if (surface_queue == NULL) {
2271 TBM_ERR("cannot allocate the surface_queue.\n");
2272 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2273 _tbm_surf_queue_mutex_unlock();
2277 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2279 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2280 sizeof(tbm_queue_sequence));
2282 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2283 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2284 free(surface_queue);
2285 _tbm_surf_queue_mutex_unlock();
2289 _tbm_surface_queue_init(surface_queue,
2291 width, height, format, flags,
2292 &tbm_queue_sequence_impl, data);
2294 _tbm_surf_queue_mutex_unlock();
2296 return surface_queue;
2299 tbm_surface_queue_error_e
2300 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2303 _tbm_surf_queue_mutex_lock();
2304 _tbm_set_last_result(TBM_ERROR_NONE);
2306 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2307 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2309 pthread_mutex_lock(&surface_queue->lock);
2311 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2312 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2314 surface_queue->modes |= modes;
2316 pthread_mutex_unlock(&surface_queue->lock);
2318 _tbm_surf_queue_mutex_unlock();
2320 return TBM_SURFACE_QUEUE_ERROR_NONE;
2323 tbm_surface_queue_error_e
2324 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2325 unsigned int sync_count)
2327 int dequeue_num, enqueue_num;
2329 _tbm_surf_queue_mutex_lock();
2330 _tbm_set_last_result(TBM_ERROR_NONE);
2332 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2333 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2335 pthread_mutex_lock(&surface_queue->lock);
2337 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2338 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2340 if (dequeue_num + sync_count == 0)
2341 surface_queue->acquire_sync_count = enqueue_num;
2343 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2345 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2346 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2348 pthread_mutex_unlock(&surface_queue->lock);
2350 _tbm_surf_queue_mutex_unlock();
2352 return TBM_SURFACE_QUEUE_ERROR_NONE;