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"
41 static tbm_bufmgr g_surf_queue_bufmgr;
42 static pthread_mutex_t tbm_surf_queue_lock;
43 void _tbm_surface_queue_mutex_unlock(void);
46 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
48 TBM_ERR("'%s' failed.\n", #cond);\
49 _tbm_surf_queue_mutex_unlock();\
54 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
56 TBM_ERR("'%s' failed.\n", #cond);\
57 _tbm_surf_queue_mutex_unlock();\
62 typedef enum _queue_node_type {
64 QUEUE_NODE_TYPE_DEQUEUE,
65 QUEUE_NODE_TYPE_ENQUEUE,
66 QUEUE_NODE_TYPE_ACQUIRE,
67 QUEUE_NODE_TYPE_RELEASE
71 struct list_head head;
76 tbm_surface_h surface;
78 struct list_head item_link;
79 struct list_head link;
83 unsigned int priv_flags; /*for each queue*/
89 struct list_head link;
91 tbm_surface_queue_notify_cb cb;
96 struct list_head link;
98 tbm_surface_queue_trace_cb cb;
102 typedef struct _tbm_surface_queue_interface {
103 void (*init)(tbm_surface_queue_h queue);
104 void (*reset)(tbm_surface_queue_h queue);
105 void (*destroy)(tbm_surface_queue_h queue);
106 void (*need_attach)(tbm_surface_queue_h queue);
108 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
109 void (*release)(tbm_surface_queue_h queue, queue_node *node);
110 queue_node *(*dequeue)(tbm_surface_queue_h queue);
111 queue_node *(*acquire)(tbm_surface_queue_h queue);
112 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
113 } tbm_surface_queue_interface;
115 struct _tbm_surface_queue {
124 struct list_head list;
126 struct list_head destory_noti;
127 struct list_head dequeuable_noti;
128 struct list_head dequeue_noti;
129 struct list_head can_dequeue_noti;
130 struct list_head acquirable_noti;
131 struct list_head reset_noti;
132 struct list_head trace_noti;
134 pthread_mutex_t lock;
135 pthread_cond_t free_cond;
136 pthread_cond_t dirty_cond;
138 const tbm_surface_queue_interface *impl;
141 //For external buffer allocation
142 tbm_surface_alloc_cb alloc_cb;
143 tbm_surface_free_cb free_cb;
146 struct list_head item_link; /* link of surface queue */
149 unsigned int enqueue_sync_count;
150 unsigned int acquire_sync_count;
154 _tbm_surf_queue_mutex_init(void)
156 static bool tbm_surf_queue_mutex_init = false;
158 if (tbm_surf_queue_mutex_init)
161 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
162 TBM_ERR("fail: pthread_mutex_init\n");
166 tbm_surf_queue_mutex_init = true;
172 _tbm_surf_queue_mutex_lock(void)
174 if (!_tbm_surf_queue_mutex_init()) {
175 TBM_ERR("fail: _tbm_surf_queue_mutex_init\n");
179 pthread_mutex_lock(&tbm_surf_queue_lock);
183 _tbm_surf_queue_mutex_unlock(void)
185 pthread_mutex_unlock(&tbm_surf_queue_lock);
189 _init_tbm_surf_queue_bufmgr(void)
191 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
195 _deinit_tbm_surf_queue_bufmgr(void)
197 if (!g_surf_queue_bufmgr)
200 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
201 g_surf_queue_bufmgr = NULL;
205 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
207 tbm_surface_queue_h old_data = NULL;
209 if (surface_queue == NULL) {
210 TBM_ERR("error: surface_queue is NULL.\n");
214 if (g_surf_queue_bufmgr == NULL) {
215 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
219 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
220 TBM_ERR("error: surf_queue_list is empty\n");
224 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
226 if (old_data == surface_queue) {
227 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
232 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
238 _queue_node_create(void)
240 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
242 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
248 _queue_node_delete(queue_node *node)
250 LIST_DEL(&node->item_link);
251 LIST_DEL(&node->link);
256 _queue_is_empty(queue *queue)
258 if (LIST_IS_EMPTY(&queue->head))
265 _queue_node_push_back(queue *queue, queue_node *node)
267 LIST_ADDTAIL(&node->item_link, &queue->head);
272 _queue_node_push_front(queue *queue, queue_node *node)
274 LIST_ADD(&node->item_link, &queue->head);
279 _queue_node_pop_front(queue *queue)
283 if (!queue->head.next) return NULL;
284 if (!queue->count) return NULL;
286 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
288 LIST_DELINIT(&node->item_link);
295 _queue_node_pop(queue *queue, queue_node *node)
297 LIST_DELINIT(&node->item_link);
304 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
305 tbm_surface_h surface, int *out_type)
307 queue_node *node = NULL;
310 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
314 if (type & FREE_QUEUE) {
315 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
317 if (node->surface == surface) {
319 *out_type = FREE_QUEUE;
326 if (type & DIRTY_QUEUE) {
327 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
329 if (node->surface == surface) {
331 *out_type = DIRTY_QUEUE;
338 if (type & NODE_LIST) {
339 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
340 if (node->surface == surface) {
342 *out_type = NODE_LIST;
349 TBM_ERR("fail to get the queue_node.\n");
355 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
358 if (surface_queue->free_cb) {
359 surface_queue->free_cb(surface_queue,
360 surface_queue->alloc_cb_data,
364 tbm_surface_destroy(node->surface);
367 _queue_node_delete(node);
371 _queue_init(queue *queue)
373 LIST_INITHEAD(&queue->head);
379 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
382 TBM_RETURN_IF_FAIL(cb != NULL);
384 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
386 TBM_RETURN_IF_FAIL(item != NULL);
388 LIST_INITHEAD(&item->link);
392 LIST_ADDTAIL(&item->link, list);
396 _notify_remove(struct list_head *list,
397 tbm_surface_queue_notify_cb cb, void *data)
399 queue_notify *item = NULL, *tmp;
401 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
402 if (item->cb == cb && item->data == data) {
403 LIST_DEL(&item->link);
409 TBM_ERR("Cannot find notifiy\n");
413 _notify_remove_all(struct list_head *list)
415 queue_notify *item = NULL, *tmp;
417 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
418 LIST_DEL(&item->link);
424 _notify_emit(tbm_surface_queue_h surface_queue,
425 struct list_head *list)
427 queue_notify *item = NULL, *tmp;;
430 The item->cb is the outside function of the libtbm.
431 The tbm user may/can remove the item of the list,
432 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
434 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
435 item->cb(surface_queue, item->data);
439 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
442 TBM_RETURN_IF_FAIL(cb != NULL);
444 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
446 TBM_RETURN_IF_FAIL(item != NULL);
448 LIST_INITHEAD(&item->link);
452 LIST_ADDTAIL(&item->link, list);
456 _trace_remove(struct list_head *list,
457 tbm_surface_queue_trace_cb cb, void *data)
459 queue_trace *item = NULL, *tmp;
461 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
462 if (item->cb == cb && item->data == data) {
463 LIST_DEL(&item->link);
469 TBM_ERR("Cannot find notifiy\n");
473 _trace_remove_all(struct list_head *list)
475 queue_trace *item = NULL, *tmp;
477 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
478 LIST_DEL(&item->link);
484 _trace_emit(tbm_surface_queue_h surface_queue,
485 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
487 queue_trace *item = NULL, *tmp;;
490 The item->cb is the outside function of the libtbm.
491 The tbm user may/can remove the item of the list,
492 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
494 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
495 item->cb(surface_queue, surface, trace, item->data);
499 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
501 queue_node *node = NULL;
504 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
505 if (node->type == type)
513 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
514 tbm_surface_h surface)
518 node = _queue_node_create();
519 TBM_RETURN_IF_FAIL(node != NULL);
521 tbm_surface_internal_ref(surface);
522 node->surface = surface;
524 LIST_ADDTAIL(&node->link, &surface_queue->list);
525 surface_queue->num_attached++;
526 _queue_node_push_back(&surface_queue->free_queue, node);
530 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
531 tbm_surface_h surface)
536 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
538 _queue_delete_node(surface_queue, node);
539 surface_queue->num_attached--;
544 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
545 queue_node *node, int push_back)
548 _queue_node_push_back(&surface_queue->dirty_queue, node);
550 _queue_node_push_front(&surface_queue->dirty_queue, node);
554 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
558 node = _queue_node_pop_front(&surface_queue->free_queue);
564 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
568 if (_queue_is_empty(&surface_queue->dirty_queue))
571 node = _queue_node_pop_front(&surface_queue->dirty_queue);
577 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
578 queue_node *node, int push_back)
581 _queue_node_push_back(&surface_queue->free_queue, node);
583 _queue_node_push_front(&surface_queue->free_queue, node);
587 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
589 int width, int height, int format,
590 const tbm_surface_queue_interface *impl, void *data)
592 TBM_RETURN_IF_FAIL(surface_queue != NULL);
593 TBM_RETURN_IF_FAIL(impl != NULL);
595 if (!g_surf_queue_bufmgr)
596 _init_tbm_surf_queue_bufmgr();
598 pthread_mutex_init(&surface_queue->lock, NULL);
599 pthread_cond_init(&surface_queue->free_cond, NULL);
600 pthread_cond_init(&surface_queue->dirty_cond, NULL);
602 surface_queue->queue_size = queue_size;
603 surface_queue->width = width;
604 surface_queue->height = height;
605 surface_queue->format = format;
606 surface_queue->impl = impl;
607 surface_queue->impl_data = data;
608 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
610 _queue_init(&surface_queue->free_queue);
611 _queue_init(&surface_queue->dirty_queue);
612 LIST_INITHEAD(&surface_queue->list);
614 LIST_INITHEAD(&surface_queue->destory_noti);
615 LIST_INITHEAD(&surface_queue->dequeuable_noti);
616 LIST_INITHEAD(&surface_queue->dequeue_noti);
617 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
618 LIST_INITHEAD(&surface_queue->acquirable_noti);
619 LIST_INITHEAD(&surface_queue->reset_noti);
620 LIST_INITHEAD(&surface_queue->trace_noti);
622 if (surface_queue->impl && surface_queue->impl->init)
623 surface_queue->impl->init(surface_queue);
625 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
628 tbm_surface_queue_error_e
629 tbm_surface_queue_add_destroy_cb(
630 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
633 _tbm_surf_queue_mutex_lock();
635 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
636 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
637 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
638 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
640 pthread_mutex_lock(&surface_queue->lock);
642 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
644 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
646 pthread_mutex_unlock(&surface_queue->lock);
648 _tbm_surf_queue_mutex_unlock();
650 return TBM_SURFACE_QUEUE_ERROR_NONE;
653 tbm_surface_queue_error_e
654 tbm_surface_queue_remove_destroy_cb(
655 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
658 _tbm_surf_queue_mutex_lock();
660 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
661 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
663 pthread_mutex_lock(&surface_queue->lock);
665 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
667 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
669 pthread_mutex_unlock(&surface_queue->lock);
671 _tbm_surf_queue_mutex_unlock();
673 return TBM_SURFACE_QUEUE_ERROR_NONE;
676 tbm_surface_queue_error_e
677 tbm_surface_queue_add_dequeuable_cb(
678 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
681 _tbm_surf_queue_mutex_lock();
683 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
684 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
685 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
686 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
688 pthread_mutex_lock(&surface_queue->lock);
690 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
692 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
694 pthread_mutex_unlock(&surface_queue->lock);
696 _tbm_surf_queue_mutex_unlock();
698 return TBM_SURFACE_QUEUE_ERROR_NONE;
701 tbm_surface_queue_error_e
702 tbm_surface_queue_remove_dequeuable_cb(
703 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
706 _tbm_surf_queue_mutex_lock();
708 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
709 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
711 pthread_mutex_lock(&surface_queue->lock);
713 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
715 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
717 pthread_mutex_unlock(&surface_queue->lock);
719 _tbm_surf_queue_mutex_unlock();
721 return TBM_SURFACE_QUEUE_ERROR_NONE;
724 tbm_surface_queue_error_e
725 tbm_surface_queue_add_dequeue_cb(
726 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
729 _tbm_surf_queue_mutex_lock();
731 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
732 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
733 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
734 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
736 pthread_mutex_lock(&surface_queue->lock);
738 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
740 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
742 pthread_mutex_unlock(&surface_queue->lock);
744 _tbm_surf_queue_mutex_unlock();
746 return TBM_SURFACE_QUEUE_ERROR_NONE;
749 tbm_surface_queue_error_e
750 tbm_surface_queue_remove_dequeue_cb(
751 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
754 _tbm_surf_queue_mutex_lock();
756 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
757 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
759 pthread_mutex_lock(&surface_queue->lock);
761 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
763 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
765 pthread_mutex_unlock(&surface_queue->lock);
767 _tbm_surf_queue_mutex_unlock();
769 return TBM_SURFACE_QUEUE_ERROR_NONE;
772 tbm_surface_queue_error_e
773 tbm_surface_queue_add_can_dequeue_cb(
774 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
777 _tbm_surf_queue_mutex_lock();
779 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
780 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
781 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
782 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
784 pthread_mutex_lock(&surface_queue->lock);
786 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
788 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
790 pthread_mutex_unlock(&surface_queue->lock);
792 _tbm_surf_queue_mutex_unlock();
794 return TBM_SURFACE_QUEUE_ERROR_NONE;
797 tbm_surface_queue_error_e
798 tbm_surface_queue_remove_can_dequeue_cb(
799 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
802 _tbm_surf_queue_mutex_lock();
804 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
805 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
807 pthread_mutex_lock(&surface_queue->lock);
809 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
811 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
813 pthread_mutex_unlock(&surface_queue->lock);
815 _tbm_surf_queue_mutex_unlock();
817 return TBM_SURFACE_QUEUE_ERROR_NONE;
820 tbm_surface_queue_error_e
821 tbm_surface_queue_add_acquirable_cb(
822 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
825 _tbm_surf_queue_mutex_lock();
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(acquirable_cb,
830 TBM_SURFACE_QUEUE_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->acquirable_noti, acquirable_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_acquirable_cb(
847 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
850 _tbm_surf_queue_mutex_lock();
852 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
853 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
855 pthread_mutex_lock(&surface_queue->lock);
857 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
859 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
861 pthread_mutex_unlock(&surface_queue->lock);
863 _tbm_surf_queue_mutex_unlock();
865 return TBM_SURFACE_QUEUE_ERROR_NONE;
868 tbm_surface_queue_error_e
869 tbm_surface_queue_add_trace_cb(
870 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
873 _tbm_surf_queue_mutex_lock();
875 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
876 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
877 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
878 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
880 pthread_mutex_lock(&surface_queue->lock);
882 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
884 _trace_add(&surface_queue->trace_noti, trace_cb, data);
886 pthread_mutex_unlock(&surface_queue->lock);
888 _tbm_surf_queue_mutex_unlock();
890 return TBM_SURFACE_QUEUE_ERROR_NONE;
893 tbm_surface_queue_error_e
894 tbm_surface_queue_remove_trace_cb(
895 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
898 _tbm_surf_queue_mutex_lock();
900 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
901 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
903 pthread_mutex_lock(&surface_queue->lock);
905 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
907 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
909 pthread_mutex_unlock(&surface_queue->lock);
911 _tbm_surf_queue_mutex_unlock();
913 return TBM_SURFACE_QUEUE_ERROR_NONE;
916 tbm_surface_queue_error_e
917 tbm_surface_queue_set_alloc_cb(
918 tbm_surface_queue_h surface_queue,
919 tbm_surface_alloc_cb alloc_cb,
920 tbm_surface_free_cb free_cb,
923 _tbm_surf_queue_mutex_lock();
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 surface_queue->alloc_cb = alloc_cb;
933 surface_queue->free_cb = free_cb;
934 surface_queue->alloc_cb_data = data;
936 pthread_mutex_unlock(&surface_queue->lock);
938 _tbm_surf_queue_mutex_unlock();
940 return TBM_SURFACE_QUEUE_ERROR_NONE;
944 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
948 _tbm_surf_queue_mutex_lock();
950 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
952 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
954 width = surface_queue->width;
956 _tbm_surf_queue_mutex_unlock();
962 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
966 _tbm_surf_queue_mutex_lock();
968 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
970 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
972 height = surface_queue->height;
974 _tbm_surf_queue_mutex_unlock();
980 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
984 _tbm_surf_queue_mutex_lock();
986 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
988 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
990 format = surface_queue->format;
992 _tbm_surf_queue_mutex_unlock();
998 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1002 _tbm_surf_queue_mutex_lock();
1004 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1006 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1008 queue_size = surface_queue->queue_size;
1010 _tbm_surf_queue_mutex_unlock();
1015 tbm_surface_queue_error_e
1016 tbm_surface_queue_add_reset_cb(
1017 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1020 _tbm_surf_queue_mutex_lock();
1022 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1023 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1024 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1025 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1027 pthread_mutex_lock(&surface_queue->lock);
1029 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1031 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1033 pthread_mutex_unlock(&surface_queue->lock);
1035 _tbm_surf_queue_mutex_unlock();
1037 return TBM_SURFACE_QUEUE_ERROR_NONE;
1040 tbm_surface_queue_error_e
1041 tbm_surface_queue_remove_reset_cb(
1042 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1045 _tbm_surf_queue_mutex_lock();
1047 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1048 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1050 pthread_mutex_lock(&surface_queue->lock);
1052 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1054 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1056 pthread_mutex_unlock(&surface_queue->lock);
1058 _tbm_surf_queue_mutex_unlock();
1060 return TBM_SURFACE_QUEUE_ERROR_NONE;
1063 tbm_surface_queue_error_e
1064 tbm_surface_queue_enqueue(tbm_surface_queue_h
1065 surface_queue, tbm_surface_h surface)
1070 _tbm_surf_queue_mutex_lock();
1072 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1073 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1074 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1075 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1078 tbm_surface_internal_dump_buffer(surface, "enqueue");
1080 pthread_mutex_lock(&surface_queue->lock);
1082 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1084 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1085 if (node == NULL || queue_type != NODE_LIST) {
1086 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1088 pthread_mutex_unlock(&surface_queue->lock);
1090 _tbm_surf_queue_mutex_unlock();
1093 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1095 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1098 if (surface_queue->impl && surface_queue->impl->enqueue)
1099 surface_queue->impl->enqueue(surface_queue, node);
1101 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1103 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1104 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1105 pthread_mutex_unlock(&surface_queue->lock);
1107 _tbm_surf_queue_mutex_unlock();
1108 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1111 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1113 if (surface_queue->enqueue_sync_count == 1) {
1114 tbm_surface_info_s info;
1117 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1118 if (ret == TBM_SURFACE_ERROR_NONE)
1119 tbm_surface_unmap(surface);
1122 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1124 pthread_mutex_unlock(&surface_queue->lock);
1125 pthread_cond_signal(&surface_queue->dirty_cond);
1127 _tbm_surf_queue_mutex_unlock();
1129 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1131 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1133 return TBM_SURFACE_QUEUE_ERROR_NONE;
1136 tbm_surface_queue_error_e
1137 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1138 surface_queue, tbm_surface_h surface)
1143 _tbm_surf_queue_mutex_lock();
1145 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1146 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1147 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1148 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1150 pthread_mutex_lock(&surface_queue->lock);
1152 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1154 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1155 if (node == NULL || queue_type != NODE_LIST) {
1156 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1158 pthread_mutex_unlock(&surface_queue->lock);
1160 _tbm_surf_queue_mutex_unlock();
1161 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1164 if (node->delete_pending) {
1165 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1167 _queue_delete_node(surface_queue, node);
1169 pthread_mutex_unlock(&surface_queue->lock);
1171 _tbm_surf_queue_mutex_unlock();
1173 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1175 return TBM_SURFACE_QUEUE_ERROR_NONE;
1178 if (surface_queue->queue_size < surface_queue->num_attached) {
1179 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1181 if (surface_queue->impl && surface_queue->impl->need_detach)
1182 surface_queue->impl->need_detach(surface_queue, node);
1184 _tbm_surface_queue_detach(surface_queue, surface);
1186 pthread_mutex_unlock(&surface_queue->lock);
1188 _tbm_surf_queue_mutex_unlock();
1190 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1192 return TBM_SURFACE_QUEUE_ERROR_NONE;
1195 if (surface_queue->impl && surface_queue->impl->release)
1196 surface_queue->impl->release(surface_queue, node);
1198 _tbm_surface_queue_release(surface_queue, node, 1);
1200 if (_queue_is_empty(&surface_queue->free_queue)) {
1201 pthread_mutex_unlock(&surface_queue->lock);
1203 TBM_ERR("surface_queue->free_queue is empty.\n");
1204 _tbm_surf_queue_mutex_unlock();
1205 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1208 node->type = QUEUE_NODE_TYPE_RELEASE;
1210 pthread_mutex_unlock(&surface_queue->lock);
1211 pthread_cond_signal(&surface_queue->free_cond);
1213 _tbm_surf_queue_mutex_unlock();
1215 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1217 return TBM_SURFACE_QUEUE_ERROR_NONE;
1220 tbm_surface_queue_error_e
1221 tbm_surface_queue_dequeue(tbm_surface_queue_h
1222 surface_queue, tbm_surface_h *surface)
1226 _tbm_surf_queue_mutex_lock();
1228 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1229 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1230 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1231 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1235 pthread_mutex_lock(&surface_queue->lock);
1237 if (_queue_is_empty(&surface_queue->free_queue)) {
1238 if (surface_queue->impl && surface_queue->impl->need_attach)
1239 surface_queue->impl->need_attach(surface_queue);
1241 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1242 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1243 pthread_mutex_unlock(&surface_queue->lock);
1244 _tbm_surf_queue_mutex_unlock();
1245 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1249 if (surface_queue->impl && surface_queue->impl->dequeue)
1250 node = surface_queue->impl->dequeue(surface_queue);
1252 node = _tbm_surface_queue_dequeue(surface_queue);
1254 if (node == NULL || node->surface == NULL) {
1255 TBM_ERR("_queue_node_pop_front failed\n");
1256 pthread_mutex_unlock(&surface_queue->lock);
1258 _tbm_surf_queue_mutex_unlock();
1259 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1262 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1263 *surface = node->surface;
1265 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1267 pthread_mutex_unlock(&surface_queue->lock);
1269 _tbm_surf_queue_mutex_unlock();
1271 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1273 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1275 return TBM_SURFACE_QUEUE_ERROR_NONE;
1279 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1281 _tbm_surf_queue_mutex_lock();
1283 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1285 _tbm_surf_queue_mutex_unlock();
1287 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1289 _tbm_surf_queue_mutex_lock();
1291 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1293 pthread_mutex_lock(&surface_queue->lock);
1295 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1297 if (_queue_is_empty(&surface_queue->free_queue)) {
1298 if (surface_queue->impl && surface_queue->impl->need_attach)
1299 surface_queue->impl->need_attach(surface_queue);
1301 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1302 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1303 pthread_mutex_unlock(&surface_queue->lock);
1304 _tbm_surf_queue_mutex_unlock();
1309 if (!_queue_is_empty(&surface_queue->free_queue)) {
1310 pthread_mutex_unlock(&surface_queue->lock);
1311 _tbm_surf_queue_mutex_unlock();
1315 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1316 QUEUE_NODE_TYPE_ACQUIRE)) {
1317 _tbm_surf_queue_mutex_unlock();
1318 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1319 pthread_mutex_unlock(&surface_queue->lock);
1323 pthread_mutex_unlock(&surface_queue->lock);
1324 _tbm_surf_queue_mutex_unlock();
1328 tbm_surface_queue_error_e
1329 tbm_surface_queue_release(tbm_surface_queue_h
1330 surface_queue, tbm_surface_h surface)
1335 _tbm_surf_queue_mutex_lock();
1337 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1338 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1339 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1340 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1342 pthread_mutex_lock(&surface_queue->lock);
1344 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1346 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1347 if (node == NULL || queue_type != NODE_LIST) {
1348 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1350 pthread_mutex_unlock(&surface_queue->lock);
1352 _tbm_surf_queue_mutex_unlock();
1355 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1357 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1360 if (node->delete_pending) {
1361 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1363 _queue_delete_node(surface_queue, node);
1365 pthread_mutex_unlock(&surface_queue->lock);
1367 _tbm_surf_queue_mutex_unlock();
1369 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1371 return TBM_SURFACE_QUEUE_ERROR_NONE;
1374 if (surface_queue->queue_size < surface_queue->num_attached) {
1375 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1377 if (surface_queue->impl && surface_queue->impl->need_detach)
1378 surface_queue->impl->need_detach(surface_queue, node);
1380 _tbm_surface_queue_detach(surface_queue, surface);
1382 pthread_mutex_unlock(&surface_queue->lock);
1384 _tbm_surf_queue_mutex_unlock();
1386 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1388 return TBM_SURFACE_QUEUE_ERROR_NONE;
1391 if (surface_queue->impl && surface_queue->impl->release)
1392 surface_queue->impl->release(surface_queue, node);
1394 _tbm_surface_queue_release(surface_queue, node, 1);
1396 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1397 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1398 pthread_mutex_unlock(&surface_queue->lock);
1400 _tbm_surf_queue_mutex_unlock();
1401 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1404 node->type = QUEUE_NODE_TYPE_RELEASE;
1406 pthread_mutex_unlock(&surface_queue->lock);
1407 pthread_cond_signal(&surface_queue->free_cond);
1409 _tbm_surf_queue_mutex_unlock();
1411 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1413 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1415 return TBM_SURFACE_QUEUE_ERROR_NONE;
1418 tbm_surface_queue_error_e
1419 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1420 surface_queue, tbm_surface_h surface)
1425 _tbm_surf_queue_mutex_lock();
1427 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1428 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1429 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1430 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1432 pthread_mutex_lock(&surface_queue->lock);
1434 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1436 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1437 if (node == NULL || queue_type != NODE_LIST) {
1438 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1440 pthread_mutex_unlock(&surface_queue->lock);
1442 _tbm_surf_queue_mutex_unlock();
1443 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1446 if (surface_queue->impl && surface_queue->impl->enqueue)
1447 surface_queue->impl->enqueue(surface_queue, node);
1449 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1451 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1452 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1453 pthread_mutex_unlock(&surface_queue->lock);
1455 _tbm_surf_queue_mutex_unlock();
1456 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1459 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1461 pthread_mutex_unlock(&surface_queue->lock);
1462 pthread_cond_signal(&surface_queue->dirty_cond);
1464 _tbm_surf_queue_mutex_unlock();
1466 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1468 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1470 return TBM_SURFACE_QUEUE_ERROR_NONE;
1473 tbm_surface_queue_error_e
1474 tbm_surface_queue_acquire(tbm_surface_queue_h
1475 surface_queue, tbm_surface_h *surface)
1479 _tbm_surf_queue_mutex_lock();
1483 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1484 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1485 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1486 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1488 pthread_mutex_lock(&surface_queue->lock);
1490 if (surface_queue->impl && surface_queue->impl->acquire)
1491 node = surface_queue->impl->acquire(surface_queue);
1493 node = _tbm_surface_queue_acquire(surface_queue);
1495 if (node == NULL || node->surface == NULL) {
1496 TBM_ERR("_queue_node_pop_front failed\n");
1497 pthread_mutex_unlock(&surface_queue->lock);
1499 _tbm_surf_queue_mutex_unlock();
1500 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1503 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1505 *surface = node->surface;
1507 if (surface_queue->acquire_sync_count == 1) {
1508 tbm_surface_info_s info;
1511 TBM_ERR("start map surface:%p", *surface);
1512 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1513 TBM_ERR("end map surface:%p", *surface);
1514 if (ret == TBM_SURFACE_ERROR_NONE)
1515 tbm_surface_unmap(*surface);
1518 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1520 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1522 pthread_mutex_unlock(&surface_queue->lock);
1524 _tbm_surf_queue_mutex_unlock();
1527 tbm_surface_internal_dump_buffer(*surface, "acquire");
1529 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1531 return TBM_SURFACE_QUEUE_ERROR_NONE;
1535 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1537 _tbm_surf_queue_mutex_lock();
1539 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1541 pthread_mutex_lock(&surface_queue->lock);
1543 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1545 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1546 pthread_mutex_unlock(&surface_queue->lock);
1547 _tbm_surf_queue_mutex_unlock();
1551 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1552 QUEUE_NODE_TYPE_DEQUEUE)) {
1553 _tbm_surf_queue_mutex_unlock();
1554 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1555 pthread_mutex_unlock(&surface_queue->lock);
1559 pthread_mutex_unlock(&surface_queue->lock);
1560 _tbm_surf_queue_mutex_unlock();
1565 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1567 queue_node *node = NULL, *tmp;
1569 _tbm_surf_queue_mutex_lock();
1571 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1573 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1575 LIST_DEL(&surface_queue->item_link);
1577 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1578 _queue_delete_node(surface_queue, node);
1580 if (surface_queue->impl && surface_queue->impl->destroy)
1581 surface_queue->impl->destroy(surface_queue);
1583 _notify_emit(surface_queue, &surface_queue->destory_noti);
1585 _notify_remove_all(&surface_queue->destory_noti);
1586 _notify_remove_all(&surface_queue->dequeuable_noti);
1587 _notify_remove_all(&surface_queue->dequeue_noti);
1588 _notify_remove_all(&surface_queue->can_dequeue_noti);
1589 _notify_remove_all(&surface_queue->acquirable_noti);
1590 _notify_remove_all(&surface_queue->reset_noti);
1591 _trace_remove_all(&surface_queue->trace_noti);
1593 pthread_mutex_destroy(&surface_queue->lock);
1595 free(surface_queue);
1597 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1598 _deinit_tbm_surf_queue_bufmgr();
1600 _tbm_surf_queue_mutex_unlock();
1603 tbm_surface_queue_error_e
1604 tbm_surface_queue_reset(tbm_surface_queue_h
1605 surface_queue, int width, int height, int format)
1607 queue_node *node = NULL, *tmp;
1609 _tbm_surf_queue_mutex_lock();
1611 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1612 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1614 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1616 if (width == surface_queue->width && height == surface_queue->height &&
1617 format == surface_queue->format) {
1618 _tbm_surf_queue_mutex_unlock();
1619 return TBM_SURFACE_QUEUE_ERROR_NONE;
1622 pthread_mutex_lock(&surface_queue->lock);
1624 surface_queue->width = width;
1625 surface_queue->height = height;
1626 surface_queue->format = format;
1628 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1629 /* Destory surface and Push to free_queue */
1630 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1631 _queue_delete_node(surface_queue, node);
1633 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1634 node->delete_pending = 1;
1636 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1637 _queue_delete_node(surface_queue, node);
1639 _queue_init(&surface_queue->dirty_queue);
1640 LIST_INITHEAD(&surface_queue->list);
1644 _queue_init(&surface_queue->free_queue);
1646 surface_queue->num_attached = 0;
1648 if (surface_queue->impl && surface_queue->impl->reset)
1649 surface_queue->impl->reset(surface_queue);
1651 pthread_mutex_unlock(&surface_queue->lock);
1652 pthread_cond_signal(&surface_queue->free_cond);
1654 _tbm_surf_queue_mutex_unlock();
1656 _notify_emit(surface_queue, &surface_queue->reset_noti);
1658 return TBM_SURFACE_QUEUE_ERROR_NONE;
1661 tbm_surface_queue_error_e
1662 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1664 _tbm_surf_queue_mutex_lock();
1666 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1667 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1669 _tbm_surf_queue_mutex_unlock();
1671 _notify_emit(surface_queue, &surface_queue->reset_noti);
1673 return TBM_SURFACE_QUEUE_ERROR_NONE;
1676 tbm_surface_queue_error_e
1677 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1679 _tbm_surf_queue_mutex_lock();
1681 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1682 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1684 _tbm_surf_queue_mutex_unlock();
1686 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1688 return TBM_SURFACE_QUEUE_ERROR_NONE;
1691 tbm_surface_queue_error_e
1692 tbm_surface_queue_set_size(tbm_surface_queue_h
1693 surface_queue, int queue_size, int flush)
1695 queue_node *node = NULL, *tmp;
1697 _tbm_surf_queue_mutex_lock();
1699 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1700 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1701 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1702 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1704 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1706 if ((surface_queue->queue_size == queue_size) && !flush) {
1707 _tbm_surf_queue_mutex_unlock();
1708 return TBM_SURFACE_QUEUE_ERROR_NONE;
1711 pthread_mutex_lock(&surface_queue->lock);
1714 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1715 /* Destory surface and Push to free_queue */
1716 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1717 _queue_delete_node(surface_queue, node);
1719 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1720 node->delete_pending = 1;
1722 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1723 _queue_delete_node(surface_queue, node);
1725 _queue_init(&surface_queue->dirty_queue);
1726 LIST_INITHEAD(&surface_queue->list);
1730 _queue_init(&surface_queue->free_queue);
1732 surface_queue->num_attached = 0;
1733 surface_queue->queue_size = queue_size;
1735 if (surface_queue->impl && surface_queue->impl->reset)
1736 surface_queue->impl->reset(surface_queue);
1738 pthread_mutex_unlock(&surface_queue->lock);
1739 pthread_cond_signal(&surface_queue->free_cond);
1741 _tbm_surf_queue_mutex_unlock();
1743 _notify_emit(surface_queue, &surface_queue->reset_noti);
1745 return TBM_SURFACE_QUEUE_ERROR_NONE;
1747 if (surface_queue->queue_size > queue_size) {
1748 int need_del = surface_queue->queue_size - queue_size;
1750 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1751 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1753 if (surface_queue->impl && surface_queue->impl->need_detach)
1754 surface_queue->impl->need_detach(surface_queue, node);
1756 _tbm_surface_queue_detach(surface_queue, node->surface);
1764 surface_queue->queue_size = queue_size;
1766 pthread_mutex_unlock(&surface_queue->lock);
1768 _tbm_surf_queue_mutex_unlock();
1770 return TBM_SURFACE_QUEUE_ERROR_NONE;
1774 tbm_surface_queue_error_e
1775 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1777 queue_node *node = NULL;
1779 _tbm_surf_queue_mutex_lock();
1781 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1782 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1784 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1786 if (surface_queue->num_attached == 0) {
1787 _tbm_surf_queue_mutex_unlock();
1788 return TBM_SURFACE_QUEUE_ERROR_NONE;
1791 pthread_mutex_lock(&surface_queue->lock);
1793 /* Destory surface in free_queue */
1794 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1795 if (surface_queue->impl && surface_queue->impl->need_detach)
1796 surface_queue->impl->need_detach(surface_queue, node);
1798 _tbm_surface_queue_detach(surface_queue, node->surface);
1802 _queue_init(&surface_queue->free_queue);
1804 pthread_mutex_unlock(&surface_queue->lock);
1805 _tbm_surf_queue_mutex_unlock();
1807 return TBM_SURFACE_QUEUE_ERROR_NONE;
1810 tbm_surface_queue_error_e
1811 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1813 queue_node *node = NULL, *tmp;
1815 _tbm_surf_queue_mutex_lock();
1817 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1818 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1820 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1822 if (surface_queue->num_attached == 0) {
1823 _tbm_surf_queue_mutex_unlock();
1824 return TBM_SURFACE_QUEUE_ERROR_NONE;
1827 pthread_mutex_lock(&surface_queue->lock);
1829 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1830 /* Destory surface and Push to free_queue */
1831 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1832 _queue_delete_node(surface_queue, node);
1834 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1835 node->delete_pending = 1;
1837 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1838 _queue_delete_node(surface_queue, node);
1840 _queue_init(&surface_queue->dirty_queue);
1841 LIST_INITHEAD(&surface_queue->list);
1845 _queue_init(&surface_queue->free_queue);
1847 surface_queue->num_attached = 0;
1849 if (surface_queue->impl && surface_queue->impl->reset)
1850 surface_queue->impl->reset(surface_queue);
1852 pthread_mutex_unlock(&surface_queue->lock);
1853 pthread_cond_signal(&surface_queue->free_cond);
1855 _tbm_surf_queue_mutex_unlock();
1857 _notify_emit(surface_queue, &surface_queue->reset_noti);
1859 return TBM_SURFACE_QUEUE_ERROR_NONE;
1862 tbm_surface_queue_error_e
1863 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1864 tbm_surface_h *surfaces, int *num)
1866 queue_node *node = NULL;
1868 _tbm_surf_queue_mutex_lock();
1870 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1871 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1872 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1873 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1877 pthread_mutex_lock(&surface_queue->lock);
1879 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1881 surfaces[*num] = node->surface;
1886 pthread_mutex_unlock(&surface_queue->lock);
1888 _tbm_surf_queue_mutex_unlock();
1890 return TBM_SURFACE_QUEUE_ERROR_NONE;
1893 tbm_surface_queue_error_e
1894 tbm_surface_queue_get_trace_surface_num(
1895 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1897 _tbm_surf_queue_mutex_lock();
1899 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1900 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1901 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1902 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1906 pthread_mutex_lock(&surface_queue->lock);
1909 case TBM_SURFACE_QUEUE_TRACE_NONE:
1912 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1913 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1915 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1916 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1918 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1919 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1921 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1922 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1928 pthread_mutex_unlock(&surface_queue->lock);
1930 _tbm_surf_queue_mutex_unlock();
1932 return TBM_SURFACE_QUEUE_ERROR_NONE;
1937 } tbm_queue_default;
1940 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1942 free(surface_queue->impl_data);
1946 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1948 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1949 tbm_surface_h surface;
1951 if (surface_queue->queue_size == surface_queue->num_attached)
1954 if (surface_queue->alloc_cb) {
1955 pthread_mutex_unlock(&surface_queue->lock);
1956 _tbm_surf_queue_mutex_unlock();
1957 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1958 _tbm_surf_queue_mutex_lock();
1959 pthread_mutex_lock(&surface_queue->lock);
1965 tbm_surface_internal_ref(surface);
1967 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1968 surface_queue->height,
1969 surface_queue->format,
1971 TBM_RETURN_IF_FAIL(surface != NULL);
1974 _tbm_surface_queue_attach(surface_queue, surface);
1975 tbm_surface_internal_unref(surface);
1978 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1979 NULL, /*__tbm_queue_default_init*/
1980 NULL, /*__tbm_queue_default_reset*/
1981 __tbm_queue_default_destroy,
1982 __tbm_queue_default_need_attach,
1983 NULL, /*__tbm_queue_default_enqueue*/
1984 NULL, /*__tbm_queue_default_release*/
1985 NULL, /*__tbm_queue_default_dequeue*/
1986 NULL, /*__tbm_queue_default_acquire*/
1987 NULL, /*__tbm_queue_default_need_detach*/
1991 tbm_surface_queue_create(int queue_size, int width,
1992 int height, int format, int flags)
1994 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1995 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1996 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1997 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1999 _tbm_surf_queue_mutex_lock();
2001 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2002 sizeof(struct _tbm_surface_queue));
2003 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2005 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2007 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2008 sizeof(tbm_queue_default));
2010 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2011 free(surface_queue);
2012 _tbm_surf_queue_mutex_unlock();
2016 data->flags = flags;
2017 _tbm_surface_queue_init(surface_queue,
2019 width, height, format,
2020 &tbm_queue_default_impl, data);
2022 _tbm_surf_queue_mutex_unlock();
2024 return surface_queue;
2030 } tbm_queue_sequence;
2033 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2035 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2037 _queue_init(&data->dequeue_list);
2041 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2043 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2045 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2048 _queue_init(&data->dequeue_list);
2052 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2054 free(surface_queue->impl_data);
2058 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2060 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2061 tbm_surface_h surface;
2063 if (surface_queue->queue_size == surface_queue->num_attached)
2066 if (surface_queue->alloc_cb) {
2067 pthread_mutex_unlock(&surface_queue->lock);
2068 _tbm_surf_queue_mutex_unlock();
2069 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2070 _tbm_surf_queue_mutex_lock();
2071 pthread_mutex_lock(&surface_queue->lock);
2077 tbm_surface_internal_ref(surface);
2079 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2080 surface_queue->height,
2081 surface_queue->format,
2083 TBM_RETURN_IF_FAIL(surface != NULL);
2086 _tbm_surface_queue_attach(surface_queue, surface);
2087 tbm_surface_internal_unref(surface);
2091 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2094 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2095 queue_node *first = NULL;
2097 first = container_of(data->dequeue_list.head.next, first, item_link);
2098 if (first != node) {
2102 node->priv_flags = 0;
2104 _queue_node_pop(&data->dequeue_list, node);
2105 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2109 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2112 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2114 if (node->priv_flags) {
2115 node->priv_flags = 0;
2116 _queue_node_pop(&data->dequeue_list, node);
2119 _tbm_surface_queue_release(surface_queue, node, 1);
2123 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2126 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2129 node = _tbm_surface_queue_dequeue(surface_queue);
2131 _queue_node_push_back(&data->dequeue_list, node);
2132 node->priv_flags = 1;
2138 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2139 __tbm_queue_sequence_init,
2140 __tbm_queue_sequence_reset,
2141 __tbm_queue_sequence_destroy,
2142 __tbm_queue_sequence_need_attach,
2143 __tbm_queue_sequence_enqueue,
2144 __tbm_queue_sequence_release,
2145 __tbm_queue_sequence_dequeue,
2146 NULL, /*__tbm_queue_sequence_acquire*/
2147 NULL, /*__tbm_queue_sequence_need_dettach*/
2151 tbm_surface_queue_sequence_create(int queue_size, int width,
2152 int height, int format, int flags)
2154 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2155 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
2156 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
2157 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
2159 _tbm_surf_queue_mutex_lock();
2161 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2162 sizeof(struct _tbm_surface_queue));
2163 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
2165 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2167 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2168 sizeof(tbm_queue_sequence));
2170 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2171 free(surface_queue);
2172 _tbm_surf_queue_mutex_unlock();
2176 data->flags = flags;
2177 _tbm_surface_queue_init(surface_queue,
2179 width, height, format,
2180 &tbm_queue_sequence_impl, data);
2182 _tbm_surf_queue_mutex_unlock();
2184 return surface_queue;
2187 tbm_surface_queue_error_e
2188 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2191 _tbm_surf_queue_mutex_lock();
2193 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2194 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2196 pthread_mutex_lock(&surface_queue->lock);
2198 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2199 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2201 surface_queue->modes |= modes;
2203 pthread_mutex_unlock(&surface_queue->lock);
2205 _tbm_surf_queue_mutex_unlock();
2207 return TBM_SURFACE_QUEUE_ERROR_NONE;
2210 tbm_surface_queue_error_e
2211 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2212 unsigned int sync_count)
2214 int dequeue_num, enqueue_num;
2216 _tbm_surf_queue_mutex_lock();
2218 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2219 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2221 pthread_mutex_lock(&surface_queue->lock);
2223 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2224 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2226 if (dequeue_num + sync_count == 0)
2227 surface_queue->acquire_sync_count = enqueue_num;
2229 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2231 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2232 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2234 pthread_mutex_unlock(&surface_queue->lock);
2236 _tbm_surf_queue_mutex_unlock();
2238 return TBM_SURFACE_QUEUE_ERROR_NONE;