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 {
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_init(void)
160 static bool tbm_surf_queue_mutex_init = false;
162 if (tbm_surf_queue_mutex_init)
165 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
166 TBM_ERR("fail: pthread_mutex_init\n");
170 tbm_surf_queue_mutex_init = true;
176 _tbm_surf_queue_mutex_lock(void)
178 if (!_tbm_surf_queue_mutex_init()) {
179 TBM_ERR("fail: _tbm_surf_queue_mutex_init\n");
183 pthread_mutex_lock(&tbm_surf_queue_lock);
187 _tbm_surf_queue_mutex_unlock(void)
189 pthread_mutex_unlock(&tbm_surf_queue_lock);
193 _init_tbm_surf_queue_bufmgr(void)
195 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
199 _deinit_tbm_surf_queue_bufmgr(void)
201 if (!g_surf_queue_bufmgr)
204 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
205 g_surf_queue_bufmgr = NULL;
209 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
211 tbm_surface_queue_h old_data = NULL;
213 if (surface_queue == NULL) {
214 TBM_ERR("error: surface_queue is NULL.\n");
218 if (g_surf_queue_bufmgr == NULL) {
219 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
223 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
224 TBM_ERR("error: surf_queue_list is empty\n");
228 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
230 if (old_data == surface_queue)
234 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
240 _queue_node_create(void)
242 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
244 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
250 _queue_node_delete(queue_node *node)
252 LIST_DEL(&node->item_link);
253 LIST_DEL(&node->link);
258 _queue_is_empty(queue *queue)
260 if (LIST_IS_EMPTY(&queue->head))
267 _queue_node_push_back(queue *queue, queue_node *node)
269 LIST_ADDTAIL(&node->item_link, &queue->head);
274 _queue_node_push_front(queue *queue, queue_node *node)
276 LIST_ADD(&node->item_link, &queue->head);
281 _queue_node_pop_front(queue *queue)
285 if (!queue->head.next) return NULL;
286 if (!queue->count) return NULL;
288 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
290 LIST_DELINIT(&node->item_link);
297 _queue_node_pop(queue *queue, queue_node *node)
299 LIST_DELINIT(&node->item_link);
306 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
307 tbm_surface_h surface, int *out_type)
309 queue_node *node = NULL;
312 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
316 if (type & FREE_QUEUE) {
317 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
319 if (node->surface == surface) {
321 *out_type = FREE_QUEUE;
328 if (type & DIRTY_QUEUE) {
329 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
331 if (node->surface == surface) {
333 *out_type = DIRTY_QUEUE;
340 if (type & NODE_LIST) {
341 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
342 if (node->surface == surface) {
344 *out_type = NODE_LIST;
351 TBM_ERR("fail to get the queue_node.\n");
357 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
360 if (surface_queue->free_cb) {
361 surface_queue->free_cb(surface_queue,
362 surface_queue->alloc_cb_data,
366 tbm_surface_destroy(node->surface);
369 _queue_node_delete(node);
373 _queue_init(queue *queue)
375 LIST_INITHEAD(&queue->head);
381 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
384 TBM_RETURN_IF_FAIL(cb != NULL);
386 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
388 TBM_RETURN_IF_FAIL(item != NULL);
390 LIST_INITHEAD(&item->link);
394 LIST_ADDTAIL(&item->link, list);
398 _notify_remove(struct list_head *list,
399 tbm_surface_queue_notify_cb cb, void *data)
401 queue_notify *item = NULL, *tmp;
403 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
404 if (item->cb == cb && item->data == data) {
405 LIST_DEL(&item->link);
411 TBM_ERR("Cannot find notifiy\n");
415 _notify_remove_all(struct list_head *list)
417 queue_notify *item = NULL, *tmp;
419 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
420 LIST_DEL(&item->link);
426 _notify_emit(tbm_surface_queue_h surface_queue,
427 struct list_head *list)
429 queue_notify *item = NULL, *tmp;;
432 The item->cb is the outside function of the libtbm.
433 The tbm user may/can remove the item of the list,
434 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
436 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
437 item->cb(surface_queue, item->data);
441 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
444 TBM_RETURN_IF_FAIL(cb != NULL);
446 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
448 TBM_RETURN_IF_FAIL(item != NULL);
450 LIST_INITHEAD(&item->link);
454 LIST_ADDTAIL(&item->link, list);
458 _trace_remove(struct list_head *list,
459 tbm_surface_queue_trace_cb cb, void *data)
461 queue_trace *item = NULL, *tmp;
463 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
464 if (item->cb == cb && item->data == data) {
465 LIST_DEL(&item->link);
471 TBM_ERR("Cannot find notifiy\n");
475 _trace_remove_all(struct list_head *list)
477 queue_trace *item = NULL, *tmp;
479 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
480 LIST_DEL(&item->link);
486 _trace_emit(tbm_surface_queue_h surface_queue,
487 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
489 queue_trace *item = NULL, *tmp;;
492 The item->cb is the outside function of the libtbm.
493 The tbm user may/can remove the item of the list,
494 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
496 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
497 item->cb(surface_queue, surface, trace, item->data);
501 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
503 queue_node *node = NULL;
506 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
507 if (node->type == type)
515 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
516 tbm_surface_h surface)
520 node = _queue_node_create();
521 TBM_RETURN_IF_FAIL(node != NULL);
523 tbm_surface_internal_ref(surface);
524 node->surface = surface;
526 LIST_ADDTAIL(&node->link, &surface_queue->list);
527 surface_queue->num_attached++;
528 _queue_node_push_back(&surface_queue->free_queue, node);
532 _tbm_surface_queue_need_attach(tbm_surface_queue_h surface_queue)
534 tbm_surface_h surface;
536 if (surface_queue->queue_size == surface_queue->num_attached)
539 if (surface_queue->alloc_cb) {
540 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
546 tbm_surface_internal_ref(surface);
548 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
549 surface_queue->height,
550 surface_queue->format,
551 surface_queue->flags);
552 TBM_RETURN_IF_FAIL(surface != NULL);
555 _tbm_surface_queue_attach(surface_queue, surface);
556 tbm_surface_internal_unref(surface);
560 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
561 tbm_surface_h surface)
566 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
568 _queue_delete_node(surface_queue, node);
569 surface_queue->num_attached--;
574 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
575 queue_node *node, int push_back)
578 _queue_node_push_back(&surface_queue->dirty_queue, node);
580 _queue_node_push_front(&surface_queue->dirty_queue, node);
584 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
588 node = _queue_node_pop_front(&surface_queue->free_queue);
594 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
598 if (_queue_is_empty(&surface_queue->dirty_queue))
601 node = _queue_node_pop_front(&surface_queue->dirty_queue);
607 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
608 queue_node *node, int push_back)
611 _queue_node_push_back(&surface_queue->free_queue, node);
613 _queue_node_push_front(&surface_queue->free_queue, node);
617 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
619 int width, int height, int format, int flags,
620 const tbm_surface_queue_interface *impl, void *data)
622 pthread_condattr_t free_attr, dirty_attr;
624 TBM_RETURN_IF_FAIL(surface_queue != NULL);
625 TBM_RETURN_IF_FAIL(impl != NULL);
627 if (!g_surf_queue_bufmgr)
628 _init_tbm_surf_queue_bufmgr();
630 pthread_mutex_init(&surface_queue->lock, NULL);
632 pthread_condattr_init(&free_attr);
633 pthread_condattr_setclock(&free_attr, CLOCK_MONOTONIC);
634 pthread_cond_init(&surface_queue->free_cond, &free_attr);
635 pthread_condattr_destroy(&free_attr);
637 pthread_condattr_init(&dirty_attr);
638 pthread_condattr_setclock(&dirty_attr, CLOCK_MONOTONIC);
639 pthread_cond_init(&surface_queue->dirty_cond, &dirty_attr);
640 pthread_condattr_destroy(&dirty_attr);
642 surface_queue->queue_size = queue_size;
643 surface_queue->width = width;
644 surface_queue->height = height;
645 surface_queue->format = format;
646 surface_queue->flags = flags;
647 surface_queue->impl = impl;
648 surface_queue->impl_data = data;
649 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
651 _queue_init(&surface_queue->free_queue);
652 _queue_init(&surface_queue->dirty_queue);
653 LIST_INITHEAD(&surface_queue->list);
655 LIST_INITHEAD(&surface_queue->destory_noti);
656 LIST_INITHEAD(&surface_queue->dequeuable_noti);
657 LIST_INITHEAD(&surface_queue->dequeue_noti);
658 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
659 LIST_INITHEAD(&surface_queue->acquirable_noti);
660 LIST_INITHEAD(&surface_queue->reset_noti);
661 LIST_INITHEAD(&surface_queue->trace_noti);
663 if (surface_queue->impl && surface_queue->impl->init)
664 surface_queue->impl->init(surface_queue);
666 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
669 tbm_surface_queue_error_e
670 tbm_surface_queue_add_destroy_cb(
671 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
674 _tbm_surf_queue_mutex_lock();
675 _tbm_set_last_result(TBM_ERROR_NONE);
677 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
678 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
679 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
680 TBM_ERROR_INVALID_PARAMETER);
682 pthread_mutex_lock(&surface_queue->lock);
684 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
686 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
688 pthread_mutex_unlock(&surface_queue->lock);
690 _tbm_surf_queue_mutex_unlock();
692 return TBM_SURFACE_QUEUE_ERROR_NONE;
695 tbm_surface_queue_error_e
696 tbm_surface_queue_remove_destroy_cb(
697 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
700 _tbm_surf_queue_mutex_lock();
701 _tbm_set_last_result(TBM_ERROR_NONE);
703 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
704 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
706 pthread_mutex_lock(&surface_queue->lock);
708 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
710 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
712 pthread_mutex_unlock(&surface_queue->lock);
714 _tbm_surf_queue_mutex_unlock();
716 return TBM_SURFACE_QUEUE_ERROR_NONE;
719 tbm_surface_queue_error_e
720 tbm_surface_queue_add_dequeuable_cb(
721 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
724 _tbm_surf_queue_mutex_lock();
725 _tbm_set_last_result(TBM_ERROR_NONE);
727 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
728 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
729 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
730 TBM_ERROR_INVALID_PARAMETER);
732 pthread_mutex_lock(&surface_queue->lock);
734 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
736 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
738 pthread_mutex_unlock(&surface_queue->lock);
740 _tbm_surf_queue_mutex_unlock();
742 return TBM_SURFACE_QUEUE_ERROR_NONE;
745 tbm_surface_queue_error_e
746 tbm_surface_queue_remove_dequeuable_cb(
747 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
750 _tbm_surf_queue_mutex_lock();
751 _tbm_set_last_result(TBM_ERROR_NONE);
753 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
754 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
756 pthread_mutex_lock(&surface_queue->lock);
758 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
760 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
762 pthread_mutex_unlock(&surface_queue->lock);
764 _tbm_surf_queue_mutex_unlock();
766 return TBM_SURFACE_QUEUE_ERROR_NONE;
769 tbm_surface_queue_error_e
770 tbm_surface_queue_add_dequeue_cb(
771 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
774 _tbm_surf_queue_mutex_lock();
775 _tbm_set_last_result(TBM_ERROR_NONE);
777 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
778 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
779 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
780 TBM_ERROR_INVALID_PARAMETER);
782 pthread_mutex_lock(&surface_queue->lock);
784 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
786 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
788 pthread_mutex_unlock(&surface_queue->lock);
790 _tbm_surf_queue_mutex_unlock();
792 return TBM_SURFACE_QUEUE_ERROR_NONE;
795 tbm_surface_queue_error_e
796 tbm_surface_queue_remove_dequeue_cb(
797 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
800 _tbm_surf_queue_mutex_lock();
801 _tbm_set_last_result(TBM_ERROR_NONE);
803 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
804 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
806 pthread_mutex_lock(&surface_queue->lock);
808 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
810 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
812 pthread_mutex_unlock(&surface_queue->lock);
814 _tbm_surf_queue_mutex_unlock();
816 return TBM_SURFACE_QUEUE_ERROR_NONE;
819 tbm_surface_queue_error_e
820 tbm_surface_queue_add_can_dequeue_cb(
821 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
824 _tbm_surf_queue_mutex_lock();
825 _tbm_set_last_result(TBM_ERROR_NONE);
827 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
828 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
829 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
830 TBM_ERROR_INVALID_PARAMETER);
832 pthread_mutex_lock(&surface_queue->lock);
834 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
836 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
838 pthread_mutex_unlock(&surface_queue->lock);
840 _tbm_surf_queue_mutex_unlock();
842 return TBM_SURFACE_QUEUE_ERROR_NONE;
845 tbm_surface_queue_error_e
846 tbm_surface_queue_remove_can_dequeue_cb(
847 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
850 _tbm_surf_queue_mutex_lock();
851 _tbm_set_last_result(TBM_ERROR_NONE);
853 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
854 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
856 pthread_mutex_lock(&surface_queue->lock);
858 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
860 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
862 pthread_mutex_unlock(&surface_queue->lock);
864 _tbm_surf_queue_mutex_unlock();
866 return TBM_SURFACE_QUEUE_ERROR_NONE;
869 tbm_surface_queue_error_e
870 tbm_surface_queue_add_acquirable_cb(
871 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
874 _tbm_surf_queue_mutex_lock();
875 _tbm_set_last_result(TBM_ERROR_NONE);
877 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
878 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
879 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
880 TBM_ERROR_INVALID_PARAMETER);
882 pthread_mutex_lock(&surface_queue->lock);
884 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
886 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
888 pthread_mutex_unlock(&surface_queue->lock);
890 _tbm_surf_queue_mutex_unlock();
892 return TBM_SURFACE_QUEUE_ERROR_NONE;
895 tbm_surface_queue_error_e
896 tbm_surface_queue_remove_acquirable_cb(
897 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
900 _tbm_surf_queue_mutex_lock();
901 _tbm_set_last_result(TBM_ERROR_NONE);
903 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
904 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
906 pthread_mutex_lock(&surface_queue->lock);
908 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
910 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
912 pthread_mutex_unlock(&surface_queue->lock);
914 _tbm_surf_queue_mutex_unlock();
916 return TBM_SURFACE_QUEUE_ERROR_NONE;
919 tbm_surface_queue_error_e
920 tbm_surface_queue_add_trace_cb(
921 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
924 _tbm_surf_queue_mutex_lock();
925 _tbm_set_last_result(TBM_ERROR_NONE);
927 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
928 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
929 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
930 TBM_ERROR_INVALID_PARAMETER);
932 pthread_mutex_lock(&surface_queue->lock);
934 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
936 _trace_add(&surface_queue->trace_noti, trace_cb, data);
938 pthread_mutex_unlock(&surface_queue->lock);
940 _tbm_surf_queue_mutex_unlock();
942 return TBM_SURFACE_QUEUE_ERROR_NONE;
945 tbm_surface_queue_error_e
946 tbm_surface_queue_remove_trace_cb(
947 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
950 _tbm_surf_queue_mutex_lock();
951 _tbm_set_last_result(TBM_ERROR_NONE);
953 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
954 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
956 pthread_mutex_lock(&surface_queue->lock);
958 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
960 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
962 pthread_mutex_unlock(&surface_queue->lock);
964 _tbm_surf_queue_mutex_unlock();
966 return TBM_SURFACE_QUEUE_ERROR_NONE;
969 tbm_surface_queue_error_e
970 tbm_surface_queue_set_alloc_cb(
971 tbm_surface_queue_h surface_queue,
972 tbm_surface_alloc_cb alloc_cb,
973 tbm_surface_free_cb free_cb,
976 _tbm_surf_queue_mutex_lock();
977 _tbm_set_last_result(TBM_ERROR_NONE);
979 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
980 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
982 pthread_mutex_lock(&surface_queue->lock);
984 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
986 surface_queue->alloc_cb = alloc_cb;
987 surface_queue->free_cb = free_cb;
988 surface_queue->alloc_cb_data = data;
990 pthread_mutex_unlock(&surface_queue->lock);
992 _tbm_surf_queue_mutex_unlock();
994 return TBM_SURFACE_QUEUE_ERROR_NONE;
998 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
1002 _tbm_surf_queue_mutex_lock();
1003 _tbm_set_last_result(TBM_ERROR_NONE);
1005 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1007 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1009 width = surface_queue->width;
1011 _tbm_surf_queue_mutex_unlock();
1017 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
1021 _tbm_surf_queue_mutex_lock();
1022 _tbm_set_last_result(TBM_ERROR_NONE);
1024 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1026 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1028 height = surface_queue->height;
1030 _tbm_surf_queue_mutex_unlock();
1036 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1040 _tbm_surf_queue_mutex_lock();
1041 _tbm_set_last_result(TBM_ERROR_NONE);
1043 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1045 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1047 format = surface_queue->format;
1049 _tbm_surf_queue_mutex_unlock();
1055 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1059 _tbm_surf_queue_mutex_lock();
1060 _tbm_set_last_result(TBM_ERROR_NONE);
1062 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1064 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1066 queue_size = surface_queue->queue_size;
1068 _tbm_surf_queue_mutex_unlock();
1073 tbm_surface_queue_error_e
1074 tbm_surface_queue_add_reset_cb(
1075 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1078 _tbm_surf_queue_mutex_lock();
1079 _tbm_set_last_result(TBM_ERROR_NONE);
1081 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1082 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1083 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1084 TBM_ERROR_INVALID_PARAMETER);
1086 pthread_mutex_lock(&surface_queue->lock);
1088 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1090 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1092 pthread_mutex_unlock(&surface_queue->lock);
1094 _tbm_surf_queue_mutex_unlock();
1096 return TBM_SURFACE_QUEUE_ERROR_NONE;
1099 tbm_surface_queue_error_e
1100 tbm_surface_queue_remove_reset_cb(
1101 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1104 _tbm_surf_queue_mutex_lock();
1105 _tbm_set_last_result(TBM_ERROR_NONE);
1107 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1108 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1110 pthread_mutex_lock(&surface_queue->lock);
1112 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1114 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1116 pthread_mutex_unlock(&surface_queue->lock);
1118 _tbm_surf_queue_mutex_unlock();
1120 return TBM_SURFACE_QUEUE_ERROR_NONE;
1123 tbm_surface_queue_error_e
1124 tbm_surface_queue_enqueue(tbm_surface_queue_h
1125 surface_queue, tbm_surface_h surface)
1130 _tbm_surf_queue_mutex_lock();
1131 _tbm_set_last_result(TBM_ERROR_NONE);
1133 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1134 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1135 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1136 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1139 tbm_surface_internal_dump_buffer(surface, "enqueue");
1141 pthread_mutex_lock(&surface_queue->lock);
1143 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1145 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1146 if (node == NULL || queue_type != NODE_LIST) {
1147 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1149 pthread_mutex_unlock(&surface_queue->lock);
1151 _tbm_surf_queue_mutex_unlock();
1154 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1155 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1157 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1158 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1162 if (surface_queue->impl && surface_queue->impl->enqueue)
1163 surface_queue->impl->enqueue(surface_queue, node);
1165 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1167 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1168 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1169 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1170 pthread_mutex_unlock(&surface_queue->lock);
1172 _tbm_surf_queue_mutex_unlock();
1173 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1176 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1178 if (surface_queue->enqueue_sync_count == 1) {
1179 tbm_surface_info_s info;
1182 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1183 if (ret == TBM_SURFACE_ERROR_NONE)
1184 tbm_surface_unmap(surface);
1187 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1189 pthread_mutex_unlock(&surface_queue->lock);
1190 pthread_cond_signal(&surface_queue->dirty_cond);
1192 _tbm_surf_queue_mutex_unlock();
1194 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1196 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1198 return TBM_SURFACE_QUEUE_ERROR_NONE;
1201 tbm_surface_queue_error_e
1202 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1203 surface_queue, tbm_surface_h surface)
1208 _tbm_surf_queue_mutex_lock();
1209 _tbm_set_last_result(TBM_ERROR_NONE);
1211 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1212 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1213 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1214 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1216 pthread_mutex_lock(&surface_queue->lock);
1218 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1220 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1221 if (node == NULL || queue_type != NODE_LIST) {
1222 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1224 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1225 pthread_mutex_unlock(&surface_queue->lock);
1227 _tbm_surf_queue_mutex_unlock();
1228 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1231 if (node->delete_pending) {
1232 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1234 _queue_delete_node(surface_queue, node);
1236 pthread_mutex_unlock(&surface_queue->lock);
1238 _tbm_surf_queue_mutex_unlock();
1240 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1242 return TBM_SURFACE_QUEUE_ERROR_NONE;
1245 if (surface_queue->queue_size < surface_queue->num_attached) {
1246 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1248 if (surface_queue->impl && surface_queue->impl->need_detach)
1249 surface_queue->impl->need_detach(surface_queue, node);
1251 _tbm_surface_queue_detach(surface_queue, surface);
1253 pthread_mutex_unlock(&surface_queue->lock);
1255 _tbm_surf_queue_mutex_unlock();
1257 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1259 return TBM_SURFACE_QUEUE_ERROR_NONE;
1262 if (surface_queue->impl && surface_queue->impl->release)
1263 surface_queue->impl->release(surface_queue, node);
1265 _tbm_surface_queue_release(surface_queue, node, 1);
1267 if (_queue_is_empty(&surface_queue->free_queue)) {
1268 TBM_ERR("surface_queue->free_queue is empty.\n");
1269 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1270 pthread_mutex_unlock(&surface_queue->lock);
1272 _tbm_surf_queue_mutex_unlock();
1273 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1276 node->type = QUEUE_NODE_TYPE_RELEASE;
1278 pthread_mutex_unlock(&surface_queue->lock);
1279 pthread_cond_signal(&surface_queue->free_cond);
1281 _tbm_surf_queue_mutex_unlock();
1283 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1285 return TBM_SURFACE_QUEUE_ERROR_NONE;
1288 tbm_surface_queue_error_e
1289 tbm_surface_queue_dequeue(tbm_surface_queue_h
1290 surface_queue, tbm_surface_h *surface)
1294 _tbm_surf_queue_mutex_lock();
1295 _tbm_set_last_result(TBM_ERROR_NONE);
1297 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1298 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1299 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1300 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1304 pthread_mutex_lock(&surface_queue->lock);
1306 if (_queue_is_empty(&surface_queue->free_queue)) {
1307 if (surface_queue->impl && surface_queue->impl->need_attach)
1308 surface_queue->impl->need_attach(surface_queue);
1310 _tbm_surface_queue_need_attach(surface_queue);
1313 if (surface_queue->impl && surface_queue->impl->dequeue)
1314 node = surface_queue->impl->dequeue(surface_queue);
1316 node = _tbm_surface_queue_dequeue(surface_queue);
1318 if (node == NULL || node->surface == NULL) {
1319 TBM_ERR("_queue_node_pop_front failed\n");
1320 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1321 pthread_mutex_unlock(&surface_queue->lock);
1323 _tbm_surf_queue_mutex_unlock();
1324 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1327 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1328 *surface = node->surface;
1330 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1332 pthread_mutex_unlock(&surface_queue->lock);
1334 _tbm_surf_queue_mutex_unlock();
1336 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1338 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1340 return TBM_SURFACE_QUEUE_ERROR_NONE;
1343 tbm_surface_queue_error_e
1344 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1349 _tbm_surf_queue_mutex_lock();
1350 _tbm_set_last_result(TBM_ERROR_NONE);
1352 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1353 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1355 _tbm_surf_queue_mutex_unlock();
1357 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1359 _tbm_surf_queue_mutex_lock();
1361 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1362 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1364 pthread_mutex_lock(&surface_queue->lock);
1366 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1368 if (_queue_is_empty(&surface_queue->free_queue)) {
1369 if (surface_queue->impl && surface_queue->impl->need_attach)
1370 surface_queue->impl->need_attach(surface_queue);
1372 _tbm_surface_queue_need_attach(surface_queue);
1375 if (!_queue_is_empty(&surface_queue->free_queue)) {
1376 pthread_mutex_unlock(&surface_queue->lock);
1377 _tbm_surf_queue_mutex_unlock();
1378 return TBM_SURFACE_QUEUE_ERROR_NONE;
1381 _tbm_surf_queue_mutex_unlock();
1384 clock_gettime(CLOCK_MONOTONIC, &tp);
1386 if (ms_timeout > 1000)
1387 tp.tv_sec += ms_timeout / 1000;
1389 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1391 if (tp.tv_nsec > 1000000000L) {
1393 tp.tv_nsec -= 1000000000L;
1396 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1398 if (ret == ETIMEDOUT) {
1399 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1400 pthread_mutex_unlock(&surface_queue->lock);
1401 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1403 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1406 if (surface_queue->impl && surface_queue->impl->need_attach)
1407 surface_queue->impl->need_attach(surface_queue);
1409 _tbm_surface_queue_need_attach(surface_queue);
1411 if (!_queue_is_empty(&surface_queue->free_queue)) {
1412 pthread_mutex_unlock(&surface_queue->lock);
1413 return TBM_SURFACE_QUEUE_ERROR_NONE;
1420 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1422 _tbm_surf_queue_mutex_lock();
1423 _tbm_set_last_result(TBM_ERROR_NONE);
1425 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1427 _tbm_surf_queue_mutex_unlock();
1429 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1431 _tbm_surf_queue_mutex_lock();
1433 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1435 pthread_mutex_lock(&surface_queue->lock);
1437 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1439 if (_queue_is_empty(&surface_queue->free_queue)) {
1440 if (surface_queue->impl && surface_queue->impl->need_attach)
1441 surface_queue->impl->need_attach(surface_queue);
1443 _tbm_surface_queue_need_attach(surface_queue);
1446 if (!_queue_is_empty(&surface_queue->free_queue)) {
1447 pthread_mutex_unlock(&surface_queue->lock);
1448 _tbm_surf_queue_mutex_unlock();
1453 _tbm_surf_queue_mutex_unlock();
1455 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1457 if (surface_queue->impl && surface_queue->impl->need_attach)
1458 surface_queue->impl->need_attach(surface_queue);
1460 _tbm_surface_queue_need_attach(surface_queue);
1462 if (!_queue_is_empty(&surface_queue->free_queue)) {
1463 pthread_mutex_unlock(&surface_queue->lock);
1469 pthread_mutex_unlock(&surface_queue->lock);
1470 _tbm_surf_queue_mutex_unlock();
1474 tbm_surface_queue_error_e
1475 tbm_surface_queue_release(tbm_surface_queue_h
1476 surface_queue, tbm_surface_h surface)
1481 _tbm_surf_queue_mutex_lock();
1482 _tbm_set_last_result(TBM_ERROR_NONE);
1484 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1485 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1486 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1487 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1489 pthread_mutex_lock(&surface_queue->lock);
1491 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1493 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1494 if (node == NULL || queue_type != NODE_LIST) {
1495 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1497 pthread_mutex_unlock(&surface_queue->lock);
1499 _tbm_surf_queue_mutex_unlock();
1502 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1503 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1505 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1506 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1510 if (node->delete_pending) {
1511 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1513 _queue_delete_node(surface_queue, node);
1515 pthread_mutex_unlock(&surface_queue->lock);
1517 _tbm_surf_queue_mutex_unlock();
1519 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1521 return TBM_SURFACE_QUEUE_ERROR_NONE;
1524 if (surface_queue->queue_size < surface_queue->num_attached) {
1525 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1527 if (surface_queue->impl && surface_queue->impl->need_detach)
1528 surface_queue->impl->need_detach(surface_queue, node);
1530 _tbm_surface_queue_detach(surface_queue, surface);
1532 pthread_mutex_unlock(&surface_queue->lock);
1534 _tbm_surf_queue_mutex_unlock();
1536 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1538 return TBM_SURFACE_QUEUE_ERROR_NONE;
1541 if (surface_queue->impl && surface_queue->impl->release)
1542 surface_queue->impl->release(surface_queue, node);
1544 _tbm_surface_queue_release(surface_queue, node, 1);
1546 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1547 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1548 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1549 pthread_mutex_unlock(&surface_queue->lock);
1551 _tbm_surf_queue_mutex_unlock();
1552 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1555 node->type = QUEUE_NODE_TYPE_RELEASE;
1557 pthread_mutex_unlock(&surface_queue->lock);
1558 pthread_cond_signal(&surface_queue->free_cond);
1560 _tbm_surf_queue_mutex_unlock();
1562 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1564 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1566 return TBM_SURFACE_QUEUE_ERROR_NONE;
1569 tbm_surface_queue_error_e
1570 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1571 surface_queue, tbm_surface_h surface)
1576 _tbm_surf_queue_mutex_lock();
1577 _tbm_set_last_result(TBM_ERROR_NONE);
1579 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1580 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1581 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1582 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1584 pthread_mutex_lock(&surface_queue->lock);
1586 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1588 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1589 if (node == NULL || queue_type != NODE_LIST) {
1590 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1592 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1593 pthread_mutex_unlock(&surface_queue->lock);
1595 _tbm_surf_queue_mutex_unlock();
1596 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1599 if (surface_queue->impl && surface_queue->impl->enqueue)
1600 surface_queue->impl->enqueue(surface_queue, node);
1602 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1604 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1605 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1606 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1607 pthread_mutex_unlock(&surface_queue->lock);
1609 _tbm_surf_queue_mutex_unlock();
1610 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1613 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1615 pthread_mutex_unlock(&surface_queue->lock);
1616 pthread_cond_signal(&surface_queue->dirty_cond);
1618 _tbm_surf_queue_mutex_unlock();
1620 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1622 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1624 return TBM_SURFACE_QUEUE_ERROR_NONE;
1627 tbm_surface_queue_error_e
1628 tbm_surface_queue_acquire(tbm_surface_queue_h
1629 surface_queue, tbm_surface_h *surface)
1633 _tbm_surf_queue_mutex_lock();
1634 _tbm_set_last_result(TBM_ERROR_NONE);
1638 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1639 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1640 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1641 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1643 pthread_mutex_lock(&surface_queue->lock);
1645 if (surface_queue->impl && surface_queue->impl->acquire)
1646 node = surface_queue->impl->acquire(surface_queue);
1648 node = _tbm_surface_queue_acquire(surface_queue);
1650 if (node == NULL || node->surface == NULL) {
1651 TBM_ERR("_queue_node_pop_front failed\n");
1652 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1653 pthread_mutex_unlock(&surface_queue->lock);
1655 _tbm_surf_queue_mutex_unlock();
1656 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1659 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1661 *surface = node->surface;
1663 if (surface_queue->acquire_sync_count == 1) {
1664 tbm_surface_info_s info;
1667 TBM_ERR("start map surface:%p", *surface);
1668 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1669 TBM_ERR("end map surface:%p", *surface);
1670 if (ret == TBM_SURFACE_ERROR_NONE)
1671 tbm_surface_unmap(*surface);
1674 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1676 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1678 pthread_mutex_unlock(&surface_queue->lock);
1680 _tbm_surf_queue_mutex_unlock();
1683 tbm_surface_internal_dump_buffer(*surface, "acquire");
1685 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1687 return TBM_SURFACE_QUEUE_ERROR_NONE;
1691 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1693 _tbm_surf_queue_mutex_lock();
1694 _tbm_set_last_result(TBM_ERROR_NONE);
1696 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1698 pthread_mutex_lock(&surface_queue->lock);
1700 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1702 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1703 pthread_mutex_unlock(&surface_queue->lock);
1704 _tbm_surf_queue_mutex_unlock();
1708 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1709 QUEUE_NODE_TYPE_DEQUEUE)) {
1710 _tbm_surf_queue_mutex_unlock();
1711 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1712 pthread_mutex_unlock(&surface_queue->lock);
1716 pthread_mutex_unlock(&surface_queue->lock);
1717 _tbm_surf_queue_mutex_unlock();
1722 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1724 queue_node *node = NULL, *tmp;
1726 _tbm_surf_queue_mutex_lock();
1727 _tbm_set_last_result(TBM_ERROR_NONE);
1729 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1731 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1733 LIST_DEL(&surface_queue->item_link);
1735 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1736 _queue_delete_node(surface_queue, node);
1738 if (surface_queue->impl && surface_queue->impl->destroy)
1739 surface_queue->impl->destroy(surface_queue);
1741 _notify_emit(surface_queue, &surface_queue->destory_noti);
1743 _notify_remove_all(&surface_queue->destory_noti);
1744 _notify_remove_all(&surface_queue->dequeuable_noti);
1745 _notify_remove_all(&surface_queue->dequeue_noti);
1746 _notify_remove_all(&surface_queue->can_dequeue_noti);
1747 _notify_remove_all(&surface_queue->acquirable_noti);
1748 _notify_remove_all(&surface_queue->reset_noti);
1749 _trace_remove_all(&surface_queue->trace_noti);
1751 pthread_mutex_destroy(&surface_queue->lock);
1753 free(surface_queue);
1755 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1756 _deinit_tbm_surf_queue_bufmgr();
1758 _tbm_surf_queue_mutex_unlock();
1761 tbm_surface_queue_error_e
1762 tbm_surface_queue_reset(tbm_surface_queue_h
1763 surface_queue, int width, int height, int format)
1765 queue_node *node = NULL, *tmp;
1767 _tbm_surf_queue_mutex_lock();
1768 _tbm_set_last_result(TBM_ERROR_NONE);
1770 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1771 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1773 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1775 if (width == surface_queue->width && height == surface_queue->height &&
1776 format == surface_queue->format) {
1777 _tbm_surf_queue_mutex_unlock();
1778 return TBM_SURFACE_QUEUE_ERROR_NONE;
1781 pthread_mutex_lock(&surface_queue->lock);
1783 surface_queue->width = width;
1784 surface_queue->height = height;
1785 surface_queue->format = format;
1787 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1788 /* Destory surface and Push to free_queue */
1789 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1790 _queue_delete_node(surface_queue, node);
1792 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1793 node->delete_pending = 1;
1795 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1796 _queue_delete_node(surface_queue, node);
1798 _queue_init(&surface_queue->dirty_queue);
1799 LIST_INITHEAD(&surface_queue->list);
1803 _queue_init(&surface_queue->free_queue);
1805 surface_queue->num_attached = 0;
1807 if (surface_queue->impl && surface_queue->impl->reset)
1808 surface_queue->impl->reset(surface_queue);
1810 pthread_mutex_unlock(&surface_queue->lock);
1811 pthread_cond_signal(&surface_queue->free_cond);
1813 _tbm_surf_queue_mutex_unlock();
1815 _notify_emit(surface_queue, &surface_queue->reset_noti);
1817 return TBM_SURFACE_QUEUE_ERROR_NONE;
1820 tbm_surface_queue_error_e
1821 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1823 _tbm_surf_queue_mutex_lock();
1824 _tbm_set_last_result(TBM_ERROR_NONE);
1826 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1827 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1829 _tbm_surf_queue_mutex_unlock();
1831 _notify_emit(surface_queue, &surface_queue->reset_noti);
1833 return TBM_SURFACE_QUEUE_ERROR_NONE;
1836 tbm_surface_queue_error_e
1837 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
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);
1845 pthread_mutex_lock(&surface_queue->lock);
1846 pthread_mutex_unlock(&surface_queue->lock);
1847 pthread_cond_signal(&surface_queue->free_cond);
1849 _tbm_surf_queue_mutex_unlock();
1851 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1853 return TBM_SURFACE_QUEUE_ERROR_NONE;
1856 tbm_surface_queue_error_e
1857 tbm_surface_queue_set_size(tbm_surface_queue_h
1858 surface_queue, int queue_size, int flush)
1860 queue_node *node = NULL, *tmp;
1862 _tbm_surf_queue_mutex_lock();
1863 _tbm_set_last_result(TBM_ERROR_NONE);
1865 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1866 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1867 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1868 TBM_ERROR_INVALID_PARAMETER);
1870 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1872 if ((surface_queue->queue_size == queue_size) && !flush) {
1873 _tbm_surf_queue_mutex_unlock();
1874 return TBM_SURFACE_QUEUE_ERROR_NONE;
1877 pthread_mutex_lock(&surface_queue->lock);
1880 surface_queue->queue_size = queue_size;
1882 if (surface_queue->num_attached == 0) {
1883 pthread_mutex_unlock(&surface_queue->lock);
1884 _tbm_surf_queue_mutex_unlock();
1885 return TBM_SURFACE_QUEUE_ERROR_NONE;
1888 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1889 /* Destory surface and Push to free_queue */
1890 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1891 _queue_delete_node(surface_queue, node);
1893 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1894 node->delete_pending = 1;
1896 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1897 _queue_delete_node(surface_queue, node);
1899 _queue_init(&surface_queue->dirty_queue);
1900 LIST_INITHEAD(&surface_queue->list);
1904 _queue_init(&surface_queue->free_queue);
1906 surface_queue->num_attached = 0;
1908 if (surface_queue->impl && surface_queue->impl->reset)
1909 surface_queue->impl->reset(surface_queue);
1911 pthread_mutex_unlock(&surface_queue->lock);
1912 pthread_cond_signal(&surface_queue->free_cond);
1914 _tbm_surf_queue_mutex_unlock();
1916 _notify_emit(surface_queue, &surface_queue->reset_noti);
1918 return TBM_SURFACE_QUEUE_ERROR_NONE;
1920 if (surface_queue->queue_size > queue_size) {
1921 int need_del = surface_queue->queue_size - queue_size;
1923 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1924 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1926 if (surface_queue->impl && surface_queue->impl->need_detach)
1927 surface_queue->impl->need_detach(surface_queue, node);
1929 _tbm_surface_queue_detach(surface_queue, node->surface);
1937 surface_queue->queue_size = queue_size;
1939 pthread_mutex_unlock(&surface_queue->lock);
1941 _tbm_surf_queue_mutex_unlock();
1943 return TBM_SURFACE_QUEUE_ERROR_NONE;
1947 tbm_surface_queue_error_e
1948 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1950 queue_node *node = NULL;
1952 _tbm_surf_queue_mutex_lock();
1953 _tbm_set_last_result(TBM_ERROR_NONE);
1955 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1956 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1958 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1960 if (surface_queue->num_attached == 0) {
1961 _tbm_surf_queue_mutex_unlock();
1962 return TBM_SURFACE_QUEUE_ERROR_NONE;
1965 pthread_mutex_lock(&surface_queue->lock);
1967 /* Destory surface in free_queue */
1968 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1969 if (surface_queue->impl && surface_queue->impl->need_detach)
1970 surface_queue->impl->need_detach(surface_queue, node);
1972 _tbm_surface_queue_detach(surface_queue, node->surface);
1976 _queue_init(&surface_queue->free_queue);
1978 pthread_mutex_unlock(&surface_queue->lock);
1979 _tbm_surf_queue_mutex_unlock();
1981 return TBM_SURFACE_QUEUE_ERROR_NONE;
1984 tbm_surface_queue_error_e
1985 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1987 queue_node *node = NULL, *tmp;
1989 _tbm_surf_queue_mutex_lock();
1990 _tbm_set_last_result(TBM_ERROR_NONE);
1992 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1993 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1995 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1997 if (surface_queue->num_attached == 0) {
1998 _tbm_surf_queue_mutex_unlock();
1999 return TBM_SURFACE_QUEUE_ERROR_NONE;
2002 pthread_mutex_lock(&surface_queue->lock);
2004 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
2005 /* Destory surface and Push to free_queue */
2006 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
2007 _queue_delete_node(surface_queue, node);
2009 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
2010 node->delete_pending = 1;
2012 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
2013 _queue_delete_node(surface_queue, node);
2015 _queue_init(&surface_queue->dirty_queue);
2016 LIST_INITHEAD(&surface_queue->list);
2020 _queue_init(&surface_queue->free_queue);
2022 surface_queue->num_attached = 0;
2024 if (surface_queue->impl && surface_queue->impl->reset)
2025 surface_queue->impl->reset(surface_queue);
2027 pthread_mutex_unlock(&surface_queue->lock);
2028 pthread_cond_signal(&surface_queue->free_cond);
2030 _tbm_surf_queue_mutex_unlock();
2032 _notify_emit(surface_queue, &surface_queue->reset_noti);
2034 return TBM_SURFACE_QUEUE_ERROR_NONE;
2037 tbm_surface_queue_error_e
2038 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
2039 tbm_surface_h *surfaces, int *num)
2041 queue_node *node = NULL;
2043 _tbm_surf_queue_mutex_lock();
2044 _tbm_set_last_result(TBM_ERROR_NONE);
2046 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2047 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2048 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2049 TBM_ERROR_INVALID_PARAMETER);
2053 pthread_mutex_lock(&surface_queue->lock);
2055 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2056 if (node->delete_pending) continue;
2059 surfaces[*num] = node->surface;
2064 pthread_mutex_unlock(&surface_queue->lock);
2066 _tbm_surf_queue_mutex_unlock();
2068 return TBM_SURFACE_QUEUE_ERROR_NONE;
2071 tbm_surface_queue_error_e
2072 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2073 tbm_surface_h *surfaces, int *num)
2075 queue_node *node = NULL;
2077 _tbm_surf_queue_mutex_lock();
2081 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2082 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2083 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2084 TBM_ERROR_INVALID_PARAMETER);
2086 pthread_mutex_lock(&surface_queue->lock);
2088 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2090 surfaces[*num] = node->surface;
2095 pthread_mutex_unlock(&surface_queue->lock);
2097 _tbm_surf_queue_mutex_unlock();
2099 return TBM_SURFACE_QUEUE_ERROR_NONE;
2102 tbm_surface_queue_error_e
2103 tbm_surface_queue_get_trace_surface_num(
2104 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2106 _tbm_surf_queue_mutex_lock();
2107 _tbm_set_last_result(TBM_ERROR_NONE);
2109 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2110 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2111 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2112 TBM_ERROR_INVALID_PARAMETER);
2116 pthread_mutex_lock(&surface_queue->lock);
2119 case TBM_SURFACE_QUEUE_TRACE_NONE:
2122 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2123 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2125 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2126 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2128 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2129 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2131 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2132 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2138 pthread_mutex_unlock(&surface_queue->lock);
2140 _tbm_surf_queue_mutex_unlock();
2142 return TBM_SURFACE_QUEUE_ERROR_NONE;
2145 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2146 NULL, /*__tbm_queue_default_init*/
2147 NULL, /*__tbm_queue_default_reset*/
2148 NULL, /*__tbm_queue_default_destroy*/
2149 NULL, /*__tbm_queue_default_need_attach*/
2150 NULL, /*__tbm_queue_default_enqueue*/
2151 NULL, /*__tbm_queue_default_release*/
2152 NULL, /*__tbm_queue_default_dequeue*/
2153 NULL, /*__tbm_queue_default_acquire*/
2154 NULL, /*__tbm_queue_default_need_detach*/
2158 tbm_surface_queue_create(int queue_size, int width,
2159 int height, int format, int flags)
2161 _tbm_surf_queue_mutex_lock();
2162 _tbm_set_last_result(TBM_ERROR_NONE);
2164 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2165 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2166 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2167 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2169 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2170 sizeof(struct _tbm_surface_queue));
2171 if (!surface_queue) {
2172 TBM_ERR("cannot allocate the surface_queue.\n");
2173 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2174 _tbm_surf_queue_mutex_unlock();
2178 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2180 _tbm_surface_queue_init(surface_queue,
2182 width, height, format, flags,
2183 &tbm_queue_default_impl, NULL);
2185 _tbm_surf_queue_mutex_unlock();
2187 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_enqueue(tbm_surface_queue_h surface_queue,
2223 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2224 queue_node *first = NULL;
2226 first = container_of(data->dequeue_list.head.next, first, item_link);
2227 if (first != node) {
2231 node->priv_flags = 0;
2233 _queue_node_pop(&data->dequeue_list, node);
2234 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2238 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2241 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2243 if (node->priv_flags) {
2244 node->priv_flags = 0;
2245 _queue_node_pop(&data->dequeue_list, node);
2248 _tbm_surface_queue_release(surface_queue, node, 1);
2252 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2255 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2258 node = _tbm_surface_queue_dequeue(surface_queue);
2260 _queue_node_push_back(&data->dequeue_list, node);
2261 node->priv_flags = 1;
2267 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2268 __tbm_queue_sequence_init,
2269 __tbm_queue_sequence_reset,
2270 __tbm_queue_sequence_destroy,
2272 __tbm_queue_sequence_enqueue,
2273 __tbm_queue_sequence_release,
2274 __tbm_queue_sequence_dequeue,
2275 NULL, /*__tbm_queue_sequence_acquire*/
2276 NULL, /*__tbm_queue_sequence_need_dettach*/
2280 tbm_surface_queue_sequence_create(int queue_size, int width,
2281 int height, int format, int flags)
2283 _tbm_surf_queue_mutex_lock();
2284 _tbm_set_last_result(TBM_ERROR_NONE);
2286 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2287 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2288 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2289 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2291 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2292 sizeof(struct _tbm_surface_queue));
2293 if (surface_queue == NULL) {
2294 TBM_ERR("cannot allocate the surface_queue.\n");
2295 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2296 _tbm_surf_queue_mutex_unlock();
2300 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2302 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2303 sizeof(tbm_queue_sequence));
2305 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2306 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2307 free(surface_queue);
2308 _tbm_surf_queue_mutex_unlock();
2312 _tbm_surface_queue_init(surface_queue,
2314 width, height, format, flags,
2315 &tbm_queue_sequence_impl, data);
2317 _tbm_surf_queue_mutex_unlock();
2319 return surface_queue;
2322 tbm_surface_queue_error_e
2323 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2326 _tbm_surf_queue_mutex_lock();
2327 _tbm_set_last_result(TBM_ERROR_NONE);
2329 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2330 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2332 pthread_mutex_lock(&surface_queue->lock);
2334 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2335 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2337 surface_queue->modes |= modes;
2339 pthread_mutex_unlock(&surface_queue->lock);
2341 _tbm_surf_queue_mutex_unlock();
2343 return TBM_SURFACE_QUEUE_ERROR_NONE;
2346 tbm_surface_queue_error_e
2347 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2348 unsigned int sync_count)
2350 int dequeue_num, enqueue_num;
2352 _tbm_surf_queue_mutex_lock();
2353 _tbm_set_last_result(TBM_ERROR_NONE);
2355 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2356 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2358 pthread_mutex_lock(&surface_queue->lock);
2360 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2361 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2363 if (dequeue_num + sync_count == 0)
2364 surface_queue->acquire_sync_count = enqueue_num;
2366 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2368 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2369 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2371 pthread_mutex_unlock(&surface_queue->lock);
2373 _tbm_surf_queue_mutex_unlock();
2375 return TBM_SURFACE_QUEUE_ERROR_NONE;