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 = NULL, tmp = NULL;
210 if (surface_queue == NULL || g_surf_queue_bufmgr == NULL) {
211 TBM_TRACE("error: tbm_surface_queue(%p)\n", surface_queue);
215 if (!LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
216 LIST_FOR_EACH_ENTRY_SAFE(old_data, tmp, &g_surf_queue_bufmgr->surf_queue_list, item_link) {
217 if (old_data == surface_queue) {
218 TBM_TRACE("tbm_surface_queue(%p)\n", surface_queue);
223 TBM_TRACE("error: tbm_surface_queue(%p)\n", surface_queue);
228 _queue_node_create(void)
230 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
232 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
238 _queue_node_delete(queue_node *node)
240 LIST_DEL(&node->item_link);
241 LIST_DEL(&node->link);
246 _queue_is_empty(queue *queue)
248 if (LIST_IS_EMPTY(&queue->head))
255 _queue_node_push_back(queue *queue, queue_node *node)
257 LIST_ADDTAIL(&node->item_link, &queue->head);
262 _queue_node_push_front(queue *queue, queue_node *node)
264 LIST_ADD(&node->item_link, &queue->head);
269 _queue_node_pop_front(queue *queue)
271 queue_node *node = NULL;
273 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
275 LIST_DEL(&node->item_link);
282 _queue_node_pop(queue *queue, queue_node *node)
284 LIST_DEL(&node->item_link);
291 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
292 tbm_surface_h surface, int *out_type)
294 queue_node *node = NULL;
295 queue_node *tmp = NULL;
298 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
302 if (type & FREE_QUEUE) {
303 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head,
305 if (node->surface == surface) {
307 *out_type = FREE_QUEUE;
314 if (type & DIRTY_QUEUE) {
315 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->dirty_queue.head,
317 if (node->surface == surface) {
319 *out_type = DIRTY_QUEUE;
326 if (type & NODE_LIST) {
327 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
328 if (node->surface == surface) {
330 *out_type = NODE_LIST;
341 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
344 if (surface_queue->free_cb) {
345 surface_queue->free_cb(surface_queue,
346 surface_queue->alloc_cb_data,
350 tbm_surface_destroy(node->surface);
353 _queue_node_delete(node);
357 _queue_init(queue *queue)
359 LIST_INITHEAD(&queue->head);
365 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
368 TBM_RETURN_IF_FAIL(cb != NULL);
370 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
372 TBM_RETURN_IF_FAIL(item != NULL);
374 LIST_INITHEAD(&item->link);
378 LIST_ADDTAIL(&item->link, list);
382 _notify_remove(struct list_head *list,
383 tbm_surface_queue_notify_cb cb, void *data)
385 queue_notify *item = NULL, *tmp = NULL;
387 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
388 if (item->cb == cb && item->data == data) {
389 LIST_DEL(&item->link);
395 TBM_LOG_E("Cannot find notifiy\n");
399 _notify_remove_all(struct list_head *list)
401 queue_notify *item = NULL, *tmp = NULL;
403 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
404 LIST_DEL(&item->link);
410 _notify_emit(tbm_surface_queue_h surface_queue,
411 struct list_head *list)
413 queue_notify *item = NULL, *tmp = NULL;
415 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
416 item->cb(surface_queue, item->data);
421 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
423 queue_node *node = NULL;
424 queue_node *tmp = NULL;
427 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
428 if (node->type == type)
436 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
437 tbm_surface_h surface)
439 queue_node *node = NULL;
441 node = _queue_node_create();
442 TBM_RETURN_IF_FAIL(node != NULL);
444 tbm_surface_internal_ref(surface);
445 node->surface = surface;
447 LIST_ADDTAIL(&node->link, &surface_queue->list);
448 surface_queue->num_attached++;
449 _queue_node_push_back(&surface_queue->free_queue, node);
453 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
454 tbm_surface_h surface)
456 queue_node *node = NULL;
459 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
461 _queue_delete_node(surface_queue, node);
462 surface_queue->num_attached--;
467 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
468 queue_node *node, int push_back)
471 _queue_node_push_back(&surface_queue->dirty_queue, node);
473 _queue_node_push_front(&surface_queue->dirty_queue, node);
477 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
479 queue_node *node = NULL;
481 if (_queue_is_empty(&surface_queue->free_queue)) {
482 if (surface_queue->impl && surface_queue->impl->need_attach)
483 surface_queue->impl->need_attach(surface_queue);
485 if (_queue_is_empty(&surface_queue->free_queue))
489 node = _queue_node_pop_front(&surface_queue->free_queue);
495 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
497 queue_node *node = NULL;
499 if (_queue_is_empty(&surface_queue->dirty_queue))
502 node = _queue_node_pop_front(&surface_queue->dirty_queue);
508 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
509 queue_node *node, int push_back)
512 _queue_node_push_back(&surface_queue->free_queue, node);
514 _queue_node_push_front(&surface_queue->free_queue, node);
518 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
520 int width, int height, int format,
521 const tbm_surface_queue_interface *impl, void *data)
523 TBM_RETURN_IF_FAIL(surface_queue != NULL);
524 TBM_RETURN_IF_FAIL(impl != NULL);
526 memset(surface_queue, 0x00, sizeof(struct _tbm_surface_queue));
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->acquirable_noti);
548 LIST_INITHEAD(&surface_queue->dequeuable_noti);
549 LIST_INITHEAD(&surface_queue->dequeue_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)
891 queue_node *node = NULL;
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 exist in free_queue or dirty_queue node:%p, queue:%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)
947 queue_node *node = NULL;
949 _tbm_surf_queue_mutex_lock();
951 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
952 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
953 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
954 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
956 pthread_mutex_lock(&surface_queue->lock);
958 if (surface_queue->impl && surface_queue->impl->dequeue)
959 node = surface_queue->impl->dequeue(surface_queue);
961 node = _tbm_surface_queue_dequeue(surface_queue);
965 pthread_mutex_unlock(&surface_queue->lock);
967 _tbm_surf_queue_mutex_unlock();
968 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
971 if (node->surface == NULL) {
973 TBM_LOG_E("_queue_node_pop_front failed\n");
974 pthread_mutex_unlock(&surface_queue->lock);
976 _tbm_surf_queue_mutex_unlock();
977 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
980 node->type = QUEUE_NODE_TYPE_DEQUEUE;
981 *surface = node->surface;
983 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
985 pthread_mutex_unlock(&surface_queue->lock);
987 _tbm_surf_queue_mutex_unlock();
989 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
991 return TBM_SURFACE_QUEUE_ERROR_NONE;
995 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
997 _tbm_surf_queue_mutex_lock();
999 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1001 pthread_mutex_lock(&surface_queue->lock);
1003 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1005 if (_queue_is_empty(&surface_queue->free_queue)) {
1006 if (surface_queue->impl && surface_queue->impl->need_attach)
1007 surface_queue->impl->need_attach(surface_queue);
1009 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1010 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1011 _tbm_surf_queue_mutex_unlock();
1016 if (_queue_is_empty(&surface_queue->free_queue)) {
1018 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE)) {
1020 _tbm_surf_queue_mutex_unlock();
1022 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1024 _tbm_surf_queue_mutex_lock();
1026 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1027 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1028 _tbm_surf_queue_mutex_unlock();
1032 pthread_mutex_unlock(&surface_queue->lock);
1034 _tbm_surf_queue_mutex_unlock();
1038 pthread_mutex_unlock(&surface_queue->lock);
1040 _tbm_surf_queue_mutex_unlock();
1044 pthread_mutex_unlock(&surface_queue->lock);
1046 _tbm_surf_queue_mutex_unlock();
1051 tbm_surface_queue_error_e
1052 tbm_surface_queue_release(tbm_surface_queue_h
1053 surface_queue, tbm_surface_h surface)
1055 queue_node *node = NULL;
1058 _tbm_surf_queue_mutex_lock();
1060 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1061 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1062 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1063 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1065 pthread_mutex_lock(&surface_queue->lock);
1067 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1069 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1070 if (node == NULL || queue_type != NODE_LIST) {
1071 TBM_LOG_E("tbm_surface_queue_release::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n",
1073 pthread_mutex_unlock(&surface_queue->lock);
1075 _tbm_surf_queue_mutex_unlock();
1076 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1079 if (surface_queue->queue_size < surface_queue->num_attached) {
1081 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1083 if (surface_queue->impl && surface_queue->impl->need_detach)
1084 surface_queue->impl->need_detach(surface_queue, node);
1086 _tbm_surface_queue_detach(surface_queue, surface);
1088 pthread_mutex_unlock(&surface_queue->lock);
1090 _tbm_surf_queue_mutex_unlock();
1091 return TBM_SURFACE_QUEUE_ERROR_NONE;
1094 if (surface_queue->impl && surface_queue->impl->release)
1095 surface_queue->impl->release(surface_queue, node);
1097 _tbm_surface_queue_release(surface_queue, node, 1);
1099 if (_queue_is_empty(&surface_queue->free_queue)) {
1100 pthread_mutex_unlock(&surface_queue->lock);
1102 _tbm_surf_queue_mutex_unlock();
1103 return TBM_SURFACE_QUEUE_ERROR_NONE;
1106 node->type = QUEUE_NODE_TYPE_RELEASE;
1108 pthread_mutex_unlock(&surface_queue->lock);
1109 pthread_cond_signal(&surface_queue->free_cond);
1111 _tbm_surf_queue_mutex_unlock();
1113 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1115 return TBM_SURFACE_QUEUE_ERROR_NONE;
1118 tbm_surface_queue_error_e
1119 tbm_surface_queue_acquire(tbm_surface_queue_h
1120 surface_queue, tbm_surface_h *surface)
1122 queue_node *node = NULL;
1124 _tbm_surf_queue_mutex_lock();
1126 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1127 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1128 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1129 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1131 pthread_mutex_lock(&surface_queue->lock);
1133 if (surface_queue->impl && surface_queue->impl->acquire)
1134 node = surface_queue->impl->acquire(surface_queue);
1136 node = _tbm_surface_queue_acquire(surface_queue);
1140 pthread_mutex_unlock(&surface_queue->lock);
1142 _tbm_surf_queue_mutex_unlock();
1143 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1146 if (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_ACQUIRE;
1157 *surface = node->surface;
1159 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1161 pthread_mutex_unlock(&surface_queue->lock);
1163 _tbm_surf_queue_mutex_unlock();
1166 tbm_surface_internal_dump_buffer(*surface, "acquire");
1168 return TBM_SURFACE_QUEUE_ERROR_NONE;
1172 tbm_surface_queue_can_acquire(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 pthread_mutex_lock(&surface_queue->lock);
1180 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1182 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1184 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE)) {
1186 _tbm_surf_queue_mutex_unlock();
1188 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1190 _tbm_surf_queue_mutex_lock();
1192 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1193 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1194 _tbm_surf_queue_mutex_unlock();
1198 pthread_mutex_unlock(&surface_queue->lock);
1200 _tbm_surf_queue_mutex_unlock();
1204 pthread_mutex_unlock(&surface_queue->lock);
1206 _tbm_surf_queue_mutex_unlock();
1210 pthread_mutex_unlock(&surface_queue->lock);
1212 _tbm_surf_queue_mutex_unlock();
1218 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1220 queue_node *node = NULL, *tmp = NULL;
1222 _tbm_surf_queue_mutex_lock();
1224 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1226 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1228 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1229 _queue_delete_node(surface_queue, node);
1232 if (surface_queue->impl && surface_queue->impl->destroy)
1233 surface_queue->impl->destroy(surface_queue);
1235 _notify_emit(surface_queue, &surface_queue->destory_noti);
1237 _notify_remove_all(&surface_queue->destory_noti);
1238 _notify_remove_all(&surface_queue->acquirable_noti);
1239 _notify_remove_all(&surface_queue->dequeuable_noti);
1240 _notify_remove_all(&surface_queue->reset_noti);
1242 pthread_mutex_destroy(&surface_queue->lock);
1244 LIST_DEL(&surface_queue->item_link);
1246 free(surface_queue);
1247 surface_queue = NULL;
1249 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1250 _deinit_tbm_surf_queue_bufmgr();
1252 _tbm_surf_queue_mutex_unlock();
1255 tbm_surface_queue_error_e
1256 tbm_surface_queue_reset(tbm_surface_queue_h
1257 surface_queue, int width, int height, int format)
1259 queue_node *node = NULL, *tmp = NULL;
1261 _tbm_surf_queue_mutex_lock();
1263 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1264 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1266 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1268 if (width == surface_queue->width && height == surface_queue->height &&
1269 format == surface_queue->format) {
1270 _tbm_surf_queue_mutex_unlock();
1271 return TBM_SURFACE_QUEUE_ERROR_NONE;
1274 pthread_mutex_lock(&surface_queue->lock);
1276 surface_queue->width = width;
1277 surface_queue->height = height;
1278 surface_queue->format = format;
1280 /* Destory surface and Push to free_queue */
1281 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1282 _queue_delete_node(surface_queue, node);
1286 _queue_init(&surface_queue->free_queue);
1287 _queue_init(&surface_queue->dirty_queue);
1288 LIST_INITHEAD(&surface_queue->list);
1290 surface_queue->num_attached = 0;
1292 if (surface_queue->impl && surface_queue->impl->reset)
1293 surface_queue->impl->reset(surface_queue);
1295 pthread_mutex_unlock(&surface_queue->lock);
1296 pthread_cond_signal(&surface_queue->free_cond);
1298 _tbm_surf_queue_mutex_unlock();
1300 _notify_emit(surface_queue, &surface_queue->reset_noti);
1302 return TBM_SURFACE_QUEUE_ERROR_NONE;
1305 tbm_surface_queue_error_e
1306 tbm_surface_queue_set_size(tbm_surface_queue_h
1307 surface_queue, int queue_size, int flush)
1309 queue_node *node = NULL, *tmp = NULL;
1312 _tbm_surf_queue_mutex_lock();
1314 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1315 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1316 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1317 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1319 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1321 if ((surface_queue->queue_size == queue_size) && !flush) {
1322 _tbm_surf_queue_mutex_unlock();
1323 return TBM_SURFACE_QUEUE_ERROR_NONE;
1326 pthread_mutex_lock(&surface_queue->lock);
1329 /* Destory surface and Push to free_queue */
1330 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1331 _queue_delete_node(surface_queue, node);
1335 _queue_init(&surface_queue->free_queue);
1336 _queue_init(&surface_queue->dirty_queue);
1337 LIST_INITHEAD(&surface_queue->list);
1339 surface_queue->num_attached = 0;
1340 surface_queue->queue_size = queue_size;
1342 if (surface_queue->impl && surface_queue->impl->reset)
1343 surface_queue->impl->reset(surface_queue);
1345 pthread_mutex_unlock(&surface_queue->lock);
1346 pthread_cond_signal(&surface_queue->free_cond);
1348 _tbm_surf_queue_mutex_unlock();
1350 _notify_emit(surface_queue, &surface_queue->reset_noti);
1352 return TBM_SURFACE_QUEUE_ERROR_NONE;
1356 if (surface_queue->queue_size > queue_size) {
1358 need_del = surface_queue->queue_size - queue_size;
1360 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1362 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1364 if (surface_queue->impl && surface_queue->impl->need_detach)
1365 surface_queue->impl->need_detach(surface_queue, node);
1367 _tbm_surface_queue_detach(surface_queue, node->surface);
1375 surface_queue->queue_size = queue_size;
1377 pthread_mutex_unlock(&surface_queue->lock);
1379 _tbm_surf_queue_mutex_unlock();
1381 return TBM_SURFACE_QUEUE_ERROR_NONE;
1385 tbm_surface_queue_error_e
1386 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1388 queue_node *node = NULL, *tmp = NULL;
1390 _tbm_surf_queue_mutex_lock();
1392 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1393 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1395 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1397 if (surface_queue->num_attached == 0) {
1398 _tbm_surf_queue_mutex_unlock();
1399 return TBM_SURFACE_QUEUE_ERROR_NONE;
1402 pthread_mutex_lock(&surface_queue->lock);
1404 /* Destory surface and Push to free_queue */
1405 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1406 _queue_delete_node(surface_queue, node);
1410 _queue_init(&surface_queue->free_queue);
1411 _queue_init(&surface_queue->dirty_queue);
1412 LIST_INITHEAD(&surface_queue->list);
1414 surface_queue->num_attached = 0;
1416 if (surface_queue->impl && surface_queue->impl->reset)
1417 surface_queue->impl->reset(surface_queue);
1419 pthread_mutex_unlock(&surface_queue->lock);
1420 pthread_cond_signal(&surface_queue->free_cond);
1422 _tbm_surf_queue_mutex_unlock();
1424 _notify_emit(surface_queue, &surface_queue->reset_noti);
1426 return TBM_SURFACE_QUEUE_ERROR_NONE;
1429 tbm_surface_queue_error_e
1430 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1431 tbm_surface_h *surfaces, int *num)
1433 queue_node *node = NULL;
1434 queue_node *tmp = NULL;
1436 _tbm_surf_queue_mutex_lock();
1438 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1439 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1440 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1441 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1443 pthread_mutex_lock(&surface_queue->lock);
1446 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
1448 surfaces[*num] = node->surface;
1453 pthread_mutex_unlock(&surface_queue->lock);
1455 _tbm_surf_queue_mutex_unlock();
1457 return TBM_SURFACE_QUEUE_ERROR_NONE;
1462 } tbm_queue_default;
1465 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1467 free(surface_queue->impl_data);
1471 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1473 tbm_queue_default *data = surface_queue->impl_data;
1474 tbm_surface_h surface;
1476 if (surface_queue->queue_size == surface_queue->num_attached)
1479 if (surface_queue->alloc_cb) {
1480 _tbm_surf_queue_mutex_unlock();
1481 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1482 _tbm_surf_queue_mutex_lock();
1487 tbm_surface_internal_ref(surface);
1489 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1490 surface_queue->height,
1491 surface_queue->format,
1493 TBM_RETURN_IF_FAIL(surface != NULL);
1496 _tbm_surface_queue_attach(surface_queue, surface);
1497 tbm_surface_internal_unref(surface);
1500 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1501 NULL, /*__tbm_queue_default_init*/
1502 NULL, /*__tbm_queue_default_reset*/
1503 __tbm_queue_default_destroy,
1504 __tbm_queue_default_need_attach,
1505 NULL, /*__tbm_queue_default_enqueue*/
1506 NULL, /*__tbm_queue_default_release*/
1507 NULL, /*__tbm_queue_default_dequeue*/
1508 NULL, /*__tbm_queue_default_acquire*/
1509 NULL, /*__tbm_queue_default_need_detach*/
1513 tbm_surface_queue_create(int queue_size, int width,
1514 int height, int format, int flags)
1516 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1517 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1518 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1519 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1521 _tbm_surf_queue_mutex_lock();
1523 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1524 sizeof(struct _tbm_surface_queue));
1525 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1527 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1529 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1530 sizeof(tbm_queue_default));
1532 free(surface_queue);
1533 _tbm_surf_queue_mutex_unlock();
1537 data->flags = flags;
1538 _tbm_surface_queue_init(surface_queue,
1540 width, height, format,
1541 &tbm_queue_default_impl, data);
1543 _tbm_surf_queue_mutex_unlock();
1545 return surface_queue;
1551 } tbm_queue_sequence;
1554 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1556 tbm_queue_sequence *data = surface_queue->impl_data;
1558 _queue_init(&data->dequeue_list);
1562 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
1564 tbm_queue_sequence *data = surface_queue->impl_data;
1566 _queue_init(&data->dequeue_list);
1570 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
1572 free(surface_queue->impl_data);
1576 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1578 tbm_queue_sequence *data = surface_queue->impl_data;
1579 tbm_surface_h surface;
1581 if (surface_queue->queue_size == surface_queue->num_attached)
1584 if (surface_queue->alloc_cb) {
1585 _tbm_surf_queue_mutex_unlock();
1586 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1587 _tbm_surf_queue_mutex_lock();
1592 tbm_surface_internal_ref(surface);
1594 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1595 surface_queue->height,
1596 surface_queue->format,
1598 TBM_RETURN_IF_FAIL(surface != NULL);
1601 _tbm_surface_queue_attach(surface_queue, surface);
1602 tbm_surface_internal_unref(surface);
1606 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1609 tbm_queue_sequence *data = surface_queue->impl_data;
1610 queue_node *next = NULL;
1611 queue_node *tmp = NULL;
1613 node->priv_flags = 0;
1615 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1616 if (next->priv_flags)
1618 _queue_node_pop(&data->dequeue_list, next);
1619 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1624 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1627 tbm_queue_sequence *data = surface_queue->impl_data;
1628 queue_node *node = NULL;
1630 node = _tbm_surface_queue_dequeue(surface_queue);
1632 _queue_node_push_back(&data->dequeue_list, node);
1633 node->priv_flags = 1;
1639 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1640 __tbm_queue_sequence_init,
1641 __tbm_queue_sequence_reset,
1642 __tbm_queue_sequence_destroy,
1643 __tbm_queue_sequence_need_attach,
1644 __tbm_queue_sequence_enqueue,
1645 NULL, /*__tbm_queue_sequence_release*/
1646 __tbm_queue_sequence_dequeue,
1647 NULL, /*__tbm_queue_sequence_acquire*/
1648 NULL, /*__tbm_queue_sequence_need_dettach*/
1652 tbm_surface_queue_sequence_create(int queue_size, int width,
1653 int height, int format, int flags)
1655 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1656 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1657 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1658 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1660 _tbm_surf_queue_mutex_lock();
1662 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1663 sizeof(struct _tbm_surface_queue));
1664 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1666 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1668 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1669 sizeof(tbm_queue_sequence));
1671 free(surface_queue);
1672 _tbm_surf_queue_mutex_unlock();
1676 data->flags = flags;
1677 _tbm_surface_queue_init(surface_queue,
1679 width, height, format,
1680 &tbm_queue_sequence_impl, data);
1682 _tbm_surf_queue_mutex_unlock();
1684 return surface_queue;
1686 /* LCOV_EXCL_STOP */