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 #define TBM_SURFACE_QUEUE_MAGIC 0xBF031234
44 static pthread_mutex_t tbm_surf_queue_lock = PTHREAD_MUTEX_INITIALIZER;
45 void _tbm_surface_queue_mutex_unlock(void);
48 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
50 TBM_ERR("'%s' failed.\n", #cond);\
51 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
52 _tbm_surf_queue_mutex_unlock();\
57 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
59 TBM_ERR("'%s' failed.\n", #cond);\
60 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
61 _tbm_surf_queue_mutex_unlock();\
66 typedef enum _queue_node_type {
68 QUEUE_NODE_TYPE_DEQUEUE,
69 QUEUE_NODE_TYPE_ENQUEUE,
70 QUEUE_NODE_TYPE_ACQUIRE,
71 QUEUE_NODE_TYPE_RELEASE
75 struct list_head head;
80 tbm_surface_h surface;
82 struct list_head item_link;
83 struct list_head link;
87 unsigned int priv_flags; /*for each queue*/
93 struct list_head link;
95 tbm_surface_queue_notify_cb cb;
100 struct list_head link;
102 tbm_surface_queue_trace_cb cb;
106 typedef struct _tbm_surface_queue_interface {
107 void (*init)(tbm_surface_queue_h queue);
108 void (*reset)(tbm_surface_queue_h queue);
109 void (*destroy)(tbm_surface_queue_h queue);
110 void (*need_attach)(tbm_surface_queue_h queue);
112 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
113 void (*release)(tbm_surface_queue_h queue, queue_node *node);
114 queue_node *(*dequeue)(tbm_surface_queue_h queue);
115 queue_node *(*acquire)(tbm_surface_queue_h queue);
116 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
117 } tbm_surface_queue_interface;
119 struct _tbm_surface_queue {
130 struct list_head list;
132 struct list_head destory_noti;
133 struct list_head dequeuable_noti;
134 struct list_head dequeue_noti;
135 struct list_head can_dequeue_noti;
136 struct list_head acquirable_noti;
137 struct list_head reset_noti;
138 struct list_head trace_noti;
140 pthread_mutex_t lock;
141 pthread_cond_t free_cond;
142 pthread_cond_t dirty_cond;
144 const tbm_surface_queue_interface *impl;
147 //For external buffer allocation
148 tbm_surface_alloc_cb alloc_cb;
149 tbm_surface_free_cb free_cb;
153 unsigned int enqueue_sync_count;
154 unsigned int acquire_sync_count;
158 _tbm_surf_queue_mutex_lock(void)
160 pthread_mutex_lock(&tbm_surf_queue_lock);
164 _tbm_surf_queue_mutex_unlock(void)
166 pthread_mutex_unlock(&tbm_surf_queue_lock);
170 _tbm_surface_queue_magic_check(tbm_surface_queue_h surface_queue)
172 if (surface_queue->magic != TBM_SURFACE_QUEUE_MAGIC)
179 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
181 if (!surface_queue) {
182 TBM_ERR("error: surface_queue is NULL.\n");
186 if (!_tbm_surface_queue_magic_check(surface_queue)) {
187 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
195 _queue_node_create(void)
197 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
199 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
205 _queue_node_delete(queue_node *node)
207 LIST_DEL(&node->item_link);
208 LIST_DEL(&node->link);
213 _queue_is_empty(queue *queue)
215 if (LIST_IS_EMPTY(&queue->head))
222 _queue_node_push_back(queue *queue, queue_node *node)
224 LIST_ADDTAIL(&node->item_link, &queue->head);
229 _queue_node_push_front(queue *queue, queue_node *node)
231 LIST_ADD(&node->item_link, &queue->head);
236 _queue_node_pop_front(queue *queue)
240 if (!queue->head.next) return NULL;
241 if (!queue->count) return NULL;
243 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
245 LIST_DELINIT(&node->item_link);
252 _queue_node_pop(queue *queue, queue_node *node)
254 LIST_DELINIT(&node->item_link);
261 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
262 tbm_surface_h surface, int *out_type)
264 queue_node *node = NULL;
267 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
271 if (type & FREE_QUEUE) {
272 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
274 if (node->surface == surface) {
276 *out_type = FREE_QUEUE;
283 if (type & DIRTY_QUEUE) {
284 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
286 if (node->surface == surface) {
288 *out_type = DIRTY_QUEUE;
295 if (type & NODE_LIST) {
296 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
297 if (node->surface == surface) {
299 *out_type = NODE_LIST;
306 TBM_ERR("fail to get the queue_node.\n");
312 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
315 if (surface_queue->free_cb) {
316 surface_queue->free_cb(surface_queue,
317 surface_queue->alloc_cb_data,
321 tbm_surface_destroy(node->surface);
324 _queue_node_delete(node);
328 _queue_init(queue *queue)
330 LIST_INITHEAD(&queue->head);
336 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
339 TBM_RETURN_IF_FAIL(cb != NULL);
341 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
343 TBM_RETURN_IF_FAIL(item != NULL);
345 LIST_INITHEAD(&item->link);
349 LIST_ADDTAIL(&item->link, list);
353 _notify_remove(struct list_head *list,
354 tbm_surface_queue_notify_cb cb, void *data)
356 queue_notify *item = NULL, *tmp;
358 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
359 if (item->cb == cb && item->data == data) {
360 LIST_DEL(&item->link);
366 TBM_ERR("Cannot find notifiy\n");
370 _notify_remove_all(struct list_head *list)
372 queue_notify *item = NULL, *tmp;
374 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
375 LIST_DEL(&item->link);
381 _notify_emit(tbm_surface_queue_h surface_queue,
382 struct list_head *list)
384 queue_notify *item = NULL, *tmp;;
387 The item->cb is the outside function of the libtbm.
388 The tbm user may/can remove the item of the list,
389 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
391 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
392 item->cb(surface_queue, item->data);
396 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
399 TBM_RETURN_IF_FAIL(cb != NULL);
401 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
403 TBM_RETURN_IF_FAIL(item != NULL);
405 LIST_INITHEAD(&item->link);
409 LIST_ADDTAIL(&item->link, list);
413 _trace_remove(struct list_head *list,
414 tbm_surface_queue_trace_cb cb, void *data)
416 queue_trace *item = NULL, *tmp;
418 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
419 if (item->cb == cb && item->data == data) {
420 LIST_DEL(&item->link);
426 TBM_ERR("Cannot find notifiy\n");
430 _trace_remove_all(struct list_head *list)
432 queue_trace *item = NULL, *tmp;
434 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
435 LIST_DEL(&item->link);
441 _trace_emit(tbm_surface_queue_h surface_queue,
442 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
444 queue_trace *item = NULL, *tmp;;
447 The item->cb is the outside function of the libtbm.
448 The tbm user may/can remove the item of the list,
449 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
451 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
452 item->cb(surface_queue, surface, trace, item->data);
456 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
458 queue_node *node = NULL;
461 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
462 if (node->type == type)
470 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
471 tbm_surface_h surface)
475 node = _queue_node_create();
476 TBM_RETURN_IF_FAIL(node != NULL);
478 tbm_surface_internal_ref(surface);
479 node->surface = surface;
481 LIST_ADDTAIL(&node->link, &surface_queue->list);
482 surface_queue->num_attached++;
483 _queue_node_push_back(&surface_queue->free_queue, node);
487 _tbm_surface_queue_need_attach(tbm_surface_queue_h surface_queue)
489 tbm_surface_h surface;
491 if (surface_queue->queue_size == surface_queue->num_attached)
494 if (surface_queue->alloc_cb) {
495 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
501 tbm_surface_internal_ref(surface);
503 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
504 surface_queue->height,
505 surface_queue->format,
506 surface_queue->flags);
507 TBM_RETURN_IF_FAIL(surface != NULL);
510 _tbm_surface_queue_attach(surface_queue, surface);
511 tbm_surface_internal_unref(surface);
515 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
516 tbm_surface_h surface)
521 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
523 _queue_delete_node(surface_queue, node);
524 surface_queue->num_attached--;
529 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
530 queue_node *node, int push_back)
533 _queue_node_push_back(&surface_queue->dirty_queue, node);
535 _queue_node_push_front(&surface_queue->dirty_queue, node);
539 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
543 node = _queue_node_pop_front(&surface_queue->free_queue);
549 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
553 if (_queue_is_empty(&surface_queue->dirty_queue))
556 node = _queue_node_pop_front(&surface_queue->dirty_queue);
562 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
563 queue_node *node, int push_back)
566 _queue_node_push_back(&surface_queue->free_queue, node);
568 _queue_node_push_front(&surface_queue->free_queue, node);
572 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
574 int width, int height, int format, int flags,
575 const tbm_surface_queue_interface *impl, void *data)
577 pthread_condattr_t free_attr, dirty_attr;
579 TBM_RETURN_IF_FAIL(surface_queue != NULL);
580 TBM_RETURN_IF_FAIL(impl != NULL);
582 pthread_mutex_init(&surface_queue->lock, NULL);
584 pthread_condattr_init(&free_attr);
585 pthread_condattr_setclock(&free_attr, CLOCK_MONOTONIC);
586 pthread_cond_init(&surface_queue->free_cond, &free_attr);
587 pthread_condattr_destroy(&free_attr);
589 pthread_condattr_init(&dirty_attr);
590 pthread_condattr_setclock(&dirty_attr, CLOCK_MONOTONIC);
591 pthread_cond_init(&surface_queue->dirty_cond, &dirty_attr);
592 pthread_condattr_destroy(&dirty_attr);
594 surface_queue->magic = TBM_SURFACE_QUEUE_MAGIC;
595 surface_queue->queue_size = queue_size;
596 surface_queue->width = width;
597 surface_queue->height = height;
598 surface_queue->format = format;
599 surface_queue->flags = flags;
600 surface_queue->impl = impl;
601 surface_queue->impl_data = data;
602 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
604 _queue_init(&surface_queue->free_queue);
605 _queue_init(&surface_queue->dirty_queue);
606 LIST_INITHEAD(&surface_queue->list);
608 LIST_INITHEAD(&surface_queue->destory_noti);
609 LIST_INITHEAD(&surface_queue->dequeuable_noti);
610 LIST_INITHEAD(&surface_queue->dequeue_noti);
611 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
612 LIST_INITHEAD(&surface_queue->acquirable_noti);
613 LIST_INITHEAD(&surface_queue->reset_noti);
614 LIST_INITHEAD(&surface_queue->trace_noti);
616 if (surface_queue->impl && surface_queue->impl->init)
617 surface_queue->impl->init(surface_queue);
620 tbm_surface_queue_error_e
621 tbm_surface_queue_add_destroy_cb(
622 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
625 _tbm_surf_queue_mutex_lock();
626 _tbm_set_last_result(TBM_ERROR_NONE);
628 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
629 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
630 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
631 TBM_ERROR_INVALID_PARAMETER);
633 pthread_mutex_lock(&surface_queue->lock);
635 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
637 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
639 pthread_mutex_unlock(&surface_queue->lock);
641 _tbm_surf_queue_mutex_unlock();
643 return TBM_SURFACE_QUEUE_ERROR_NONE;
646 tbm_surface_queue_error_e
647 tbm_surface_queue_remove_destroy_cb(
648 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
651 _tbm_surf_queue_mutex_lock();
652 _tbm_set_last_result(TBM_ERROR_NONE);
654 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
655 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
657 pthread_mutex_lock(&surface_queue->lock);
659 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
661 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
663 pthread_mutex_unlock(&surface_queue->lock);
665 _tbm_surf_queue_mutex_unlock();
667 return TBM_SURFACE_QUEUE_ERROR_NONE;
670 tbm_surface_queue_error_e
671 tbm_surface_queue_add_dequeuable_cb(
672 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
675 _tbm_surf_queue_mutex_lock();
676 _tbm_set_last_result(TBM_ERROR_NONE);
678 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
679 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
680 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
681 TBM_ERROR_INVALID_PARAMETER);
683 pthread_mutex_lock(&surface_queue->lock);
685 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
687 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
689 pthread_mutex_unlock(&surface_queue->lock);
691 _tbm_surf_queue_mutex_unlock();
693 return TBM_SURFACE_QUEUE_ERROR_NONE;
696 tbm_surface_queue_error_e
697 tbm_surface_queue_remove_dequeuable_cb(
698 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
701 _tbm_surf_queue_mutex_lock();
702 _tbm_set_last_result(TBM_ERROR_NONE);
704 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
705 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
707 pthread_mutex_lock(&surface_queue->lock);
709 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
711 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
713 pthread_mutex_unlock(&surface_queue->lock);
715 _tbm_surf_queue_mutex_unlock();
717 return TBM_SURFACE_QUEUE_ERROR_NONE;
720 tbm_surface_queue_error_e
721 tbm_surface_queue_add_dequeue_cb(
722 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
725 _tbm_surf_queue_mutex_lock();
726 _tbm_set_last_result(TBM_ERROR_NONE);
728 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
729 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
730 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
731 TBM_ERROR_INVALID_PARAMETER);
733 pthread_mutex_lock(&surface_queue->lock);
735 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
737 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
739 pthread_mutex_unlock(&surface_queue->lock);
741 _tbm_surf_queue_mutex_unlock();
743 return TBM_SURFACE_QUEUE_ERROR_NONE;
746 tbm_surface_queue_error_e
747 tbm_surface_queue_remove_dequeue_cb(
748 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
751 _tbm_surf_queue_mutex_lock();
752 _tbm_set_last_result(TBM_ERROR_NONE);
754 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
755 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
757 pthread_mutex_lock(&surface_queue->lock);
759 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
761 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
763 pthread_mutex_unlock(&surface_queue->lock);
765 _tbm_surf_queue_mutex_unlock();
767 return TBM_SURFACE_QUEUE_ERROR_NONE;
770 tbm_surface_queue_error_e
771 tbm_surface_queue_add_can_dequeue_cb(
772 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
775 _tbm_surf_queue_mutex_lock();
776 _tbm_set_last_result(TBM_ERROR_NONE);
778 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
779 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
780 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
781 TBM_ERROR_INVALID_PARAMETER);
783 pthread_mutex_lock(&surface_queue->lock);
785 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
787 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
789 pthread_mutex_unlock(&surface_queue->lock);
791 _tbm_surf_queue_mutex_unlock();
793 return TBM_SURFACE_QUEUE_ERROR_NONE;
796 tbm_surface_queue_error_e
797 tbm_surface_queue_remove_can_dequeue_cb(
798 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
801 _tbm_surf_queue_mutex_lock();
802 _tbm_set_last_result(TBM_ERROR_NONE);
804 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
805 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
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();
826 _tbm_set_last_result(TBM_ERROR_NONE);
828 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
829 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
830 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
831 TBM_ERROR_INVALID_PARAMETER);
833 pthread_mutex_lock(&surface_queue->lock);
835 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
837 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
839 pthread_mutex_unlock(&surface_queue->lock);
841 _tbm_surf_queue_mutex_unlock();
843 return TBM_SURFACE_QUEUE_ERROR_NONE;
846 tbm_surface_queue_error_e
847 tbm_surface_queue_remove_acquirable_cb(
848 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
851 _tbm_surf_queue_mutex_lock();
852 _tbm_set_last_result(TBM_ERROR_NONE);
854 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
855 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
857 pthread_mutex_lock(&surface_queue->lock);
859 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
861 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
863 pthread_mutex_unlock(&surface_queue->lock);
865 _tbm_surf_queue_mutex_unlock();
867 return TBM_SURFACE_QUEUE_ERROR_NONE;
870 tbm_surface_queue_error_e
871 tbm_surface_queue_add_trace_cb(
872 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
875 _tbm_surf_queue_mutex_lock();
876 _tbm_set_last_result(TBM_ERROR_NONE);
878 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
879 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
880 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
881 TBM_ERROR_INVALID_PARAMETER);
883 pthread_mutex_lock(&surface_queue->lock);
885 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
887 _trace_add(&surface_queue->trace_noti, trace_cb, data);
889 pthread_mutex_unlock(&surface_queue->lock);
891 _tbm_surf_queue_mutex_unlock();
893 return TBM_SURFACE_QUEUE_ERROR_NONE;
896 tbm_surface_queue_error_e
897 tbm_surface_queue_remove_trace_cb(
898 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
901 _tbm_surf_queue_mutex_lock();
902 _tbm_set_last_result(TBM_ERROR_NONE);
904 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
905 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
907 pthread_mutex_lock(&surface_queue->lock);
909 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
911 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
913 pthread_mutex_unlock(&surface_queue->lock);
915 _tbm_surf_queue_mutex_unlock();
917 return TBM_SURFACE_QUEUE_ERROR_NONE;
920 tbm_surface_queue_error_e
921 tbm_surface_queue_set_alloc_cb(
922 tbm_surface_queue_h surface_queue,
923 tbm_surface_alloc_cb alloc_cb,
924 tbm_surface_free_cb free_cb,
927 _tbm_surf_queue_mutex_lock();
928 _tbm_set_last_result(TBM_ERROR_NONE);
930 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
931 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
933 pthread_mutex_lock(&surface_queue->lock);
935 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
937 surface_queue->alloc_cb = alloc_cb;
938 surface_queue->free_cb = free_cb;
939 surface_queue->alloc_cb_data = data;
941 pthread_mutex_unlock(&surface_queue->lock);
943 _tbm_surf_queue_mutex_unlock();
945 return TBM_SURFACE_QUEUE_ERROR_NONE;
949 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
953 _tbm_surf_queue_mutex_lock();
954 _tbm_set_last_result(TBM_ERROR_NONE);
956 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
958 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
960 width = surface_queue->width;
962 _tbm_surf_queue_mutex_unlock();
968 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
972 _tbm_surf_queue_mutex_lock();
973 _tbm_set_last_result(TBM_ERROR_NONE);
975 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
977 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
979 height = surface_queue->height;
981 _tbm_surf_queue_mutex_unlock();
987 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
991 _tbm_surf_queue_mutex_lock();
992 _tbm_set_last_result(TBM_ERROR_NONE);
994 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
996 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
998 format = surface_queue->format;
1000 _tbm_surf_queue_mutex_unlock();
1006 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1010 _tbm_surf_queue_mutex_lock();
1011 _tbm_set_last_result(TBM_ERROR_NONE);
1013 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1015 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1017 queue_size = surface_queue->queue_size;
1019 _tbm_surf_queue_mutex_unlock();
1024 tbm_surface_queue_error_e
1025 tbm_surface_queue_add_reset_cb(
1026 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1029 _tbm_surf_queue_mutex_lock();
1030 _tbm_set_last_result(TBM_ERROR_NONE);
1032 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1033 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1034 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1035 TBM_ERROR_INVALID_PARAMETER);
1037 pthread_mutex_lock(&surface_queue->lock);
1039 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1041 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1043 pthread_mutex_unlock(&surface_queue->lock);
1045 _tbm_surf_queue_mutex_unlock();
1047 return TBM_SURFACE_QUEUE_ERROR_NONE;
1050 tbm_surface_queue_error_e
1051 tbm_surface_queue_remove_reset_cb(
1052 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1055 _tbm_surf_queue_mutex_lock();
1056 _tbm_set_last_result(TBM_ERROR_NONE);
1058 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1059 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1061 pthread_mutex_lock(&surface_queue->lock);
1063 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1065 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1067 pthread_mutex_unlock(&surface_queue->lock);
1069 _tbm_surf_queue_mutex_unlock();
1071 return TBM_SURFACE_QUEUE_ERROR_NONE;
1074 tbm_surface_queue_error_e
1075 tbm_surface_queue_enqueue(tbm_surface_queue_h
1076 surface_queue, tbm_surface_h surface)
1081 _tbm_surf_queue_mutex_lock();
1082 _tbm_set_last_result(TBM_ERROR_NONE);
1084 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1085 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1086 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1087 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1090 tbm_surface_internal_dump_buffer(surface, "enqueue");
1092 pthread_mutex_lock(&surface_queue->lock);
1094 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1096 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1097 if (node == NULL || queue_type != NODE_LIST) {
1098 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1100 pthread_mutex_unlock(&surface_queue->lock);
1102 _tbm_surf_queue_mutex_unlock();
1105 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1106 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1108 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1109 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1113 if (surface_queue->impl && surface_queue->impl->enqueue)
1114 surface_queue->impl->enqueue(surface_queue, node);
1116 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1118 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1119 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1120 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1121 pthread_mutex_unlock(&surface_queue->lock);
1123 _tbm_surf_queue_mutex_unlock();
1124 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1127 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1129 if (surface_queue->enqueue_sync_count == 1) {
1130 tbm_surface_info_s info;
1133 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1134 if (ret == TBM_SURFACE_ERROR_NONE)
1135 tbm_surface_unmap(surface);
1138 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1140 pthread_mutex_unlock(&surface_queue->lock);
1141 pthread_cond_signal(&surface_queue->dirty_cond);
1143 _tbm_surf_queue_mutex_unlock();
1145 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1147 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1149 return TBM_SURFACE_QUEUE_ERROR_NONE;
1152 tbm_surface_queue_error_e
1153 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1154 surface_queue, tbm_surface_h surface)
1159 _tbm_surf_queue_mutex_lock();
1160 _tbm_set_last_result(TBM_ERROR_NONE);
1162 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1163 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1164 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1165 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1167 pthread_mutex_lock(&surface_queue->lock);
1169 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1171 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1172 if (node == NULL || queue_type != NODE_LIST) {
1173 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1175 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1176 pthread_mutex_unlock(&surface_queue->lock);
1178 _tbm_surf_queue_mutex_unlock();
1179 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1182 if (node->delete_pending) {
1183 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1185 _queue_delete_node(surface_queue, node);
1187 pthread_mutex_unlock(&surface_queue->lock);
1189 _tbm_surf_queue_mutex_unlock();
1191 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1193 return TBM_SURFACE_QUEUE_ERROR_NONE;
1196 if (surface_queue->queue_size < surface_queue->num_attached) {
1197 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1199 if (surface_queue->impl && surface_queue->impl->need_detach)
1200 surface_queue->impl->need_detach(surface_queue, node);
1202 _tbm_surface_queue_detach(surface_queue, surface);
1204 pthread_mutex_unlock(&surface_queue->lock);
1206 _tbm_surf_queue_mutex_unlock();
1208 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1210 return TBM_SURFACE_QUEUE_ERROR_NONE;
1213 if (surface_queue->impl && surface_queue->impl->release)
1214 surface_queue->impl->release(surface_queue, node);
1216 _tbm_surface_queue_release(surface_queue, node, 1);
1218 if (_queue_is_empty(&surface_queue->free_queue)) {
1219 TBM_ERR("surface_queue->free_queue is empty.\n");
1220 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1221 pthread_mutex_unlock(&surface_queue->lock);
1223 _tbm_surf_queue_mutex_unlock();
1224 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1227 node->type = QUEUE_NODE_TYPE_RELEASE;
1229 pthread_mutex_unlock(&surface_queue->lock);
1230 pthread_cond_signal(&surface_queue->free_cond);
1232 _tbm_surf_queue_mutex_unlock();
1234 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1236 return TBM_SURFACE_QUEUE_ERROR_NONE;
1239 tbm_surface_queue_error_e
1240 tbm_surface_queue_dequeue(tbm_surface_queue_h
1241 surface_queue, tbm_surface_h *surface)
1245 _tbm_surf_queue_mutex_lock();
1246 _tbm_set_last_result(TBM_ERROR_NONE);
1248 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1249 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1250 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1251 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1255 pthread_mutex_lock(&surface_queue->lock);
1257 if (_queue_is_empty(&surface_queue->free_queue)) {
1258 if (surface_queue->impl && surface_queue->impl->need_attach)
1259 surface_queue->impl->need_attach(surface_queue);
1261 _tbm_surface_queue_need_attach(surface_queue);
1264 if (surface_queue->impl && surface_queue->impl->dequeue)
1265 node = surface_queue->impl->dequeue(surface_queue);
1267 node = _tbm_surface_queue_dequeue(surface_queue);
1269 if (node == NULL || node->surface == NULL) {
1270 TBM_ERR("_queue_node_pop_front failed\n");
1271 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1272 pthread_mutex_unlock(&surface_queue->lock);
1274 _tbm_surf_queue_mutex_unlock();
1275 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1278 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1279 *surface = node->surface;
1281 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1283 pthread_mutex_unlock(&surface_queue->lock);
1285 _tbm_surf_queue_mutex_unlock();
1287 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1289 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1291 return TBM_SURFACE_QUEUE_ERROR_NONE;
1294 tbm_surface_queue_error_e
1295 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1300 _tbm_surf_queue_mutex_lock();
1301 _tbm_set_last_result(TBM_ERROR_NONE);
1303 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1304 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1306 _tbm_surf_queue_mutex_unlock();
1308 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1310 _tbm_surf_queue_mutex_lock();
1312 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1313 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1315 pthread_mutex_lock(&surface_queue->lock);
1317 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1319 if (_queue_is_empty(&surface_queue->free_queue)) {
1320 if (surface_queue->impl && surface_queue->impl->need_attach)
1321 surface_queue->impl->need_attach(surface_queue);
1323 _tbm_surface_queue_need_attach(surface_queue);
1326 if (!_queue_is_empty(&surface_queue->free_queue)) {
1327 pthread_mutex_unlock(&surface_queue->lock);
1328 _tbm_surf_queue_mutex_unlock();
1329 return TBM_SURFACE_QUEUE_ERROR_NONE;
1332 _tbm_surf_queue_mutex_unlock();
1335 clock_gettime(CLOCK_MONOTONIC, &tp);
1337 if (ms_timeout > 1000)
1338 tp.tv_sec += ms_timeout / 1000;
1340 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1342 if (tp.tv_nsec > 1000000000L) {
1344 tp.tv_nsec -= 1000000000L;
1347 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1349 if (ret == ETIMEDOUT) {
1350 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1351 pthread_mutex_unlock(&surface_queue->lock);
1352 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1354 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1357 if (surface_queue->impl && surface_queue->impl->need_attach)
1358 surface_queue->impl->need_attach(surface_queue);
1360 _tbm_surface_queue_need_attach(surface_queue);
1362 if (!_queue_is_empty(&surface_queue->free_queue)) {
1363 pthread_mutex_unlock(&surface_queue->lock);
1364 return TBM_SURFACE_QUEUE_ERROR_NONE;
1371 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1373 _tbm_surf_queue_mutex_lock();
1374 _tbm_set_last_result(TBM_ERROR_NONE);
1376 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1378 _tbm_surf_queue_mutex_unlock();
1380 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1382 _tbm_surf_queue_mutex_lock();
1384 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1386 pthread_mutex_lock(&surface_queue->lock);
1388 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1390 if (_queue_is_empty(&surface_queue->free_queue)) {
1391 if (surface_queue->impl && surface_queue->impl->need_attach)
1392 surface_queue->impl->need_attach(surface_queue);
1394 _tbm_surface_queue_need_attach(surface_queue);
1397 if (!_queue_is_empty(&surface_queue->free_queue)) {
1398 pthread_mutex_unlock(&surface_queue->lock);
1399 _tbm_surf_queue_mutex_unlock();
1404 _tbm_surf_queue_mutex_unlock();
1406 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1408 if (surface_queue->impl && surface_queue->impl->need_attach)
1409 surface_queue->impl->need_attach(surface_queue);
1411 _tbm_surface_queue_need_attach(surface_queue);
1413 if (!_queue_is_empty(&surface_queue->free_queue)) {
1414 pthread_mutex_unlock(&surface_queue->lock);
1420 pthread_mutex_unlock(&surface_queue->lock);
1421 _tbm_surf_queue_mutex_unlock();
1425 tbm_surface_queue_error_e
1426 tbm_surface_queue_release(tbm_surface_queue_h
1427 surface_queue, tbm_surface_h surface)
1432 _tbm_surf_queue_mutex_lock();
1433 _tbm_set_last_result(TBM_ERROR_NONE);
1435 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1436 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1437 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1438 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1440 pthread_mutex_lock(&surface_queue->lock);
1442 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1444 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1445 if (node == NULL || queue_type != NODE_LIST) {
1446 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1448 pthread_mutex_unlock(&surface_queue->lock);
1450 _tbm_surf_queue_mutex_unlock();
1453 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1454 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1456 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1457 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1461 if (node->delete_pending) {
1462 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1464 _queue_delete_node(surface_queue, node);
1466 pthread_mutex_unlock(&surface_queue->lock);
1468 _tbm_surf_queue_mutex_unlock();
1470 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1472 return TBM_SURFACE_QUEUE_ERROR_NONE;
1475 if (surface_queue->queue_size < surface_queue->num_attached) {
1476 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1478 if (surface_queue->impl && surface_queue->impl->need_detach)
1479 surface_queue->impl->need_detach(surface_queue, node);
1481 _tbm_surface_queue_detach(surface_queue, surface);
1483 pthread_mutex_unlock(&surface_queue->lock);
1485 _tbm_surf_queue_mutex_unlock();
1487 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1489 return TBM_SURFACE_QUEUE_ERROR_NONE;
1492 if (surface_queue->impl && surface_queue->impl->release)
1493 surface_queue->impl->release(surface_queue, node);
1495 _tbm_surface_queue_release(surface_queue, node, 1);
1497 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1498 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1499 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1500 pthread_mutex_unlock(&surface_queue->lock);
1502 _tbm_surf_queue_mutex_unlock();
1503 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1506 node->type = QUEUE_NODE_TYPE_RELEASE;
1508 pthread_mutex_unlock(&surface_queue->lock);
1509 pthread_cond_signal(&surface_queue->free_cond);
1511 _tbm_surf_queue_mutex_unlock();
1513 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1515 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1517 return TBM_SURFACE_QUEUE_ERROR_NONE;
1520 tbm_surface_queue_error_e
1521 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1522 surface_queue, tbm_surface_h surface)
1527 _tbm_surf_queue_mutex_lock();
1528 _tbm_set_last_result(TBM_ERROR_NONE);
1530 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1531 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1532 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1533 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1535 pthread_mutex_lock(&surface_queue->lock);
1537 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1539 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1540 if (node == NULL || queue_type != NODE_LIST) {
1541 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1543 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1544 pthread_mutex_unlock(&surface_queue->lock);
1546 _tbm_surf_queue_mutex_unlock();
1547 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1550 if (surface_queue->impl && surface_queue->impl->enqueue)
1551 surface_queue->impl->enqueue(surface_queue, node);
1553 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1555 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1556 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1557 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1558 pthread_mutex_unlock(&surface_queue->lock);
1560 _tbm_surf_queue_mutex_unlock();
1561 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1564 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1566 pthread_mutex_unlock(&surface_queue->lock);
1567 pthread_cond_signal(&surface_queue->dirty_cond);
1569 _tbm_surf_queue_mutex_unlock();
1571 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1573 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1575 return TBM_SURFACE_QUEUE_ERROR_NONE;
1578 tbm_surface_queue_error_e
1579 tbm_surface_queue_acquire(tbm_surface_queue_h
1580 surface_queue, tbm_surface_h *surface)
1584 _tbm_surf_queue_mutex_lock();
1585 _tbm_set_last_result(TBM_ERROR_NONE);
1589 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1590 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1591 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1592 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1594 pthread_mutex_lock(&surface_queue->lock);
1596 if (surface_queue->impl && surface_queue->impl->acquire)
1597 node = surface_queue->impl->acquire(surface_queue);
1599 node = _tbm_surface_queue_acquire(surface_queue);
1601 if (node == NULL || node->surface == NULL) {
1602 TBM_ERR("_queue_node_pop_front failed\n");
1603 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1604 pthread_mutex_unlock(&surface_queue->lock);
1606 _tbm_surf_queue_mutex_unlock();
1607 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1610 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1612 *surface = node->surface;
1614 if (surface_queue->acquire_sync_count == 1) {
1615 tbm_surface_info_s info;
1618 TBM_ERR("start map surface:%p", *surface);
1619 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1620 TBM_ERR("end map surface:%p", *surface);
1621 if (ret == TBM_SURFACE_ERROR_NONE)
1622 tbm_surface_unmap(*surface);
1625 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1627 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1629 pthread_mutex_unlock(&surface_queue->lock);
1631 _tbm_surf_queue_mutex_unlock();
1634 tbm_surface_internal_dump_buffer(*surface, "acquire");
1636 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1638 return TBM_SURFACE_QUEUE_ERROR_NONE;
1642 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1644 _tbm_surf_queue_mutex_lock();
1645 _tbm_set_last_result(TBM_ERROR_NONE);
1647 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1649 pthread_mutex_lock(&surface_queue->lock);
1651 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1653 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1654 pthread_mutex_unlock(&surface_queue->lock);
1655 _tbm_surf_queue_mutex_unlock();
1659 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1660 QUEUE_NODE_TYPE_DEQUEUE)) {
1661 _tbm_surf_queue_mutex_unlock();
1662 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1663 pthread_mutex_unlock(&surface_queue->lock);
1667 pthread_mutex_unlock(&surface_queue->lock);
1668 _tbm_surf_queue_mutex_unlock();
1673 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1675 queue_node *node = NULL, *tmp;
1677 _tbm_surf_queue_mutex_lock();
1678 _tbm_set_last_result(TBM_ERROR_NONE);
1680 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1682 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1684 surface_queue->magic = 0;
1686 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1687 _queue_delete_node(surface_queue, node);
1689 if (surface_queue->impl && surface_queue->impl->destroy)
1690 surface_queue->impl->destroy(surface_queue);
1692 _notify_emit(surface_queue, &surface_queue->destory_noti);
1694 _notify_remove_all(&surface_queue->destory_noti);
1695 _notify_remove_all(&surface_queue->dequeuable_noti);
1696 _notify_remove_all(&surface_queue->dequeue_noti);
1697 _notify_remove_all(&surface_queue->can_dequeue_noti);
1698 _notify_remove_all(&surface_queue->acquirable_noti);
1699 _notify_remove_all(&surface_queue->reset_noti);
1700 _trace_remove_all(&surface_queue->trace_noti);
1702 pthread_mutex_destroy(&surface_queue->lock);
1704 free(surface_queue);
1706 _tbm_surf_queue_mutex_unlock();
1709 tbm_surface_queue_error_e
1710 tbm_surface_queue_reset(tbm_surface_queue_h
1711 surface_queue, int width, int height, int format)
1713 queue_node *node = NULL, *tmp;
1715 _tbm_surf_queue_mutex_lock();
1716 _tbm_set_last_result(TBM_ERROR_NONE);
1718 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1719 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1721 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1723 if (width == surface_queue->width && height == surface_queue->height &&
1724 format == surface_queue->format) {
1725 _tbm_surf_queue_mutex_unlock();
1726 return TBM_SURFACE_QUEUE_ERROR_NONE;
1729 pthread_mutex_lock(&surface_queue->lock);
1731 surface_queue->width = width;
1732 surface_queue->height = height;
1733 surface_queue->format = format;
1735 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1736 /* Destory surface and Push to free_queue */
1737 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1738 _queue_delete_node(surface_queue, node);
1740 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1741 node->delete_pending = 1;
1743 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1744 _queue_delete_node(surface_queue, node);
1746 _queue_init(&surface_queue->dirty_queue);
1747 LIST_INITHEAD(&surface_queue->list);
1751 _queue_init(&surface_queue->free_queue);
1753 surface_queue->num_attached = 0;
1755 if (surface_queue->impl && surface_queue->impl->reset)
1756 surface_queue->impl->reset(surface_queue);
1758 pthread_mutex_unlock(&surface_queue->lock);
1759 pthread_cond_signal(&surface_queue->free_cond);
1761 _tbm_surf_queue_mutex_unlock();
1763 _notify_emit(surface_queue, &surface_queue->reset_noti);
1765 return TBM_SURFACE_QUEUE_ERROR_NONE;
1768 tbm_surface_queue_error_e
1769 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1771 _tbm_surf_queue_mutex_lock();
1772 _tbm_set_last_result(TBM_ERROR_NONE);
1774 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1775 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1777 _tbm_surf_queue_mutex_unlock();
1779 _notify_emit(surface_queue, &surface_queue->reset_noti);
1781 return TBM_SURFACE_QUEUE_ERROR_NONE;
1784 tbm_surface_queue_error_e
1785 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1787 _tbm_surf_queue_mutex_lock();
1788 _tbm_set_last_result(TBM_ERROR_NONE);
1790 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1791 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1793 pthread_mutex_lock(&surface_queue->lock);
1794 pthread_mutex_unlock(&surface_queue->lock);
1795 pthread_cond_signal(&surface_queue->free_cond);
1797 _tbm_surf_queue_mutex_unlock();
1799 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1801 return TBM_SURFACE_QUEUE_ERROR_NONE;
1804 tbm_surface_queue_error_e
1805 tbm_surface_queue_set_size(tbm_surface_queue_h
1806 surface_queue, int queue_size, int flush)
1808 queue_node *node = NULL, *tmp;
1810 _tbm_surf_queue_mutex_lock();
1811 _tbm_set_last_result(TBM_ERROR_NONE);
1813 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1814 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1815 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1816 TBM_ERROR_INVALID_PARAMETER);
1818 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1820 if ((surface_queue->queue_size == queue_size) && !flush) {
1821 _tbm_surf_queue_mutex_unlock();
1822 return TBM_SURFACE_QUEUE_ERROR_NONE;
1825 pthread_mutex_lock(&surface_queue->lock);
1828 surface_queue->queue_size = queue_size;
1830 if (surface_queue->num_attached == 0) {
1831 pthread_mutex_unlock(&surface_queue->lock);
1832 _tbm_surf_queue_mutex_unlock();
1833 return TBM_SURFACE_QUEUE_ERROR_NONE;
1836 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1837 /* Destory surface and Push to free_queue */
1838 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1839 _queue_delete_node(surface_queue, node);
1841 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1842 node->delete_pending = 1;
1844 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1845 _queue_delete_node(surface_queue, node);
1847 _queue_init(&surface_queue->dirty_queue);
1848 LIST_INITHEAD(&surface_queue->list);
1852 _queue_init(&surface_queue->free_queue);
1854 surface_queue->num_attached = 0;
1856 if (surface_queue->impl && surface_queue->impl->reset)
1857 surface_queue->impl->reset(surface_queue);
1859 pthread_mutex_unlock(&surface_queue->lock);
1860 pthread_cond_signal(&surface_queue->free_cond);
1862 _tbm_surf_queue_mutex_unlock();
1864 _notify_emit(surface_queue, &surface_queue->reset_noti);
1866 return TBM_SURFACE_QUEUE_ERROR_NONE;
1868 if (surface_queue->queue_size > queue_size) {
1869 int need_del = surface_queue->queue_size - queue_size;
1871 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1872 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1874 if (surface_queue->impl && surface_queue->impl->need_detach)
1875 surface_queue->impl->need_detach(surface_queue, node);
1877 _tbm_surface_queue_detach(surface_queue, node->surface);
1885 surface_queue->queue_size = queue_size;
1887 pthread_mutex_unlock(&surface_queue->lock);
1889 _tbm_surf_queue_mutex_unlock();
1891 return TBM_SURFACE_QUEUE_ERROR_NONE;
1895 tbm_surface_queue_error_e
1896 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1898 queue_node *node = NULL;
1899 int is_guarantee_cycle = 0;
1901 _tbm_surf_queue_mutex_lock();
1902 _tbm_set_last_result(TBM_ERROR_NONE);
1904 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1905 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1907 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1909 if (surface_queue->num_attached == 0) {
1910 _tbm_surf_queue_mutex_unlock();
1911 return TBM_SURFACE_QUEUE_ERROR_NONE;
1914 pthread_mutex_lock(&surface_queue->lock);
1916 /* Destory surface in free_queue */
1917 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1918 if (surface_queue->impl && surface_queue->impl->need_detach)
1919 surface_queue->impl->need_detach(surface_queue, node);
1921 _tbm_surface_queue_detach(surface_queue, node->surface);
1925 _queue_init(&surface_queue->free_queue);
1927 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
1928 is_guarantee_cycle = 1;
1930 pthread_mutex_unlock(&surface_queue->lock);
1931 _tbm_surf_queue_mutex_unlock();
1933 if (is_guarantee_cycle)
1934 _notify_emit(surface_queue, &surface_queue->reset_noti);
1936 return TBM_SURFACE_QUEUE_ERROR_NONE;
1939 tbm_surface_queue_error_e
1940 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1942 queue_node *node = NULL, *tmp;
1944 _tbm_surf_queue_mutex_lock();
1945 _tbm_set_last_result(TBM_ERROR_NONE);
1947 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1948 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1950 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1952 if (surface_queue->num_attached == 0) {
1953 _tbm_surf_queue_mutex_unlock();
1954 return TBM_SURFACE_QUEUE_ERROR_NONE;
1957 pthread_mutex_lock(&surface_queue->lock);
1959 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1960 /* Destory surface and Push to free_queue */
1961 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1962 _queue_delete_node(surface_queue, node);
1964 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1965 node->delete_pending = 1;
1967 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1968 _queue_delete_node(surface_queue, node);
1970 _queue_init(&surface_queue->dirty_queue);
1971 LIST_INITHEAD(&surface_queue->list);
1975 _queue_init(&surface_queue->free_queue);
1977 surface_queue->num_attached = 0;
1979 if (surface_queue->impl && surface_queue->impl->reset)
1980 surface_queue->impl->reset(surface_queue);
1982 pthread_mutex_unlock(&surface_queue->lock);
1983 pthread_cond_signal(&surface_queue->free_cond);
1985 _tbm_surf_queue_mutex_unlock();
1987 _notify_emit(surface_queue, &surface_queue->reset_noti);
1989 return TBM_SURFACE_QUEUE_ERROR_NONE;
1992 tbm_surface_queue_error_e
1993 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1994 tbm_surface_h *surfaces, int *num)
1996 queue_node *node = NULL;
1998 _tbm_surf_queue_mutex_lock();
1999 _tbm_set_last_result(TBM_ERROR_NONE);
2001 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2002 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2003 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2004 TBM_ERROR_INVALID_PARAMETER);
2008 pthread_mutex_lock(&surface_queue->lock);
2010 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2011 if (node->delete_pending) continue;
2014 surfaces[*num] = node->surface;
2019 pthread_mutex_unlock(&surface_queue->lock);
2021 _tbm_surf_queue_mutex_unlock();
2023 return TBM_SURFACE_QUEUE_ERROR_NONE;
2026 tbm_surface_queue_error_e
2027 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2028 tbm_surface_h *surfaces, int *num)
2030 queue_node *node = NULL;
2032 _tbm_surf_queue_mutex_lock();
2036 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2037 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2038 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2039 TBM_ERROR_INVALID_PARAMETER);
2041 pthread_mutex_lock(&surface_queue->lock);
2043 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2045 surfaces[*num] = node->surface;
2050 pthread_mutex_unlock(&surface_queue->lock);
2052 _tbm_surf_queue_mutex_unlock();
2054 return TBM_SURFACE_QUEUE_ERROR_NONE;
2057 tbm_surface_queue_error_e
2058 tbm_surface_queue_get_trace_surface_num(
2059 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2061 _tbm_surf_queue_mutex_lock();
2062 _tbm_set_last_result(TBM_ERROR_NONE);
2064 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2065 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2066 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2067 TBM_ERROR_INVALID_PARAMETER);
2071 pthread_mutex_lock(&surface_queue->lock);
2074 case TBM_SURFACE_QUEUE_TRACE_NONE:
2077 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2078 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2080 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2081 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2083 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2084 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2086 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2087 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2093 pthread_mutex_unlock(&surface_queue->lock);
2095 _tbm_surf_queue_mutex_unlock();
2097 return TBM_SURFACE_QUEUE_ERROR_NONE;
2100 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2101 NULL, /*__tbm_queue_default_init*/
2102 NULL, /*__tbm_queue_default_reset*/
2103 NULL, /*__tbm_queue_default_destroy*/
2104 NULL, /*__tbm_queue_default_need_attach*/
2105 NULL, /*__tbm_queue_default_enqueue*/
2106 NULL, /*__tbm_queue_default_release*/
2107 NULL, /*__tbm_queue_default_dequeue*/
2108 NULL, /*__tbm_queue_default_acquire*/
2109 NULL, /*__tbm_queue_default_need_detach*/
2113 tbm_surface_queue_create(int queue_size, int width,
2114 int height, int format, int flags)
2116 _tbm_surf_queue_mutex_lock();
2117 _tbm_set_last_result(TBM_ERROR_NONE);
2119 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2120 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2121 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2122 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2124 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2125 sizeof(struct _tbm_surface_queue));
2126 if (!surface_queue) {
2127 TBM_ERR("cannot allocate the surface_queue.\n");
2128 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2129 _tbm_surf_queue_mutex_unlock();
2133 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2135 _tbm_surface_queue_init(surface_queue,
2137 width, height, format, flags,
2138 &tbm_queue_default_impl, NULL);
2140 _tbm_surf_queue_mutex_unlock();
2142 return surface_queue;
2147 } tbm_queue_sequence;
2150 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2152 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2154 _queue_init(&data->dequeue_list);
2158 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2160 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2162 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2165 _queue_init(&data->dequeue_list);
2169 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2171 free(surface_queue->impl_data);
2175 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2178 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2179 queue_node *first = NULL;
2181 first = container_of(data->dequeue_list.head.next, first, item_link);
2182 if (first != node) {
2186 node->priv_flags = 0;
2188 _queue_node_pop(&data->dequeue_list, node);
2189 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2193 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2196 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2198 if (node->priv_flags) {
2199 node->priv_flags = 0;
2200 _queue_node_pop(&data->dequeue_list, node);
2203 _tbm_surface_queue_release(surface_queue, node, 1);
2207 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2210 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2213 node = _tbm_surface_queue_dequeue(surface_queue);
2215 _queue_node_push_back(&data->dequeue_list, node);
2216 node->priv_flags = 1;
2222 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2223 __tbm_queue_sequence_init,
2224 __tbm_queue_sequence_reset,
2225 __tbm_queue_sequence_destroy,
2227 __tbm_queue_sequence_enqueue,
2228 __tbm_queue_sequence_release,
2229 __tbm_queue_sequence_dequeue,
2230 NULL, /*__tbm_queue_sequence_acquire*/
2231 NULL, /*__tbm_queue_sequence_need_dettach*/
2235 tbm_surface_queue_sequence_create(int queue_size, int width,
2236 int height, int format, int flags)
2238 _tbm_surf_queue_mutex_lock();
2239 _tbm_set_last_result(TBM_ERROR_NONE);
2241 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2242 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2243 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2244 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2246 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2247 sizeof(struct _tbm_surface_queue));
2248 if (surface_queue == NULL) {
2249 TBM_ERR("cannot allocate the surface_queue.\n");
2250 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2251 _tbm_surf_queue_mutex_unlock();
2255 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2257 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2258 sizeof(tbm_queue_sequence));
2260 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2261 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2262 free(surface_queue);
2263 _tbm_surf_queue_mutex_unlock();
2267 _tbm_surface_queue_init(surface_queue,
2269 width, height, format, flags,
2270 &tbm_queue_sequence_impl, data);
2272 _tbm_surf_queue_mutex_unlock();
2274 return surface_queue;
2277 tbm_surface_queue_error_e
2278 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2281 _tbm_surf_queue_mutex_lock();
2282 _tbm_set_last_result(TBM_ERROR_NONE);
2284 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2285 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2287 pthread_mutex_lock(&surface_queue->lock);
2289 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2290 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2292 surface_queue->modes |= modes;
2294 pthread_mutex_unlock(&surface_queue->lock);
2296 _tbm_surf_queue_mutex_unlock();
2298 return TBM_SURFACE_QUEUE_ERROR_NONE;
2301 tbm_surface_queue_error_e
2302 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2303 unsigned int sync_count)
2305 int dequeue_num, enqueue_num;
2307 _tbm_surf_queue_mutex_lock();
2308 _tbm_set_last_result(TBM_ERROR_NONE);
2310 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2311 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2313 pthread_mutex_lock(&surface_queue->lock);
2315 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2316 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2318 if (dequeue_num + sync_count == 0)
2319 surface_queue->acquire_sync_count = enqueue_num;
2321 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2323 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2324 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2326 pthread_mutex_unlock(&surface_queue->lock);
2328 _tbm_surf_queue_mutex_unlock();
2330 return TBM_SURFACE_QUEUE_ERROR_NONE;