1 /**************************************************************************
5 Copyright 2014 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
34 #include "tbm_bufmgr_int.h"
42 static tbm_bufmgr g_surf_queue_bufmgr;
43 static pthread_mutex_t tbm_surf_queue_lock;
44 void _tbm_surface_queue_mutex_unlock(void);
47 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
49 TBM_ERR("'%s' failed.\n", #cond);\
50 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
51 _tbm_surf_queue_mutex_unlock();\
56 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
58 TBM_ERR("'%s' failed.\n", #cond);\
59 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
60 _tbm_surf_queue_mutex_unlock();\
65 typedef enum _queue_node_type {
67 QUEUE_NODE_TYPE_DEQUEUE,
68 QUEUE_NODE_TYPE_ENQUEUE,
69 QUEUE_NODE_TYPE_ACQUIRE,
70 QUEUE_NODE_TYPE_RELEASE
74 struct list_head head;
79 tbm_surface_h surface;
81 struct list_head item_link;
82 struct list_head link;
86 unsigned int priv_flags; /*for each queue*/
92 struct list_head link;
94 tbm_surface_queue_notify_cb cb;
99 struct list_head link;
101 tbm_surface_queue_trace_cb cb;
105 typedef struct _tbm_surface_queue_interface {
106 void (*init)(tbm_surface_queue_h queue);
107 void (*reset)(tbm_surface_queue_h queue);
108 void (*destroy)(tbm_surface_queue_h queue);
109 void (*need_attach)(tbm_surface_queue_h queue);
111 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
112 void (*release)(tbm_surface_queue_h queue, queue_node *node);
113 queue_node *(*dequeue)(tbm_surface_queue_h queue);
114 queue_node *(*acquire)(tbm_surface_queue_h queue);
115 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
116 } tbm_surface_queue_interface;
118 struct _tbm_surface_queue {
127 struct list_head list;
129 struct list_head destory_noti;
130 struct list_head dequeuable_noti;
131 struct list_head dequeue_noti;
132 struct list_head can_dequeue_noti;
133 struct list_head acquirable_noti;
134 struct list_head reset_noti;
135 struct list_head trace_noti;
137 pthread_mutex_t lock;
138 pthread_cond_t free_cond;
139 pthread_cond_t dirty_cond;
141 const tbm_surface_queue_interface *impl;
144 //For external buffer allocation
145 tbm_surface_alloc_cb alloc_cb;
146 tbm_surface_free_cb free_cb;
149 struct list_head item_link; /* link of surface queue */
152 unsigned int enqueue_sync_count;
153 unsigned int acquire_sync_count;
157 _tbm_surf_queue_mutex_init(void)
159 static bool tbm_surf_queue_mutex_init = false;
161 if (tbm_surf_queue_mutex_init)
164 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
165 TBM_ERR("fail: pthread_mutex_init\n");
169 tbm_surf_queue_mutex_init = true;
175 _tbm_surf_queue_mutex_lock(void)
177 if (!_tbm_surf_queue_mutex_init()) {
178 TBM_ERR("fail: _tbm_surf_queue_mutex_init\n");
182 pthread_mutex_lock(&tbm_surf_queue_lock);
186 _tbm_surf_queue_mutex_unlock(void)
188 pthread_mutex_unlock(&tbm_surf_queue_lock);
192 _init_tbm_surf_queue_bufmgr(void)
194 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
198 _deinit_tbm_surf_queue_bufmgr(void)
200 if (!g_surf_queue_bufmgr)
203 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
204 g_surf_queue_bufmgr = NULL;
208 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
210 tbm_surface_queue_h old_data = NULL;
212 if (surface_queue == NULL) {
213 TBM_ERR("error: surface_queue is NULL.\n");
217 if (g_surf_queue_bufmgr == NULL) {
218 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
222 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
223 TBM_ERR("error: surf_queue_list is empty\n");
227 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
229 if (old_data == surface_queue) {
230 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
235 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
241 _queue_node_create(void)
243 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
245 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
251 _queue_node_delete(queue_node *node)
253 LIST_DEL(&node->item_link);
254 LIST_DEL(&node->link);
259 _queue_is_empty(queue *queue)
261 if (LIST_IS_EMPTY(&queue->head))
268 _queue_node_push_back(queue *queue, queue_node *node)
270 LIST_ADDTAIL(&node->item_link, &queue->head);
275 _queue_node_push_front(queue *queue, queue_node *node)
277 LIST_ADD(&node->item_link, &queue->head);
282 _queue_node_pop_front(queue *queue)
286 if (!queue->head.next) return NULL;
287 if (!queue->count) return NULL;
289 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
291 LIST_DELINIT(&node->item_link);
298 _queue_node_pop(queue *queue, queue_node *node)
300 LIST_DELINIT(&node->item_link);
307 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
308 tbm_surface_h surface, int *out_type)
310 queue_node *node = NULL;
313 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
317 if (type & FREE_QUEUE) {
318 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
320 if (node->surface == surface) {
322 *out_type = FREE_QUEUE;
329 if (type & DIRTY_QUEUE) {
330 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
332 if (node->surface == surface) {
334 *out_type = DIRTY_QUEUE;
341 if (type & NODE_LIST) {
342 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
343 if (node->surface == surface) {
345 *out_type = NODE_LIST;
352 TBM_ERR("fail to get the queue_node.\n");
358 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
361 if (surface_queue->free_cb) {
362 surface_queue->free_cb(surface_queue,
363 surface_queue->alloc_cb_data,
367 tbm_surface_destroy(node->surface);
370 _queue_node_delete(node);
374 _queue_init(queue *queue)
376 LIST_INITHEAD(&queue->head);
382 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
385 TBM_RETURN_IF_FAIL(cb != NULL);
387 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
389 TBM_RETURN_IF_FAIL(item != NULL);
391 LIST_INITHEAD(&item->link);
395 LIST_ADDTAIL(&item->link, list);
399 _notify_remove(struct list_head *list,
400 tbm_surface_queue_notify_cb cb, void *data)
402 queue_notify *item = NULL, *tmp;
404 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
405 if (item->cb == cb && item->data == data) {
406 LIST_DEL(&item->link);
412 TBM_ERR("Cannot find notifiy\n");
416 _notify_remove_all(struct list_head *list)
418 queue_notify *item = NULL, *tmp;
420 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
421 LIST_DEL(&item->link);
427 _notify_emit(tbm_surface_queue_h surface_queue,
428 struct list_head *list)
430 queue_notify *item = NULL, *tmp;;
433 The item->cb is the outside function of the libtbm.
434 The tbm user may/can remove the item of the list,
435 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
437 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
438 item->cb(surface_queue, item->data);
442 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
445 TBM_RETURN_IF_FAIL(cb != NULL);
447 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
449 TBM_RETURN_IF_FAIL(item != NULL);
451 LIST_INITHEAD(&item->link);
455 LIST_ADDTAIL(&item->link, list);
459 _trace_remove(struct list_head *list,
460 tbm_surface_queue_trace_cb cb, void *data)
462 queue_trace *item = NULL, *tmp;
464 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
465 if (item->cb == cb && item->data == data) {
466 LIST_DEL(&item->link);
472 TBM_ERR("Cannot find notifiy\n");
476 _trace_remove_all(struct list_head *list)
478 queue_trace *item = NULL, *tmp;
480 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
481 LIST_DEL(&item->link);
487 _trace_emit(tbm_surface_queue_h surface_queue,
488 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
490 queue_trace *item = NULL, *tmp;;
493 The item->cb is the outside function of the libtbm.
494 The tbm user may/can remove the item of the list,
495 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
497 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
498 item->cb(surface_queue, surface, trace, item->data);
502 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
504 queue_node *node = NULL;
507 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
508 if (node->type == type)
516 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
517 tbm_surface_h surface)
521 node = _queue_node_create();
522 TBM_RETURN_IF_FAIL(node != NULL);
524 tbm_surface_internal_ref(surface);
525 node->surface = surface;
527 LIST_ADDTAIL(&node->link, &surface_queue->list);
528 surface_queue->num_attached++;
529 _queue_node_push_back(&surface_queue->free_queue, node);
533 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
534 tbm_surface_h surface)
539 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
541 _queue_delete_node(surface_queue, node);
542 surface_queue->num_attached--;
547 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
548 queue_node *node, int push_back)
551 _queue_node_push_back(&surface_queue->dirty_queue, node);
553 _queue_node_push_front(&surface_queue->dirty_queue, node);
557 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
561 node = _queue_node_pop_front(&surface_queue->free_queue);
567 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
571 if (_queue_is_empty(&surface_queue->dirty_queue))
574 node = _queue_node_pop_front(&surface_queue->dirty_queue);
580 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
581 queue_node *node, int push_back)
584 _queue_node_push_back(&surface_queue->free_queue, node);
586 _queue_node_push_front(&surface_queue->free_queue, node);
590 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
592 int width, int height, int format,
593 const tbm_surface_queue_interface *impl, void *data)
595 pthread_condattr_t free_attr, dirty_attr;
597 TBM_RETURN_IF_FAIL(surface_queue != NULL);
598 TBM_RETURN_IF_FAIL(impl != NULL);
600 if (!g_surf_queue_bufmgr)
601 _init_tbm_surf_queue_bufmgr();
603 pthread_mutex_init(&surface_queue->lock, NULL);
605 pthread_condattr_init(&free_attr);
606 pthread_condattr_setclock(&free_attr, CLOCK_MONOTONIC);
607 pthread_cond_init(&surface_queue->free_cond, &free_attr);
608 pthread_condattr_destroy(&free_attr);
610 pthread_condattr_init(&dirty_attr);
611 pthread_condattr_setclock(&dirty_attr, CLOCK_MONOTONIC);
612 pthread_cond_init(&surface_queue->dirty_cond, &dirty_attr);
613 pthread_condattr_destroy(&dirty_attr);
615 surface_queue->queue_size = queue_size;
616 surface_queue->width = width;
617 surface_queue->height = height;
618 surface_queue->format = format;
619 surface_queue->impl = impl;
620 surface_queue->impl_data = data;
621 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
623 _queue_init(&surface_queue->free_queue);
624 _queue_init(&surface_queue->dirty_queue);
625 LIST_INITHEAD(&surface_queue->list);
627 LIST_INITHEAD(&surface_queue->destory_noti);
628 LIST_INITHEAD(&surface_queue->dequeuable_noti);
629 LIST_INITHEAD(&surface_queue->dequeue_noti);
630 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
631 LIST_INITHEAD(&surface_queue->acquirable_noti);
632 LIST_INITHEAD(&surface_queue->reset_noti);
633 LIST_INITHEAD(&surface_queue->trace_noti);
635 if (surface_queue->impl && surface_queue->impl->init)
636 surface_queue->impl->init(surface_queue);
638 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
641 tbm_surface_queue_error_e
642 tbm_surface_queue_add_destroy_cb(
643 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
646 _tbm_surf_queue_mutex_lock();
647 _tbm_set_last_result(TBM_ERROR_NONE);
649 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
650 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
651 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
652 TBM_ERROR_INVALID_PARAMETER);
654 pthread_mutex_lock(&surface_queue->lock);
656 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
658 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
660 pthread_mutex_unlock(&surface_queue->lock);
662 _tbm_surf_queue_mutex_unlock();
664 return TBM_SURFACE_QUEUE_ERROR_NONE;
667 tbm_surface_queue_error_e
668 tbm_surface_queue_remove_destroy_cb(
669 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
672 _tbm_surf_queue_mutex_lock();
673 _tbm_set_last_result(TBM_ERROR_NONE);
675 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
676 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
678 pthread_mutex_lock(&surface_queue->lock);
680 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
682 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
684 pthread_mutex_unlock(&surface_queue->lock);
686 _tbm_surf_queue_mutex_unlock();
688 return TBM_SURFACE_QUEUE_ERROR_NONE;
691 tbm_surface_queue_error_e
692 tbm_surface_queue_add_dequeuable_cb(
693 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
696 _tbm_surf_queue_mutex_lock();
697 _tbm_set_last_result(TBM_ERROR_NONE);
699 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
700 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
701 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
702 TBM_ERROR_INVALID_PARAMETER);
704 pthread_mutex_lock(&surface_queue->lock);
706 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
708 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
710 pthread_mutex_unlock(&surface_queue->lock);
712 _tbm_surf_queue_mutex_unlock();
714 return TBM_SURFACE_QUEUE_ERROR_NONE;
717 tbm_surface_queue_error_e
718 tbm_surface_queue_remove_dequeuable_cb(
719 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
722 _tbm_surf_queue_mutex_lock();
723 _tbm_set_last_result(TBM_ERROR_NONE);
725 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
726 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
728 pthread_mutex_lock(&surface_queue->lock);
730 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
732 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
734 pthread_mutex_unlock(&surface_queue->lock);
736 _tbm_surf_queue_mutex_unlock();
738 return TBM_SURFACE_QUEUE_ERROR_NONE;
741 tbm_surface_queue_error_e
742 tbm_surface_queue_add_dequeue_cb(
743 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
746 _tbm_surf_queue_mutex_lock();
747 _tbm_set_last_result(TBM_ERROR_NONE);
749 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
750 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
751 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
752 TBM_ERROR_INVALID_PARAMETER);
754 pthread_mutex_lock(&surface_queue->lock);
756 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
758 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
760 pthread_mutex_unlock(&surface_queue->lock);
762 _tbm_surf_queue_mutex_unlock();
764 return TBM_SURFACE_QUEUE_ERROR_NONE;
767 tbm_surface_queue_error_e
768 tbm_surface_queue_remove_dequeue_cb(
769 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
772 _tbm_surf_queue_mutex_lock();
773 _tbm_set_last_result(TBM_ERROR_NONE);
775 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
776 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
778 pthread_mutex_lock(&surface_queue->lock);
780 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
782 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
784 pthread_mutex_unlock(&surface_queue->lock);
786 _tbm_surf_queue_mutex_unlock();
788 return TBM_SURFACE_QUEUE_ERROR_NONE;
791 tbm_surface_queue_error_e
792 tbm_surface_queue_add_can_dequeue_cb(
793 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
796 _tbm_surf_queue_mutex_lock();
797 _tbm_set_last_result(TBM_ERROR_NONE);
799 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
800 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
801 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
802 TBM_ERROR_INVALID_PARAMETER);
804 pthread_mutex_lock(&surface_queue->lock);
806 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
808 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
810 pthread_mutex_unlock(&surface_queue->lock);
812 _tbm_surf_queue_mutex_unlock();
814 return TBM_SURFACE_QUEUE_ERROR_NONE;
817 tbm_surface_queue_error_e
818 tbm_surface_queue_remove_can_dequeue_cb(
819 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
822 _tbm_surf_queue_mutex_lock();
823 _tbm_set_last_result(TBM_ERROR_NONE);
825 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
826 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
828 pthread_mutex_lock(&surface_queue->lock);
830 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
832 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
834 pthread_mutex_unlock(&surface_queue->lock);
836 _tbm_surf_queue_mutex_unlock();
838 return TBM_SURFACE_QUEUE_ERROR_NONE;
841 tbm_surface_queue_error_e
842 tbm_surface_queue_add_acquirable_cb(
843 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
846 _tbm_surf_queue_mutex_lock();
847 _tbm_set_last_result(TBM_ERROR_NONE);
849 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
850 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
851 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
852 TBM_ERROR_INVALID_PARAMETER);
854 pthread_mutex_lock(&surface_queue->lock);
856 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
858 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
860 pthread_mutex_unlock(&surface_queue->lock);
862 _tbm_surf_queue_mutex_unlock();
864 return TBM_SURFACE_QUEUE_ERROR_NONE;
867 tbm_surface_queue_error_e
868 tbm_surface_queue_remove_acquirable_cb(
869 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
872 _tbm_surf_queue_mutex_lock();
873 _tbm_set_last_result(TBM_ERROR_NONE);
875 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
876 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
878 pthread_mutex_lock(&surface_queue->lock);
880 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
882 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
884 pthread_mutex_unlock(&surface_queue->lock);
886 _tbm_surf_queue_mutex_unlock();
888 return TBM_SURFACE_QUEUE_ERROR_NONE;
891 tbm_surface_queue_error_e
892 tbm_surface_queue_add_trace_cb(
893 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
896 _tbm_surf_queue_mutex_lock();
897 _tbm_set_last_result(TBM_ERROR_NONE);
899 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
900 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
901 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
902 TBM_ERROR_INVALID_PARAMETER);
904 pthread_mutex_lock(&surface_queue->lock);
906 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
908 _trace_add(&surface_queue->trace_noti, trace_cb, data);
910 pthread_mutex_unlock(&surface_queue->lock);
912 _tbm_surf_queue_mutex_unlock();
914 return TBM_SURFACE_QUEUE_ERROR_NONE;
917 tbm_surface_queue_error_e
918 tbm_surface_queue_remove_trace_cb(
919 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
922 _tbm_surf_queue_mutex_lock();
923 _tbm_set_last_result(TBM_ERROR_NONE);
925 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
926 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
928 pthread_mutex_lock(&surface_queue->lock);
930 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
932 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
934 pthread_mutex_unlock(&surface_queue->lock);
936 _tbm_surf_queue_mutex_unlock();
938 return TBM_SURFACE_QUEUE_ERROR_NONE;
941 tbm_surface_queue_error_e
942 tbm_surface_queue_set_alloc_cb(
943 tbm_surface_queue_h surface_queue,
944 tbm_surface_alloc_cb alloc_cb,
945 tbm_surface_free_cb free_cb,
948 _tbm_surf_queue_mutex_lock();
949 _tbm_set_last_result(TBM_ERROR_NONE);
951 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
952 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
954 pthread_mutex_lock(&surface_queue->lock);
956 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
958 surface_queue->alloc_cb = alloc_cb;
959 surface_queue->free_cb = free_cb;
960 surface_queue->alloc_cb_data = data;
962 pthread_mutex_unlock(&surface_queue->lock);
964 _tbm_surf_queue_mutex_unlock();
966 return TBM_SURFACE_QUEUE_ERROR_NONE;
970 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
974 _tbm_surf_queue_mutex_lock();
975 _tbm_set_last_result(TBM_ERROR_NONE);
977 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
979 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
981 width = surface_queue->width;
983 _tbm_surf_queue_mutex_unlock();
989 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
993 _tbm_surf_queue_mutex_lock();
994 _tbm_set_last_result(TBM_ERROR_NONE);
996 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
998 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1000 height = surface_queue->height;
1002 _tbm_surf_queue_mutex_unlock();
1008 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1012 _tbm_surf_queue_mutex_lock();
1013 _tbm_set_last_result(TBM_ERROR_NONE);
1015 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1017 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1019 format = surface_queue->format;
1021 _tbm_surf_queue_mutex_unlock();
1027 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1031 _tbm_surf_queue_mutex_lock();
1032 _tbm_set_last_result(TBM_ERROR_NONE);
1034 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1036 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1038 queue_size = surface_queue->queue_size;
1040 _tbm_surf_queue_mutex_unlock();
1045 tbm_surface_queue_error_e
1046 tbm_surface_queue_add_reset_cb(
1047 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1050 _tbm_surf_queue_mutex_lock();
1051 _tbm_set_last_result(TBM_ERROR_NONE);
1053 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1054 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1055 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1056 TBM_ERROR_INVALID_PARAMETER);
1058 pthread_mutex_lock(&surface_queue->lock);
1060 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1062 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1064 pthread_mutex_unlock(&surface_queue->lock);
1066 _tbm_surf_queue_mutex_unlock();
1068 return TBM_SURFACE_QUEUE_ERROR_NONE;
1071 tbm_surface_queue_error_e
1072 tbm_surface_queue_remove_reset_cb(
1073 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1076 _tbm_surf_queue_mutex_lock();
1077 _tbm_set_last_result(TBM_ERROR_NONE);
1079 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1080 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1082 pthread_mutex_lock(&surface_queue->lock);
1084 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1086 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1088 pthread_mutex_unlock(&surface_queue->lock);
1090 _tbm_surf_queue_mutex_unlock();
1092 return TBM_SURFACE_QUEUE_ERROR_NONE;
1095 tbm_surface_queue_error_e
1096 tbm_surface_queue_enqueue(tbm_surface_queue_h
1097 surface_queue, tbm_surface_h surface)
1102 _tbm_surf_queue_mutex_lock();
1103 _tbm_set_last_result(TBM_ERROR_NONE);
1105 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1106 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1107 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1108 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1111 tbm_surface_internal_dump_buffer(surface, "enqueue");
1113 pthread_mutex_lock(&surface_queue->lock);
1115 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1117 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1118 if (node == NULL || queue_type != NODE_LIST) {
1119 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1121 pthread_mutex_unlock(&surface_queue->lock);
1123 _tbm_surf_queue_mutex_unlock();
1126 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1127 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1129 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1130 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1134 if (surface_queue->impl && surface_queue->impl->enqueue)
1135 surface_queue->impl->enqueue(surface_queue, node);
1137 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1139 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1140 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1141 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1142 pthread_mutex_unlock(&surface_queue->lock);
1144 _tbm_surf_queue_mutex_unlock();
1145 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1148 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1150 if (surface_queue->enqueue_sync_count == 1) {
1151 tbm_surface_info_s info;
1154 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1155 if (ret == TBM_SURFACE_ERROR_NONE)
1156 tbm_surface_unmap(surface);
1159 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1161 pthread_mutex_unlock(&surface_queue->lock);
1162 pthread_cond_signal(&surface_queue->dirty_cond);
1164 _tbm_surf_queue_mutex_unlock();
1166 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1168 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1170 return TBM_SURFACE_QUEUE_ERROR_NONE;
1173 tbm_surface_queue_error_e
1174 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1175 surface_queue, tbm_surface_h surface)
1180 _tbm_surf_queue_mutex_lock();
1181 _tbm_set_last_result(TBM_ERROR_NONE);
1183 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1184 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1185 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1186 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1188 pthread_mutex_lock(&surface_queue->lock);
1190 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1192 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1193 if (node == NULL || queue_type != NODE_LIST) {
1194 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1196 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1197 pthread_mutex_unlock(&surface_queue->lock);
1199 _tbm_surf_queue_mutex_unlock();
1200 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1203 if (node->delete_pending) {
1204 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1206 _queue_delete_node(surface_queue, node);
1208 pthread_mutex_unlock(&surface_queue->lock);
1210 _tbm_surf_queue_mutex_unlock();
1212 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1214 return TBM_SURFACE_QUEUE_ERROR_NONE;
1217 if (surface_queue->queue_size < surface_queue->num_attached) {
1218 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1220 if (surface_queue->impl && surface_queue->impl->need_detach)
1221 surface_queue->impl->need_detach(surface_queue, node);
1223 _tbm_surface_queue_detach(surface_queue, surface);
1225 pthread_mutex_unlock(&surface_queue->lock);
1227 _tbm_surf_queue_mutex_unlock();
1229 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1231 return TBM_SURFACE_QUEUE_ERROR_NONE;
1234 if (surface_queue->impl && surface_queue->impl->release)
1235 surface_queue->impl->release(surface_queue, node);
1237 _tbm_surface_queue_release(surface_queue, node, 1);
1239 if (_queue_is_empty(&surface_queue->free_queue)) {
1240 TBM_ERR("surface_queue->free_queue is empty.\n");
1241 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1242 pthread_mutex_unlock(&surface_queue->lock);
1244 _tbm_surf_queue_mutex_unlock();
1245 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1248 node->type = QUEUE_NODE_TYPE_RELEASE;
1250 pthread_mutex_unlock(&surface_queue->lock);
1251 pthread_cond_signal(&surface_queue->free_cond);
1253 _tbm_surf_queue_mutex_unlock();
1255 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1257 return TBM_SURFACE_QUEUE_ERROR_NONE;
1260 tbm_surface_queue_error_e
1261 tbm_surface_queue_dequeue(tbm_surface_queue_h
1262 surface_queue, tbm_surface_h *surface)
1266 _tbm_surf_queue_mutex_lock();
1267 _tbm_set_last_result(TBM_ERROR_NONE);
1269 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1270 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1271 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1272 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1276 pthread_mutex_lock(&surface_queue->lock);
1278 if (_queue_is_empty(&surface_queue->free_queue)) {
1279 if (surface_queue->impl && surface_queue->impl->need_attach)
1280 surface_queue->impl->need_attach(surface_queue);
1283 if (surface_queue->impl && surface_queue->impl->dequeue)
1284 node = surface_queue->impl->dequeue(surface_queue);
1286 node = _tbm_surface_queue_dequeue(surface_queue);
1288 if (node == NULL || node->surface == NULL) {
1289 TBM_ERR("_queue_node_pop_front failed\n");
1290 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1291 pthread_mutex_unlock(&surface_queue->lock);
1293 _tbm_surf_queue_mutex_unlock();
1294 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1297 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1298 *surface = node->surface;
1300 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1302 pthread_mutex_unlock(&surface_queue->lock);
1304 _tbm_surf_queue_mutex_unlock();
1306 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1308 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1310 return TBM_SURFACE_QUEUE_ERROR_NONE;
1313 tbm_surface_queue_error_e
1314 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1319 _tbm_surf_queue_mutex_lock();
1320 _tbm_set_last_result(TBM_ERROR_NONE);
1322 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1323 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1325 _tbm_surf_queue_mutex_unlock();
1327 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1329 _tbm_surf_queue_mutex_lock();
1331 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1332 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1334 pthread_mutex_lock(&surface_queue->lock);
1336 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1338 if (_queue_is_empty(&surface_queue->free_queue)) {
1339 if (surface_queue->impl && surface_queue->impl->need_attach)
1340 surface_queue->impl->need_attach(surface_queue);
1343 if (!_queue_is_empty(&surface_queue->free_queue)) {
1344 pthread_mutex_unlock(&surface_queue->lock);
1345 _tbm_surf_queue_mutex_unlock();
1346 return TBM_SURFACE_QUEUE_ERROR_NONE;
1349 _tbm_surf_queue_mutex_unlock();
1352 clock_gettime(CLOCK_MONOTONIC, &tp);
1354 if (ms_timeout > 1000)
1355 tp.tv_sec += ms_timeout / 1000;
1357 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1359 if (tp.tv_nsec > 1000000000L) {
1361 tp.tv_nsec -= 1000000000L;
1364 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1366 if (ret == ETIMEDOUT) {
1367 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1368 pthread_mutex_unlock(&surface_queue->lock);
1369 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1371 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1374 pthread_mutex_unlock(&surface_queue->lock);
1375 return TBM_SURFACE_QUEUE_ERROR_NONE;
1381 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1383 _tbm_surf_queue_mutex_lock();
1384 _tbm_set_last_result(TBM_ERROR_NONE);
1386 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1388 _tbm_surf_queue_mutex_unlock();
1390 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1392 _tbm_surf_queue_mutex_lock();
1394 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1396 pthread_mutex_lock(&surface_queue->lock);
1398 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1400 if (_queue_is_empty(&surface_queue->free_queue)) {
1401 if (surface_queue->impl && surface_queue->impl->need_attach)
1402 surface_queue->impl->need_attach(surface_queue);
1405 if (!_queue_is_empty(&surface_queue->free_queue)) {
1406 pthread_mutex_unlock(&surface_queue->lock);
1407 _tbm_surf_queue_mutex_unlock();
1412 _tbm_surf_queue_mutex_unlock();
1413 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1414 pthread_mutex_unlock(&surface_queue->lock);
1418 pthread_mutex_unlock(&surface_queue->lock);
1419 _tbm_surf_queue_mutex_unlock();
1423 tbm_surface_queue_error_e
1424 tbm_surface_queue_release(tbm_surface_queue_h
1425 surface_queue, tbm_surface_h surface)
1430 _tbm_surf_queue_mutex_lock();
1431 _tbm_set_last_result(TBM_ERROR_NONE);
1433 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1434 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1435 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1436 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1438 pthread_mutex_lock(&surface_queue->lock);
1440 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1442 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1443 if (node == NULL || queue_type != NODE_LIST) {
1444 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1446 pthread_mutex_unlock(&surface_queue->lock);
1448 _tbm_surf_queue_mutex_unlock();
1451 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1452 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1454 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1455 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1459 if (node->delete_pending) {
1460 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1462 _queue_delete_node(surface_queue, node);
1464 pthread_mutex_unlock(&surface_queue->lock);
1466 _tbm_surf_queue_mutex_unlock();
1468 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1470 return TBM_SURFACE_QUEUE_ERROR_NONE;
1473 if (surface_queue->queue_size < surface_queue->num_attached) {
1474 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1476 if (surface_queue->impl && surface_queue->impl->need_detach)
1477 surface_queue->impl->need_detach(surface_queue, node);
1479 _tbm_surface_queue_detach(surface_queue, surface);
1481 pthread_mutex_unlock(&surface_queue->lock);
1483 _tbm_surf_queue_mutex_unlock();
1485 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1487 return TBM_SURFACE_QUEUE_ERROR_NONE;
1490 if (surface_queue->impl && surface_queue->impl->release)
1491 surface_queue->impl->release(surface_queue, node);
1493 _tbm_surface_queue_release(surface_queue, node, 1);
1495 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1496 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1497 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1498 pthread_mutex_unlock(&surface_queue->lock);
1500 _tbm_surf_queue_mutex_unlock();
1501 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1504 node->type = QUEUE_NODE_TYPE_RELEASE;
1506 pthread_mutex_unlock(&surface_queue->lock);
1507 pthread_cond_signal(&surface_queue->free_cond);
1509 _tbm_surf_queue_mutex_unlock();
1511 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1513 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1515 return TBM_SURFACE_QUEUE_ERROR_NONE;
1518 tbm_surface_queue_error_e
1519 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1520 surface_queue, tbm_surface_h surface)
1525 _tbm_surf_queue_mutex_lock();
1526 _tbm_set_last_result(TBM_ERROR_NONE);
1528 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1529 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1530 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1531 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1533 pthread_mutex_lock(&surface_queue->lock);
1535 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1537 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1538 if (node == NULL || queue_type != NODE_LIST) {
1539 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1541 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1542 pthread_mutex_unlock(&surface_queue->lock);
1544 _tbm_surf_queue_mutex_unlock();
1545 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1548 if (surface_queue->impl && surface_queue->impl->enqueue)
1549 surface_queue->impl->enqueue(surface_queue, node);
1551 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1553 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1554 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1555 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1556 pthread_mutex_unlock(&surface_queue->lock);
1558 _tbm_surf_queue_mutex_unlock();
1559 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1562 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1564 pthread_mutex_unlock(&surface_queue->lock);
1565 pthread_cond_signal(&surface_queue->dirty_cond);
1567 _tbm_surf_queue_mutex_unlock();
1569 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1571 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1573 return TBM_SURFACE_QUEUE_ERROR_NONE;
1576 tbm_surface_queue_error_e
1577 tbm_surface_queue_acquire(tbm_surface_queue_h
1578 surface_queue, tbm_surface_h *surface)
1582 _tbm_surf_queue_mutex_lock();
1583 _tbm_set_last_result(TBM_ERROR_NONE);
1587 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1588 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1589 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1590 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1592 pthread_mutex_lock(&surface_queue->lock);
1594 if (surface_queue->impl && surface_queue->impl->acquire)
1595 node = surface_queue->impl->acquire(surface_queue);
1597 node = _tbm_surface_queue_acquire(surface_queue);
1599 if (node == NULL || node->surface == NULL) {
1600 TBM_ERR("_queue_node_pop_front failed\n");
1601 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1602 pthread_mutex_unlock(&surface_queue->lock);
1604 _tbm_surf_queue_mutex_unlock();
1605 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1608 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1610 *surface = node->surface;
1612 if (surface_queue->acquire_sync_count == 1) {
1613 tbm_surface_info_s info;
1616 TBM_ERR("start map surface:%p", *surface);
1617 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1618 TBM_ERR("end map surface:%p", *surface);
1619 if (ret == TBM_SURFACE_ERROR_NONE)
1620 tbm_surface_unmap(*surface);
1623 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1625 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1627 pthread_mutex_unlock(&surface_queue->lock);
1629 _tbm_surf_queue_mutex_unlock();
1632 tbm_surface_internal_dump_buffer(*surface, "acquire");
1634 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1636 return TBM_SURFACE_QUEUE_ERROR_NONE;
1640 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1642 _tbm_surf_queue_mutex_lock();
1643 _tbm_set_last_result(TBM_ERROR_NONE);
1645 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1647 pthread_mutex_lock(&surface_queue->lock);
1649 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1651 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1652 pthread_mutex_unlock(&surface_queue->lock);
1653 _tbm_surf_queue_mutex_unlock();
1657 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1658 QUEUE_NODE_TYPE_DEQUEUE)) {
1659 _tbm_surf_queue_mutex_unlock();
1660 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1661 pthread_mutex_unlock(&surface_queue->lock);
1665 pthread_mutex_unlock(&surface_queue->lock);
1666 _tbm_surf_queue_mutex_unlock();
1671 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1673 queue_node *node = NULL, *tmp;
1675 _tbm_surf_queue_mutex_lock();
1676 _tbm_set_last_result(TBM_ERROR_NONE);
1678 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1680 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1682 LIST_DEL(&surface_queue->item_link);
1684 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1685 _queue_delete_node(surface_queue, node);
1687 if (surface_queue->impl && surface_queue->impl->destroy)
1688 surface_queue->impl->destroy(surface_queue);
1690 _notify_emit(surface_queue, &surface_queue->destory_noti);
1692 _notify_remove_all(&surface_queue->destory_noti);
1693 _notify_remove_all(&surface_queue->dequeuable_noti);
1694 _notify_remove_all(&surface_queue->dequeue_noti);
1695 _notify_remove_all(&surface_queue->can_dequeue_noti);
1696 _notify_remove_all(&surface_queue->acquirable_noti);
1697 _notify_remove_all(&surface_queue->reset_noti);
1698 _trace_remove_all(&surface_queue->trace_noti);
1700 pthread_mutex_destroy(&surface_queue->lock);
1702 free(surface_queue);
1704 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1705 _deinit_tbm_surf_queue_bufmgr();
1707 _tbm_surf_queue_mutex_unlock();
1710 tbm_surface_queue_error_e
1711 tbm_surface_queue_reset(tbm_surface_queue_h
1712 surface_queue, int width, int height, int format)
1714 queue_node *node = NULL, *tmp;
1716 _tbm_surf_queue_mutex_lock();
1717 _tbm_set_last_result(TBM_ERROR_NONE);
1719 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1720 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1722 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1724 if (width == surface_queue->width && height == surface_queue->height &&
1725 format == surface_queue->format) {
1726 _tbm_surf_queue_mutex_unlock();
1727 return TBM_SURFACE_QUEUE_ERROR_NONE;
1730 pthread_mutex_lock(&surface_queue->lock);
1732 surface_queue->width = width;
1733 surface_queue->height = height;
1734 surface_queue->format = format;
1736 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1737 /* Destory surface and Push to free_queue */
1738 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1739 _queue_delete_node(surface_queue, node);
1741 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1742 node->delete_pending = 1;
1744 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1745 _queue_delete_node(surface_queue, node);
1747 _queue_init(&surface_queue->dirty_queue);
1748 LIST_INITHEAD(&surface_queue->list);
1752 _queue_init(&surface_queue->free_queue);
1754 surface_queue->num_attached = 0;
1756 if (surface_queue->impl && surface_queue->impl->reset)
1757 surface_queue->impl->reset(surface_queue);
1759 pthread_mutex_unlock(&surface_queue->lock);
1760 pthread_cond_signal(&surface_queue->free_cond);
1762 _tbm_surf_queue_mutex_unlock();
1764 _notify_emit(surface_queue, &surface_queue->reset_noti);
1766 return TBM_SURFACE_QUEUE_ERROR_NONE;
1769 tbm_surface_queue_error_e
1770 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1772 _tbm_surf_queue_mutex_lock();
1773 _tbm_set_last_result(TBM_ERROR_NONE);
1775 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1776 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1778 _tbm_surf_queue_mutex_unlock();
1780 _notify_emit(surface_queue, &surface_queue->reset_noti);
1782 return TBM_SURFACE_QUEUE_ERROR_NONE;
1785 tbm_surface_queue_error_e
1786 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1788 _tbm_surf_queue_mutex_lock();
1789 _tbm_set_last_result(TBM_ERROR_NONE);
1791 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1792 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1794 pthread_mutex_lock(&surface_queue->lock);
1795 pthread_mutex_unlock(&surface_queue->lock);
1796 pthread_cond_signal(&surface_queue->free_cond);
1798 _tbm_surf_queue_mutex_unlock();
1800 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1802 return TBM_SURFACE_QUEUE_ERROR_NONE;
1805 tbm_surface_queue_error_e
1806 tbm_surface_queue_set_size(tbm_surface_queue_h
1807 surface_queue, int queue_size, int flush)
1809 queue_node *node = NULL, *tmp;
1811 _tbm_surf_queue_mutex_lock();
1812 _tbm_set_last_result(TBM_ERROR_NONE);
1814 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1815 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1816 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1817 TBM_ERROR_INVALID_PARAMETER);
1819 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1821 if ((surface_queue->queue_size == queue_size) && !flush) {
1822 _tbm_surf_queue_mutex_unlock();
1823 return TBM_SURFACE_QUEUE_ERROR_NONE;
1826 pthread_mutex_lock(&surface_queue->lock);
1829 surface_queue->queue_size = queue_size;
1831 if (surface_queue->num_attached == 0) {
1832 pthread_mutex_unlock(&surface_queue->lock);
1833 _tbm_surf_queue_mutex_unlock();
1834 return TBM_SURFACE_QUEUE_ERROR_NONE;
1837 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1838 /* Destory surface and Push to free_queue */
1839 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1840 _queue_delete_node(surface_queue, node);
1842 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1843 node->delete_pending = 1;
1845 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1846 _queue_delete_node(surface_queue, node);
1848 _queue_init(&surface_queue->dirty_queue);
1849 LIST_INITHEAD(&surface_queue->list);
1853 _queue_init(&surface_queue->free_queue);
1855 surface_queue->num_attached = 0;
1857 if (surface_queue->impl && surface_queue->impl->reset)
1858 surface_queue->impl->reset(surface_queue);
1860 pthread_mutex_unlock(&surface_queue->lock);
1861 pthread_cond_signal(&surface_queue->free_cond);
1863 _tbm_surf_queue_mutex_unlock();
1865 _notify_emit(surface_queue, &surface_queue->reset_noti);
1867 return TBM_SURFACE_QUEUE_ERROR_NONE;
1869 if (surface_queue->queue_size > queue_size) {
1870 int need_del = surface_queue->queue_size - queue_size;
1872 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1873 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1875 if (surface_queue->impl && surface_queue->impl->need_detach)
1876 surface_queue->impl->need_detach(surface_queue, node);
1878 _tbm_surface_queue_detach(surface_queue, node->surface);
1886 surface_queue->queue_size = queue_size;
1888 pthread_mutex_unlock(&surface_queue->lock);
1890 _tbm_surf_queue_mutex_unlock();
1892 return TBM_SURFACE_QUEUE_ERROR_NONE;
1896 tbm_surface_queue_error_e
1897 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1899 queue_node *node = NULL;
1901 _tbm_surf_queue_mutex_lock();
1902 _tbm_set_last_result(TBM_ERROR_NONE);
1904 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1905 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1907 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1909 if (surface_queue->num_attached == 0) {
1910 _tbm_surf_queue_mutex_unlock();
1911 return TBM_SURFACE_QUEUE_ERROR_NONE;
1914 pthread_mutex_lock(&surface_queue->lock);
1916 /* Destory surface in free_queue */
1917 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1918 if (surface_queue->impl && surface_queue->impl->need_detach)
1919 surface_queue->impl->need_detach(surface_queue, node);
1921 _tbm_surface_queue_detach(surface_queue, node->surface);
1925 _queue_init(&surface_queue->free_queue);
1927 pthread_mutex_unlock(&surface_queue->lock);
1928 _tbm_surf_queue_mutex_unlock();
1930 return TBM_SURFACE_QUEUE_ERROR_NONE;
1933 tbm_surface_queue_error_e
1934 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1936 queue_node *node = NULL, *tmp;
1938 _tbm_surf_queue_mutex_lock();
1939 _tbm_set_last_result(TBM_ERROR_NONE);
1941 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1942 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1944 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1946 if (surface_queue->num_attached == 0) {
1947 _tbm_surf_queue_mutex_unlock();
1948 return TBM_SURFACE_QUEUE_ERROR_NONE;
1951 pthread_mutex_lock(&surface_queue->lock);
1953 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1954 /* Destory surface and Push to free_queue */
1955 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1956 _queue_delete_node(surface_queue, node);
1958 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1959 node->delete_pending = 1;
1961 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1962 _queue_delete_node(surface_queue, node);
1964 _queue_init(&surface_queue->dirty_queue);
1965 LIST_INITHEAD(&surface_queue->list);
1969 _queue_init(&surface_queue->free_queue);
1971 surface_queue->num_attached = 0;
1973 if (surface_queue->impl && surface_queue->impl->reset)
1974 surface_queue->impl->reset(surface_queue);
1976 pthread_mutex_unlock(&surface_queue->lock);
1977 pthread_cond_signal(&surface_queue->free_cond);
1979 _tbm_surf_queue_mutex_unlock();
1981 _notify_emit(surface_queue, &surface_queue->reset_noti);
1983 return TBM_SURFACE_QUEUE_ERROR_NONE;
1986 tbm_surface_queue_error_e
1987 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1988 tbm_surface_h *surfaces, int *num)
1990 queue_node *node = NULL;
1992 _tbm_surf_queue_mutex_lock();
1993 _tbm_set_last_result(TBM_ERROR_NONE);
1995 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1996 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1997 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1998 TBM_ERROR_INVALID_PARAMETER);
2002 pthread_mutex_lock(&surface_queue->lock);
2004 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2005 if (node->delete_pending) continue;
2008 surfaces[*num] = node->surface;
2013 pthread_mutex_unlock(&surface_queue->lock);
2015 _tbm_surf_queue_mutex_unlock();
2017 return TBM_SURFACE_QUEUE_ERROR_NONE;
2020 tbm_surface_queue_error_e
2021 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2022 tbm_surface_h *surfaces, int *num)
2024 queue_node *node = NULL;
2026 _tbm_surf_queue_mutex_lock();
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);
2035 pthread_mutex_lock(&surface_queue->lock);
2037 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2039 surfaces[*num] = node->surface;
2044 pthread_mutex_unlock(&surface_queue->lock);
2046 _tbm_surf_queue_mutex_unlock();
2048 return TBM_SURFACE_QUEUE_ERROR_NONE;
2051 tbm_surface_queue_error_e
2052 tbm_surface_queue_get_trace_surface_num(
2053 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2055 _tbm_surf_queue_mutex_lock();
2056 _tbm_set_last_result(TBM_ERROR_NONE);
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);
2065 pthread_mutex_lock(&surface_queue->lock);
2068 case TBM_SURFACE_QUEUE_TRACE_NONE:
2071 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2072 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2074 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2075 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2077 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2078 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2080 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2081 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2087 pthread_mutex_unlock(&surface_queue->lock);
2089 _tbm_surf_queue_mutex_unlock();
2091 return TBM_SURFACE_QUEUE_ERROR_NONE;
2096 } tbm_queue_default;
2099 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
2101 free(surface_queue->impl_data);
2105 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
2107 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
2108 tbm_surface_h surface;
2110 if (surface_queue->queue_size == surface_queue->num_attached)
2113 if (surface_queue->alloc_cb) {
2114 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2120 tbm_surface_internal_ref(surface);
2122 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2123 surface_queue->height,
2124 surface_queue->format,
2126 TBM_RETURN_IF_FAIL(surface != NULL);
2129 _tbm_surface_queue_attach(surface_queue, surface);
2130 tbm_surface_internal_unref(surface);
2133 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2134 NULL, /*__tbm_queue_default_init*/
2135 NULL, /*__tbm_queue_default_reset*/
2136 __tbm_queue_default_destroy,
2137 __tbm_queue_default_need_attach,
2138 NULL, /*__tbm_queue_default_enqueue*/
2139 NULL, /*__tbm_queue_default_release*/
2140 NULL, /*__tbm_queue_default_dequeue*/
2141 NULL, /*__tbm_queue_default_acquire*/
2142 NULL, /*__tbm_queue_default_need_detach*/
2146 tbm_surface_queue_create(int queue_size, int width,
2147 int height, int format, int flags)
2149 _tbm_surf_queue_mutex_lock();
2150 _tbm_set_last_result(TBM_ERROR_NONE);
2152 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2153 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2154 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2155 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2157 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2158 sizeof(struct _tbm_surface_queue));
2159 if (!surface_queue) {
2160 TBM_ERR("cannot allocate the surface_queue.\n");
2161 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2162 _tbm_surf_queue_mutex_unlock();
2166 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2168 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2169 sizeof(tbm_queue_default));
2171 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2172 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2173 free(surface_queue);
2174 _tbm_surf_queue_mutex_unlock();
2178 data->flags = flags;
2179 _tbm_surface_queue_init(surface_queue,
2181 width, height, format,
2182 &tbm_queue_default_impl, data);
2184 _tbm_surf_queue_mutex_unlock();
2186 return surface_queue;
2192 } tbm_queue_sequence;
2195 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2197 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2199 _queue_init(&data->dequeue_list);
2203 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2205 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2207 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2210 _queue_init(&data->dequeue_list);
2214 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2216 free(surface_queue->impl_data);
2220 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2222 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2223 tbm_surface_h surface;
2225 if (surface_queue->queue_size == surface_queue->num_attached)
2228 if (surface_queue->alloc_cb) {
2229 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2235 tbm_surface_internal_ref(surface);
2237 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2238 surface_queue->height,
2239 surface_queue->format,
2241 TBM_RETURN_IF_FAIL(surface != NULL);
2244 _tbm_surface_queue_attach(surface_queue, surface);
2245 tbm_surface_internal_unref(surface);
2249 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2252 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2253 queue_node *first = NULL;
2255 first = container_of(data->dequeue_list.head.next, first, item_link);
2256 if (first != node) {
2260 node->priv_flags = 0;
2262 _queue_node_pop(&data->dequeue_list, node);
2263 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2267 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2270 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2272 if (node->priv_flags) {
2273 node->priv_flags = 0;
2274 _queue_node_pop(&data->dequeue_list, node);
2277 _tbm_surface_queue_release(surface_queue, node, 1);
2281 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2284 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2287 node = _tbm_surface_queue_dequeue(surface_queue);
2289 _queue_node_push_back(&data->dequeue_list, node);
2290 node->priv_flags = 1;
2296 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2297 __tbm_queue_sequence_init,
2298 __tbm_queue_sequence_reset,
2299 __tbm_queue_sequence_destroy,
2300 __tbm_queue_sequence_need_attach,
2301 __tbm_queue_sequence_enqueue,
2302 __tbm_queue_sequence_release,
2303 __tbm_queue_sequence_dequeue,
2304 NULL, /*__tbm_queue_sequence_acquire*/
2305 NULL, /*__tbm_queue_sequence_need_dettach*/
2309 tbm_surface_queue_sequence_create(int queue_size, int width,
2310 int height, int format, int flags)
2312 _tbm_surf_queue_mutex_lock();
2313 _tbm_set_last_result(TBM_ERROR_NONE);
2315 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2316 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2317 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2318 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2320 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2321 sizeof(struct _tbm_surface_queue));
2322 if (surface_queue == NULL) {
2323 TBM_ERR("cannot allocate the surface_queue.\n");
2324 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2325 _tbm_surf_queue_mutex_unlock();
2329 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2331 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2332 sizeof(tbm_queue_sequence));
2334 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2335 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2336 free(surface_queue);
2337 _tbm_surf_queue_mutex_unlock();
2341 data->flags = flags;
2342 _tbm_surface_queue_init(surface_queue,
2344 width, height, format,
2345 &tbm_queue_sequence_impl, data);
2347 _tbm_surf_queue_mutex_unlock();
2349 return surface_queue;
2352 tbm_surface_queue_error_e
2353 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2356 _tbm_surf_queue_mutex_lock();
2357 _tbm_set_last_result(TBM_ERROR_NONE);
2359 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2360 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2362 pthread_mutex_lock(&surface_queue->lock);
2364 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2365 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2367 surface_queue->modes |= modes;
2369 pthread_mutex_unlock(&surface_queue->lock);
2371 _tbm_surf_queue_mutex_unlock();
2373 return TBM_SURFACE_QUEUE_ERROR_NONE;
2376 tbm_surface_queue_error_e
2377 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2378 unsigned int sync_count)
2380 int dequeue_num, enqueue_num;
2382 _tbm_surf_queue_mutex_lock();
2383 _tbm_set_last_result(TBM_ERROR_NONE);
2385 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2386 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2388 pthread_mutex_lock(&surface_queue->lock);
2390 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2391 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2393 if (dequeue_num + sync_count == 0)
2394 surface_queue->acquire_sync_count = enqueue_num;
2396 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2398 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2399 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2401 pthread_mutex_unlock(&surface_queue->lock);
2403 _tbm_surf_queue_mutex_unlock();
2405 return TBM_SURFACE_QUEUE_ERROR_NONE;