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 #define TBM_QUEUE_DEBUG 0
44 #define TBM_QUEUE_TRACE(fmt, ...) { if (bTrace&0x1) fprintf(stderr, "[TBM:TRACE(%d)(%s:%d)] " fmt, getpid(), __func__, __LINE__, ##__VA_ARGS__); }
46 #define TBM_QUEUE_TRACE(fmt, ...)
50 #define TBM_LOCK() TBM_LOG_D("[LOCK] %s:%d surface:%p\n", __func__, __LINE__, surface_queue)
51 #define TBM_UNLOCK() TBM_LOG_D("[UNLOCK] %s:%d surface:%p\n", __func__, __LINE__, surface_queue)
57 static tbm_bufmgr g_surf_queue_bufmgr;
58 static pthread_mutex_t tbm_surf_queue_lock;
59 void _tbm_surface_queue_mutex_unlock(void);
62 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
64 TBM_LOG_E("'%s' failed.\n", #cond);\
65 _tbm_surf_queue_mutex_unlock();\
70 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
72 TBM_LOG_E("'%s' failed.\n", #cond);\
73 _tbm_surf_queue_mutex_unlock();\
78 typedef enum _queue_node_type {
80 QUEUE_NODE_TYPE_DEQUEUE,
81 QUEUE_NODE_TYPE_ENQUEUE,
82 QUEUE_NODE_TYPE_ACQUIRE,
83 QUEUE_NODE_TYPE_RELEASE
87 struct list_head head;
92 tbm_surface_h surface;
94 struct list_head item_link;
95 struct list_head link;
99 unsigned int priv_flags; /*for each queue*/
103 struct list_head link;
105 tbm_surface_queue_notify_cb cb;
110 struct list_head link;
112 tbm_surface_queue_trace_cb cb;
116 typedef struct _tbm_surface_queue_interface {
117 void (*init)(tbm_surface_queue_h queue);
118 void (*reset)(tbm_surface_queue_h queue);
119 void (*destroy)(tbm_surface_queue_h queue);
120 void (*need_attach)(tbm_surface_queue_h queue);
122 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
123 void (*release)(tbm_surface_queue_h queue, queue_node *node);
124 queue_node *(*dequeue)(tbm_surface_queue_h queue);
125 queue_node *(*acquire)(tbm_surface_queue_h queue);
126 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
127 } tbm_surface_queue_interface;
129 struct _tbm_surface_queue {
138 struct list_head list;
140 struct list_head destory_noti;
141 struct list_head dequeuable_noti;
142 struct list_head dequeue_noti;
143 struct list_head can_dequeue_noti;
144 struct list_head acquirable_noti;
145 struct list_head reset_noti;
146 struct list_head trace_noti;
148 pthread_mutex_t lock;
149 pthread_cond_t free_cond;
150 pthread_cond_t dirty_cond;
152 const tbm_surface_queue_interface *impl;
155 //For external buffer allocation
156 tbm_surface_alloc_cb alloc_cb;
157 tbm_surface_free_cb free_cb;
160 struct list_head item_link; /* link of surface queue */
163 /* LCOV_EXCL_START */
166 _tbm_surf_queue_mutex_init(void)
168 static bool tbm_surf_queue_mutex_init = false;
170 if (tbm_surf_queue_mutex_init)
173 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
174 TBM_LOG_E("fail: pthread_mutex_init\n");
178 tbm_surf_queue_mutex_init = true;
184 _tbm_surf_queue_mutex_lock(void)
186 if (!_tbm_surf_queue_mutex_init()) {
187 TBM_LOG_E("fail: _tbm_surf_queue_mutex_init\n");
191 pthread_mutex_lock(&tbm_surf_queue_lock);
195 _tbm_surf_queue_mutex_unlock(void)
197 pthread_mutex_unlock(&tbm_surf_queue_lock);
201 _init_tbm_surf_queue_bufmgr(void)
203 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
207 _deinit_tbm_surf_queue_bufmgr(void)
209 if (!g_surf_queue_bufmgr)
212 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
213 g_surf_queue_bufmgr = NULL;
217 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
219 tbm_surface_queue_h old_data = NULL;
221 if (surface_queue == NULL) {
222 TBM_LOG_E("error: surface_queue is NULL.\n");
226 if (g_surf_queue_bufmgr == NULL) {
227 TBM_LOG_E("error: g_surf_queue_bufmgr is NULL.\n");
231 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
232 TBM_LOG_E("error: surf_queue_list is empty\n");
236 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
238 if (old_data == surface_queue) {
239 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
244 TBM_LOG_E("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
250 _queue_node_create(void)
252 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
254 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
260 _queue_node_delete(queue_node *node)
262 LIST_DEL(&node->item_link);
263 LIST_DEL(&node->link);
268 _queue_is_empty(queue *queue)
270 if (LIST_IS_EMPTY(&queue->head))
277 _queue_node_push_back(queue *queue, queue_node *node)
279 LIST_ADDTAIL(&node->item_link, &queue->head);
284 _queue_node_push_front(queue *queue, queue_node *node)
286 LIST_ADD(&node->item_link, &queue->head);
291 _queue_node_pop_front(queue *queue)
295 if (!queue->head.next) return NULL;
296 if (!queue->count) return NULL;
298 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
300 LIST_DELINIT(&node->item_link);
307 _queue_node_pop(queue *queue, queue_node *node)
309 LIST_DELINIT(&node->item_link);
316 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
317 tbm_surface_h surface, int *out_type)
319 queue_node *node = NULL;
322 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
326 if (type & FREE_QUEUE) {
327 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
329 if (node->surface == surface) {
331 *out_type = FREE_QUEUE;
338 if (type & DIRTY_QUEUE) {
339 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
341 if (node->surface == surface) {
343 *out_type = DIRTY_QUEUE;
350 if (type & NODE_LIST) {
351 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
352 if (node->surface == surface) {
354 *out_type = NODE_LIST;
361 TBM_LOG_E("fail to get the queue_node.\n");
367 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
370 if (surface_queue->free_cb) {
371 surface_queue->free_cb(surface_queue,
372 surface_queue->alloc_cb_data,
376 tbm_surface_destroy(node->surface);
379 _queue_node_delete(node);
383 _queue_init(queue *queue)
385 LIST_INITHEAD(&queue->head);
391 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
394 TBM_RETURN_IF_FAIL(cb != NULL);
396 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
398 TBM_RETURN_IF_FAIL(item != NULL);
400 LIST_INITHEAD(&item->link);
404 LIST_ADDTAIL(&item->link, list);
408 _notify_remove(struct list_head *list,
409 tbm_surface_queue_notify_cb cb, void *data)
411 queue_notify *item = NULL, *tmp;
413 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
414 if (item->cb == cb && item->data == data) {
415 LIST_DEL(&item->link);
421 TBM_LOG_E("Cannot find notifiy\n");
425 _notify_remove_all(struct list_head *list)
427 queue_notify *item = NULL, *tmp;
429 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
430 LIST_DEL(&item->link);
436 _notify_emit(tbm_surface_queue_h surface_queue,
437 struct list_head *list)
439 queue_notify *item = NULL, *tmp;;
442 The item->cb is the outside function of the libtbm.
443 The tbm user may/can remove the item of the list,
444 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
446 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
447 item->cb(surface_queue, item->data);
451 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
454 TBM_RETURN_IF_FAIL(cb != NULL);
456 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
458 TBM_RETURN_IF_FAIL(item != NULL);
460 LIST_INITHEAD(&item->link);
464 LIST_ADDTAIL(&item->link, list);
468 _trace_remove(struct list_head *list,
469 tbm_surface_queue_trace_cb cb, void *data)
471 queue_trace *item = NULL, *tmp;
473 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
474 if (item->cb == cb && item->data == data) {
475 LIST_DEL(&item->link);
481 TBM_LOG_E("Cannot find notifiy\n");
485 _trace_remove_all(struct list_head *list)
487 queue_trace *item = NULL, *tmp;
489 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
490 LIST_DEL(&item->link);
496 _trace_emit(tbm_surface_queue_h surface_queue,
497 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
499 queue_trace *item = NULL, *tmp;;
502 The item->cb is the outside function of the libtbm.
503 The tbm user may/can remove the item of the list,
504 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
506 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
507 item->cb(surface_queue, surface, trace, item->data);
511 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
513 queue_node *node = NULL;
516 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
517 if (node->type == type)
525 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
526 tbm_surface_h surface)
530 node = _queue_node_create();
531 TBM_RETURN_IF_FAIL(node != NULL);
533 tbm_surface_internal_ref(surface);
534 node->surface = surface;
536 LIST_ADDTAIL(&node->link, &surface_queue->list);
537 surface_queue->num_attached++;
538 _queue_node_push_back(&surface_queue->free_queue, node);
542 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
543 tbm_surface_h surface)
548 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
550 _queue_delete_node(surface_queue, node);
551 surface_queue->num_attached--;
556 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
557 queue_node *node, int push_back)
560 _queue_node_push_back(&surface_queue->dirty_queue, node);
562 _queue_node_push_front(&surface_queue->dirty_queue, node);
566 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
570 if (_queue_is_empty(&surface_queue->free_queue)) {
571 if (surface_queue->impl && surface_queue->impl->need_attach)
572 surface_queue->impl->need_attach(surface_queue);
574 if (_queue_is_empty(&surface_queue->free_queue)) {
575 TBM_LOG_E("surface_queue->free_queue is empty.\n");
580 node = _queue_node_pop_front(&surface_queue->free_queue);
586 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
590 if (_queue_is_empty(&surface_queue->dirty_queue))
593 node = _queue_node_pop_front(&surface_queue->dirty_queue);
599 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
600 queue_node *node, int push_back)
603 _queue_node_push_back(&surface_queue->free_queue, node);
605 _queue_node_push_front(&surface_queue->free_queue, node);
609 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
611 int width, int height, int format,
612 const tbm_surface_queue_interface *impl, void *data)
614 TBM_RETURN_IF_FAIL(surface_queue != NULL);
615 TBM_RETURN_IF_FAIL(impl != NULL);
617 if (!g_surf_queue_bufmgr)
618 _init_tbm_surf_queue_bufmgr();
620 pthread_mutex_init(&surface_queue->lock, NULL);
621 pthread_cond_init(&surface_queue->free_cond, NULL);
622 pthread_cond_init(&surface_queue->dirty_cond, NULL);
624 surface_queue->queue_size = queue_size;
625 surface_queue->width = width;
626 surface_queue->height = height;
627 surface_queue->format = format;
628 surface_queue->impl = impl;
629 surface_queue->impl_data = data;
631 _queue_init(&surface_queue->free_queue);
632 _queue_init(&surface_queue->dirty_queue);
633 LIST_INITHEAD(&surface_queue->list);
635 LIST_INITHEAD(&surface_queue->destory_noti);
636 LIST_INITHEAD(&surface_queue->dequeuable_noti);
637 LIST_INITHEAD(&surface_queue->dequeue_noti);
638 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
639 LIST_INITHEAD(&surface_queue->acquirable_noti);
640 LIST_INITHEAD(&surface_queue->reset_noti);
641 LIST_INITHEAD(&surface_queue->trace_noti);
643 if (surface_queue->impl && surface_queue->impl->init)
644 surface_queue->impl->init(surface_queue);
646 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
649 tbm_surface_queue_error_e
650 tbm_surface_queue_add_destroy_cb(
651 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
654 _tbm_surf_queue_mutex_lock();
656 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
657 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
659 pthread_mutex_lock(&surface_queue->lock);
661 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
663 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
665 pthread_mutex_unlock(&surface_queue->lock);
667 _tbm_surf_queue_mutex_unlock();
669 return TBM_SURFACE_QUEUE_ERROR_NONE;
672 tbm_surface_queue_error_e
673 tbm_surface_queue_remove_destroy_cb(
674 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
677 _tbm_surf_queue_mutex_lock();
679 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
680 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
682 pthread_mutex_lock(&surface_queue->lock);
684 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
686 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
688 pthread_mutex_unlock(&surface_queue->lock);
690 _tbm_surf_queue_mutex_unlock();
692 return TBM_SURFACE_QUEUE_ERROR_NONE;
695 tbm_surface_queue_error_e
696 tbm_surface_queue_add_dequeuable_cb(
697 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
700 _tbm_surf_queue_mutex_lock();
702 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
703 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
705 pthread_mutex_lock(&surface_queue->lock);
707 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
709 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
711 pthread_mutex_unlock(&surface_queue->lock);
713 _tbm_surf_queue_mutex_unlock();
715 return TBM_SURFACE_QUEUE_ERROR_NONE;
718 tbm_surface_queue_error_e
719 tbm_surface_queue_remove_dequeuable_cb(
720 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
723 _tbm_surf_queue_mutex_lock();
725 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
726 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
728 pthread_mutex_lock(&surface_queue->lock);
730 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
732 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
734 pthread_mutex_unlock(&surface_queue->lock);
736 _tbm_surf_queue_mutex_unlock();
738 return TBM_SURFACE_QUEUE_ERROR_NONE;
741 tbm_surface_queue_error_e
742 tbm_surface_queue_add_dequeue_cb(
743 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
746 _tbm_surf_queue_mutex_lock();
748 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
749 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
751 pthread_mutex_lock(&surface_queue->lock);
753 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
755 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
757 pthread_mutex_unlock(&surface_queue->lock);
759 _tbm_surf_queue_mutex_unlock();
761 return TBM_SURFACE_QUEUE_ERROR_NONE;
764 tbm_surface_queue_error_e
765 tbm_surface_queue_remove_dequeue_cb(
766 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
769 _tbm_surf_queue_mutex_lock();
771 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
772 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
774 pthread_mutex_lock(&surface_queue->lock);
776 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
778 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
780 pthread_mutex_unlock(&surface_queue->lock);
782 _tbm_surf_queue_mutex_unlock();
784 return TBM_SURFACE_QUEUE_ERROR_NONE;
787 tbm_surface_queue_error_e
788 tbm_surface_queue_add_can_dequeue_cb(
789 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
792 _tbm_surf_queue_mutex_lock();
794 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
795 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
797 pthread_mutex_lock(&surface_queue->lock);
799 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
801 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
803 pthread_mutex_unlock(&surface_queue->lock);
805 _tbm_surf_queue_mutex_unlock();
807 return TBM_SURFACE_QUEUE_ERROR_NONE;
810 tbm_surface_queue_error_e
811 tbm_surface_queue_remove_can_dequeue_cb(
812 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
815 _tbm_surf_queue_mutex_lock();
817 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
818 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
820 pthread_mutex_lock(&surface_queue->lock);
822 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
824 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
826 pthread_mutex_unlock(&surface_queue->lock);
828 _tbm_surf_queue_mutex_unlock();
830 return TBM_SURFACE_QUEUE_ERROR_NONE;
833 tbm_surface_queue_error_e
834 tbm_surface_queue_add_acquirable_cb(
835 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
838 _tbm_surf_queue_mutex_lock();
840 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
841 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
843 pthread_mutex_lock(&surface_queue->lock);
845 TBM_QUEUE_TRACE("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();
863 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
864 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
866 pthread_mutex_lock(&surface_queue->lock);
868 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
870 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
872 pthread_mutex_unlock(&surface_queue->lock);
874 _tbm_surf_queue_mutex_unlock();
876 return TBM_SURFACE_QUEUE_ERROR_NONE;
879 tbm_surface_queue_error_e
880 tbm_surface_queue_add_trace_cb(
881 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
884 _tbm_surf_queue_mutex_lock();
886 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
887 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
889 pthread_mutex_lock(&surface_queue->lock);
891 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
893 _trace_add(&surface_queue->trace_noti, trace_cb, data);
895 pthread_mutex_unlock(&surface_queue->lock);
897 _tbm_surf_queue_mutex_unlock();
899 return TBM_SURFACE_QUEUE_ERROR_NONE;
902 tbm_surface_queue_error_e
903 tbm_surface_queue_remove_trace_cb(
904 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
907 _tbm_surf_queue_mutex_lock();
909 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
910 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
912 pthread_mutex_lock(&surface_queue->lock);
914 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
916 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
918 pthread_mutex_unlock(&surface_queue->lock);
920 _tbm_surf_queue_mutex_unlock();
922 return TBM_SURFACE_QUEUE_ERROR_NONE;
925 tbm_surface_queue_error_e
926 tbm_surface_queue_set_alloc_cb(
927 tbm_surface_queue_h surface_queue,
928 tbm_surface_alloc_cb alloc_cb,
929 tbm_surface_free_cb free_cb,
932 _tbm_surf_queue_mutex_lock();
934 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
935 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
937 pthread_mutex_lock(&surface_queue->lock);
939 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
941 surface_queue->alloc_cb = alloc_cb;
942 surface_queue->free_cb = free_cb;
943 surface_queue->alloc_cb_data = data;
945 pthread_mutex_unlock(&surface_queue->lock);
947 _tbm_surf_queue_mutex_unlock();
949 return TBM_SURFACE_QUEUE_ERROR_NONE;
953 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
957 _tbm_surf_queue_mutex_lock();
959 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
961 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
963 width = surface_queue->width;
965 _tbm_surf_queue_mutex_unlock();
971 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
975 _tbm_surf_queue_mutex_lock();
977 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
979 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
981 height = surface_queue->height;
983 _tbm_surf_queue_mutex_unlock();
989 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
993 _tbm_surf_queue_mutex_lock();
995 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
997 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
999 format = surface_queue->format;
1001 _tbm_surf_queue_mutex_unlock();
1007 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1011 _tbm_surf_queue_mutex_lock();
1013 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1015 TBM_QUEUE_TRACE("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();
1031 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1032 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1034 pthread_mutex_lock(&surface_queue->lock);
1036 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1038 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1040 pthread_mutex_unlock(&surface_queue->lock);
1042 _tbm_surf_queue_mutex_unlock();
1044 return TBM_SURFACE_QUEUE_ERROR_NONE;
1047 tbm_surface_queue_error_e
1048 tbm_surface_queue_remove_reset_cb(
1049 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1052 _tbm_surf_queue_mutex_lock();
1054 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1055 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1057 pthread_mutex_lock(&surface_queue->lock);
1059 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1061 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1063 pthread_mutex_unlock(&surface_queue->lock);
1065 _tbm_surf_queue_mutex_unlock();
1067 return TBM_SURFACE_QUEUE_ERROR_NONE;
1070 tbm_surface_queue_error_e
1071 tbm_surface_queue_enqueue(tbm_surface_queue_h
1072 surface_queue, tbm_surface_h surface)
1077 _tbm_surf_queue_mutex_lock();
1079 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1080 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1081 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1082 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1085 tbm_surface_internal_dump_buffer(surface, "enqueue");
1087 pthread_mutex_lock(&surface_queue->lock);
1089 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1091 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1092 if (node == NULL || queue_type != NODE_LIST) {
1093 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1095 pthread_mutex_unlock(&surface_queue->lock);
1097 _tbm_surf_queue_mutex_unlock();
1098 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1101 if (surface_queue->impl && surface_queue->impl->enqueue)
1102 surface_queue->impl->enqueue(surface_queue, node);
1104 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1106 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1107 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1108 pthread_mutex_unlock(&surface_queue->lock);
1110 _tbm_surf_queue_mutex_unlock();
1111 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1114 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1116 pthread_mutex_unlock(&surface_queue->lock);
1117 pthread_cond_signal(&surface_queue->dirty_cond);
1119 _tbm_surf_queue_mutex_unlock();
1121 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1123 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1125 return TBM_SURFACE_QUEUE_ERROR_NONE;
1128 tbm_surface_queue_error_e
1129 tbm_surface_queue_dequeue(tbm_surface_queue_h
1130 surface_queue, tbm_surface_h *surface)
1134 _tbm_surf_queue_mutex_lock();
1138 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1139 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1140 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1141 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1143 pthread_mutex_lock(&surface_queue->lock);
1145 if (surface_queue->impl && surface_queue->impl->dequeue)
1146 node = surface_queue->impl->dequeue(surface_queue);
1148 node = _tbm_surface_queue_dequeue(surface_queue);
1150 if (node == NULL || node->surface == NULL) {
1151 TBM_LOG_E("_queue_node_pop_front failed\n");
1152 pthread_mutex_unlock(&surface_queue->lock);
1154 _tbm_surf_queue_mutex_unlock();
1155 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1158 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1159 *surface = node->surface;
1161 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1163 pthread_mutex_unlock(&surface_queue->lock);
1165 _tbm_surf_queue_mutex_unlock();
1167 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1169 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1171 return TBM_SURFACE_QUEUE_ERROR_NONE;
1175 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1177 _tbm_surf_queue_mutex_lock();
1179 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1181 _tbm_surf_queue_mutex_unlock();
1183 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1185 _tbm_surf_queue_mutex_lock();
1187 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1189 pthread_mutex_lock(&surface_queue->lock);
1191 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1193 if (_queue_is_empty(&surface_queue->free_queue)) {
1194 if (surface_queue->impl && surface_queue->impl->need_attach)
1195 surface_queue->impl->need_attach(surface_queue);
1197 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1198 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1199 pthread_mutex_unlock(&surface_queue->lock);
1200 _tbm_surf_queue_mutex_unlock();
1205 if (!_queue_is_empty(&surface_queue->free_queue)) {
1206 pthread_mutex_unlock(&surface_queue->lock);
1207 _tbm_surf_queue_mutex_unlock();
1211 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1212 QUEUE_NODE_TYPE_ACQUIRE)) {
1213 _tbm_surf_queue_mutex_unlock();
1214 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1215 _tbm_surf_queue_mutex_lock();
1217 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1218 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1219 pthread_mutex_unlock(&surface_queue->lock);
1220 _tbm_surf_queue_mutex_unlock();
1224 pthread_mutex_unlock(&surface_queue->lock);
1225 _tbm_surf_queue_mutex_unlock();
1229 pthread_mutex_unlock(&surface_queue->lock);
1230 _tbm_surf_queue_mutex_unlock();
1234 tbm_surface_queue_error_e
1235 tbm_surface_queue_release(tbm_surface_queue_h
1236 surface_queue, tbm_surface_h surface)
1241 _tbm_surf_queue_mutex_lock();
1243 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1244 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1245 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1246 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1248 pthread_mutex_lock(&surface_queue->lock);
1250 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1252 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1253 if (node == NULL || queue_type != NODE_LIST) {
1254 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1256 pthread_mutex_unlock(&surface_queue->lock);
1258 _tbm_surf_queue_mutex_unlock();
1259 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1262 if (surface_queue->queue_size < surface_queue->num_attached) {
1263 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1265 if (surface_queue->impl && surface_queue->impl->need_detach)
1266 surface_queue->impl->need_detach(surface_queue, node);
1268 _tbm_surface_queue_detach(surface_queue, surface);
1270 pthread_mutex_unlock(&surface_queue->lock);
1272 _tbm_surf_queue_mutex_unlock();
1273 return TBM_SURFACE_QUEUE_ERROR_NONE;
1276 if (surface_queue->impl && surface_queue->impl->release)
1277 surface_queue->impl->release(surface_queue, node);
1279 _tbm_surface_queue_release(surface_queue, node, 1);
1281 if (_queue_is_empty(&surface_queue->free_queue)) {
1282 pthread_mutex_unlock(&surface_queue->lock);
1284 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1285 _tbm_surf_queue_mutex_unlock();
1286 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1289 node->type = QUEUE_NODE_TYPE_RELEASE;
1291 pthread_mutex_unlock(&surface_queue->lock);
1292 pthread_cond_signal(&surface_queue->free_cond);
1294 _tbm_surf_queue_mutex_unlock();
1296 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1298 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1300 return TBM_SURFACE_QUEUE_ERROR_NONE;
1303 tbm_surface_queue_error_e
1304 tbm_surface_queue_acquire(tbm_surface_queue_h
1305 surface_queue, tbm_surface_h *surface)
1309 _tbm_surf_queue_mutex_lock();
1313 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1314 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1315 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1316 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1318 pthread_mutex_lock(&surface_queue->lock);
1320 if (surface_queue->impl && surface_queue->impl->acquire)
1321 node = surface_queue->impl->acquire(surface_queue);
1323 node = _tbm_surface_queue_acquire(surface_queue);
1325 if (node == NULL || node->surface == NULL) {
1326 TBM_LOG_E("_queue_node_pop_front failed\n");
1327 pthread_mutex_unlock(&surface_queue->lock);
1329 _tbm_surf_queue_mutex_unlock();
1330 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1333 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1335 *surface = node->surface;
1337 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1339 pthread_mutex_unlock(&surface_queue->lock);
1341 _tbm_surf_queue_mutex_unlock();
1344 tbm_surface_internal_dump_buffer(*surface, "acquire");
1346 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1348 return TBM_SURFACE_QUEUE_ERROR_NONE;
1352 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1354 _tbm_surf_queue_mutex_lock();
1356 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1358 pthread_mutex_lock(&surface_queue->lock);
1360 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1362 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1363 pthread_mutex_unlock(&surface_queue->lock);
1364 _tbm_surf_queue_mutex_unlock();
1368 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1369 QUEUE_NODE_TYPE_DEQUEUE)) {
1370 _tbm_surf_queue_mutex_unlock();
1371 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1372 _tbm_surf_queue_mutex_lock();
1374 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1375 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1376 pthread_mutex_unlock(&surface_queue->lock);
1377 _tbm_surf_queue_mutex_unlock();
1381 pthread_mutex_unlock(&surface_queue->lock);
1382 _tbm_surf_queue_mutex_unlock();
1386 pthread_mutex_unlock(&surface_queue->lock);
1387 _tbm_surf_queue_mutex_unlock();
1392 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1394 queue_node *node = NULL, *tmp;
1396 _tbm_surf_queue_mutex_lock();
1398 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1400 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1402 LIST_DEL(&surface_queue->item_link);
1404 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1405 _queue_delete_node(surface_queue, node);
1407 if (surface_queue->impl && surface_queue->impl->destroy)
1408 surface_queue->impl->destroy(surface_queue);
1410 _notify_emit(surface_queue, &surface_queue->destory_noti);
1412 _notify_remove_all(&surface_queue->destory_noti);
1413 _notify_remove_all(&surface_queue->dequeuable_noti);
1414 _notify_remove_all(&surface_queue->dequeue_noti);
1415 _notify_remove_all(&surface_queue->can_dequeue_noti);
1416 _notify_remove_all(&surface_queue->acquirable_noti);
1417 _notify_remove_all(&surface_queue->reset_noti);
1418 _trace_remove_all(&surface_queue->trace_noti);
1420 pthread_mutex_destroy(&surface_queue->lock);
1422 free(surface_queue);
1424 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1425 _deinit_tbm_surf_queue_bufmgr();
1427 _tbm_surf_queue_mutex_unlock();
1430 tbm_surface_queue_error_e
1431 tbm_surface_queue_reset(tbm_surface_queue_h
1432 surface_queue, int width, int height, int format)
1434 queue_node *node = NULL, *tmp;
1436 _tbm_surf_queue_mutex_lock();
1438 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1439 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1441 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1443 if (width == surface_queue->width && height == surface_queue->height &&
1444 format == surface_queue->format) {
1445 _tbm_surf_queue_mutex_unlock();
1446 return TBM_SURFACE_QUEUE_ERROR_NONE;
1449 pthread_mutex_lock(&surface_queue->lock);
1451 surface_queue->width = width;
1452 surface_queue->height = height;
1453 surface_queue->format = format;
1455 /* Destory surface and Push to free_queue */
1456 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1457 _queue_delete_node(surface_queue, node);
1460 _queue_init(&surface_queue->free_queue);
1461 _queue_init(&surface_queue->dirty_queue);
1462 LIST_INITHEAD(&surface_queue->list);
1464 surface_queue->num_attached = 0;
1466 if (surface_queue->impl && surface_queue->impl->reset)
1467 surface_queue->impl->reset(surface_queue);
1469 pthread_mutex_unlock(&surface_queue->lock);
1470 pthread_cond_signal(&surface_queue->free_cond);
1472 _tbm_surf_queue_mutex_unlock();
1474 _notify_emit(surface_queue, &surface_queue->reset_noti);
1476 return TBM_SURFACE_QUEUE_ERROR_NONE;
1479 tbm_surface_queue_error_e
1480 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1482 _tbm_surf_queue_mutex_lock();
1484 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1485 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1487 _tbm_surf_queue_mutex_unlock();
1489 _notify_emit(surface_queue, &surface_queue->reset_noti);
1491 return TBM_SURFACE_QUEUE_ERROR_NONE;
1494 tbm_surface_queue_error_e
1495 tbm_surface_queue_set_size(tbm_surface_queue_h
1496 surface_queue, int queue_size, int flush)
1498 queue_node *node = NULL, *tmp;
1500 _tbm_surf_queue_mutex_lock();
1502 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1503 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1504 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1505 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1507 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1509 if ((surface_queue->queue_size == queue_size) && !flush) {
1510 _tbm_surf_queue_mutex_unlock();
1511 return TBM_SURFACE_QUEUE_ERROR_NONE;
1514 pthread_mutex_lock(&surface_queue->lock);
1517 /* Destory surface and Push to free_queue */
1518 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1519 _queue_delete_node(surface_queue, node);
1522 _queue_init(&surface_queue->free_queue);
1523 _queue_init(&surface_queue->dirty_queue);
1524 LIST_INITHEAD(&surface_queue->list);
1526 surface_queue->num_attached = 0;
1527 surface_queue->queue_size = queue_size;
1529 if (surface_queue->impl && surface_queue->impl->reset)
1530 surface_queue->impl->reset(surface_queue);
1532 pthread_mutex_unlock(&surface_queue->lock);
1533 pthread_cond_signal(&surface_queue->free_cond);
1535 _tbm_surf_queue_mutex_unlock();
1537 _notify_emit(surface_queue, &surface_queue->reset_noti);
1539 return TBM_SURFACE_QUEUE_ERROR_NONE;
1541 if (surface_queue->queue_size > queue_size) {
1542 int need_del = surface_queue->queue_size - queue_size;
1544 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1545 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1547 if (surface_queue->impl && surface_queue->impl->need_detach)
1548 surface_queue->impl->need_detach(surface_queue, node);
1550 _tbm_surface_queue_detach(surface_queue, node->surface);
1558 surface_queue->queue_size = queue_size;
1560 pthread_mutex_unlock(&surface_queue->lock);
1562 _tbm_surf_queue_mutex_unlock();
1564 return TBM_SURFACE_QUEUE_ERROR_NONE;
1568 tbm_surface_queue_error_e
1569 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1571 queue_node *node = NULL;
1573 _tbm_surf_queue_mutex_lock();
1575 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1576 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1578 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1580 if (surface_queue->num_attached == 0) {
1581 _tbm_surf_queue_mutex_unlock();
1582 return TBM_SURFACE_QUEUE_ERROR_NONE;
1585 pthread_mutex_lock(&surface_queue->lock);
1587 /* Destory surface in free_queue */
1588 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1589 if (surface_queue->impl && surface_queue->impl->need_detach)
1590 surface_queue->impl->need_detach(surface_queue, node);
1592 _tbm_surface_queue_detach(surface_queue, node->surface);
1596 _queue_init(&surface_queue->free_queue);
1598 pthread_mutex_unlock(&surface_queue->lock);
1599 _tbm_surf_queue_mutex_unlock();
1601 return TBM_SURFACE_QUEUE_ERROR_NONE;
1604 tbm_surface_queue_error_e
1605 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1607 queue_node *node = NULL, *tmp;
1609 _tbm_surf_queue_mutex_lock();
1611 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1612 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1614 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1616 if (surface_queue->num_attached == 0) {
1617 _tbm_surf_queue_mutex_unlock();
1618 return TBM_SURFACE_QUEUE_ERROR_NONE;
1621 pthread_mutex_lock(&surface_queue->lock);
1623 /* Destory surface and Push to free_queue */
1624 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1625 _queue_delete_node(surface_queue, node);
1628 _queue_init(&surface_queue->free_queue);
1629 _queue_init(&surface_queue->dirty_queue);
1630 LIST_INITHEAD(&surface_queue->list);
1632 surface_queue->num_attached = 0;
1634 if (surface_queue->impl && surface_queue->impl->reset)
1635 surface_queue->impl->reset(surface_queue);
1637 pthread_mutex_unlock(&surface_queue->lock);
1638 pthread_cond_signal(&surface_queue->free_cond);
1640 _tbm_surf_queue_mutex_unlock();
1642 _notify_emit(surface_queue, &surface_queue->reset_noti);
1644 return TBM_SURFACE_QUEUE_ERROR_NONE;
1647 tbm_surface_queue_error_e
1648 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1649 tbm_surface_h *surfaces, int *num)
1651 queue_node *node = NULL;
1653 _tbm_surf_queue_mutex_lock();
1657 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1658 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1659 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1660 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1662 pthread_mutex_lock(&surface_queue->lock);
1664 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1666 surfaces[*num] = node->surface;
1671 pthread_mutex_unlock(&surface_queue->lock);
1673 _tbm_surf_queue_mutex_unlock();
1675 return TBM_SURFACE_QUEUE_ERROR_NONE;
1678 tbm_surface_queue_error_e
1679 tbm_surface_queue_get_trace_surface_num(
1680 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1682 _tbm_surf_queue_mutex_lock();
1686 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1687 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1688 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1689 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1691 pthread_mutex_lock(&surface_queue->lock);
1694 case TBM_SURFACE_QUEUE_TRACE_NONE:
1697 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1698 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1700 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1701 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1703 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1704 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1706 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1707 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1711 pthread_mutex_unlock(&surface_queue->lock);
1713 _tbm_surf_queue_mutex_unlock();
1715 return TBM_SURFACE_QUEUE_ERROR_NONE;
1720 } tbm_queue_default;
1723 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1725 free(surface_queue->impl_data);
1729 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1731 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1732 tbm_surface_h surface;
1734 if (surface_queue->queue_size == surface_queue->num_attached)
1737 if (surface_queue->alloc_cb) {
1738 pthread_mutex_unlock(&surface_queue->lock);
1739 _tbm_surf_queue_mutex_unlock();
1740 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1741 _tbm_surf_queue_mutex_lock();
1742 pthread_mutex_lock(&surface_queue->lock);
1748 tbm_surface_internal_ref(surface);
1750 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1751 surface_queue->height,
1752 surface_queue->format,
1754 TBM_RETURN_IF_FAIL(surface != NULL);
1757 _tbm_surface_queue_attach(surface_queue, surface);
1758 tbm_surface_internal_unref(surface);
1761 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1762 NULL, /*__tbm_queue_default_init*/
1763 NULL, /*__tbm_queue_default_reset*/
1764 __tbm_queue_default_destroy,
1765 __tbm_queue_default_need_attach,
1766 NULL, /*__tbm_queue_default_enqueue*/
1767 NULL, /*__tbm_queue_default_release*/
1768 NULL, /*__tbm_queue_default_dequeue*/
1769 NULL, /*__tbm_queue_default_acquire*/
1770 NULL, /*__tbm_queue_default_need_detach*/
1774 tbm_surface_queue_create(int queue_size, int width,
1775 int height, int format, int flags)
1777 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1778 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1779 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1780 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1782 _tbm_surf_queue_mutex_lock();
1784 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1785 sizeof(struct _tbm_surface_queue));
1786 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1788 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1790 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1791 sizeof(tbm_queue_default));
1793 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
1794 free(surface_queue);
1795 _tbm_surf_queue_mutex_unlock();
1799 data->flags = flags;
1800 _tbm_surface_queue_init(surface_queue,
1802 width, height, format,
1803 &tbm_queue_default_impl, data);
1805 _tbm_surf_queue_mutex_unlock();
1807 return surface_queue;
1813 } tbm_queue_sequence;
1816 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1818 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1820 _queue_init(&data->dequeue_list);
1824 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1826 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1828 _queue_init(&data->dequeue_list);
1832 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1834 free(surface_queue->impl_data);
1838 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1840 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1841 tbm_surface_h surface;
1843 if (surface_queue->queue_size == surface_queue->num_attached)
1846 if (surface_queue->alloc_cb) {
1847 pthread_mutex_unlock(&surface_queue->lock);
1848 _tbm_surf_queue_mutex_unlock();
1849 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1850 _tbm_surf_queue_mutex_lock();
1851 pthread_mutex_lock(&surface_queue->lock);
1857 tbm_surface_internal_ref(surface);
1859 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1860 surface_queue->height,
1861 surface_queue->format,
1863 TBM_RETURN_IF_FAIL(surface != NULL);
1866 _tbm_surface_queue_attach(surface_queue, surface);
1867 tbm_surface_internal_unref(surface);
1871 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1874 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1875 queue_node *next = NULL, *tmp;
1877 node->priv_flags = 0;
1879 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1880 if (next->priv_flags)
1882 _queue_node_pop(&data->dequeue_list, next);
1883 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1888 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1891 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1894 node = _tbm_surface_queue_dequeue(surface_queue);
1896 _queue_node_push_back(&data->dequeue_list, node);
1897 node->priv_flags = 1;
1903 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1904 __tbm_queue_sequence_init,
1905 __tbm_queue_sequence_reset,
1906 __tbm_queue_sequence_destroy,
1907 __tbm_queue_sequence_need_attach,
1908 __tbm_queue_sequence_enqueue,
1909 NULL, /*__tbm_queue_sequence_release*/
1910 __tbm_queue_sequence_dequeue,
1911 NULL, /*__tbm_queue_sequence_acquire*/
1912 NULL, /*__tbm_queue_sequence_need_dettach*/
1916 tbm_surface_queue_sequence_create(int queue_size, int width,
1917 int height, int format, int flags)
1919 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1920 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1921 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1922 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1924 _tbm_surf_queue_mutex_lock();
1926 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1927 sizeof(struct _tbm_surface_queue));
1928 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1930 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1932 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1933 sizeof(tbm_queue_sequence));
1935 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
1936 free(surface_queue);
1937 _tbm_surf_queue_mutex_unlock();
1941 data->flags = flags;
1942 _tbm_surface_queue_init(surface_queue,
1944 width, height, format,
1945 &tbm_queue_sequence_impl, data);
1947 _tbm_surf_queue_mutex_unlock();
1949 return surface_queue;
1951 /* LCOV_EXCL_STOP */