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;
109 typedef struct _tbm_surface_queue_interface {
110 void (*init)(tbm_surface_queue_h queue);
111 void (*reset)(tbm_surface_queue_h queue);
112 void (*destroy)(tbm_surface_queue_h queue);
113 void (*need_attach)(tbm_surface_queue_h queue);
115 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
116 void (*release)(tbm_surface_queue_h queue, queue_node *node);
117 queue_node *(*dequeue)(tbm_surface_queue_h queue);
118 queue_node *(*acquire)(tbm_surface_queue_h queue);
119 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
120 } tbm_surface_queue_interface;
122 struct _tbm_surface_queue {
131 struct list_head list;
133 struct list_head destory_noti;
134 struct list_head dequeuable_noti;
135 struct list_head dequeue_noti;
136 struct list_head acquirable_noti;
137 struct list_head reset_noti;
139 pthread_mutex_t lock;
140 pthread_cond_t free_cond;
141 pthread_cond_t dirty_cond;
143 const tbm_surface_queue_interface *impl;
146 //For external buffer allocation
147 tbm_surface_alloc_cb alloc_cb;
148 tbm_surface_free_cb free_cb;
151 struct list_head item_link; /* link of surface queue */
154 /* LCOV_EXCL_START */
157 _tbm_surf_queue_mutex_init(void)
159 static bool tbm_surf_queue_mutex_init = false;
161 if (tbm_surf_queue_mutex_init)
164 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
165 TBM_LOG_E("fail: tbm_surf_queue mutex init\n");
169 tbm_surf_queue_mutex_init = true;
175 _tbm_surf_queue_mutex_lock(void)
177 if (!_tbm_surf_queue_mutex_init())
180 pthread_mutex_lock(&tbm_surf_queue_lock);
184 _tbm_surf_queue_mutex_unlock(void)
186 pthread_mutex_unlock(&tbm_surf_queue_lock);
190 _init_tbm_surf_queue_bufmgr(void)
192 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
196 _deinit_tbm_surf_queue_bufmgr(void)
198 if (!g_surf_queue_bufmgr)
201 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
202 g_surf_queue_bufmgr = NULL;
206 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
208 tbm_surface_queue_h old_data;
210 if (surface_queue == NULL || g_surf_queue_bufmgr == NULL) {
211 TBM_TRACE("error: surface_queue is NULL or not initialized\n");
215 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
216 TBM_TRACE("error: surf_queue_list is empty\n");
220 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
222 if (old_data == surface_queue) {
223 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
228 TBM_TRACE("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
233 _queue_node_create(void)
235 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
237 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
243 _queue_node_delete(queue_node *node)
245 LIST_DEL(&node->item_link);
246 LIST_DEL(&node->link);
251 _queue_is_empty(queue *queue)
253 if (LIST_IS_EMPTY(&queue->head))
260 _queue_node_push_back(queue *queue, queue_node *node)
262 LIST_ADDTAIL(&node->item_link, &queue->head);
267 _queue_node_push_front(queue *queue, queue_node *node)
269 LIST_ADD(&node->item_link, &queue->head);
274 _queue_node_pop_front(queue *queue)
278 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
280 LIST_DEL(&node->item_link);
287 _queue_node_pop(queue *queue, queue_node *node)
289 LIST_DEL(&node->item_link);
296 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
297 tbm_surface_h surface, int *out_type)
302 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
306 if (type & FREE_QUEUE) {
307 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
309 if (node->surface == surface) {
311 *out_type = FREE_QUEUE;
318 if (type & DIRTY_QUEUE) {
319 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
321 if (node->surface == surface) {
323 *out_type = DIRTY_QUEUE;
330 if (type & NODE_LIST) {
331 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
332 if (node->surface == surface) {
334 *out_type = NODE_LIST;
345 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
348 if (surface_queue->free_cb) {
349 surface_queue->free_cb(surface_queue,
350 surface_queue->alloc_cb_data,
354 tbm_surface_destroy(node->surface);
357 _queue_node_delete(node);
361 _queue_init(queue *queue)
363 LIST_INITHEAD(&queue->head);
369 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
372 TBM_RETURN_IF_FAIL(cb != NULL);
374 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
376 TBM_RETURN_IF_FAIL(item != NULL);
378 LIST_INITHEAD(&item->link);
382 LIST_ADDTAIL(&item->link, list);
386 _notify_remove(struct list_head *list,
387 tbm_surface_queue_notify_cb cb, void *data)
389 queue_notify *item, *tmp;
391 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
392 if (item->cb == cb && item->data == data) {
393 LIST_DEL(&item->link);
399 TBM_LOG_E("Cannot find notifiy\n");
403 _notify_remove_all(struct list_head *list)
405 queue_notify *item, *tmp;
407 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
408 LIST_DEL(&item->link);
414 _notify_emit(tbm_surface_queue_h surface_queue,
415 struct list_head *list)
419 LIST_FOR_EACH_ENTRY(item, list, link)
420 item->cb(surface_queue, item->data);
424 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
429 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
430 if (node->type == type)
438 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
439 tbm_surface_h surface)
443 node = _queue_node_create();
444 TBM_RETURN_IF_FAIL(node != NULL);
446 tbm_surface_internal_ref(surface);
447 node->surface = surface;
449 LIST_ADDTAIL(&node->link, &surface_queue->list);
450 surface_queue->num_attached++;
451 _queue_node_push_back(&surface_queue->free_queue, node);
455 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
456 tbm_surface_h surface)
461 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
463 _queue_delete_node(surface_queue, node);
464 surface_queue->num_attached--;
469 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
470 queue_node *node, int push_back)
473 _queue_node_push_back(&surface_queue->dirty_queue, node);
475 _queue_node_push_front(&surface_queue->dirty_queue, node);
479 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
483 if (_queue_is_empty(&surface_queue->free_queue)) {
484 if (surface_queue->impl && surface_queue->impl->need_attach)
485 surface_queue->impl->need_attach(surface_queue);
487 if (_queue_is_empty(&surface_queue->free_queue))
491 node = _queue_node_pop_front(&surface_queue->free_queue);
497 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
501 if (_queue_is_empty(&surface_queue->dirty_queue))
504 node = _queue_node_pop_front(&surface_queue->dirty_queue);
510 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
511 queue_node *node, int push_back)
514 _queue_node_push_back(&surface_queue->free_queue, node);
516 _queue_node_push_front(&surface_queue->free_queue, node);
520 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
522 int width, int height, int format,
523 const tbm_surface_queue_interface *impl, void *data)
525 TBM_RETURN_IF_FAIL(surface_queue != NULL);
526 TBM_RETURN_IF_FAIL(impl != NULL);
528 if (!g_surf_queue_bufmgr)
529 _init_tbm_surf_queue_bufmgr();
531 pthread_mutex_init(&surface_queue->lock, NULL);
532 pthread_cond_init(&surface_queue->free_cond, NULL);
533 pthread_cond_init(&surface_queue->dirty_cond, NULL);
535 surface_queue->queue_size = queue_size;
536 surface_queue->width = width;
537 surface_queue->height = height;
538 surface_queue->format = format;
539 surface_queue->impl = impl;
540 surface_queue->impl_data = data;
542 _queue_init(&surface_queue->free_queue);
543 _queue_init(&surface_queue->dirty_queue);
544 LIST_INITHEAD(&surface_queue->list);
546 LIST_INITHEAD(&surface_queue->destory_noti);
547 LIST_INITHEAD(&surface_queue->dequeuable_noti);
548 LIST_INITHEAD(&surface_queue->dequeue_noti);
549 LIST_INITHEAD(&surface_queue->acquirable_noti);
550 LIST_INITHEAD(&surface_queue->reset_noti);
552 if (surface_queue->impl && surface_queue->impl->init)
553 surface_queue->impl->init(surface_queue);
555 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
558 tbm_surface_queue_error_e
559 tbm_surface_queue_add_destroy_cb(
560 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
563 _tbm_surf_queue_mutex_lock();
565 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
566 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
568 pthread_mutex_lock(&surface_queue->lock);
570 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
572 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
574 pthread_mutex_unlock(&surface_queue->lock);
576 _tbm_surf_queue_mutex_unlock();
578 return TBM_SURFACE_QUEUE_ERROR_NONE;
581 tbm_surface_queue_error_e
582 tbm_surface_queue_remove_destroy_cb(
583 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
586 _tbm_surf_queue_mutex_lock();
588 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
589 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
591 pthread_mutex_lock(&surface_queue->lock);
593 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
595 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
597 pthread_mutex_unlock(&surface_queue->lock);
599 _tbm_surf_queue_mutex_unlock();
601 return TBM_SURFACE_QUEUE_ERROR_NONE;
604 tbm_surface_queue_error_e
605 tbm_surface_queue_add_dequeuable_cb(
606 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
609 _tbm_surf_queue_mutex_lock();
611 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
612 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
614 pthread_mutex_lock(&surface_queue->lock);
616 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
618 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
620 pthread_mutex_unlock(&surface_queue->lock);
622 _tbm_surf_queue_mutex_unlock();
624 return TBM_SURFACE_QUEUE_ERROR_NONE;
627 tbm_surface_queue_error_e
628 tbm_surface_queue_remove_dequeuable_cb(
629 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
632 _tbm_surf_queue_mutex_lock();
634 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
635 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
637 pthread_mutex_lock(&surface_queue->lock);
639 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
641 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
643 pthread_mutex_unlock(&surface_queue->lock);
645 _tbm_surf_queue_mutex_unlock();
647 return TBM_SURFACE_QUEUE_ERROR_NONE;
650 tbm_surface_queue_error_e
651 tbm_surface_queue_add_dequeue_cb(
652 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
655 _tbm_surf_queue_mutex_lock();
657 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
658 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
660 pthread_mutex_lock(&surface_queue->lock);
662 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
664 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
666 pthread_mutex_unlock(&surface_queue->lock);
668 _tbm_surf_queue_mutex_unlock();
670 return TBM_SURFACE_QUEUE_ERROR_NONE;
673 tbm_surface_queue_error_e
674 tbm_surface_queue_remove_dequeue_cb(
675 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
678 _tbm_surf_queue_mutex_lock();
680 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
681 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
683 pthread_mutex_lock(&surface_queue->lock);
685 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
687 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
689 pthread_mutex_unlock(&surface_queue->lock);
691 _tbm_surf_queue_mutex_unlock();
693 return TBM_SURFACE_QUEUE_ERROR_NONE;
696 tbm_surface_queue_error_e
697 tbm_surface_queue_add_acquirable_cb(
698 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
701 _tbm_surf_queue_mutex_lock();
703 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
704 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
706 pthread_mutex_lock(&surface_queue->lock);
708 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
710 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
712 pthread_mutex_unlock(&surface_queue->lock);
714 _tbm_surf_queue_mutex_unlock();
716 return TBM_SURFACE_QUEUE_ERROR_NONE;
719 tbm_surface_queue_error_e
720 tbm_surface_queue_remove_acquirable_cb(
721 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
724 _tbm_surf_queue_mutex_lock();
726 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
727 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
729 pthread_mutex_lock(&surface_queue->lock);
731 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
733 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
735 pthread_mutex_unlock(&surface_queue->lock);
737 _tbm_surf_queue_mutex_unlock();
739 return TBM_SURFACE_QUEUE_ERROR_NONE;
742 tbm_surface_queue_error_e
743 tbm_surface_queue_set_alloc_cb(
744 tbm_surface_queue_h surface_queue,
745 tbm_surface_alloc_cb alloc_cb,
746 tbm_surface_free_cb free_cb,
749 _tbm_surf_queue_mutex_lock();
751 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
752 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
754 pthread_mutex_lock(&surface_queue->lock);
756 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
758 surface_queue->alloc_cb = alloc_cb;
759 surface_queue->free_cb = free_cb;
760 surface_queue->alloc_cb_data = data;
762 pthread_mutex_unlock(&surface_queue->lock);
764 _tbm_surf_queue_mutex_unlock();
766 return TBM_SURFACE_QUEUE_ERROR_NONE;
770 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
774 _tbm_surf_queue_mutex_lock();
776 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
778 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
780 width = surface_queue->width;
782 _tbm_surf_queue_mutex_unlock();
788 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
792 _tbm_surf_queue_mutex_lock();
794 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
796 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
798 height = surface_queue->height;
800 _tbm_surf_queue_mutex_unlock();
806 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
810 _tbm_surf_queue_mutex_lock();
812 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
814 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
816 format = surface_queue->format;
818 _tbm_surf_queue_mutex_unlock();
824 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
828 _tbm_surf_queue_mutex_lock();
830 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
832 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
834 queue_size = surface_queue->queue_size;
836 _tbm_surf_queue_mutex_unlock();
841 tbm_surface_queue_error_e
842 tbm_surface_queue_add_reset_cb(
843 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
846 _tbm_surf_queue_mutex_lock();
848 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
849 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
851 pthread_mutex_lock(&surface_queue->lock);
853 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
855 _notify_add(&surface_queue->reset_noti, reset_cb, data);
857 pthread_mutex_unlock(&surface_queue->lock);
859 _tbm_surf_queue_mutex_unlock();
861 return TBM_SURFACE_QUEUE_ERROR_NONE;
864 tbm_surface_queue_error_e
865 tbm_surface_queue_remove_reset_cb(
866 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
869 _tbm_surf_queue_mutex_lock();
871 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
872 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
874 pthread_mutex_lock(&surface_queue->lock);
876 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
878 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
880 pthread_mutex_unlock(&surface_queue->lock);
882 _tbm_surf_queue_mutex_unlock();
884 return TBM_SURFACE_QUEUE_ERROR_NONE;
887 tbm_surface_queue_error_e
888 tbm_surface_queue_enqueue(tbm_surface_queue_h
889 surface_queue, tbm_surface_h surface)
894 _tbm_surf_queue_mutex_lock();
896 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
897 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
898 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
899 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
902 tbm_surface_internal_dump_buffer(surface, "enqueue");
904 pthread_mutex_lock(&surface_queue->lock);
906 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
908 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
909 if (node == NULL || queue_type != NODE_LIST) {
910 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
912 pthread_mutex_unlock(&surface_queue->lock);
914 _tbm_surf_queue_mutex_unlock();
915 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
918 if (surface_queue->impl && surface_queue->impl->enqueue)
919 surface_queue->impl->enqueue(surface_queue, node);
921 _tbm_surface_queue_enqueue(surface_queue, node, 1);
923 if (_queue_is_empty(&surface_queue->dirty_queue)) {
924 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
925 pthread_mutex_unlock(&surface_queue->lock);
927 _tbm_surf_queue_mutex_unlock();
928 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
931 node->type = QUEUE_NODE_TYPE_ENQUEUE;
933 pthread_mutex_unlock(&surface_queue->lock);
934 pthread_cond_signal(&surface_queue->dirty_cond);
936 _tbm_surf_queue_mutex_unlock();
938 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
940 return TBM_SURFACE_QUEUE_ERROR_NONE;
943 tbm_surface_queue_error_e
944 tbm_surface_queue_dequeue(tbm_surface_queue_h
945 surface_queue, tbm_surface_h *surface)
949 _tbm_surf_queue_mutex_lock();
953 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
954 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
955 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
956 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
958 pthread_mutex_lock(&surface_queue->lock);
960 if (surface_queue->impl && surface_queue->impl->dequeue)
961 node = surface_queue->impl->dequeue(surface_queue);
963 node = _tbm_surface_queue_dequeue(surface_queue);
965 if (node == NULL || node->surface == NULL) {
966 TBM_LOG_E("_queue_node_pop_front failed\n");
967 pthread_mutex_unlock(&surface_queue->lock);
969 _tbm_surf_queue_mutex_unlock();
970 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
973 node->type = QUEUE_NODE_TYPE_DEQUEUE;
974 *surface = node->surface;
976 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
978 pthread_mutex_unlock(&surface_queue->lock);
980 _tbm_surf_queue_mutex_unlock();
982 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
984 return TBM_SURFACE_QUEUE_ERROR_NONE;
988 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
990 _tbm_surf_queue_mutex_lock();
992 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
994 pthread_mutex_lock(&surface_queue->lock);
996 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
998 if (_queue_is_empty(&surface_queue->free_queue)) {
999 if (surface_queue->impl && surface_queue->impl->need_attach)
1000 surface_queue->impl->need_attach(surface_queue);
1002 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1003 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1004 _tbm_surf_queue_mutex_unlock();
1009 if (_queue_is_empty(&surface_queue->free_queue)) {
1011 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE)) {
1013 _tbm_surf_queue_mutex_unlock();
1015 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1017 _tbm_surf_queue_mutex_lock();
1019 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1020 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1021 _tbm_surf_queue_mutex_unlock();
1025 pthread_mutex_unlock(&surface_queue->lock);
1027 _tbm_surf_queue_mutex_unlock();
1031 pthread_mutex_unlock(&surface_queue->lock);
1033 _tbm_surf_queue_mutex_unlock();
1037 pthread_mutex_unlock(&surface_queue->lock);
1039 _tbm_surf_queue_mutex_unlock();
1044 tbm_surface_queue_error_e
1045 tbm_surface_queue_release(tbm_surface_queue_h
1046 surface_queue, tbm_surface_h surface)
1051 _tbm_surf_queue_mutex_lock();
1053 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1054 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1055 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1056 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1058 pthread_mutex_lock(&surface_queue->lock);
1060 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1062 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1063 if (node == NULL || queue_type != NODE_LIST) {
1064 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1066 pthread_mutex_unlock(&surface_queue->lock);
1068 _tbm_surf_queue_mutex_unlock();
1069 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1072 if (surface_queue->queue_size < surface_queue->num_attached) {
1074 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1076 if (surface_queue->impl && surface_queue->impl->need_detach)
1077 surface_queue->impl->need_detach(surface_queue, node);
1079 _tbm_surface_queue_detach(surface_queue, surface);
1081 pthread_mutex_unlock(&surface_queue->lock);
1083 _tbm_surf_queue_mutex_unlock();
1084 return TBM_SURFACE_QUEUE_ERROR_NONE;
1087 if (surface_queue->impl && surface_queue->impl->release)
1088 surface_queue->impl->release(surface_queue, node);
1090 _tbm_surface_queue_release(surface_queue, node, 1);
1092 if (_queue_is_empty(&surface_queue->free_queue)) {
1093 pthread_mutex_unlock(&surface_queue->lock);
1095 _tbm_surf_queue_mutex_unlock();
1096 return TBM_SURFACE_QUEUE_ERROR_NONE;
1099 node->type = QUEUE_NODE_TYPE_RELEASE;
1101 pthread_mutex_unlock(&surface_queue->lock);
1102 pthread_cond_signal(&surface_queue->free_cond);
1104 _tbm_surf_queue_mutex_unlock();
1106 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1108 return TBM_SURFACE_QUEUE_ERROR_NONE;
1111 tbm_surface_queue_error_e
1112 tbm_surface_queue_acquire(tbm_surface_queue_h
1113 surface_queue, tbm_surface_h *surface)
1117 _tbm_surf_queue_mutex_lock();
1121 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1122 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1123 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1124 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1126 pthread_mutex_lock(&surface_queue->lock);
1128 if (surface_queue->impl && surface_queue->impl->acquire)
1129 node = surface_queue->impl->acquire(surface_queue);
1131 node = _tbm_surface_queue_acquire(surface_queue);
1133 if (node == NULL || node->surface == NULL) {
1134 TBM_LOG_E("_queue_node_pop_front failed\n");
1135 pthread_mutex_unlock(&surface_queue->lock);
1137 _tbm_surf_queue_mutex_unlock();
1138 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1141 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1143 *surface = node->surface;
1145 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1147 pthread_mutex_unlock(&surface_queue->lock);
1149 _tbm_surf_queue_mutex_unlock();
1152 tbm_surface_internal_dump_buffer(*surface, "acquire");
1154 return TBM_SURFACE_QUEUE_ERROR_NONE;
1158 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1160 _tbm_surf_queue_mutex_lock();
1162 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1164 pthread_mutex_lock(&surface_queue->lock);
1166 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1168 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1170 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE)) {
1172 _tbm_surf_queue_mutex_unlock();
1174 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1176 _tbm_surf_queue_mutex_lock();
1178 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1179 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1180 _tbm_surf_queue_mutex_unlock();
1184 pthread_mutex_unlock(&surface_queue->lock);
1186 _tbm_surf_queue_mutex_unlock();
1190 pthread_mutex_unlock(&surface_queue->lock);
1192 _tbm_surf_queue_mutex_unlock();
1196 pthread_mutex_unlock(&surface_queue->lock);
1198 _tbm_surf_queue_mutex_unlock();
1204 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1206 queue_node *node, *tmp;
1208 _tbm_surf_queue_mutex_lock();
1210 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1212 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1214 LIST_DEL(&surface_queue->item_link);
1216 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1217 _queue_delete_node(surface_queue, node);
1219 if (surface_queue->impl && surface_queue->impl->destroy)
1220 surface_queue->impl->destroy(surface_queue);
1222 _notify_emit(surface_queue, &surface_queue->destory_noti);
1224 _notify_remove_all(&surface_queue->destory_noti);
1225 _notify_remove_all(&surface_queue->dequeuable_noti);
1226 _notify_remove_all(&surface_queue->dequeue_noti);
1227 _notify_remove_all(&surface_queue->acquirable_noti);
1228 _notify_remove_all(&surface_queue->reset_noti);
1230 pthread_mutex_destroy(&surface_queue->lock);
1232 free(surface_queue);
1234 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1235 _deinit_tbm_surf_queue_bufmgr();
1237 _tbm_surf_queue_mutex_unlock();
1240 tbm_surface_queue_error_e
1241 tbm_surface_queue_reset(tbm_surface_queue_h
1242 surface_queue, int width, int height, int format)
1244 queue_node *node, *tmp;
1246 _tbm_surf_queue_mutex_lock();
1248 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1249 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1251 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1253 if (width == surface_queue->width && height == surface_queue->height &&
1254 format == surface_queue->format) {
1255 _tbm_surf_queue_mutex_unlock();
1256 return TBM_SURFACE_QUEUE_ERROR_NONE;
1259 pthread_mutex_lock(&surface_queue->lock);
1261 surface_queue->width = width;
1262 surface_queue->height = height;
1263 surface_queue->format = format;
1265 /* Destory surface and Push to free_queue */
1266 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1267 _queue_delete_node(surface_queue, node);
1270 _queue_init(&surface_queue->free_queue);
1271 _queue_init(&surface_queue->dirty_queue);
1272 LIST_INITHEAD(&surface_queue->list);
1274 surface_queue->num_attached = 0;
1276 if (surface_queue->impl && surface_queue->impl->reset)
1277 surface_queue->impl->reset(surface_queue);
1279 pthread_mutex_unlock(&surface_queue->lock);
1280 pthread_cond_signal(&surface_queue->free_cond);
1282 _tbm_surf_queue_mutex_unlock();
1284 _notify_emit(surface_queue, &surface_queue->reset_noti);
1286 return TBM_SURFACE_QUEUE_ERROR_NONE;
1289 tbm_surface_queue_error_e
1290 tbm_surface_queue_set_size(tbm_surface_queue_h
1291 surface_queue, int queue_size, int flush)
1293 queue_node *node, *tmp;
1295 _tbm_surf_queue_mutex_lock();
1297 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1298 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1299 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1300 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1302 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1304 if ((surface_queue->queue_size == queue_size) && !flush) {
1305 _tbm_surf_queue_mutex_unlock();
1306 return TBM_SURFACE_QUEUE_ERROR_NONE;
1309 pthread_mutex_lock(&surface_queue->lock);
1312 /* Destory surface and Push to free_queue */
1313 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1314 _queue_delete_node(surface_queue, node);
1317 _queue_init(&surface_queue->free_queue);
1318 _queue_init(&surface_queue->dirty_queue);
1319 LIST_INITHEAD(&surface_queue->list);
1321 surface_queue->num_attached = 0;
1322 surface_queue->queue_size = queue_size;
1324 if (surface_queue->impl && surface_queue->impl->reset)
1325 surface_queue->impl->reset(surface_queue);
1327 pthread_mutex_unlock(&surface_queue->lock);
1328 pthread_cond_signal(&surface_queue->free_cond);
1330 _tbm_surf_queue_mutex_unlock();
1332 _notify_emit(surface_queue, &surface_queue->reset_noti);
1334 return TBM_SURFACE_QUEUE_ERROR_NONE;
1336 if (surface_queue->queue_size > queue_size) {
1337 int need_del = surface_queue->queue_size - queue_size;
1339 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1340 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1342 if (surface_queue->impl && surface_queue->impl->need_detach)
1343 surface_queue->impl->need_detach(surface_queue, node);
1345 _tbm_surface_queue_detach(surface_queue, node->surface);
1353 surface_queue->queue_size = queue_size;
1355 pthread_mutex_unlock(&surface_queue->lock);
1357 _tbm_surf_queue_mutex_unlock();
1359 return TBM_SURFACE_QUEUE_ERROR_NONE;
1363 tbm_surface_queue_error_e
1364 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1366 queue_node *node, *tmp;
1368 _tbm_surf_queue_mutex_lock();
1370 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1371 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1373 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1375 if (surface_queue->num_attached == 0) {
1376 _tbm_surf_queue_mutex_unlock();
1377 return TBM_SURFACE_QUEUE_ERROR_NONE;
1380 pthread_mutex_lock(&surface_queue->lock);
1382 /* Destory surface and Push to free_queue */
1383 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1384 _queue_delete_node(surface_queue, node);
1387 _queue_init(&surface_queue->free_queue);
1388 _queue_init(&surface_queue->dirty_queue);
1389 LIST_INITHEAD(&surface_queue->list);
1391 surface_queue->num_attached = 0;
1393 if (surface_queue->impl && surface_queue->impl->reset)
1394 surface_queue->impl->reset(surface_queue);
1396 pthread_mutex_unlock(&surface_queue->lock);
1397 pthread_cond_signal(&surface_queue->free_cond);
1399 _tbm_surf_queue_mutex_unlock();
1401 _notify_emit(surface_queue, &surface_queue->reset_noti);
1403 return TBM_SURFACE_QUEUE_ERROR_NONE;
1406 tbm_surface_queue_error_e
1407 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1408 tbm_surface_h *surfaces, int *num)
1412 _tbm_surf_queue_mutex_lock();
1416 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1417 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1418 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1419 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1421 pthread_mutex_lock(&surface_queue->lock);
1423 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1425 surfaces[*num] = node->surface;
1430 pthread_mutex_unlock(&surface_queue->lock);
1432 _tbm_surf_queue_mutex_unlock();
1434 return TBM_SURFACE_QUEUE_ERROR_NONE;
1439 } tbm_queue_default;
1442 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1444 free(surface_queue->impl_data);
1448 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1450 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1451 tbm_surface_h surface;
1453 if (surface_queue->queue_size == surface_queue->num_attached)
1456 if (surface_queue->alloc_cb) {
1457 _tbm_surf_queue_mutex_unlock();
1458 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1459 _tbm_surf_queue_mutex_lock();
1464 tbm_surface_internal_ref(surface);
1466 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1467 surface_queue->height,
1468 surface_queue->format,
1470 TBM_RETURN_IF_FAIL(surface != NULL);
1473 _tbm_surface_queue_attach(surface_queue, surface);
1474 tbm_surface_internal_unref(surface);
1477 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1478 NULL, /*__tbm_queue_default_init*/
1479 NULL, /*__tbm_queue_default_reset*/
1480 __tbm_queue_default_destroy,
1481 __tbm_queue_default_need_attach,
1482 NULL, /*__tbm_queue_default_enqueue*/
1483 NULL, /*__tbm_queue_default_release*/
1484 NULL, /*__tbm_queue_default_dequeue*/
1485 NULL, /*__tbm_queue_default_acquire*/
1486 NULL, /*__tbm_queue_default_need_detach*/
1490 tbm_surface_queue_create(int queue_size, int width,
1491 int height, int format, int flags)
1493 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1494 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1495 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1496 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1498 _tbm_surf_queue_mutex_lock();
1500 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1501 sizeof(struct _tbm_surface_queue));
1502 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1504 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1506 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1507 sizeof(tbm_queue_default));
1509 free(surface_queue);
1510 _tbm_surf_queue_mutex_unlock();
1514 data->flags = flags;
1515 _tbm_surface_queue_init(surface_queue,
1517 width, height, format,
1518 &tbm_queue_default_impl, data);
1520 _tbm_surf_queue_mutex_unlock();
1522 return surface_queue;
1528 } tbm_queue_sequence;
1531 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1533 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1535 _queue_init(&data->dequeue_list);
1539 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1541 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1543 _queue_init(&data->dequeue_list);
1547 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1549 free(surface_queue->impl_data);
1553 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1555 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1556 tbm_surface_h surface;
1558 if (surface_queue->queue_size == surface_queue->num_attached)
1561 if (surface_queue->alloc_cb) {
1562 _tbm_surf_queue_mutex_unlock();
1563 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1564 _tbm_surf_queue_mutex_lock();
1569 tbm_surface_internal_ref(surface);
1571 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1572 surface_queue->height,
1573 surface_queue->format,
1575 TBM_RETURN_IF_FAIL(surface != NULL);
1578 _tbm_surface_queue_attach(surface_queue, surface);
1579 tbm_surface_internal_unref(surface);
1583 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1586 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1587 queue_node *next, *tmp;
1589 node->priv_flags = 0;
1591 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1592 if (next->priv_flags)
1594 _queue_node_pop(&data->dequeue_list, next);
1595 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1600 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1603 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1606 node = _tbm_surface_queue_dequeue(surface_queue);
1608 _queue_node_push_back(&data->dequeue_list, node);
1609 node->priv_flags = 1;
1615 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1616 __tbm_queue_sequence_init,
1617 __tbm_queue_sequence_reset,
1618 __tbm_queue_sequence_destroy,
1619 __tbm_queue_sequence_need_attach,
1620 __tbm_queue_sequence_enqueue,
1621 NULL, /*__tbm_queue_sequence_release*/
1622 __tbm_queue_sequence_dequeue,
1623 NULL, /*__tbm_queue_sequence_acquire*/
1624 NULL, /*__tbm_queue_sequence_need_dettach*/
1628 tbm_surface_queue_sequence_create(int queue_size, int width,
1629 int height, int format, int flags)
1631 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1632 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1633 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1634 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1636 _tbm_surf_queue_mutex_lock();
1638 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1639 sizeof(struct _tbm_surface_queue));
1640 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1642 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1644 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1645 sizeof(tbm_queue_sequence));
1647 free(surface_queue);
1648 _tbm_surf_queue_mutex_unlock();
1652 data->flags = flags;
1653 _tbm_surface_queue_init(surface_queue,
1655 width, height, format,
1656 &tbm_queue_sequence_impl, data);
1658 _tbm_surf_queue_mutex_unlock();
1660 return surface_queue;
1662 /* LCOV_EXCL_STOP */