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;
1928 int is_guarantee_cycle = 0;
1930 _tbm_surf_queue_mutex_lock();
1931 _tbm_set_last_result(TBM_ERROR_NONE);
1933 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1934 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1936 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1938 if (surface_queue->num_attached == 0) {
1939 _tbm_surf_queue_mutex_unlock();
1940 return TBM_SURFACE_QUEUE_ERROR_NONE;
1943 pthread_mutex_lock(&surface_queue->lock);
1945 /* Destory surface in free_queue */
1946 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1947 if (surface_queue->impl && surface_queue->impl->need_detach)
1948 surface_queue->impl->need_detach(surface_queue, node);
1950 _tbm_surface_queue_detach(surface_queue, node->surface);
1954 _queue_init(&surface_queue->free_queue);
1956 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
1957 is_guarantee_cycle = 1;
1959 pthread_mutex_unlock(&surface_queue->lock);
1960 _tbm_surf_queue_mutex_unlock();
1962 if (is_guarantee_cycle)
1963 _notify_emit(surface_queue, &surface_queue->reset_noti);
1965 return TBM_SURFACE_QUEUE_ERROR_NONE;
1968 tbm_surface_queue_error_e
1969 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1971 queue_node *node = NULL, *tmp;
1973 _tbm_surf_queue_mutex_lock();
1974 _tbm_set_last_result(TBM_ERROR_NONE);
1976 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1977 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1979 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1981 if (surface_queue->num_attached == 0) {
1982 _tbm_surf_queue_mutex_unlock();
1983 return TBM_SURFACE_QUEUE_ERROR_NONE;
1986 pthread_mutex_lock(&surface_queue->lock);
1988 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1989 /* Destory surface and Push to free_queue */
1990 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1991 _queue_delete_node(surface_queue, node);
1993 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1994 node->delete_pending = 1;
1996 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1997 _queue_delete_node(surface_queue, node);
1999 _queue_init(&surface_queue->dirty_queue);
2000 LIST_INITHEAD(&surface_queue->list);
2004 _queue_init(&surface_queue->free_queue);
2006 surface_queue->num_attached = 0;
2008 if (surface_queue->impl && surface_queue->impl->reset)
2009 surface_queue->impl->reset(surface_queue);
2011 pthread_mutex_unlock(&surface_queue->lock);
2012 pthread_cond_signal(&surface_queue->free_cond);
2014 _tbm_surf_queue_mutex_unlock();
2016 _notify_emit(surface_queue, &surface_queue->reset_noti);
2018 return TBM_SURFACE_QUEUE_ERROR_NONE;
2021 tbm_surface_queue_error_e
2022 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
2023 tbm_surface_h *surfaces, int *num)
2025 queue_node *node = NULL;
2027 _tbm_surf_queue_mutex_lock();
2028 _tbm_set_last_result(TBM_ERROR_NONE);
2030 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2031 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2032 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2033 TBM_ERROR_INVALID_PARAMETER);
2037 pthread_mutex_lock(&surface_queue->lock);
2039 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2040 if (node->delete_pending) continue;
2043 surfaces[*num] = node->surface;
2048 pthread_mutex_unlock(&surface_queue->lock);
2050 _tbm_surf_queue_mutex_unlock();
2052 return TBM_SURFACE_QUEUE_ERROR_NONE;
2055 tbm_surface_queue_error_e
2056 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2057 tbm_surface_h *surfaces, int *num)
2059 queue_node *node = NULL;
2061 _tbm_surf_queue_mutex_lock();
2065 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2066 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2067 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2068 TBM_ERROR_INVALID_PARAMETER);
2070 pthread_mutex_lock(&surface_queue->lock);
2072 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2074 surfaces[*num] = node->surface;
2079 pthread_mutex_unlock(&surface_queue->lock);
2081 _tbm_surf_queue_mutex_unlock();
2083 return TBM_SURFACE_QUEUE_ERROR_NONE;
2086 tbm_surface_queue_error_e
2087 tbm_surface_queue_get_trace_surface_num(
2088 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2090 _tbm_surf_queue_mutex_lock();
2091 _tbm_set_last_result(TBM_ERROR_NONE);
2093 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2094 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2095 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2096 TBM_ERROR_INVALID_PARAMETER);
2100 pthread_mutex_lock(&surface_queue->lock);
2103 case TBM_SURFACE_QUEUE_TRACE_NONE:
2106 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2107 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2109 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2110 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2112 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2113 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2115 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2116 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2122 pthread_mutex_unlock(&surface_queue->lock);
2124 _tbm_surf_queue_mutex_unlock();
2126 return TBM_SURFACE_QUEUE_ERROR_NONE;
2129 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2130 NULL, /*__tbm_queue_default_init*/
2131 NULL, /*__tbm_queue_default_reset*/
2132 NULL, /*__tbm_queue_default_destroy*/
2133 NULL, /*__tbm_queue_default_need_attach*/
2134 NULL, /*__tbm_queue_default_enqueue*/
2135 NULL, /*__tbm_queue_default_release*/
2136 NULL, /*__tbm_queue_default_dequeue*/
2137 NULL, /*__tbm_queue_default_acquire*/
2138 NULL, /*__tbm_queue_default_need_detach*/
2142 tbm_surface_queue_create(int queue_size, int width,
2143 int height, int format, int flags)
2145 _tbm_surf_queue_mutex_lock();
2146 _tbm_set_last_result(TBM_ERROR_NONE);
2148 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2149 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2150 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2151 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2153 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2154 sizeof(struct _tbm_surface_queue));
2155 if (!surface_queue) {
2156 TBM_ERR("cannot allocate the surface_queue.\n");
2157 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2158 _tbm_surf_queue_mutex_unlock();
2162 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2164 _tbm_surface_queue_init(surface_queue,
2166 width, height, format, flags,
2167 &tbm_queue_default_impl, NULL);
2169 _tbm_surf_queue_mutex_unlock();
2171 return surface_queue;
2176 } tbm_queue_sequence;
2179 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2181 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2183 _queue_init(&data->dequeue_list);
2187 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2189 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2191 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2194 _queue_init(&data->dequeue_list);
2198 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2200 free(surface_queue->impl_data);
2204 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2207 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2208 queue_node *first = NULL;
2210 first = container_of(data->dequeue_list.head.next, first, item_link);
2211 if (first != node) {
2215 node->priv_flags = 0;
2217 _queue_node_pop(&data->dequeue_list, node);
2218 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2222 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2225 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2227 if (node->priv_flags) {
2228 node->priv_flags = 0;
2229 _queue_node_pop(&data->dequeue_list, node);
2232 _tbm_surface_queue_release(surface_queue, node, 1);
2236 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2239 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2242 node = _tbm_surface_queue_dequeue(surface_queue);
2244 _queue_node_push_back(&data->dequeue_list, node);
2245 node->priv_flags = 1;
2251 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2252 __tbm_queue_sequence_init,
2253 __tbm_queue_sequence_reset,
2254 __tbm_queue_sequence_destroy,
2256 __tbm_queue_sequence_enqueue,
2257 __tbm_queue_sequence_release,
2258 __tbm_queue_sequence_dequeue,
2259 NULL, /*__tbm_queue_sequence_acquire*/
2260 NULL, /*__tbm_queue_sequence_need_dettach*/
2264 tbm_surface_queue_sequence_create(int queue_size, int width,
2265 int height, int format, int flags)
2267 _tbm_surf_queue_mutex_lock();
2268 _tbm_set_last_result(TBM_ERROR_NONE);
2270 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2271 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2272 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2273 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2275 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2276 sizeof(struct _tbm_surface_queue));
2277 if (surface_queue == NULL) {
2278 TBM_ERR("cannot allocate the surface_queue.\n");
2279 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2280 _tbm_surf_queue_mutex_unlock();
2284 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2286 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2287 sizeof(tbm_queue_sequence));
2289 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2290 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2291 free(surface_queue);
2292 _tbm_surf_queue_mutex_unlock();
2296 _tbm_surface_queue_init(surface_queue,
2298 width, height, format, flags,
2299 &tbm_queue_sequence_impl, data);
2301 _tbm_surf_queue_mutex_unlock();
2303 return surface_queue;
2306 tbm_surface_queue_error_e
2307 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2310 _tbm_surf_queue_mutex_lock();
2311 _tbm_set_last_result(TBM_ERROR_NONE);
2313 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2314 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2316 pthread_mutex_lock(&surface_queue->lock);
2318 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2319 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2321 surface_queue->modes |= modes;
2323 pthread_mutex_unlock(&surface_queue->lock);
2325 _tbm_surf_queue_mutex_unlock();
2327 return TBM_SURFACE_QUEUE_ERROR_NONE;
2330 tbm_surface_queue_error_e
2331 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2332 unsigned int sync_count)
2334 int dequeue_num, enqueue_num;
2336 _tbm_surf_queue_mutex_lock();
2337 _tbm_set_last_result(TBM_ERROR_NONE);
2339 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2340 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2342 pthread_mutex_lock(&surface_queue->lock);
2344 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2345 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2347 if (dequeue_num + sync_count == 0)
2348 surface_queue->acquire_sync_count = enqueue_num;
2350 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2352 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2353 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2355 pthread_mutex_unlock(&surface_queue->lock);
2357 _tbm_surf_queue_mutex_unlock();
2359 return TBM_SURFACE_QUEUE_ERROR_NONE;