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_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
50 _tbm_surf_queue_mutex_unlock();\
55 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
57 TBM_ERR("'%s' failed.\n", #cond);\
58 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
59 _tbm_surf_queue_mutex_unlock();\
64 typedef enum _queue_node_type {
66 QUEUE_NODE_TYPE_DEQUEUE,
67 QUEUE_NODE_TYPE_ENQUEUE,
68 QUEUE_NODE_TYPE_ACQUIRE,
69 QUEUE_NODE_TYPE_RELEASE
73 struct list_head head;
78 tbm_surface_h surface;
80 struct list_head item_link;
81 struct list_head link;
85 unsigned int priv_flags; /*for each queue*/
91 struct list_head link;
93 tbm_surface_queue_notify_cb cb;
98 struct list_head link;
100 tbm_surface_queue_trace_cb cb;
104 typedef struct _tbm_surface_queue_interface {
105 void (*init)(tbm_surface_queue_h queue);
106 void (*reset)(tbm_surface_queue_h queue);
107 void (*destroy)(tbm_surface_queue_h queue);
108 void (*need_attach)(tbm_surface_queue_h queue);
110 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
111 void (*release)(tbm_surface_queue_h queue, queue_node *node);
112 queue_node *(*dequeue)(tbm_surface_queue_h queue);
113 queue_node *(*acquire)(tbm_surface_queue_h queue);
114 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
115 } tbm_surface_queue_interface;
117 struct _tbm_surface_queue {
126 struct list_head list;
128 struct list_head destory_noti;
129 struct list_head dequeuable_noti;
130 struct list_head dequeue_noti;
131 struct list_head can_dequeue_noti;
132 struct list_head acquirable_noti;
133 struct list_head reset_noti;
134 struct list_head trace_noti;
136 pthread_mutex_t lock;
137 pthread_cond_t free_cond;
138 pthread_cond_t dirty_cond;
140 const tbm_surface_queue_interface *impl;
143 //For external buffer allocation
144 tbm_surface_alloc_cb alloc_cb;
145 tbm_surface_free_cb free_cb;
148 struct list_head item_link; /* link of surface queue */
151 unsigned int enqueue_sync_count;
152 unsigned int acquire_sync_count;
156 _tbm_surf_queue_mutex_init(void)
158 static bool tbm_surf_queue_mutex_init = false;
160 if (tbm_surf_queue_mutex_init)
163 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
164 TBM_ERR("fail: pthread_mutex_init\n");
168 tbm_surf_queue_mutex_init = true;
174 _tbm_surf_queue_mutex_lock(void)
176 if (!_tbm_surf_queue_mutex_init()) {
177 TBM_ERR("fail: _tbm_surf_queue_mutex_init\n");
181 pthread_mutex_lock(&tbm_surf_queue_lock);
185 _tbm_surf_queue_mutex_unlock(void)
187 pthread_mutex_unlock(&tbm_surf_queue_lock);
191 _init_tbm_surf_queue_bufmgr(void)
193 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
197 _deinit_tbm_surf_queue_bufmgr(void)
199 if (!g_surf_queue_bufmgr)
202 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
203 g_surf_queue_bufmgr = NULL;
207 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
209 tbm_surface_queue_h old_data = NULL;
211 if (surface_queue == NULL) {
212 TBM_ERR("error: surface_queue is NULL.\n");
216 if (g_surf_queue_bufmgr == NULL) {
217 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
221 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
222 TBM_ERR("error: surf_queue_list is empty\n");
226 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
228 if (old_data == surface_queue) {
229 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
234 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
240 _queue_node_create(void)
242 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
244 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
250 _queue_node_delete(queue_node *node)
252 LIST_DEL(&node->item_link);
253 LIST_DEL(&node->link);
258 _queue_is_empty(queue *queue)
260 if (LIST_IS_EMPTY(&queue->head))
267 _queue_node_push_back(queue *queue, queue_node *node)
269 LIST_ADDTAIL(&node->item_link, &queue->head);
274 _queue_node_push_front(queue *queue, queue_node *node)
276 LIST_ADD(&node->item_link, &queue->head);
281 _queue_node_pop_front(queue *queue)
285 if (!queue->head.next) return NULL;
286 if (!queue->count) return NULL;
288 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
290 LIST_DELINIT(&node->item_link);
297 _queue_node_pop(queue *queue, queue_node *node)
299 LIST_DELINIT(&node->item_link);
306 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
307 tbm_surface_h surface, int *out_type)
309 queue_node *node = NULL;
312 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
316 if (type & FREE_QUEUE) {
317 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
319 if (node->surface == surface) {
321 *out_type = FREE_QUEUE;
328 if (type & DIRTY_QUEUE) {
329 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
331 if (node->surface == surface) {
333 *out_type = DIRTY_QUEUE;
340 if (type & NODE_LIST) {
341 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
342 if (node->surface == surface) {
344 *out_type = NODE_LIST;
351 TBM_ERR("fail to get the queue_node.\n");
357 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
360 if (surface_queue->free_cb) {
361 surface_queue->free_cb(surface_queue,
362 surface_queue->alloc_cb_data,
366 tbm_surface_destroy(node->surface);
369 _queue_node_delete(node);
373 _queue_init(queue *queue)
375 LIST_INITHEAD(&queue->head);
381 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
384 TBM_RETURN_IF_FAIL(cb != NULL);
386 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
388 TBM_RETURN_IF_FAIL(item != NULL);
390 LIST_INITHEAD(&item->link);
394 LIST_ADDTAIL(&item->link, list);
398 _notify_remove(struct list_head *list,
399 tbm_surface_queue_notify_cb cb, void *data)
401 queue_notify *item = NULL, *tmp;
403 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
404 if (item->cb == cb && item->data == data) {
405 LIST_DEL(&item->link);
411 TBM_ERR("Cannot find notifiy\n");
415 _notify_remove_all(struct list_head *list)
417 queue_notify *item = NULL, *tmp;
419 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
420 LIST_DEL(&item->link);
426 _notify_emit(tbm_surface_queue_h surface_queue,
427 struct list_head *list)
429 queue_notify *item = NULL, *tmp;;
432 The item->cb is the outside function of the libtbm.
433 The tbm user may/can remove the item of the list,
434 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
436 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
437 item->cb(surface_queue, item->data);
441 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
444 TBM_RETURN_IF_FAIL(cb != NULL);
446 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
448 TBM_RETURN_IF_FAIL(item != NULL);
450 LIST_INITHEAD(&item->link);
454 LIST_ADDTAIL(&item->link, list);
458 _trace_remove(struct list_head *list,
459 tbm_surface_queue_trace_cb cb, void *data)
461 queue_trace *item = NULL, *tmp;
463 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
464 if (item->cb == cb && item->data == data) {
465 LIST_DEL(&item->link);
471 TBM_ERR("Cannot find notifiy\n");
475 _trace_remove_all(struct list_head *list)
477 queue_trace *item = NULL, *tmp;
479 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
480 LIST_DEL(&item->link);
486 _trace_emit(tbm_surface_queue_h surface_queue,
487 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
489 queue_trace *item = NULL, *tmp;;
492 The item->cb is the outside function of the libtbm.
493 The tbm user may/can remove the item of the list,
494 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
496 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
497 item->cb(surface_queue, surface, trace, item->data);
501 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
503 queue_node *node = NULL;
506 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
507 if (node->type == type)
515 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
516 tbm_surface_h surface)
520 node = _queue_node_create();
521 TBM_RETURN_IF_FAIL(node != NULL);
523 tbm_surface_internal_ref(surface);
524 node->surface = surface;
526 LIST_ADDTAIL(&node->link, &surface_queue->list);
527 surface_queue->num_attached++;
528 _queue_node_push_back(&surface_queue->free_queue, node);
532 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
533 tbm_surface_h surface)
538 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
540 _queue_delete_node(surface_queue, node);
541 surface_queue->num_attached--;
546 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
547 queue_node *node, int push_back)
550 _queue_node_push_back(&surface_queue->dirty_queue, node);
552 _queue_node_push_front(&surface_queue->dirty_queue, node);
556 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
560 node = _queue_node_pop_front(&surface_queue->free_queue);
566 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
570 if (_queue_is_empty(&surface_queue->dirty_queue))
573 node = _queue_node_pop_front(&surface_queue->dirty_queue);
579 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
580 queue_node *node, int push_back)
583 _queue_node_push_back(&surface_queue->free_queue, node);
585 _queue_node_push_front(&surface_queue->free_queue, node);
589 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
591 int width, int height, int format,
592 const tbm_surface_queue_interface *impl, void *data)
594 TBM_RETURN_IF_FAIL(surface_queue != NULL);
595 TBM_RETURN_IF_FAIL(impl != NULL);
597 if (!g_surf_queue_bufmgr)
598 _init_tbm_surf_queue_bufmgr();
600 pthread_mutex_init(&surface_queue->lock, NULL);
601 pthread_cond_init(&surface_queue->free_cond, NULL);
602 pthread_cond_init(&surface_queue->dirty_cond, NULL);
604 surface_queue->queue_size = queue_size;
605 surface_queue->width = width;
606 surface_queue->height = height;
607 surface_queue->format = format;
608 surface_queue->impl = impl;
609 surface_queue->impl_data = data;
610 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
612 _queue_init(&surface_queue->free_queue);
613 _queue_init(&surface_queue->dirty_queue);
614 LIST_INITHEAD(&surface_queue->list);
616 LIST_INITHEAD(&surface_queue->destory_noti);
617 LIST_INITHEAD(&surface_queue->dequeuable_noti);
618 LIST_INITHEAD(&surface_queue->dequeue_noti);
619 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
620 LIST_INITHEAD(&surface_queue->acquirable_noti);
621 LIST_INITHEAD(&surface_queue->reset_noti);
622 LIST_INITHEAD(&surface_queue->trace_noti);
624 if (surface_queue->impl && surface_queue->impl->init)
625 surface_queue->impl->init(surface_queue);
627 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
630 tbm_surface_queue_error_e
631 tbm_surface_queue_add_destroy_cb(
632 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
635 _tbm_surf_queue_mutex_lock();
636 _tbm_set_last_result(TBM_ERROR_NONE);
638 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
639 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
640 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
641 TBM_ERROR_INVALID_PARAMETER);
643 pthread_mutex_lock(&surface_queue->lock);
645 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
647 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
649 pthread_mutex_unlock(&surface_queue->lock);
651 _tbm_surf_queue_mutex_unlock();
653 return TBM_SURFACE_QUEUE_ERROR_NONE;
656 tbm_surface_queue_error_e
657 tbm_surface_queue_remove_destroy_cb(
658 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
661 _tbm_surf_queue_mutex_lock();
662 _tbm_set_last_result(TBM_ERROR_NONE);
664 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
665 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
667 pthread_mutex_lock(&surface_queue->lock);
669 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
671 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
673 pthread_mutex_unlock(&surface_queue->lock);
675 _tbm_surf_queue_mutex_unlock();
677 return TBM_SURFACE_QUEUE_ERROR_NONE;
680 tbm_surface_queue_error_e
681 tbm_surface_queue_add_dequeuable_cb(
682 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
685 _tbm_surf_queue_mutex_lock();
686 _tbm_set_last_result(TBM_ERROR_NONE);
688 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
689 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
690 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
691 TBM_ERROR_INVALID_PARAMETER);
693 pthread_mutex_lock(&surface_queue->lock);
695 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
697 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
699 pthread_mutex_unlock(&surface_queue->lock);
701 _tbm_surf_queue_mutex_unlock();
703 return TBM_SURFACE_QUEUE_ERROR_NONE;
706 tbm_surface_queue_error_e
707 tbm_surface_queue_remove_dequeuable_cb(
708 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
711 _tbm_surf_queue_mutex_lock();
712 _tbm_set_last_result(TBM_ERROR_NONE);
714 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
715 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
717 pthread_mutex_lock(&surface_queue->lock);
719 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
721 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
723 pthread_mutex_unlock(&surface_queue->lock);
725 _tbm_surf_queue_mutex_unlock();
727 return TBM_SURFACE_QUEUE_ERROR_NONE;
730 tbm_surface_queue_error_e
731 tbm_surface_queue_add_dequeue_cb(
732 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
735 _tbm_surf_queue_mutex_lock();
736 _tbm_set_last_result(TBM_ERROR_NONE);
738 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
739 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
740 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
741 TBM_ERROR_INVALID_PARAMETER);
743 pthread_mutex_lock(&surface_queue->lock);
745 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
747 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
749 pthread_mutex_unlock(&surface_queue->lock);
751 _tbm_surf_queue_mutex_unlock();
753 return TBM_SURFACE_QUEUE_ERROR_NONE;
756 tbm_surface_queue_error_e
757 tbm_surface_queue_remove_dequeue_cb(
758 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
761 _tbm_surf_queue_mutex_lock();
762 _tbm_set_last_result(TBM_ERROR_NONE);
764 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
765 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
767 pthread_mutex_lock(&surface_queue->lock);
769 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
771 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
773 pthread_mutex_unlock(&surface_queue->lock);
775 _tbm_surf_queue_mutex_unlock();
777 return TBM_SURFACE_QUEUE_ERROR_NONE;
780 tbm_surface_queue_error_e
781 tbm_surface_queue_add_can_dequeue_cb(
782 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
785 _tbm_surf_queue_mutex_lock();
786 _tbm_set_last_result(TBM_ERROR_NONE);
788 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
789 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
790 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
791 TBM_ERROR_INVALID_PARAMETER);
793 pthread_mutex_lock(&surface_queue->lock);
795 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
797 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
799 pthread_mutex_unlock(&surface_queue->lock);
801 _tbm_surf_queue_mutex_unlock();
803 return TBM_SURFACE_QUEUE_ERROR_NONE;
806 tbm_surface_queue_error_e
807 tbm_surface_queue_remove_can_dequeue_cb(
808 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
811 _tbm_surf_queue_mutex_lock();
812 _tbm_set_last_result(TBM_ERROR_NONE);
814 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
815 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
817 pthread_mutex_lock(&surface_queue->lock);
819 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
821 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
823 pthread_mutex_unlock(&surface_queue->lock);
825 _tbm_surf_queue_mutex_unlock();
827 return TBM_SURFACE_QUEUE_ERROR_NONE;
830 tbm_surface_queue_error_e
831 tbm_surface_queue_add_acquirable_cb(
832 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
835 _tbm_surf_queue_mutex_lock();
836 _tbm_set_last_result(TBM_ERROR_NONE);
838 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
839 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
840 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
841 TBM_ERROR_INVALID_PARAMETER);
843 pthread_mutex_lock(&surface_queue->lock);
845 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
847 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
849 pthread_mutex_unlock(&surface_queue->lock);
851 _tbm_surf_queue_mutex_unlock();
853 return TBM_SURFACE_QUEUE_ERROR_NONE;
856 tbm_surface_queue_error_e
857 tbm_surface_queue_remove_acquirable_cb(
858 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
861 _tbm_surf_queue_mutex_lock();
862 _tbm_set_last_result(TBM_ERROR_NONE);
864 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
865 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
867 pthread_mutex_lock(&surface_queue->lock);
869 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
871 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
873 pthread_mutex_unlock(&surface_queue->lock);
875 _tbm_surf_queue_mutex_unlock();
877 return TBM_SURFACE_QUEUE_ERROR_NONE;
880 tbm_surface_queue_error_e
881 tbm_surface_queue_add_trace_cb(
882 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
885 _tbm_surf_queue_mutex_lock();
886 _tbm_set_last_result(TBM_ERROR_NONE);
888 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
889 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
890 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
891 TBM_ERROR_INVALID_PARAMETER);
893 pthread_mutex_lock(&surface_queue->lock);
895 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
897 _trace_add(&surface_queue->trace_noti, trace_cb, data);
899 pthread_mutex_unlock(&surface_queue->lock);
901 _tbm_surf_queue_mutex_unlock();
903 return TBM_SURFACE_QUEUE_ERROR_NONE;
906 tbm_surface_queue_error_e
907 tbm_surface_queue_remove_trace_cb(
908 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
911 _tbm_surf_queue_mutex_lock();
912 _tbm_set_last_result(TBM_ERROR_NONE);
914 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
915 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
917 pthread_mutex_lock(&surface_queue->lock);
919 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
921 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
923 pthread_mutex_unlock(&surface_queue->lock);
925 _tbm_surf_queue_mutex_unlock();
927 return TBM_SURFACE_QUEUE_ERROR_NONE;
930 tbm_surface_queue_error_e
931 tbm_surface_queue_set_alloc_cb(
932 tbm_surface_queue_h surface_queue,
933 tbm_surface_alloc_cb alloc_cb,
934 tbm_surface_free_cb free_cb,
937 _tbm_surf_queue_mutex_lock();
938 _tbm_set_last_result(TBM_ERROR_NONE);
940 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
941 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
943 pthread_mutex_lock(&surface_queue->lock);
945 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
947 surface_queue->alloc_cb = alloc_cb;
948 surface_queue->free_cb = free_cb;
949 surface_queue->alloc_cb_data = data;
951 pthread_mutex_unlock(&surface_queue->lock);
953 _tbm_surf_queue_mutex_unlock();
955 return TBM_SURFACE_QUEUE_ERROR_NONE;
959 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
963 _tbm_surf_queue_mutex_lock();
964 _tbm_set_last_result(TBM_ERROR_NONE);
966 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
968 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
970 width = surface_queue->width;
972 _tbm_surf_queue_mutex_unlock();
978 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
982 _tbm_surf_queue_mutex_lock();
983 _tbm_set_last_result(TBM_ERROR_NONE);
985 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
987 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
989 height = surface_queue->height;
991 _tbm_surf_queue_mutex_unlock();
997 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1001 _tbm_surf_queue_mutex_lock();
1002 _tbm_set_last_result(TBM_ERROR_NONE);
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 format = surface_queue->format;
1010 _tbm_surf_queue_mutex_unlock();
1016 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1020 _tbm_surf_queue_mutex_lock();
1021 _tbm_set_last_result(TBM_ERROR_NONE);
1023 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1025 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1027 queue_size = surface_queue->queue_size;
1029 _tbm_surf_queue_mutex_unlock();
1034 tbm_surface_queue_error_e
1035 tbm_surface_queue_add_reset_cb(
1036 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1039 _tbm_surf_queue_mutex_lock();
1040 _tbm_set_last_result(TBM_ERROR_NONE);
1042 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1043 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1044 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1045 TBM_ERROR_INVALID_PARAMETER);
1047 pthread_mutex_lock(&surface_queue->lock);
1049 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1051 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1053 pthread_mutex_unlock(&surface_queue->lock);
1055 _tbm_surf_queue_mutex_unlock();
1057 return TBM_SURFACE_QUEUE_ERROR_NONE;
1060 tbm_surface_queue_error_e
1061 tbm_surface_queue_remove_reset_cb(
1062 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1065 _tbm_surf_queue_mutex_lock();
1066 _tbm_set_last_result(TBM_ERROR_NONE);
1068 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1069 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1071 pthread_mutex_lock(&surface_queue->lock);
1073 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1075 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1077 pthread_mutex_unlock(&surface_queue->lock);
1079 _tbm_surf_queue_mutex_unlock();
1081 return TBM_SURFACE_QUEUE_ERROR_NONE;
1084 tbm_surface_queue_error_e
1085 tbm_surface_queue_enqueue(tbm_surface_queue_h
1086 surface_queue, tbm_surface_h surface)
1091 _tbm_surf_queue_mutex_lock();
1092 _tbm_set_last_result(TBM_ERROR_NONE);
1094 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1095 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1096 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1097 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1100 tbm_surface_internal_dump_buffer(surface, "enqueue");
1102 pthread_mutex_lock(&surface_queue->lock);
1104 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1106 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1107 if (node == NULL || queue_type != NODE_LIST) {
1108 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1110 pthread_mutex_unlock(&surface_queue->lock);
1112 _tbm_surf_queue_mutex_unlock();
1115 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1116 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1118 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1119 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1123 if (surface_queue->impl && surface_queue->impl->enqueue)
1124 surface_queue->impl->enqueue(surface_queue, node);
1126 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1128 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1129 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1130 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1131 pthread_mutex_unlock(&surface_queue->lock);
1133 _tbm_surf_queue_mutex_unlock();
1134 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1137 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1139 if (surface_queue->enqueue_sync_count == 1) {
1140 tbm_surface_info_s info;
1143 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1144 if (ret == TBM_SURFACE_ERROR_NONE)
1145 tbm_surface_unmap(surface);
1148 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1150 pthread_mutex_unlock(&surface_queue->lock);
1151 pthread_cond_signal(&surface_queue->dirty_cond);
1153 _tbm_surf_queue_mutex_unlock();
1155 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1157 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1159 return TBM_SURFACE_QUEUE_ERROR_NONE;
1162 tbm_surface_queue_error_e
1163 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1164 surface_queue, tbm_surface_h surface)
1169 _tbm_surf_queue_mutex_lock();
1170 _tbm_set_last_result(TBM_ERROR_NONE);
1172 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1173 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1174 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1175 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1177 pthread_mutex_lock(&surface_queue->lock);
1179 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1181 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1182 if (node == NULL || queue_type != NODE_LIST) {
1183 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1185 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1186 pthread_mutex_unlock(&surface_queue->lock);
1188 _tbm_surf_queue_mutex_unlock();
1189 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1192 if (node->delete_pending) {
1193 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1195 _queue_delete_node(surface_queue, node);
1197 pthread_mutex_unlock(&surface_queue->lock);
1199 _tbm_surf_queue_mutex_unlock();
1201 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1203 return TBM_SURFACE_QUEUE_ERROR_NONE;
1206 if (surface_queue->queue_size < surface_queue->num_attached) {
1207 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1209 if (surface_queue->impl && surface_queue->impl->need_detach)
1210 surface_queue->impl->need_detach(surface_queue, node);
1212 _tbm_surface_queue_detach(surface_queue, surface);
1214 pthread_mutex_unlock(&surface_queue->lock);
1216 _tbm_surf_queue_mutex_unlock();
1218 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1220 return TBM_SURFACE_QUEUE_ERROR_NONE;
1223 if (surface_queue->impl && surface_queue->impl->release)
1224 surface_queue->impl->release(surface_queue, node);
1226 _tbm_surface_queue_release(surface_queue, node, 1);
1228 if (_queue_is_empty(&surface_queue->free_queue)) {
1229 TBM_ERR("surface_queue->free_queue is empty.\n");
1230 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1231 pthread_mutex_unlock(&surface_queue->lock);
1233 _tbm_surf_queue_mutex_unlock();
1234 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1237 node->type = QUEUE_NODE_TYPE_RELEASE;
1239 pthread_mutex_unlock(&surface_queue->lock);
1240 pthread_cond_signal(&surface_queue->free_cond);
1242 _tbm_surf_queue_mutex_unlock();
1244 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1246 return TBM_SURFACE_QUEUE_ERROR_NONE;
1249 tbm_surface_queue_error_e
1250 tbm_surface_queue_dequeue(tbm_surface_queue_h
1251 surface_queue, tbm_surface_h *surface)
1255 _tbm_surf_queue_mutex_lock();
1256 _tbm_set_last_result(TBM_ERROR_NONE);
1258 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1259 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1260 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1261 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1265 pthread_mutex_lock(&surface_queue->lock);
1267 if (_queue_is_empty(&surface_queue->free_queue)) {
1268 if (surface_queue->impl && surface_queue->impl->need_attach)
1269 surface_queue->impl->need_attach(surface_queue);
1271 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1272 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1273 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1274 pthread_mutex_unlock(&surface_queue->lock);
1275 _tbm_surf_queue_mutex_unlock();
1276 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1280 if (surface_queue->impl && surface_queue->impl->dequeue)
1281 node = surface_queue->impl->dequeue(surface_queue);
1283 node = _tbm_surface_queue_dequeue(surface_queue);
1285 if (node == NULL || node->surface == NULL) {
1286 TBM_ERR("_queue_node_pop_front failed\n");
1287 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1288 pthread_mutex_unlock(&surface_queue->lock);
1290 _tbm_surf_queue_mutex_unlock();
1291 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1294 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1295 *surface = node->surface;
1297 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1299 pthread_mutex_unlock(&surface_queue->lock);
1301 _tbm_surf_queue_mutex_unlock();
1303 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1305 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1307 return TBM_SURFACE_QUEUE_ERROR_NONE;
1310 tbm_surface_queue_error_e
1311 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1316 _tbm_surf_queue_mutex_lock();
1317 _tbm_set_last_result(TBM_ERROR_NONE);
1319 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1320 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1322 _tbm_surf_queue_mutex_unlock();
1324 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1326 _tbm_surf_queue_mutex_lock();
1328 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1329 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1331 pthread_mutex_lock(&surface_queue->lock);
1333 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1335 if (_queue_is_empty(&surface_queue->free_queue)) {
1336 if (surface_queue->impl && surface_queue->impl->need_attach)
1337 surface_queue->impl->need_attach(surface_queue);
1339 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1340 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1341 pthread_mutex_unlock(&surface_queue->lock);
1342 _tbm_surf_queue_mutex_unlock();
1343 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1347 if (!_queue_is_empty(&surface_queue->free_queue)) {
1348 pthread_mutex_unlock(&surface_queue->lock);
1349 _tbm_surf_queue_mutex_unlock();
1350 return TBM_SURFACE_QUEUE_ERROR_NONE;
1353 _tbm_surf_queue_mutex_unlock();
1356 clock_gettime(CLOCK_REALTIME, &tp);
1358 if (ms_timeout > 1000)
1359 tp.tv_sec += ms_timeout / 1000;
1361 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1363 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1365 if (ret == ETIMEDOUT) {
1366 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1367 pthread_mutex_unlock(&surface_queue->lock);
1368 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1370 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1374 pthread_mutex_unlock(&surface_queue->lock);
1375 return TBM_SURFACE_QUEUE_ERROR_NONE;
1381 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1383 _tbm_surf_queue_mutex_lock();
1384 _tbm_set_last_result(TBM_ERROR_NONE);
1386 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1388 _tbm_surf_queue_mutex_unlock();
1390 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1392 _tbm_surf_queue_mutex_lock();
1394 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1396 pthread_mutex_lock(&surface_queue->lock);
1398 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1400 if (_queue_is_empty(&surface_queue->free_queue)) {
1401 if (surface_queue->impl && surface_queue->impl->need_attach)
1402 surface_queue->impl->need_attach(surface_queue);
1404 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1405 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1406 pthread_mutex_unlock(&surface_queue->lock);
1407 _tbm_surf_queue_mutex_unlock();
1412 if (!_queue_is_empty(&surface_queue->free_queue)) {
1413 pthread_mutex_unlock(&surface_queue->lock);
1414 _tbm_surf_queue_mutex_unlock();
1419 _tbm_surf_queue_mutex_unlock();
1420 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1421 pthread_mutex_unlock(&surface_queue->lock);
1425 pthread_mutex_unlock(&surface_queue->lock);
1426 _tbm_surf_queue_mutex_unlock();
1430 tbm_surface_queue_error_e
1431 tbm_surface_queue_release(tbm_surface_queue_h
1432 surface_queue, tbm_surface_h surface)
1437 _tbm_surf_queue_mutex_lock();
1438 _tbm_set_last_result(TBM_ERROR_NONE);
1440 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1441 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1442 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1443 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1445 pthread_mutex_lock(&surface_queue->lock);
1447 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1449 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1450 if (node == NULL || queue_type != NODE_LIST) {
1451 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1453 pthread_mutex_unlock(&surface_queue->lock);
1455 _tbm_surf_queue_mutex_unlock();
1458 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1459 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1461 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1462 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1466 if (node->delete_pending) {
1467 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1469 _queue_delete_node(surface_queue, node);
1471 pthread_mutex_unlock(&surface_queue->lock);
1473 _tbm_surf_queue_mutex_unlock();
1475 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1477 return TBM_SURFACE_QUEUE_ERROR_NONE;
1480 if (surface_queue->queue_size < surface_queue->num_attached) {
1481 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1483 if (surface_queue->impl && surface_queue->impl->need_detach)
1484 surface_queue->impl->need_detach(surface_queue, node);
1486 _tbm_surface_queue_detach(surface_queue, surface);
1488 pthread_mutex_unlock(&surface_queue->lock);
1490 _tbm_surf_queue_mutex_unlock();
1492 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1494 return TBM_SURFACE_QUEUE_ERROR_NONE;
1497 if (surface_queue->impl && surface_queue->impl->release)
1498 surface_queue->impl->release(surface_queue, node);
1500 _tbm_surface_queue_release(surface_queue, node, 1);
1502 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1503 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1504 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1505 pthread_mutex_unlock(&surface_queue->lock);
1507 _tbm_surf_queue_mutex_unlock();
1508 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1511 node->type = QUEUE_NODE_TYPE_RELEASE;
1513 pthread_mutex_unlock(&surface_queue->lock);
1514 pthread_cond_signal(&surface_queue->free_cond);
1516 _tbm_surf_queue_mutex_unlock();
1518 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1520 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1522 return TBM_SURFACE_QUEUE_ERROR_NONE;
1525 tbm_surface_queue_error_e
1526 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1527 surface_queue, tbm_surface_h surface)
1532 _tbm_surf_queue_mutex_lock();
1533 _tbm_set_last_result(TBM_ERROR_NONE);
1535 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1536 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1537 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1538 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1540 pthread_mutex_lock(&surface_queue->lock);
1542 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1544 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1545 if (node == NULL || queue_type != NODE_LIST) {
1546 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1548 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1549 pthread_mutex_unlock(&surface_queue->lock);
1551 _tbm_surf_queue_mutex_unlock();
1552 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1555 if (surface_queue->impl && surface_queue->impl->enqueue)
1556 surface_queue->impl->enqueue(surface_queue, node);
1558 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1560 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1561 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1562 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1563 pthread_mutex_unlock(&surface_queue->lock);
1565 _tbm_surf_queue_mutex_unlock();
1566 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1569 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1571 pthread_mutex_unlock(&surface_queue->lock);
1572 pthread_cond_signal(&surface_queue->dirty_cond);
1574 _tbm_surf_queue_mutex_unlock();
1576 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1578 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1580 return TBM_SURFACE_QUEUE_ERROR_NONE;
1583 tbm_surface_queue_error_e
1584 tbm_surface_queue_acquire(tbm_surface_queue_h
1585 surface_queue, tbm_surface_h *surface)
1589 _tbm_surf_queue_mutex_lock();
1590 _tbm_set_last_result(TBM_ERROR_NONE);
1594 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1595 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1596 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1597 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1599 pthread_mutex_lock(&surface_queue->lock);
1601 if (surface_queue->impl && surface_queue->impl->acquire)
1602 node = surface_queue->impl->acquire(surface_queue);
1604 node = _tbm_surface_queue_acquire(surface_queue);
1606 if (node == NULL || node->surface == NULL) {
1607 TBM_ERR("_queue_node_pop_front failed\n");
1608 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1609 pthread_mutex_unlock(&surface_queue->lock);
1611 _tbm_surf_queue_mutex_unlock();
1612 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1615 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1617 *surface = node->surface;
1619 if (surface_queue->acquire_sync_count == 1) {
1620 tbm_surface_info_s info;
1623 TBM_ERR("start map surface:%p", *surface);
1624 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1625 TBM_ERR("end map surface:%p", *surface);
1626 if (ret == TBM_SURFACE_ERROR_NONE)
1627 tbm_surface_unmap(*surface);
1630 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1632 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1634 pthread_mutex_unlock(&surface_queue->lock);
1636 _tbm_surf_queue_mutex_unlock();
1639 tbm_surface_internal_dump_buffer(*surface, "acquire");
1641 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1643 return TBM_SURFACE_QUEUE_ERROR_NONE;
1647 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1649 _tbm_surf_queue_mutex_lock();
1650 _tbm_set_last_result(TBM_ERROR_NONE);
1652 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1654 pthread_mutex_lock(&surface_queue->lock);
1656 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1658 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1659 pthread_mutex_unlock(&surface_queue->lock);
1660 _tbm_surf_queue_mutex_unlock();
1664 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1665 QUEUE_NODE_TYPE_DEQUEUE)) {
1666 _tbm_surf_queue_mutex_unlock();
1667 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1668 pthread_mutex_unlock(&surface_queue->lock);
1672 pthread_mutex_unlock(&surface_queue->lock);
1673 _tbm_surf_queue_mutex_unlock();
1678 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1680 queue_node *node = NULL, *tmp;
1682 _tbm_surf_queue_mutex_lock();
1683 _tbm_set_last_result(TBM_ERROR_NONE);
1685 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1687 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1689 LIST_DEL(&surface_queue->item_link);
1691 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1692 _queue_delete_node(surface_queue, node);
1694 if (surface_queue->impl && surface_queue->impl->destroy)
1695 surface_queue->impl->destroy(surface_queue);
1697 _notify_emit(surface_queue, &surface_queue->destory_noti);
1699 _notify_remove_all(&surface_queue->destory_noti);
1700 _notify_remove_all(&surface_queue->dequeuable_noti);
1701 _notify_remove_all(&surface_queue->dequeue_noti);
1702 _notify_remove_all(&surface_queue->can_dequeue_noti);
1703 _notify_remove_all(&surface_queue->acquirable_noti);
1704 _notify_remove_all(&surface_queue->reset_noti);
1705 _trace_remove_all(&surface_queue->trace_noti);
1707 pthread_mutex_destroy(&surface_queue->lock);
1709 free(surface_queue);
1711 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1712 _deinit_tbm_surf_queue_bufmgr();
1714 _tbm_surf_queue_mutex_unlock();
1717 tbm_surface_queue_error_e
1718 tbm_surface_queue_reset(tbm_surface_queue_h
1719 surface_queue, int width, int height, int format)
1721 queue_node *node = NULL, *tmp;
1723 _tbm_surf_queue_mutex_lock();
1724 _tbm_set_last_result(TBM_ERROR_NONE);
1726 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1727 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1729 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1731 if (width == surface_queue->width && height == surface_queue->height &&
1732 format == surface_queue->format) {
1733 _tbm_surf_queue_mutex_unlock();
1734 return TBM_SURFACE_QUEUE_ERROR_NONE;
1737 pthread_mutex_lock(&surface_queue->lock);
1739 surface_queue->width = width;
1740 surface_queue->height = height;
1741 surface_queue->format = format;
1743 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1744 /* Destory surface and Push to free_queue */
1745 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1746 _queue_delete_node(surface_queue, node);
1748 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1749 node->delete_pending = 1;
1751 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1752 _queue_delete_node(surface_queue, node);
1754 _queue_init(&surface_queue->dirty_queue);
1755 LIST_INITHEAD(&surface_queue->list);
1759 _queue_init(&surface_queue->free_queue);
1761 surface_queue->num_attached = 0;
1763 if (surface_queue->impl && surface_queue->impl->reset)
1764 surface_queue->impl->reset(surface_queue);
1766 pthread_mutex_unlock(&surface_queue->lock);
1767 pthread_cond_signal(&surface_queue->free_cond);
1769 _tbm_surf_queue_mutex_unlock();
1771 _notify_emit(surface_queue, &surface_queue->reset_noti);
1773 return TBM_SURFACE_QUEUE_ERROR_NONE;
1776 tbm_surface_queue_error_e
1777 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1779 _tbm_surf_queue_mutex_lock();
1780 _tbm_set_last_result(TBM_ERROR_NONE);
1782 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1783 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1785 _tbm_surf_queue_mutex_unlock();
1787 _notify_emit(surface_queue, &surface_queue->reset_noti);
1789 return TBM_SURFACE_QUEUE_ERROR_NONE;
1792 tbm_surface_queue_error_e
1793 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1795 _tbm_surf_queue_mutex_lock();
1796 _tbm_set_last_result(TBM_ERROR_NONE);
1798 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1799 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1801 pthread_mutex_lock(&surface_queue->lock);
1802 pthread_mutex_unlock(&surface_queue->lock);
1803 pthread_cond_signal(&surface_queue->free_cond);
1805 _tbm_surf_queue_mutex_unlock();
1807 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1809 return TBM_SURFACE_QUEUE_ERROR_NONE;
1812 tbm_surface_queue_error_e
1813 tbm_surface_queue_set_size(tbm_surface_queue_h
1814 surface_queue, int queue_size, int flush)
1816 queue_node *node = NULL, *tmp;
1818 _tbm_surf_queue_mutex_lock();
1819 _tbm_set_last_result(TBM_ERROR_NONE);
1821 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1822 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1823 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1824 TBM_ERROR_INVALID_PARAMETER);
1826 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1828 if ((surface_queue->queue_size == queue_size) && !flush) {
1829 _tbm_surf_queue_mutex_unlock();
1830 return TBM_SURFACE_QUEUE_ERROR_NONE;
1833 pthread_mutex_lock(&surface_queue->lock);
1836 surface_queue->queue_size = queue_size;
1838 if (surface_queue->num_attached == 0) {
1839 pthread_mutex_unlock(&surface_queue->lock);
1840 _tbm_surf_queue_mutex_unlock();
1841 return TBM_SURFACE_QUEUE_ERROR_NONE;
1844 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1845 /* Destory surface and Push to free_queue */
1846 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1847 _queue_delete_node(surface_queue, node);
1849 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1850 node->delete_pending = 1;
1852 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1853 _queue_delete_node(surface_queue, node);
1855 _queue_init(&surface_queue->dirty_queue);
1856 LIST_INITHEAD(&surface_queue->list);
1860 _queue_init(&surface_queue->free_queue);
1862 surface_queue->num_attached = 0;
1864 if (surface_queue->impl && surface_queue->impl->reset)
1865 surface_queue->impl->reset(surface_queue);
1867 pthread_mutex_unlock(&surface_queue->lock);
1868 pthread_cond_signal(&surface_queue->free_cond);
1870 _tbm_surf_queue_mutex_unlock();
1872 _notify_emit(surface_queue, &surface_queue->reset_noti);
1874 return TBM_SURFACE_QUEUE_ERROR_NONE;
1876 if (surface_queue->queue_size > queue_size) {
1877 int need_del = surface_queue->queue_size - queue_size;
1879 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1880 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1882 if (surface_queue->impl && surface_queue->impl->need_detach)
1883 surface_queue->impl->need_detach(surface_queue, node);
1885 _tbm_surface_queue_detach(surface_queue, node->surface);
1893 surface_queue->queue_size = queue_size;
1895 pthread_mutex_unlock(&surface_queue->lock);
1897 _tbm_surf_queue_mutex_unlock();
1899 return TBM_SURFACE_QUEUE_ERROR_NONE;
1903 tbm_surface_queue_error_e
1904 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1906 queue_node *node = NULL;
1908 _tbm_surf_queue_mutex_lock();
1909 _tbm_set_last_result(TBM_ERROR_NONE);
1911 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1912 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1914 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1916 if (surface_queue->num_attached == 0) {
1917 _tbm_surf_queue_mutex_unlock();
1918 return TBM_SURFACE_QUEUE_ERROR_NONE;
1921 pthread_mutex_lock(&surface_queue->lock);
1923 /* Destory surface in free_queue */
1924 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1925 if (surface_queue->impl && surface_queue->impl->need_detach)
1926 surface_queue->impl->need_detach(surface_queue, node);
1928 _tbm_surface_queue_detach(surface_queue, node->surface);
1932 _queue_init(&surface_queue->free_queue);
1934 pthread_mutex_unlock(&surface_queue->lock);
1935 _tbm_surf_queue_mutex_unlock();
1937 return TBM_SURFACE_QUEUE_ERROR_NONE;
1940 tbm_surface_queue_error_e
1941 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1943 queue_node *node = NULL, *tmp;
1945 _tbm_surf_queue_mutex_lock();
1946 _tbm_set_last_result(TBM_ERROR_NONE);
1948 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1949 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1951 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1953 if (surface_queue->num_attached == 0) {
1954 _tbm_surf_queue_mutex_unlock();
1955 return TBM_SURFACE_QUEUE_ERROR_NONE;
1958 pthread_mutex_lock(&surface_queue->lock);
1960 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1961 /* Destory surface and Push to free_queue */
1962 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1963 _queue_delete_node(surface_queue, node);
1965 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1966 node->delete_pending = 1;
1968 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1969 _queue_delete_node(surface_queue, node);
1971 _queue_init(&surface_queue->dirty_queue);
1972 LIST_INITHEAD(&surface_queue->list);
1976 _queue_init(&surface_queue->free_queue);
1978 surface_queue->num_attached = 0;
1980 if (surface_queue->impl && surface_queue->impl->reset)
1981 surface_queue->impl->reset(surface_queue);
1983 pthread_mutex_unlock(&surface_queue->lock);
1984 pthread_cond_signal(&surface_queue->free_cond);
1986 _tbm_surf_queue_mutex_unlock();
1988 _notify_emit(surface_queue, &surface_queue->reset_noti);
1990 return TBM_SURFACE_QUEUE_ERROR_NONE;
1993 tbm_surface_queue_error_e
1994 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1995 tbm_surface_h *surfaces, int *num)
1997 queue_node *node = NULL;
1999 _tbm_surf_queue_mutex_lock();
2000 _tbm_set_last_result(TBM_ERROR_NONE);
2002 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2003 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2004 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2005 TBM_ERROR_INVALID_PARAMETER);
2009 pthread_mutex_lock(&surface_queue->lock);
2011 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2012 if (node->delete_pending) continue;
2015 surfaces[*num] = node->surface;
2020 pthread_mutex_unlock(&surface_queue->lock);
2022 _tbm_surf_queue_mutex_unlock();
2024 return TBM_SURFACE_QUEUE_ERROR_NONE;
2027 tbm_surface_queue_error_e
2028 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2029 tbm_surface_h *surfaces, int *num)
2031 queue_node *node = NULL;
2033 _tbm_surf_queue_mutex_lock();
2037 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2038 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2039 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2040 TBM_ERROR_INVALID_PARAMETER);
2042 pthread_mutex_lock(&surface_queue->lock);
2044 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2046 surfaces[*num] = node->surface;
2051 pthread_mutex_unlock(&surface_queue->lock);
2053 _tbm_surf_queue_mutex_unlock();
2055 return TBM_SURFACE_QUEUE_ERROR_NONE;
2058 tbm_surface_queue_error_e
2059 tbm_surface_queue_get_trace_surface_num(
2060 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2062 _tbm_surf_queue_mutex_lock();
2063 _tbm_set_last_result(TBM_ERROR_NONE);
2065 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2066 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2067 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2068 TBM_ERROR_INVALID_PARAMETER);
2072 pthread_mutex_lock(&surface_queue->lock);
2075 case TBM_SURFACE_QUEUE_TRACE_NONE:
2078 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2079 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2081 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2082 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2084 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2085 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2087 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2088 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2094 pthread_mutex_unlock(&surface_queue->lock);
2096 _tbm_surf_queue_mutex_unlock();
2098 return TBM_SURFACE_QUEUE_ERROR_NONE;
2103 } tbm_queue_default;
2106 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
2108 free(surface_queue->impl_data);
2112 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
2114 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
2115 tbm_surface_h surface;
2117 if (surface_queue->queue_size == surface_queue->num_attached)
2120 if (surface_queue->alloc_cb) {
2121 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2127 tbm_surface_internal_ref(surface);
2129 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2130 surface_queue->height,
2131 surface_queue->format,
2133 TBM_RETURN_IF_FAIL(surface != NULL);
2136 _tbm_surface_queue_attach(surface_queue, surface);
2137 tbm_surface_internal_unref(surface);
2140 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2141 NULL, /*__tbm_queue_default_init*/
2142 NULL, /*__tbm_queue_default_reset*/
2143 __tbm_queue_default_destroy,
2144 __tbm_queue_default_need_attach,
2145 NULL, /*__tbm_queue_default_enqueue*/
2146 NULL, /*__tbm_queue_default_release*/
2147 NULL, /*__tbm_queue_default_dequeue*/
2148 NULL, /*__tbm_queue_default_acquire*/
2149 NULL, /*__tbm_queue_default_need_detach*/
2153 tbm_surface_queue_create(int queue_size, int width,
2154 int height, int format, int flags)
2156 _tbm_surf_queue_mutex_lock();
2157 _tbm_set_last_result(TBM_ERROR_NONE);
2159 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2160 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2161 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2162 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2164 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2165 sizeof(struct _tbm_surface_queue));
2166 if (!surface_queue) {
2167 TBM_ERR("cannot allocate the surface_queue.\n");
2168 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2169 _tbm_surf_queue_mutex_unlock();
2173 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2175 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2176 sizeof(tbm_queue_default));
2178 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2179 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2180 free(surface_queue);
2181 _tbm_surf_queue_mutex_unlock();
2185 data->flags = flags;
2186 _tbm_surface_queue_init(surface_queue,
2188 width, height, format,
2189 &tbm_queue_default_impl, data);
2191 _tbm_surf_queue_mutex_unlock();
2193 return surface_queue;
2199 } tbm_queue_sequence;
2202 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2204 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2206 _queue_init(&data->dequeue_list);
2210 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2212 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2214 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2217 _queue_init(&data->dequeue_list);
2221 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2223 free(surface_queue->impl_data);
2227 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2229 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2230 tbm_surface_h surface;
2232 if (surface_queue->queue_size == surface_queue->num_attached)
2235 if (surface_queue->alloc_cb) {
2236 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2242 tbm_surface_internal_ref(surface);
2244 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2245 surface_queue->height,
2246 surface_queue->format,
2248 TBM_RETURN_IF_FAIL(surface != NULL);
2251 _tbm_surface_queue_attach(surface_queue, surface);
2252 tbm_surface_internal_unref(surface);
2256 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2259 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2260 queue_node *first = NULL;
2262 first = container_of(data->dequeue_list.head.next, first, item_link);
2263 if (first != node) {
2267 node->priv_flags = 0;
2269 _queue_node_pop(&data->dequeue_list, node);
2270 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2274 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2277 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2279 if (node->priv_flags) {
2280 node->priv_flags = 0;
2281 _queue_node_pop(&data->dequeue_list, node);
2284 _tbm_surface_queue_release(surface_queue, node, 1);
2288 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2291 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2294 node = _tbm_surface_queue_dequeue(surface_queue);
2296 _queue_node_push_back(&data->dequeue_list, node);
2297 node->priv_flags = 1;
2303 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2304 __tbm_queue_sequence_init,
2305 __tbm_queue_sequence_reset,
2306 __tbm_queue_sequence_destroy,
2307 __tbm_queue_sequence_need_attach,
2308 __tbm_queue_sequence_enqueue,
2309 __tbm_queue_sequence_release,
2310 __tbm_queue_sequence_dequeue,
2311 NULL, /*__tbm_queue_sequence_acquire*/
2312 NULL, /*__tbm_queue_sequence_need_dettach*/
2316 tbm_surface_queue_sequence_create(int queue_size, int width,
2317 int height, int format, int flags)
2319 _tbm_surf_queue_mutex_lock();
2320 _tbm_set_last_result(TBM_ERROR_NONE);
2322 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2323 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2324 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2325 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2327 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2328 sizeof(struct _tbm_surface_queue));
2329 if (surface_queue == NULL) {
2330 TBM_ERR("cannot allocate the surface_queue.\n");
2331 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2332 _tbm_surf_queue_mutex_unlock();
2336 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2338 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2339 sizeof(tbm_queue_sequence));
2341 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2342 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2343 free(surface_queue);
2344 _tbm_surf_queue_mutex_unlock();
2348 data->flags = flags;
2349 _tbm_surface_queue_init(surface_queue,
2351 width, height, format,
2352 &tbm_queue_sequence_impl, data);
2354 _tbm_surf_queue_mutex_unlock();
2356 return surface_queue;
2359 tbm_surface_queue_error_e
2360 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2363 _tbm_surf_queue_mutex_lock();
2364 _tbm_set_last_result(TBM_ERROR_NONE);
2366 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2367 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2369 pthread_mutex_lock(&surface_queue->lock);
2371 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2372 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2374 surface_queue->modes |= modes;
2376 pthread_mutex_unlock(&surface_queue->lock);
2378 _tbm_surf_queue_mutex_unlock();
2380 return TBM_SURFACE_QUEUE_ERROR_NONE;
2383 tbm_surface_queue_error_e
2384 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2385 unsigned int sync_count)
2387 int dequeue_num, enqueue_num;
2389 _tbm_surf_queue_mutex_lock();
2390 _tbm_set_last_result(TBM_ERROR_NONE);
2392 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2393 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2395 pthread_mutex_lock(&surface_queue->lock);
2397 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2398 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2400 if (dequeue_num + sync_count == 0)
2401 surface_queue->acquire_sync_count = enqueue_num;
2403 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2405 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2406 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2408 pthread_mutex_unlock(&surface_queue->lock);
2410 _tbm_surf_queue_mutex_unlock();
2412 return TBM_SURFACE_QUEUE_ERROR_NONE;