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 memset(surface_queue, 0x00, sizeof(struct _tbm_surface_queue));
530 if (!g_surf_queue_bufmgr)
531 _init_tbm_surf_queue_bufmgr();
533 pthread_mutex_init(&surface_queue->lock, NULL);
534 pthread_cond_init(&surface_queue->free_cond, NULL);
535 pthread_cond_init(&surface_queue->dirty_cond, NULL);
537 surface_queue->queue_size = queue_size;
538 surface_queue->width = width;
539 surface_queue->height = height;
540 surface_queue->format = format;
541 surface_queue->impl = impl;
542 surface_queue->impl_data = data;
544 _queue_init(&surface_queue->free_queue);
545 _queue_init(&surface_queue->dirty_queue);
546 LIST_INITHEAD(&surface_queue->list);
548 LIST_INITHEAD(&surface_queue->destory_noti);
549 LIST_INITHEAD(&surface_queue->acquirable_noti);
550 LIST_INITHEAD(&surface_queue->dequeuable_noti);
551 LIST_INITHEAD(&surface_queue->dequeue_noti);
552 LIST_INITHEAD(&surface_queue->reset_noti);
554 if (surface_queue->impl && surface_queue->impl->init)
555 surface_queue->impl->init(surface_queue);
557 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
560 tbm_surface_queue_error_e
561 tbm_surface_queue_add_destroy_cb(
562 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
565 _tbm_surf_queue_mutex_lock();
567 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
568 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
570 pthread_mutex_lock(&surface_queue->lock);
572 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
574 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
576 pthread_mutex_unlock(&surface_queue->lock);
578 _tbm_surf_queue_mutex_unlock();
580 return TBM_SURFACE_QUEUE_ERROR_NONE;
583 tbm_surface_queue_error_e
584 tbm_surface_queue_remove_destroy_cb(
585 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
588 _tbm_surf_queue_mutex_lock();
590 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
591 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
593 pthread_mutex_lock(&surface_queue->lock);
595 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
597 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
599 pthread_mutex_unlock(&surface_queue->lock);
601 _tbm_surf_queue_mutex_unlock();
603 return TBM_SURFACE_QUEUE_ERROR_NONE;
606 tbm_surface_queue_error_e
607 tbm_surface_queue_add_dequeuable_cb(
608 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
611 _tbm_surf_queue_mutex_lock();
613 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
614 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
616 pthread_mutex_lock(&surface_queue->lock);
618 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
620 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
622 pthread_mutex_unlock(&surface_queue->lock);
624 _tbm_surf_queue_mutex_unlock();
626 return TBM_SURFACE_QUEUE_ERROR_NONE;
629 tbm_surface_queue_error_e
630 tbm_surface_queue_remove_dequeuable_cb(
631 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
634 _tbm_surf_queue_mutex_lock();
636 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
637 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
639 pthread_mutex_lock(&surface_queue->lock);
641 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
643 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
645 pthread_mutex_unlock(&surface_queue->lock);
647 _tbm_surf_queue_mutex_unlock();
649 return TBM_SURFACE_QUEUE_ERROR_NONE;
652 tbm_surface_queue_error_e
653 tbm_surface_queue_add_dequeue_cb(
654 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
657 _tbm_surf_queue_mutex_lock();
659 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
660 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
662 pthread_mutex_lock(&surface_queue->lock);
664 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
666 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
668 pthread_mutex_unlock(&surface_queue->lock);
670 _tbm_surf_queue_mutex_unlock();
672 return TBM_SURFACE_QUEUE_ERROR_NONE;
675 tbm_surface_queue_error_e
676 tbm_surface_queue_remove_dequeue_cb(
677 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
680 _tbm_surf_queue_mutex_lock();
682 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
683 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
685 pthread_mutex_lock(&surface_queue->lock);
687 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
689 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
691 pthread_mutex_unlock(&surface_queue->lock);
693 _tbm_surf_queue_mutex_unlock();
695 return TBM_SURFACE_QUEUE_ERROR_NONE;
698 tbm_surface_queue_error_e
699 tbm_surface_queue_add_acquirable_cb(
700 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
703 _tbm_surf_queue_mutex_lock();
705 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
706 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
708 pthread_mutex_lock(&surface_queue->lock);
710 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
712 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
714 pthread_mutex_unlock(&surface_queue->lock);
716 _tbm_surf_queue_mutex_unlock();
718 return TBM_SURFACE_QUEUE_ERROR_NONE;
721 tbm_surface_queue_error_e
722 tbm_surface_queue_remove_acquirable_cb(
723 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
726 _tbm_surf_queue_mutex_lock();
728 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
729 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
731 pthread_mutex_lock(&surface_queue->lock);
733 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
735 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
737 pthread_mutex_unlock(&surface_queue->lock);
739 _tbm_surf_queue_mutex_unlock();
741 return TBM_SURFACE_QUEUE_ERROR_NONE;
744 tbm_surface_queue_error_e
745 tbm_surface_queue_set_alloc_cb(
746 tbm_surface_queue_h surface_queue,
747 tbm_surface_alloc_cb alloc_cb,
748 tbm_surface_free_cb free_cb,
751 _tbm_surf_queue_mutex_lock();
753 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
754 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
756 pthread_mutex_lock(&surface_queue->lock);
758 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
760 surface_queue->alloc_cb = alloc_cb;
761 surface_queue->free_cb = free_cb;
762 surface_queue->alloc_cb_data = data;
764 pthread_mutex_unlock(&surface_queue->lock);
766 _tbm_surf_queue_mutex_unlock();
768 return TBM_SURFACE_QUEUE_ERROR_NONE;
772 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
776 _tbm_surf_queue_mutex_lock();
778 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
780 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
782 width = surface_queue->width;
784 _tbm_surf_queue_mutex_unlock();
790 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
794 _tbm_surf_queue_mutex_lock();
796 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
798 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
800 height = surface_queue->height;
802 _tbm_surf_queue_mutex_unlock();
808 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
812 _tbm_surf_queue_mutex_lock();
814 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
816 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
818 format = surface_queue->format;
820 _tbm_surf_queue_mutex_unlock();
826 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
830 _tbm_surf_queue_mutex_lock();
832 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
834 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
836 queue_size = surface_queue->queue_size;
838 _tbm_surf_queue_mutex_unlock();
843 tbm_surface_queue_error_e
844 tbm_surface_queue_add_reset_cb(
845 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
848 _tbm_surf_queue_mutex_lock();
850 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
851 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
853 pthread_mutex_lock(&surface_queue->lock);
855 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
857 _notify_add(&surface_queue->reset_noti, reset_cb, data);
859 pthread_mutex_unlock(&surface_queue->lock);
861 _tbm_surf_queue_mutex_unlock();
863 return TBM_SURFACE_QUEUE_ERROR_NONE;
866 tbm_surface_queue_error_e
867 tbm_surface_queue_remove_reset_cb(
868 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
871 _tbm_surf_queue_mutex_lock();
873 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
874 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
876 pthread_mutex_lock(&surface_queue->lock);
878 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
880 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
882 pthread_mutex_unlock(&surface_queue->lock);
884 _tbm_surf_queue_mutex_unlock();
886 return TBM_SURFACE_QUEUE_ERROR_NONE;
889 tbm_surface_queue_error_e
890 tbm_surface_queue_enqueue(tbm_surface_queue_h
891 surface_queue, tbm_surface_h surface)
896 _tbm_surf_queue_mutex_lock();
898 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
899 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
900 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
901 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
904 tbm_surface_internal_dump_buffer(surface, "enqueue");
906 pthread_mutex_lock(&surface_queue->lock);
908 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
910 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
911 if (node == NULL || queue_type != NODE_LIST) {
912 TBM_LOG_E("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
914 pthread_mutex_unlock(&surface_queue->lock);
916 _tbm_surf_queue_mutex_unlock();
917 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
920 if (surface_queue->impl && surface_queue->impl->enqueue)
921 surface_queue->impl->enqueue(surface_queue, node);
923 _tbm_surface_queue_enqueue(surface_queue, node, 1);
925 if (_queue_is_empty(&surface_queue->dirty_queue)) {
926 TBM_LOG_E("enqueue surface but queue is empty node:%p\n", node);
927 pthread_mutex_unlock(&surface_queue->lock);
929 _tbm_surf_queue_mutex_unlock();
930 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
933 node->type = QUEUE_NODE_TYPE_ENQUEUE;
935 pthread_mutex_unlock(&surface_queue->lock);
936 pthread_cond_signal(&surface_queue->dirty_cond);
938 _tbm_surf_queue_mutex_unlock();
940 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
942 return TBM_SURFACE_QUEUE_ERROR_NONE;
945 tbm_surface_queue_error_e
946 tbm_surface_queue_dequeue(tbm_surface_queue_h
947 surface_queue, tbm_surface_h *surface)
951 _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);
967 pthread_mutex_unlock(&surface_queue->lock);
969 _tbm_surf_queue_mutex_unlock();
970 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
973 if (node->surface == NULL) {
975 TBM_LOG_E("_queue_node_pop_front failed\n");
976 pthread_mutex_unlock(&surface_queue->lock);
978 _tbm_surf_queue_mutex_unlock();
979 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
982 node->type = QUEUE_NODE_TYPE_DEQUEUE;
983 *surface = node->surface;
985 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
987 pthread_mutex_unlock(&surface_queue->lock);
989 _tbm_surf_queue_mutex_unlock();
991 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
993 return TBM_SURFACE_QUEUE_ERROR_NONE;
997 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
999 _tbm_surf_queue_mutex_lock();
1001 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1003 pthread_mutex_lock(&surface_queue->lock);
1005 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1007 if (_queue_is_empty(&surface_queue->free_queue)) {
1008 if (surface_queue->impl && surface_queue->impl->need_attach)
1009 surface_queue->impl->need_attach(surface_queue);
1011 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1012 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1013 _tbm_surf_queue_mutex_unlock();
1018 if (_queue_is_empty(&surface_queue->free_queue)) {
1020 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE)) {
1022 _tbm_surf_queue_mutex_unlock();
1024 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1026 _tbm_surf_queue_mutex_lock();
1028 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1029 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1030 _tbm_surf_queue_mutex_unlock();
1034 pthread_mutex_unlock(&surface_queue->lock);
1036 _tbm_surf_queue_mutex_unlock();
1040 pthread_mutex_unlock(&surface_queue->lock);
1042 _tbm_surf_queue_mutex_unlock();
1046 pthread_mutex_unlock(&surface_queue->lock);
1048 _tbm_surf_queue_mutex_unlock();
1053 tbm_surface_queue_error_e
1054 tbm_surface_queue_release(tbm_surface_queue_h
1055 surface_queue, tbm_surface_h surface)
1060 _tbm_surf_queue_mutex_lock();
1062 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1063 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1064 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1065 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1067 pthread_mutex_lock(&surface_queue->lock);
1069 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1071 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1072 if (node == NULL || queue_type != NODE_LIST) {
1073 TBM_LOG_E("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1075 pthread_mutex_unlock(&surface_queue->lock);
1077 _tbm_surf_queue_mutex_unlock();
1078 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1081 if (surface_queue->queue_size < surface_queue->num_attached) {
1083 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1085 if (surface_queue->impl && surface_queue->impl->need_detach)
1086 surface_queue->impl->need_detach(surface_queue, node);
1088 _tbm_surface_queue_detach(surface_queue, surface);
1090 pthread_mutex_unlock(&surface_queue->lock);
1092 _tbm_surf_queue_mutex_unlock();
1093 return TBM_SURFACE_QUEUE_ERROR_NONE;
1096 if (surface_queue->impl && surface_queue->impl->release)
1097 surface_queue->impl->release(surface_queue, node);
1099 _tbm_surface_queue_release(surface_queue, node, 1);
1101 if (_queue_is_empty(&surface_queue->free_queue)) {
1102 pthread_mutex_unlock(&surface_queue->lock);
1104 _tbm_surf_queue_mutex_unlock();
1105 return TBM_SURFACE_QUEUE_ERROR_NONE;
1108 node->type = QUEUE_NODE_TYPE_RELEASE;
1110 pthread_mutex_unlock(&surface_queue->lock);
1111 pthread_cond_signal(&surface_queue->free_cond);
1113 _tbm_surf_queue_mutex_unlock();
1115 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1117 return TBM_SURFACE_QUEUE_ERROR_NONE;
1120 tbm_surface_queue_error_e
1121 tbm_surface_queue_acquire(tbm_surface_queue_h
1122 surface_queue, tbm_surface_h *surface)
1126 _tbm_surf_queue_mutex_lock();
1128 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1129 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1130 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1131 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1133 pthread_mutex_lock(&surface_queue->lock);
1135 if (surface_queue->impl && surface_queue->impl->acquire)
1136 node = surface_queue->impl->acquire(surface_queue);
1138 node = _tbm_surface_queue_acquire(surface_queue);
1142 pthread_mutex_unlock(&surface_queue->lock);
1144 _tbm_surf_queue_mutex_unlock();
1145 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1148 if (node->surface == NULL) {
1150 TBM_LOG_E("_queue_node_pop_front failed\n");
1151 pthread_mutex_unlock(&surface_queue->lock);
1153 _tbm_surf_queue_mutex_unlock();
1154 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1157 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1159 *surface = node->surface;
1161 TBM_QUEUE_TRACE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1163 pthread_mutex_unlock(&surface_queue->lock);
1165 _tbm_surf_queue_mutex_unlock();
1168 tbm_surface_internal_dump_buffer(*surface, "acquire");
1170 return TBM_SURFACE_QUEUE_ERROR_NONE;
1174 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1176 _tbm_surf_queue_mutex_lock();
1178 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1180 pthread_mutex_lock(&surface_queue->lock);
1182 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1184 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1186 _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE)) {
1188 _tbm_surf_queue_mutex_unlock();
1190 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1192 _tbm_surf_queue_mutex_lock();
1194 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1195 TBM_LOG_E("surface_queue:%p is invalid", surface_queue);
1196 _tbm_surf_queue_mutex_unlock();
1200 pthread_mutex_unlock(&surface_queue->lock);
1202 _tbm_surf_queue_mutex_unlock();
1206 pthread_mutex_unlock(&surface_queue->lock);
1208 _tbm_surf_queue_mutex_unlock();
1212 pthread_mutex_unlock(&surface_queue->lock);
1214 _tbm_surf_queue_mutex_unlock();
1220 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1222 queue_node *node, *tmp;
1224 _tbm_surf_queue_mutex_lock();
1226 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1228 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1230 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1231 _queue_delete_node(surface_queue, node);
1233 if (surface_queue->impl && surface_queue->impl->destroy)
1234 surface_queue->impl->destroy(surface_queue);
1236 _notify_emit(surface_queue, &surface_queue->destory_noti);
1238 _notify_remove_all(&surface_queue->destory_noti);
1239 _notify_remove_all(&surface_queue->acquirable_noti);
1240 _notify_remove_all(&surface_queue->dequeuable_noti);
1241 _notify_remove_all(&surface_queue->reset_noti);
1243 pthread_mutex_destroy(&surface_queue->lock);
1245 LIST_DEL(&surface_queue->item_link);
1247 free(surface_queue);
1248 surface_queue = NULL;
1250 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1251 _deinit_tbm_surf_queue_bufmgr();
1253 _tbm_surf_queue_mutex_unlock();
1256 tbm_surface_queue_error_e
1257 tbm_surface_queue_reset(tbm_surface_queue_h
1258 surface_queue, int width, int height, int format)
1260 queue_node *node, *tmp;
1262 _tbm_surf_queue_mutex_lock();
1264 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1265 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1267 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1269 if (width == surface_queue->width && height == surface_queue->height &&
1270 format == surface_queue->format) {
1271 _tbm_surf_queue_mutex_unlock();
1272 return TBM_SURFACE_QUEUE_ERROR_NONE;
1275 pthread_mutex_lock(&surface_queue->lock);
1277 surface_queue->width = width;
1278 surface_queue->height = height;
1279 surface_queue->format = format;
1281 /* Destory surface and Push to free_queue */
1282 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1283 _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, *tmp;
1311 _tbm_surf_queue_mutex_lock();
1313 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1314 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1315 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1316 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1318 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1320 if ((surface_queue->queue_size == queue_size) && !flush) {
1321 _tbm_surf_queue_mutex_unlock();
1322 return TBM_SURFACE_QUEUE_ERROR_NONE;
1325 pthread_mutex_lock(&surface_queue->lock);
1328 /* Destory surface and Push to free_queue */
1329 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1330 _queue_delete_node(surface_queue, node);
1333 _queue_init(&surface_queue->free_queue);
1334 _queue_init(&surface_queue->dirty_queue);
1335 LIST_INITHEAD(&surface_queue->list);
1337 surface_queue->num_attached = 0;
1338 surface_queue->queue_size = queue_size;
1340 if (surface_queue->impl && surface_queue->impl->reset)
1341 surface_queue->impl->reset(surface_queue);
1343 pthread_mutex_unlock(&surface_queue->lock);
1344 pthread_cond_signal(&surface_queue->free_cond);
1346 _tbm_surf_queue_mutex_unlock();
1348 _notify_emit(surface_queue, &surface_queue->reset_noti);
1350 return TBM_SURFACE_QUEUE_ERROR_NONE;
1352 if (surface_queue->queue_size > queue_size) {
1353 int need_del = surface_queue->queue_size - queue_size;
1355 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1356 TBM_QUEUE_TRACE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1358 if (surface_queue->impl && surface_queue->impl->need_detach)
1359 surface_queue->impl->need_detach(surface_queue, node);
1361 _tbm_surface_queue_detach(surface_queue, node->surface);
1369 surface_queue->queue_size = queue_size;
1371 pthread_mutex_unlock(&surface_queue->lock);
1373 _tbm_surf_queue_mutex_unlock();
1375 return TBM_SURFACE_QUEUE_ERROR_NONE;
1379 tbm_surface_queue_error_e
1380 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1382 queue_node *node, *tmp;
1384 _tbm_surf_queue_mutex_lock();
1386 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1387 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1389 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1391 if (surface_queue->num_attached == 0) {
1392 _tbm_surf_queue_mutex_unlock();
1393 return TBM_SURFACE_QUEUE_ERROR_NONE;
1396 pthread_mutex_lock(&surface_queue->lock);
1398 /* Destory surface and Push to free_queue */
1399 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1400 _queue_delete_node(surface_queue, node);
1403 _queue_init(&surface_queue->free_queue);
1404 _queue_init(&surface_queue->dirty_queue);
1405 LIST_INITHEAD(&surface_queue->list);
1407 surface_queue->num_attached = 0;
1409 if (surface_queue->impl && surface_queue->impl->reset)
1410 surface_queue->impl->reset(surface_queue);
1412 pthread_mutex_unlock(&surface_queue->lock);
1413 pthread_cond_signal(&surface_queue->free_cond);
1415 _tbm_surf_queue_mutex_unlock();
1417 _notify_emit(surface_queue, &surface_queue->reset_noti);
1419 return TBM_SURFACE_QUEUE_ERROR_NONE;
1422 tbm_surface_queue_error_e
1423 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1424 tbm_surface_h *surfaces, int *num)
1428 _tbm_surf_queue_mutex_lock();
1430 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1431 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1432 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1433 TBM_SURFACE_QUEUE_ERROR_INVALID_PARAMETER);
1435 pthread_mutex_lock(&surface_queue->lock);
1438 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1440 surfaces[*num] = node->surface;
1445 pthread_mutex_unlock(&surface_queue->lock);
1447 _tbm_surf_queue_mutex_unlock();
1449 return TBM_SURFACE_QUEUE_ERROR_NONE;
1454 } tbm_queue_default;
1457 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1459 free(surface_queue->impl_data);
1463 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
1465 tbm_queue_default *data = surface_queue->impl_data;
1466 tbm_surface_h surface;
1468 if (surface_queue->queue_size == surface_queue->num_attached)
1471 if (surface_queue->alloc_cb) {
1472 _tbm_surf_queue_mutex_unlock();
1473 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1474 _tbm_surf_queue_mutex_lock();
1479 tbm_surface_internal_ref(surface);
1481 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1482 surface_queue->height,
1483 surface_queue->format,
1485 TBM_RETURN_IF_FAIL(surface != NULL);
1488 _tbm_surface_queue_attach(surface_queue, surface);
1489 tbm_surface_internal_unref(surface);
1492 static const tbm_surface_queue_interface tbm_queue_default_impl = {
1493 NULL, /*__tbm_queue_default_init*/
1494 NULL, /*__tbm_queue_default_reset*/
1495 __tbm_queue_default_destroy,
1496 __tbm_queue_default_need_attach,
1497 NULL, /*__tbm_queue_default_enqueue*/
1498 NULL, /*__tbm_queue_default_release*/
1499 NULL, /*__tbm_queue_default_dequeue*/
1500 NULL, /*__tbm_queue_default_acquire*/
1501 NULL, /*__tbm_queue_default_need_detach*/
1505 tbm_surface_queue_create(int queue_size, int width,
1506 int height, int format, int flags)
1508 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1509 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1510 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1511 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1513 _tbm_surf_queue_mutex_lock();
1515 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1516 sizeof(struct _tbm_surface_queue));
1517 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1519 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1521 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
1522 sizeof(tbm_queue_default));
1524 free(surface_queue);
1525 _tbm_surf_queue_mutex_unlock();
1529 data->flags = flags;
1530 _tbm_surface_queue_init(surface_queue,
1532 width, height, format,
1533 &tbm_queue_default_impl, data);
1535 _tbm_surf_queue_mutex_unlock();
1537 return surface_queue;
1543 } tbm_queue_sequence;
1546 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
1548 tbm_queue_sequence *data = surface_queue->impl_data;
1550 _queue_init(&data->dequeue_list);
1554 __tbm_queue_sequence_reset(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_destroy(tbm_surface_queue_h surface_queue)
1564 free(surface_queue->impl_data);
1568 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
1570 tbm_queue_sequence *data = surface_queue->impl_data;
1571 tbm_surface_h surface;
1573 if (surface_queue->queue_size == surface_queue->num_attached)
1576 if (surface_queue->alloc_cb) {
1577 _tbm_surf_queue_mutex_unlock();
1578 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
1579 _tbm_surf_queue_mutex_lock();
1584 tbm_surface_internal_ref(surface);
1586 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
1587 surface_queue->height,
1588 surface_queue->format,
1590 TBM_RETURN_IF_FAIL(surface != NULL);
1593 _tbm_surface_queue_attach(surface_queue, surface);
1594 tbm_surface_internal_unref(surface);
1598 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
1601 tbm_queue_sequence *data = surface_queue->impl_data;
1602 queue_node *next, *tmp;
1604 node->priv_flags = 0;
1606 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
1607 if (next->priv_flags)
1609 _queue_node_pop(&data->dequeue_list, next);
1610 _tbm_surface_queue_enqueue(surface_queue, next, 1);
1615 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
1618 tbm_queue_sequence *data = surface_queue->impl_data;
1621 node = _tbm_surface_queue_dequeue(surface_queue);
1623 _queue_node_push_back(&data->dequeue_list, node);
1624 node->priv_flags = 1;
1630 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
1631 __tbm_queue_sequence_init,
1632 __tbm_queue_sequence_reset,
1633 __tbm_queue_sequence_destroy,
1634 __tbm_queue_sequence_need_attach,
1635 __tbm_queue_sequence_enqueue,
1636 NULL, /*__tbm_queue_sequence_release*/
1637 __tbm_queue_sequence_dequeue,
1638 NULL, /*__tbm_queue_sequence_acquire*/
1639 NULL, /*__tbm_queue_sequence_need_dettach*/
1643 tbm_surface_queue_sequence_create(int queue_size, int width,
1644 int height, int format, int flags)
1646 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
1647 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
1648 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
1649 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
1651 _tbm_surf_queue_mutex_lock();
1653 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
1654 sizeof(struct _tbm_surface_queue));
1655 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
1657 TBM_QUEUE_TRACE("tbm_surface_queue(%p)\n", surface_queue);
1659 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
1660 sizeof(tbm_queue_sequence));
1662 free(surface_queue);
1663 _tbm_surf_queue_mutex_unlock();
1667 data->flags = flags;
1668 _tbm_surface_queue_init(surface_queue,
1670 width, height, format,
1671 &tbm_queue_sequence_impl, data);
1673 _tbm_surf_queue_mutex_unlock();
1675 return surface_queue;
1677 /* LCOV_EXCL_STOP */