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 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
297 LIST_DEL(&node->item_link);
304 _queue_node_pop(queue *queue, queue_node *node)
306 LIST_DEL(&node->item_link);
313 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
314 tbm_surface_h surface, int *out_type)
316 queue_node *node = NULL;
319 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
323 if (type & FREE_QUEUE) {
324 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
326 if (node->surface == surface) {
328 *out_type = FREE_QUEUE;
335 if (type & DIRTY_QUEUE) {
336 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
338 if (node->surface == surface) {
340 *out_type = DIRTY_QUEUE;
347 if (type & NODE_LIST) {
348 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
349 if (node->surface == surface) {
351 *out_type = NODE_LIST;
358 TBM_LOG_E("fail to get the queue_node.\n");
364 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
367 if (surface_queue->free_cb) {
368 surface_queue->free_cb(surface_queue,
369 surface_queue->alloc_cb_data,
373 tbm_surface_destroy(node->surface);
376 _queue_node_delete(node);
380 _queue_init(queue *queue)
382 LIST_INITHEAD(&queue->head);
388 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
391 TBM_RETURN_IF_FAIL(cb != NULL);
393 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
395 TBM_RETURN_IF_FAIL(item != NULL);
397 LIST_INITHEAD(&item->link);
401 LIST_ADDTAIL(&item->link, list);
405 _notify_remove(struct list_head *list,
406 tbm_surface_queue_notify_cb cb, void *data)
408 queue_notify *item = NULL, *tmp;
410 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
411 if (item->cb == cb && item->data == data) {
412 LIST_DEL(&item->link);
418 TBM_LOG_E("Cannot find notifiy\n");
422 _notify_remove_all(struct list_head *list)
424 queue_notify *item = NULL, *tmp;
426 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
427 LIST_DEL(&item->link);
433 _notify_emit(tbm_surface_queue_h surface_queue,
434 struct list_head *list)
436 queue_notify *item = NULL, *tmp;;
439 The item->cb is the outside function of the libtbm.
440 The tbm user may/can remove the item of the list,
441 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
443 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
444 item->cb(surface_queue, item->data);
448 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
451 TBM_RETURN_IF_FAIL(cb != NULL);
453 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
455 TBM_RETURN_IF_FAIL(item != NULL);
457 LIST_INITHEAD(&item->link);
461 LIST_ADDTAIL(&item->link, list);
465 _trace_remove(struct list_head *list,
466 tbm_surface_queue_trace_cb cb, void *data)
468 queue_trace *item = NULL, *tmp;
470 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
471 if (item->cb == cb && item->data == data) {
472 LIST_DEL(&item->link);
478 TBM_LOG_E("Cannot find notifiy\n");
482 _trace_remove_all(struct list_head *list)
484 queue_trace *item = NULL, *tmp;
486 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
487 LIST_DEL(&item->link);
493 _trace_emit(tbm_surface_queue_h surface_queue,
494 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
496 queue_trace *item = NULL, *tmp;;
499 The item->cb is the outside function of the libtbm.
500 The tbm user may/can remove the item of the list,
501 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
503 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
504 item->cb(surface_queue, surface, trace, item->data);
508 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
510 queue_node *node = NULL;
513 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
514 if (node->type == type)
522 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
523 tbm_surface_h surface)
527 node = _queue_node_create();
528 TBM_RETURN_IF_FAIL(node != NULL);
530 tbm_surface_internal_ref(surface);
531 node->surface = surface;
533 LIST_ADDTAIL(&node->link, &surface_queue->list);
534 surface_queue->num_attached++;
535 _queue_node_push_back(&surface_queue->free_queue, node);
539 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
540 tbm_surface_h surface)
545 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
547 _queue_delete_node(surface_queue, node);
548 surface_queue->num_attached--;
553 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
554 queue_node *node, int push_back)
557 _queue_node_push_back(&surface_queue->dirty_queue, node);
559 _queue_node_push_front(&surface_queue->dirty_queue, node);
563 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
567 if (_queue_is_empty(&surface_queue->free_queue)) {
568 if (surface_queue->impl && surface_queue->impl->need_attach)
569 surface_queue->impl->need_attach(surface_queue);
571 if (_queue_is_empty(&surface_queue->free_queue)) {
572 TBM_LOG_E("surface_queue->free_queue is empty.\n");
577 node = _queue_node_pop_front(&surface_queue->free_queue);
583 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
587 if (_queue_is_empty(&surface_queue->dirty_queue))
590 node = _queue_node_pop_front(&surface_queue->dirty_queue);
596 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
597 queue_node *node, int push_back)
600 _queue_node_push_back(&surface_queue->free_queue, node);
602 _queue_node_push_front(&surface_queue->free_queue, node);
606 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
608 int width, int height, int format,
609 const tbm_surface_queue_interface *impl, void *data)
611 TBM_RETURN_IF_FAIL(surface_queue != NULL);
612 TBM_RETURN_IF_FAIL(impl != NULL);
614 if (!g_surf_queue_bufmgr)
615 _init_tbm_surf_queue_bufmgr();
617 pthread_mutex_init(&surface_queue->lock, NULL);
618 pthread_cond_init(&surface_queue->free_cond, NULL);
619 pthread_cond_init(&surface_queue->dirty_cond, NULL);
621 surface_queue->queue_size = queue_size;
622 surface_queue->width = width;
623 surface_queue->height = height;
624 surface_queue->format = format;
625 surface_queue->impl = impl;
626 surface_queue->impl_data = data;
628 _queue_init(&surface_queue->free_queue);
629 _queue_init(&surface_queue->dirty_queue);
630 LIST_INITHEAD(&surface_queue->list);
632 LIST_INITHEAD(&surface_queue->destory_noti);
633 LIST_INITHEAD(&surface_queue->dequeuable_noti);
634 LIST_INITHEAD(&surface_queue->dequeue_noti);
635 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
636 LIST_INITHEAD(&surface_queue->acquirable_noti);
637 LIST_INITHEAD(&surface_queue->reset_noti);
638 LIST_INITHEAD(&surface_queue->trace_noti);
640 if (surface_queue->impl && surface_queue->impl->init)
641 surface_queue->impl->init(surface_queue);
643 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
646 tbm_surface_queue_error_e
647 tbm_surface_queue_add_destroy_cb(
648 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
651 _tbm_surf_queue_mutex_lock();
653 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
654 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
656 pthread_mutex_lock(&surface_queue->lock);
658 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
660 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
662 pthread_mutex_unlock(&surface_queue->lock);
664 _tbm_surf_queue_mutex_unlock();
666 return TBM_SURFACE_QUEUE_ERROR_NONE;
669 tbm_surface_queue_error_e
670 tbm_surface_queue_remove_destroy_cb(
671 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
674 _tbm_surf_queue_mutex_lock();
676 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
677 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
679 pthread_mutex_lock(&surface_queue->lock);
681 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
683 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
685 pthread_mutex_unlock(&surface_queue->lock);
687 _tbm_surf_queue_mutex_unlock();
689 return TBM_SURFACE_QUEUE_ERROR_NONE;
692 tbm_surface_queue_error_e
693 tbm_surface_queue_add_dequeuable_cb(
694 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
697 _tbm_surf_queue_mutex_lock();
699 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
700 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
702 pthread_mutex_lock(&surface_queue->lock);
704 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
706 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
708 pthread_mutex_unlock(&surface_queue->lock);
710 _tbm_surf_queue_mutex_unlock();
712 return TBM_SURFACE_QUEUE_ERROR_NONE;
715 tbm_surface_queue_error_e
716 tbm_surface_queue_remove_dequeuable_cb(
717 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
720 _tbm_surf_queue_mutex_lock();
722 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
723 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
725 pthread_mutex_lock(&surface_queue->lock);
727 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
729 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
731 pthread_mutex_unlock(&surface_queue->lock);
733 _tbm_surf_queue_mutex_unlock();
735 return TBM_SURFACE_QUEUE_ERROR_NONE;
738 tbm_surface_queue_error_e
739 tbm_surface_queue_add_dequeue_cb(
740 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
743 _tbm_surf_queue_mutex_lock();
745 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
746 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
748 pthread_mutex_lock(&surface_queue->lock);
750 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
752 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
754 pthread_mutex_unlock(&surface_queue->lock);
756 _tbm_surf_queue_mutex_unlock();
758 return TBM_SURFACE_QUEUE_ERROR_NONE;
761 tbm_surface_queue_error_e
762 tbm_surface_queue_remove_dequeue_cb(
763 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
766 _tbm_surf_queue_mutex_lock();
768 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
769 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
771 pthread_mutex_lock(&surface_queue->lock);
773 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
775 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
777 pthread_mutex_unlock(&surface_queue->lock);
779 _tbm_surf_queue_mutex_unlock();
781 return TBM_SURFACE_QUEUE_ERROR_NONE;
784 tbm_surface_queue_error_e
785 tbm_surface_queue_add_can_dequeue_cb(
786 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
789 _tbm_surf_queue_mutex_lock();
791 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
792 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
794 pthread_mutex_lock(&surface_queue->lock);
796 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
798 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
800 pthread_mutex_unlock(&surface_queue->lock);
802 _tbm_surf_queue_mutex_unlock();
804 return TBM_SURFACE_QUEUE_ERROR_NONE;
807 tbm_surface_queue_error_e
808 tbm_surface_queue_remove_can_dequeue_cb(
809 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
812 _tbm_surf_queue_mutex_lock();
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_QUEUE_TRACE("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();
837 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
838 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
840 pthread_mutex_lock(&surface_queue->lock);
842 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
844 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
846 pthread_mutex_unlock(&surface_queue->lock);
848 _tbm_surf_queue_mutex_unlock();
850 return TBM_SURFACE_QUEUE_ERROR_NONE;
853 tbm_surface_queue_error_e
854 tbm_surface_queue_remove_acquirable_cb(
855 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
858 _tbm_surf_queue_mutex_lock();
860 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
861 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
863 pthread_mutex_lock(&surface_queue->lock);
865 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
867 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
869 pthread_mutex_unlock(&surface_queue->lock);
871 _tbm_surf_queue_mutex_unlock();
873 return TBM_SURFACE_QUEUE_ERROR_NONE;
876 tbm_surface_queue_error_e
877 tbm_surface_queue_add_trace_cb(
878 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
881 _tbm_surf_queue_mutex_lock();
883 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
884 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
886 pthread_mutex_lock(&surface_queue->lock);
888 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
890 _trace_add(&surface_queue->trace_noti, trace_cb, data);
892 pthread_mutex_unlock(&surface_queue->lock);
894 _tbm_surf_queue_mutex_unlock();
896 return TBM_SURFACE_QUEUE_ERROR_NONE;
899 tbm_surface_queue_error_e
900 tbm_surface_queue_remove_trace_cb(
901 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
904 _tbm_surf_queue_mutex_lock();
906 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
907 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
909 pthread_mutex_lock(&surface_queue->lock);
911 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
913 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
915 pthread_mutex_unlock(&surface_queue->lock);
917 _tbm_surf_queue_mutex_unlock();
919 return TBM_SURFACE_QUEUE_ERROR_NONE;
922 tbm_surface_queue_error_e
923 tbm_surface_queue_set_alloc_cb(
924 tbm_surface_queue_h surface_queue,
925 tbm_surface_alloc_cb alloc_cb,
926 tbm_surface_free_cb free_cb,
929 _tbm_surf_queue_mutex_lock();
931 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
932 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
934 pthread_mutex_lock(&surface_queue->lock);
936 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
938 surface_queue->alloc_cb = alloc_cb;
939 surface_queue->free_cb = free_cb;
940 surface_queue->alloc_cb_data = data;
942 pthread_mutex_unlock(&surface_queue->lock);
944 _tbm_surf_queue_mutex_unlock();
946 return TBM_SURFACE_QUEUE_ERROR_NONE;
950 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
954 _tbm_surf_queue_mutex_lock();
956 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
958 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
960 width = surface_queue->width;
962 _tbm_surf_queue_mutex_unlock();
968 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
972 _tbm_surf_queue_mutex_lock();
974 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
976 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
978 height = surface_queue->height;
980 _tbm_surf_queue_mutex_unlock();
986 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
990 _tbm_surf_queue_mutex_lock();
992 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
994 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
996 format = surface_queue->format;
998 _tbm_surf_queue_mutex_unlock();
1004 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1008 _tbm_surf_queue_mutex_lock();
1010 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1012 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1014 queue_size = surface_queue->queue_size;
1016 _tbm_surf_queue_mutex_unlock();
1021 tbm_surface_queue_error_e
1022 tbm_surface_queue_add_reset_cb(
1023 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1026 _tbm_surf_queue_mutex_lock();
1028 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1029 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1031 pthread_mutex_lock(&surface_queue->lock);
1033 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1035 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1037 pthread_mutex_unlock(&surface_queue->lock);
1039 _tbm_surf_queue_mutex_unlock();
1041 return TBM_SURFACE_QUEUE_ERROR_NONE;
1044 tbm_surface_queue_error_e
1045 tbm_surface_queue_remove_reset_cb(
1046 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1049 _tbm_surf_queue_mutex_lock();
1051 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1052 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1054 pthread_mutex_lock(&surface_queue->lock);
1056 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1058 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1060 pthread_mutex_unlock(&surface_queue->lock);
1062 _tbm_surf_queue_mutex_unlock();
1064 return TBM_SURFACE_QUEUE_ERROR_NONE;
1067 tbm_surface_queue_error_e
1068 tbm_surface_queue_enqueue(tbm_surface_queue_h
1069 surface_queue, tbm_surface_h surface)
1074 _tbm_surf_queue_mutex_lock();
1076 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1077 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1078 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1079 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1082 tbm_surface_internal_dump_buffer(surface, "enqueue");
1084 pthread_mutex_lock(&surface_queue->lock);
1086 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1088 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1089 if (node == NULL || queue_type != NODE_LIST) {
1090 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1092 pthread_mutex_unlock(&surface_queue->lock);
1094 _tbm_surf_queue_mutex_unlock();
1095 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1098 if (surface_queue->impl && surface_queue->impl->enqueue)
1099 surface_queue->impl->enqueue(surface_queue, node);
1101 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1103 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1104 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
1105 pthread_mutex_unlock(&surface_queue->lock);
1107 _tbm_surf_queue_mutex_unlock();
1108 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1111 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1113 pthread_mutex_unlock(&surface_queue->lock);
1114 pthread_cond_signal(&surface_queue->dirty_cond);
1116 _tbm_surf_queue_mutex_unlock();
1118 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1120 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1122 return TBM_SURFACE_QUEUE_ERROR_NONE;
1125 tbm_surface_queue_error_e
1126 tbm_surface_queue_dequeue(tbm_surface_queue_h
1127 surface_queue, tbm_surface_h *surface)
1131 _tbm_surf_queue_mutex_lock();
1135 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1136 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1137 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1138 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1140 pthread_mutex_lock(&surface_queue->lock);
1142 if (surface_queue->impl && surface_queue->impl->dequeue)
1143 node = surface_queue->impl->dequeue(surface_queue);
1145 node = _tbm_surface_queue_dequeue(surface_queue);
1147 if (node == NULL || node->surface == NULL) {
1148 TBM_LOG_E("_queue_node_pop_front failed\n");
1149 pthread_mutex_unlock(&surface_queue->lock);
1151 _tbm_surf_queue_mutex_unlock();
1152 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1155 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1156 *surface = node->surface;
1158 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1160 pthread_mutex_unlock(&surface_queue->lock);
1162 _tbm_surf_queue_mutex_unlock();
1164 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1166 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1168 return TBM_SURFACE_QUEUE_ERROR_NONE;
1172 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1174 _tbm_surf_queue_mutex_lock();
1176 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1178 _tbm_surf_queue_mutex_unlock();
1180 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1182 _tbm_surf_queue_mutex_lock();
1184 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1186 pthread_mutex_lock(&surface_queue->lock);
1188 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1190 if (_queue_is_empty(&surface_queue->free_queue)) {
1191 if (surface_queue->impl && surface_queue->impl->need_attach)
1192 surface_queue->impl->need_attach(surface_queue);
1194 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1195 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1196 _tbm_surf_queue_mutex_unlock();
1201 if (!_queue_is_empty(&surface_queue->free_queue)) {
1202 pthread_mutex_unlock(&surface_queue->lock);
1203 _tbm_surf_queue_mutex_unlock();
1207 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1208 QUEUE_NODE_TYPE_ACQUIRE)) {
1209 _tbm_surf_queue_mutex_unlock();
1210 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1211 _tbm_surf_queue_mutex_lock();
1213 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1214 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1215 pthread_mutex_unlock(&surface_queue->lock);
1216 _tbm_surf_queue_mutex_unlock();
1220 pthread_mutex_unlock(&surface_queue->lock);
1221 _tbm_surf_queue_mutex_unlock();
1225 pthread_mutex_unlock(&surface_queue->lock);
1226 _tbm_surf_queue_mutex_unlock();
1230 tbm_surface_queue_error_e
1231 tbm_surface_queue_release(tbm_surface_queue_h
1232 surface_queue, tbm_surface_h surface)
1237 _tbm_surf_queue_mutex_lock();
1239 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1240 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1241 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1242 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1244 pthread_mutex_lock(&surface_queue->lock);
1246 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1248 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1249 if (node == NULL || queue_type != NODE_LIST) {
1250 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1252 pthread_mutex_unlock(&surface_queue->lock);
1254 _tbm_surf_queue_mutex_unlock();
1255 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1258 if (surface_queue->queue_size < surface_queue->num_attached) {
1259 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1261 if (surface_queue->impl && surface_queue->impl->need_detach)
1262 surface_queue->impl->need_detach(surface_queue, node);
1264 _tbm_surface_queue_detach(surface_queue, surface);
1266 pthread_mutex_unlock(&surface_queue->lock);
1268 _tbm_surf_queue_mutex_unlock();
1269 return TBM_SURFACE_QUEUE_ERROR_NONE;
1272 if (surface_queue->impl && surface_queue->impl->release)
1273 surface_queue->impl->release(surface_queue, node);
1275 _tbm_surface_queue_release(surface_queue, node, 1);
1277 if (_queue_is_empty(&surface_queue->free_queue)) {
1278 pthread_mutex_unlock(&surface_queue->lock);
1280 TBM_LOG_E("surface_queue->free_queue is empty.\n");
1281 _tbm_surf_queue_mutex_unlock();
1282 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1285 node->type = QUEUE_NODE_TYPE_RELEASE;
1287 pthread_mutex_unlock(&surface_queue->lock);
1288 pthread_cond_signal(&surface_queue->free_cond);
1290 _tbm_surf_queue_mutex_unlock();
1292 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1294 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1296 return TBM_SURFACE_QUEUE_ERROR_NONE;
1299 tbm_surface_queue_error_e
1300 tbm_surface_queue_acquire(tbm_surface_queue_h
1301 surface_queue, tbm_surface_h *surface)
1305 _tbm_surf_queue_mutex_lock();
1309 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1310 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1311 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1312 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1314 pthread_mutex_lock(&surface_queue->lock);
1316 if (surface_queue->impl && surface_queue->impl->acquire)
1317 node = surface_queue->impl->acquire(surface_queue);
1319 node = _tbm_surface_queue_acquire(surface_queue);
1321 if (node == NULL || node->surface == NULL) {
1322 TBM_LOG_E("_queue_node_pop_front failed\n");
1323 pthread_mutex_unlock(&surface_queue->lock);
1325 _tbm_surf_queue_mutex_unlock();
1326 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1329 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1331 *surface = node->surface;
1333 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1335 pthread_mutex_unlock(&surface_queue->lock);
1337 _tbm_surf_queue_mutex_unlock();
1340 tbm_surface_internal_dump_buffer(*surface, "acquire");
1342 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1344 return TBM_SURFACE_QUEUE_ERROR_NONE;
1348 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1350 _tbm_surf_queue_mutex_lock();
1352 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1354 pthread_mutex_lock(&surface_queue->lock);
1356 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1358 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1359 pthread_mutex_unlock(&surface_queue->lock);
1360 _tbm_surf_queue_mutex_unlock();
1364 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1365 QUEUE_NODE_TYPE_DEQUEUE)) {
1366 _tbm_surf_queue_mutex_unlock();
1367 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1368 _tbm_surf_queue_mutex_lock();
1370 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1371 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1372 pthread_mutex_unlock(&surface_queue->lock);
1373 _tbm_surf_queue_mutex_unlock();
1377 pthread_mutex_unlock(&surface_queue->lock);
1378 _tbm_surf_queue_mutex_unlock();
1382 pthread_mutex_unlock(&surface_queue->lock);
1383 _tbm_surf_queue_mutex_unlock();
1388 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1390 queue_node *node = NULL, *tmp;
1392 _tbm_surf_queue_mutex_lock();
1394 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1396 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1398 LIST_DEL(&surface_queue->item_link);
1400 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1401 _queue_delete_node(surface_queue, node);
1403 if (surface_queue->impl && surface_queue->impl->destroy)
1404 surface_queue->impl->destroy(surface_queue);
1406 _notify_emit(surface_queue, &surface_queue->destory_noti);
1408 _notify_remove_all(&surface_queue->destory_noti);
1409 _notify_remove_all(&surface_queue->dequeuable_noti);
1410 _notify_remove_all(&surface_queue->dequeue_noti);
1411 _notify_remove_all(&surface_queue->can_dequeue_noti);
1412 _notify_remove_all(&surface_queue->acquirable_noti);
1413 _notify_remove_all(&surface_queue->reset_noti);
1414 _trace_remove_all(&surface_queue->trace_noti);
1416 pthread_mutex_destroy(&surface_queue->lock);
1418 free(surface_queue);
1420 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1421 _deinit_tbm_surf_queue_bufmgr();
1423 _tbm_surf_queue_mutex_unlock();
1426 tbm_surface_queue_error_e
1427 tbm_surface_queue_reset(tbm_surface_queue_h
1428 surface_queue, int width, int height, int format)
1430 queue_node *node = NULL, *tmp;
1432 _tbm_surf_queue_mutex_lock();
1434 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1435 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1437 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1439 if (width == surface_queue->width && height == surface_queue->height &&
1440 format == surface_queue->format) {
1441 _tbm_surf_queue_mutex_unlock();
1442 return TBM_SURFACE_QUEUE_ERROR_NONE;
1445 pthread_mutex_lock(&surface_queue->lock);
1447 surface_queue->width = width;
1448 surface_queue->height = height;
1449 surface_queue->format = format;
1451 /* Destory surface and Push to free_queue */
1452 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1453 _queue_delete_node(surface_queue, node);
1456 _queue_init(&surface_queue->free_queue);
1457 _queue_init(&surface_queue->dirty_queue);
1458 LIST_INITHEAD(&surface_queue->list);
1460 surface_queue->num_attached = 0;
1462 if (surface_queue->impl && surface_queue->impl->reset)
1463 surface_queue->impl->reset(surface_queue);
1465 pthread_mutex_unlock(&surface_queue->lock);
1466 pthread_cond_signal(&surface_queue->free_cond);
1468 _tbm_surf_queue_mutex_unlock();
1470 _notify_emit(surface_queue, &surface_queue->reset_noti);
1472 return TBM_SURFACE_QUEUE_ERROR_NONE;
1475 tbm_surface_queue_error_e
1476 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1478 _tbm_surf_queue_mutex_lock();
1480 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1481 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1483 _tbm_surf_queue_mutex_unlock();
1485 _notify_emit(surface_queue, &surface_queue->reset_noti);
1487 return TBM_SURFACE_QUEUE_ERROR_NONE;
1490 tbm_surface_queue_error_e
1491 tbm_surface_queue_set_size(tbm_surface_queue_h
1492 surface_queue, int queue_size, int flush)
1494 queue_node *node = NULL, *tmp;
1496 _tbm_surf_queue_mutex_lock();
1498 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1499 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1500 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1501 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1503 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1505 if ((surface_queue->queue_size == queue_size) && !flush) {
1506 _tbm_surf_queue_mutex_unlock();
1507 return TBM_SURFACE_QUEUE_ERROR_NONE;
1510 pthread_mutex_lock(&surface_queue->lock);
1513 /* Destory surface and Push to free_queue */
1514 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1515 _queue_delete_node(surface_queue, node);
1518 _queue_init(&surface_queue->free_queue);
1519 _queue_init(&surface_queue->dirty_queue);
1520 LIST_INITHEAD(&surface_queue->list);
1522 surface_queue->num_attached = 0;
1523 surface_queue->queue_size = queue_size;
1525 if (surface_queue->impl && surface_queue->impl->reset)
1526 surface_queue->impl->reset(surface_queue);
1528 pthread_mutex_unlock(&surface_queue->lock);
1529 pthread_cond_signal(&surface_queue->free_cond);
1531 _tbm_surf_queue_mutex_unlock();
1533 _notify_emit(surface_queue, &surface_queue->reset_noti);
1535 return TBM_SURFACE_QUEUE_ERROR_NONE;
1537 if (surface_queue->queue_size > queue_size) {
1538 int need_del = surface_queue->queue_size - queue_size;
1540 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1541 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1543 if (surface_queue->impl && surface_queue->impl->need_detach)
1544 surface_queue->impl->need_detach(surface_queue, node);
1546 _tbm_surface_queue_detach(surface_queue, node->surface);
1554 surface_queue->queue_size = queue_size;
1556 pthread_mutex_unlock(&surface_queue->lock);
1558 _tbm_surf_queue_mutex_unlock();
1560 return TBM_SURFACE_QUEUE_ERROR_NONE;
1564 tbm_surface_queue_error_e
1565 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1567 queue_node *node = NULL, *tmp;
1569 _tbm_surf_queue_mutex_lock();
1571 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1572 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1574 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1576 if (surface_queue->num_attached == 0) {
1577 _tbm_surf_queue_mutex_unlock();
1578 return TBM_SURFACE_QUEUE_ERROR_NONE;
1581 pthread_mutex_lock(&surface_queue->lock);
1583 /* Destory surface and Push to free_queue */
1584 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1585 _queue_delete_node(surface_queue, node);
1588 _queue_init(&surface_queue->free_queue);
1589 _queue_init(&surface_queue->dirty_queue);
1590 LIST_INITHEAD(&surface_queue->list);
1592 surface_queue->num_attached = 0;
1594 if (surface_queue->impl && surface_queue->impl->reset)
1595 surface_queue->impl->reset(surface_queue);
1597 pthread_mutex_unlock(&surface_queue->lock);
1598 pthread_cond_signal(&surface_queue->free_cond);
1600 _tbm_surf_queue_mutex_unlock();
1602 _notify_emit(surface_queue, &surface_queue->reset_noti);
1604 return TBM_SURFACE_QUEUE_ERROR_NONE;
1607 tbm_surface_queue_error_e
1608 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1609 tbm_surface_h *surfaces, int *num)
1611 queue_node *node = NULL;
1613 _tbm_surf_queue_mutex_lock();
1617 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1618 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1619 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1620 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1622 pthread_mutex_lock(&surface_queue->lock);
1624 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1626 surfaces[*num] = node->surface;
1631 pthread_mutex_unlock(&surface_queue->lock);
1633 _tbm_surf_queue_mutex_unlock();
1635 return TBM_SURFACE_QUEUE_ERROR_NONE;
1640 } tbm_queue_default;
1643 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1645 free(surface_queue->impl_data);
1649 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1651 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1652 tbm_surface_h surface;
1654 if (surface_queue->queue_size == surface_queue->num_attached)
1657 if (surface_queue->alloc_cb) {
1658 pthread_mutex_unlock(&surface_queue->lock);
1659 _tbm_surf_queue_mutex_unlock();
1660 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1661 _tbm_surf_queue_mutex_lock();
1662 pthread_mutex_lock(&surface_queue->lock);
1668 tbm_surface_internal_ref(surface);
1670 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1671 surface_queue->height,
1672 surface_queue->format,
1674 TBM_RETURN_IF_FAIL(surface != NULL);
1677 _tbm_surface_queue_attach(surface_queue, surface);
1678 tbm_surface_internal_unref(surface);
1681 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1682 NULL, /*__tbm_queue_default_init*/
1683 NULL, /*__tbm_queue_default_reset*/
1684 __tbm_queue_default_destroy,
1685 __tbm_queue_default_need_attach,
1686 NULL, /*__tbm_queue_default_enqueue*/
1687 NULL, /*__tbm_queue_default_release*/
1688 NULL, /*__tbm_queue_default_dequeue*/
1689 NULL, /*__tbm_queue_default_acquire*/
1690 NULL, /*__tbm_queue_default_need_detach*/
1694 tbm_surface_queue_create(int queue_size, int width,
1695 int height, int format, int flags)
1697 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1698 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1699 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1700 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1702 _tbm_surf_queue_mutex_lock();
1704 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1705 sizeof(struct _tbm_surface_queue));
1706 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1708 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1710 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1711 sizeof(tbm_queue_default));
1713 TBM_LOG_E("cannot allocate the tbm_queue_default.\n");
1714 free(surface_queue);
1715 _tbm_surf_queue_mutex_unlock();
1719 data->flags = flags;
1720 _tbm_surface_queue_init(surface_queue,
1722 width, height, format,
1723 &tbm_queue_default_impl, data);
1725 _tbm_surf_queue_mutex_unlock();
1727 return surface_queue;
1733 } tbm_queue_sequence;
1736 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1738 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1740 _queue_init(&data->dequeue_list);
1744 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1746 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1748 _queue_init(&data->dequeue_list);
1752 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1754 free(surface_queue->impl_data);
1758 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1760 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1761 tbm_surface_h surface;
1763 if (surface_queue->queue_size == surface_queue->num_attached)
1766 if (surface_queue->alloc_cb) {
1767 pthread_mutex_unlock(&surface_queue->lock);
1768 _tbm_surf_queue_mutex_unlock();
1769 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1770 _tbm_surf_queue_mutex_lock();
1771 pthread_mutex_lock(&surface_queue->lock);
1777 tbm_surface_internal_ref(surface);
1779 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1780 surface_queue->height,
1781 surface_queue->format,
1783 TBM_RETURN_IF_FAIL(surface != NULL);
1786 _tbm_surface_queue_attach(surface_queue, surface);
1787 tbm_surface_internal_unref(surface);
1791 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1794 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1795 queue_node *next = NULL, *tmp;
1797 node->priv_flags = 0;
1799 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1800 if (next->priv_flags)
1802 _queue_node_pop(&data->dequeue_list, next);
1803 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1808 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1811 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1814 node = _tbm_surface_queue_dequeue(surface_queue);
1816 _queue_node_push_back(&data->dequeue_list, node);
1817 node->priv_flags = 1;
1823 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1824 __tbm_queue_sequence_init,
1825 __tbm_queue_sequence_reset,
1826 __tbm_queue_sequence_destroy,
1827 __tbm_queue_sequence_need_attach,
1828 __tbm_queue_sequence_enqueue,
1829 NULL, /*__tbm_queue_sequence_release*/
1830 __tbm_queue_sequence_dequeue,
1831 NULL, /*__tbm_queue_sequence_acquire*/
1832 NULL, /*__tbm_queue_sequence_need_dettach*/
1836 tbm_surface_queue_sequence_create(int queue_size, int width,
1837 int height, int format, int flags)
1839 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1840 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1841 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1842 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1844 _tbm_surf_queue_mutex_lock();
1846 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1847 sizeof(struct _tbm_surface_queue));
1848 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1850 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1852 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1853 sizeof(tbm_queue_sequence));
1855 TBM_LOG_E("cannot allocate the tbm_queue_sequence.\n");
1856 free(surface_queue);
1857 _tbm_surf_queue_mutex_unlock();
1861 data->flags = flags;
1862 _tbm_surface_queue_init(surface_queue,
1864 width, height, format,
1865 &tbm_queue_sequence_impl, data);
1867 _tbm_surf_queue_mutex_unlock();
1869 return surface_queue;
1871 /* LCOV_EXCL_STOP */