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) {
1073 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1075 if (surface_queue->impl && surface_queue->impl->need_detach)
1076 surface_queue->impl->need_detach(surface_queue, node);
1078 _tbm_surface_queue_detach(surface_queue, surface);
1080 pthread_mutex_unlock(&surface_queue->lock);
1082 _tbm_surf_queue_mutex_unlock();
1083 return TBM_SURFACE_QUEUE_ERROR_NONE;
1086 if (surface_queue->impl && surface_queue->impl->release)
1087 surface_queue->impl->release(surface_queue, node);
1089 _tbm_surface_queue_release(surface_queue, node, 1);
1091 if (_queue_is_empty(&surface_queue->free_queue)) {
1092 pthread_mutex_unlock(&surface_queue->lock);
1094 _tbm_surf_queue_mutex_unlock();
1095 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1098 node->type = QUEUE_NODE_TYPE_RELEASE;
1100 pthread_mutex_unlock(&surface_queue->lock);
1101 pthread_cond_signal(&surface_queue->free_cond);
1103 _tbm_surf_queue_mutex_unlock();
1105 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1107 return TBM_SURFACE_QUEUE_ERROR_NONE;
1110 tbm_surface_queue_error_e
1111 tbm_surface_queue_acquire(tbm_surface_queue_h
1112 surface_queue, tbm_surface_h *surface)
1116 _tbm_surf_queue_mutex_lock();
1120 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1121 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1122 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1123 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1125 pthread_mutex_lock(&surface_queue->lock);
1127 if (surface_queue->impl && surface_queue->impl->acquire)
1128 node = surface_queue->impl->acquire(surface_queue);
1130 node = _tbm_surface_queue_acquire(surface_queue);
1132 if (node == NULL || node->surface == NULL) {
1133 TBM_LOG_E("_queue_node_pop_front failed\n");
1134 pthread_mutex_unlock(&surface_queue->lock);
1136 _tbm_surf_queue_mutex_unlock();
1137 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1140 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1142 *surface = node->surface;
1144 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1146 pthread_mutex_unlock(&surface_queue->lock);
1148 _tbm_surf_queue_mutex_unlock();
1151 tbm_surface_internal_dump_buffer(*surface, "acquire");
1153 return TBM_SURFACE_QUEUE_ERROR_NONE;
1157 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1159 _tbm_surf_queue_mutex_lock();
1161 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1163 pthread_mutex_lock(&surface_queue->lock);
1165 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1167 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1169 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE)) {
1171 _tbm_surf_queue_mutex_unlock();
1173 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1175 _tbm_surf_queue_mutex_lock();
1177 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1178 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1179 _tbm_surf_queue_mutex_unlock();
1183 pthread_mutex_unlock(&surface_queue->lock);
1185 _tbm_surf_queue_mutex_unlock();
1189 pthread_mutex_unlock(&surface_queue->lock);
1191 _tbm_surf_queue_mutex_unlock();
1195 pthread_mutex_unlock(&surface_queue->lock);
1197 _tbm_surf_queue_mutex_unlock();
1203 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1205 queue_node *node, *tmp;
1207 _tbm_surf_queue_mutex_lock();
1209 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1211 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1213 LIST_DEL(&surface_queue->item_link);
1215 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1216 _queue_delete_node(surface_queue, node);
1218 if (surface_queue->impl && surface_queue->impl->destroy)
1219 surface_queue->impl->destroy(surface_queue);
1221 _notify_emit(surface_queue, &surface_queue->destory_noti);
1223 _notify_remove_all(&surface_queue->destory_noti);
1224 _notify_remove_all(&surface_queue->dequeuable_noti);
1225 _notify_remove_all(&surface_queue->dequeue_noti);
1226 _notify_remove_all(&surface_queue->acquirable_noti);
1227 _notify_remove_all(&surface_queue->reset_noti);
1229 pthread_mutex_destroy(&surface_queue->lock);
1231 free(surface_queue);
1233 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1234 _deinit_tbm_surf_queue_bufmgr();
1236 _tbm_surf_queue_mutex_unlock();
1239 tbm_surface_queue_error_e
1240 tbm_surface_queue_reset(tbm_surface_queue_h
1241 surface_queue, int width, int height, int format)
1243 queue_node *node, *tmp;
1245 _tbm_surf_queue_mutex_lock();
1247 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1248 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1250 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1252 if (width == surface_queue->width && height == surface_queue->height &&
1253 format == surface_queue->format) {
1254 _tbm_surf_queue_mutex_unlock();
1255 return TBM_SURFACE_QUEUE_ERROR_NONE;
1258 pthread_mutex_lock(&surface_queue->lock);
1260 surface_queue->width = width;
1261 surface_queue->height = height;
1262 surface_queue->format = format;
1264 /* Destory surface and Push to free_queue */
1265 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1266 _queue_delete_node(surface_queue, node);
1269 _queue_init(&surface_queue->free_queue);
1270 _queue_init(&surface_queue->dirty_queue);
1271 LIST_INITHEAD(&surface_queue->list);
1273 surface_queue->num_attached = 0;
1275 if (surface_queue->impl && surface_queue->impl->reset)
1276 surface_queue->impl->reset(surface_queue);
1278 pthread_mutex_unlock(&surface_queue->lock);
1279 pthread_cond_signal(&surface_queue->free_cond);
1281 _tbm_surf_queue_mutex_unlock();
1283 _notify_emit(surface_queue, &surface_queue->reset_noti);
1285 return TBM_SURFACE_QUEUE_ERROR_NONE;
1288 tbm_surface_queue_error_e
1289 tbm_surface_queue_set_size(tbm_surface_queue_h
1290 surface_queue, int queue_size, int flush)
1292 queue_node *node, *tmp;
1294 _tbm_surf_queue_mutex_lock();
1296 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1297 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1298 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1299 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1301 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1303 if ((surface_queue->queue_size == queue_size) && !flush) {
1304 _tbm_surf_queue_mutex_unlock();
1305 return TBM_SURFACE_QUEUE_ERROR_NONE;
1308 pthread_mutex_lock(&surface_queue->lock);
1311 /* Destory surface and Push to free_queue */
1312 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1313 _queue_delete_node(surface_queue, node);
1316 _queue_init(&surface_queue->free_queue);
1317 _queue_init(&surface_queue->dirty_queue);
1318 LIST_INITHEAD(&surface_queue->list);
1320 surface_queue->num_attached = 0;
1321 surface_queue->queue_size = queue_size;
1323 if (surface_queue->impl && surface_queue->impl->reset)
1324 surface_queue->impl->reset(surface_queue);
1326 pthread_mutex_unlock(&surface_queue->lock);
1327 pthread_cond_signal(&surface_queue->free_cond);
1329 _tbm_surf_queue_mutex_unlock();
1331 _notify_emit(surface_queue, &surface_queue->reset_noti);
1333 return TBM_SURFACE_QUEUE_ERROR_NONE;
1335 if (surface_queue->queue_size > queue_size) {
1336 int need_del = surface_queue->queue_size - queue_size;
1338 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1339 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1341 if (surface_queue->impl && surface_queue->impl->need_detach)
1342 surface_queue->impl->need_detach(surface_queue, node);
1344 _tbm_surface_queue_detach(surface_queue, node->surface);
1352 surface_queue->queue_size = queue_size;
1354 pthread_mutex_unlock(&surface_queue->lock);
1356 _tbm_surf_queue_mutex_unlock();
1358 return TBM_SURFACE_QUEUE_ERROR_NONE;
1362 tbm_surface_queue_error_e
1363 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1365 queue_node *node, *tmp;
1367 _tbm_surf_queue_mutex_lock();
1369 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1370 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1372 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1374 if (surface_queue->num_attached == 0) {
1375 _tbm_surf_queue_mutex_unlock();
1376 return TBM_SURFACE_QUEUE_ERROR_NONE;
1379 pthread_mutex_lock(&surface_queue->lock);
1381 /* Destory surface and Push to free_queue */
1382 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1383 _queue_delete_node(surface_queue, node);
1386 _queue_init(&surface_queue->free_queue);
1387 _queue_init(&surface_queue->dirty_queue);
1388 LIST_INITHEAD(&surface_queue->list);
1390 surface_queue->num_attached = 0;
1392 if (surface_queue->impl && surface_queue->impl->reset)
1393 surface_queue->impl->reset(surface_queue);
1395 pthread_mutex_unlock(&surface_queue->lock);
1396 pthread_cond_signal(&surface_queue->free_cond);
1398 _tbm_surf_queue_mutex_unlock();
1400 _notify_emit(surface_queue, &surface_queue->reset_noti);
1402 return TBM_SURFACE_QUEUE_ERROR_NONE;
1405 tbm_surface_queue_error_e
1406 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1407 tbm_surface_h *surfaces, int *num)
1411 _tbm_surf_queue_mutex_lock();
1415 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1416 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1417 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1418 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1420 pthread_mutex_lock(&surface_queue->lock);
1422 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1424 surfaces[*num] = node->surface;
1429 pthread_mutex_unlock(&surface_queue->lock);
1431 _tbm_surf_queue_mutex_unlock();
1433 return TBM_SURFACE_QUEUE_ERROR_NONE;
1438 } tbm_queue_default;
1441 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1443 free(surface_queue->impl_data);
1447 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1449 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
1450 tbm_surface_h surface;
1452 if (surface_queue->queue_size == surface_queue->num_attached)
1455 if (surface_queue->alloc_cb) {
1456 _tbm_surf_queue_mutex_unlock();
1457 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1458 _tbm_surf_queue_mutex_lock();
1463 tbm_surface_internal_ref(surface);
1465 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1466 surface_queue->height,
1467 surface_queue->format,
1469 TBM_RETURN_IF_FAIL(surface != NULL);
1472 _tbm_surface_queue_attach(surface_queue, surface);
1473 tbm_surface_internal_unref(surface);
1476 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1477 NULL, /*__tbm_queue_default_init*/
1478 NULL, /*__tbm_queue_default_reset*/
1479 __tbm_queue_default_destroy,
1480 __tbm_queue_default_need_attach,
1481 NULL, /*__tbm_queue_default_enqueue*/
1482 NULL, /*__tbm_queue_default_release*/
1483 NULL, /*__tbm_queue_default_dequeue*/
1484 NULL, /*__tbm_queue_default_acquire*/
1485 NULL, /*__tbm_queue_default_need_detach*/
1489 tbm_surface_queue_create(int queue_size, int width,
1490 int height, int format, int flags)
1492 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1493 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1494 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1495 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1497 _tbm_surf_queue_mutex_lock();
1499 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1500 sizeof(struct _tbm_surface_queue));
1501 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1503 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1505 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1506 sizeof(tbm_queue_default));
1508 free(surface_queue);
1509 _tbm_surf_queue_mutex_unlock();
1513 data->flags = flags;
1514 _tbm_surface_queue_init(surface_queue,
1516 width, height, format,
1517 &tbm_queue_default_impl, data);
1519 _tbm_surf_queue_mutex_unlock();
1521 return surface_queue;
1527 } tbm_queue_sequence;
1530 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1532 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1534 _queue_init(&data->dequeue_list);
1538 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1540 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1542 _queue_init(&data->dequeue_list);
1546 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1548 free(surface_queue->impl_data);
1552 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1554 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1555 tbm_surface_h surface;
1557 if (surface_queue->queue_size == surface_queue->num_attached)
1560 if (surface_queue->alloc_cb) {
1561 _tbm_surf_queue_mutex_unlock();
1562 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1563 _tbm_surf_queue_mutex_lock();
1568 tbm_surface_internal_ref(surface);
1570 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1571 surface_queue->height,
1572 surface_queue->format,
1574 TBM_RETURN_IF_FAIL(surface != NULL);
1577 _tbm_surface_queue_attach(surface_queue, surface);
1578 tbm_surface_internal_unref(surface);
1582 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1585 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1586 queue_node *next, *tmp;
1588 node->priv_flags = 0;
1590 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1591 if (next->priv_flags)
1593 _queue_node_pop(&data->dequeue_list, next);
1594 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1599 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1602 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
1605 node = _tbm_surface_queue_dequeue(surface_queue);
1607 _queue_node_push_back(&data->dequeue_list, node);
1608 node->priv_flags = 1;
1614 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1615 __tbm_queue_sequence_init,
1616 __tbm_queue_sequence_reset,
1617 __tbm_queue_sequence_destroy,
1618 __tbm_queue_sequence_need_attach,
1619 __tbm_queue_sequence_enqueue,
1620 NULL, /*__tbm_queue_sequence_release*/
1621 __tbm_queue_sequence_dequeue,
1622 NULL, /*__tbm_queue_sequence_acquire*/
1623 NULL, /*__tbm_queue_sequence_need_dettach*/
1627 tbm_surface_queue_sequence_create(int queue_size, int width,
1628 int height, int format, int flags)
1630 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1631 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1632 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1633 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1635 _tbm_surf_queue_mutex_lock();
1637 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1638 sizeof(struct _tbm_surface_queue));
1639 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1641 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1643 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1644 sizeof(tbm_queue_sequence));
1646 free(surface_queue);
1647 _tbm_surf_queue_mutex_unlock();
1651 data->flags = flags;
1652 _tbm_surface_queue_init(surface_queue,
1654 width, height, format,
1655 &tbm_queue_sequence_impl, data);
1657 _tbm_surf_queue_mutex_unlock();
1659 return surface_queue;
1661 /* LCOV_EXCL_STOP */