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 static tbm_bufmgr g_surf_queue_bufmgr;
42 static pthread_mutex_t tbm_surf_queue_lock;
43 void _tbm_surface_queue_mutex_unlock(void);
46 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
48 TBM_ERR("'%s' failed.\n", #cond);\
49 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
50 _tbm_surf_queue_mutex_unlock();\
55 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
57 TBM_ERR("'%s' failed.\n", #cond);\
58 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
59 _tbm_surf_queue_mutex_unlock();\
64 typedef enum _queue_node_type {
66 QUEUE_NODE_TYPE_DEQUEUE,
67 QUEUE_NODE_TYPE_ENQUEUE,
68 QUEUE_NODE_TYPE_ACQUIRE,
69 QUEUE_NODE_TYPE_RELEASE
73 struct list_head head;
78 tbm_surface_h surface;
80 struct list_head item_link;
81 struct list_head link;
85 unsigned int priv_flags; /*for each queue*/
91 struct list_head link;
93 tbm_surface_queue_notify_cb cb;
98 struct list_head link;
100 tbm_surface_queue_trace_cb cb;
104 typedef struct _tbm_surface_queue_interface {
105 void (*init)(tbm_surface_queue_h queue);
106 void (*reset)(tbm_surface_queue_h queue);
107 void (*destroy)(tbm_surface_queue_h queue);
108 void (*need_attach)(tbm_surface_queue_h queue);
110 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
111 void (*release)(tbm_surface_queue_h queue, queue_node *node);
112 queue_node *(*dequeue)(tbm_surface_queue_h queue);
113 queue_node *(*acquire)(tbm_surface_queue_h queue);
114 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
115 } tbm_surface_queue_interface;
117 struct _tbm_surface_queue {
126 struct list_head list;
128 struct list_head destory_noti;
129 struct list_head dequeuable_noti;
130 struct list_head dequeue_noti;
131 struct list_head can_dequeue_noti;
132 struct list_head acquirable_noti;
133 struct list_head reset_noti;
134 struct list_head trace_noti;
136 pthread_mutex_t lock;
137 pthread_cond_t free_cond;
138 pthread_cond_t dirty_cond;
140 const tbm_surface_queue_interface *impl;
143 //For external buffer allocation
144 tbm_surface_alloc_cb alloc_cb;
145 tbm_surface_free_cb free_cb;
148 struct list_head item_link; /* link of surface queue */
151 unsigned int enqueue_sync_count;
152 unsigned int acquire_sync_count;
156 _tbm_surf_queue_mutex_init(void)
158 static bool tbm_surf_queue_mutex_init = false;
160 if (tbm_surf_queue_mutex_init)
163 if (pthread_mutex_init(&tbm_surf_queue_lock, NULL)) {
164 TBM_ERR("fail: pthread_mutex_init\n");
168 tbm_surf_queue_mutex_init = true;
174 _tbm_surf_queue_mutex_lock(void)
176 if (!_tbm_surf_queue_mutex_init()) {
177 TBM_ERR("fail: _tbm_surf_queue_mutex_init\n");
181 pthread_mutex_lock(&tbm_surf_queue_lock);
185 _tbm_surf_queue_mutex_unlock(void)
187 pthread_mutex_unlock(&tbm_surf_queue_lock);
191 _init_tbm_surf_queue_bufmgr(void)
193 g_surf_queue_bufmgr = tbm_bufmgr_init(-1);
197 _deinit_tbm_surf_queue_bufmgr(void)
199 if (!g_surf_queue_bufmgr)
202 tbm_bufmgr_deinit(g_surf_queue_bufmgr);
203 g_surf_queue_bufmgr = NULL;
207 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
209 tbm_surface_queue_h old_data = NULL;
211 if (surface_queue == NULL) {
212 TBM_ERR("error: surface_queue is NULL.\n");
216 if (g_surf_queue_bufmgr == NULL) {
217 TBM_ERR("error: g_surf_queue_bufmgr is NULL.\n");
221 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list)) {
222 TBM_ERR("error: surf_queue_list is empty\n");
226 LIST_FOR_EACH_ENTRY(old_data, &g_surf_queue_bufmgr->surf_queue_list,
228 if (old_data == surface_queue) {
229 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
234 TBM_ERR("error: Invalid tbm_surface_queue(%p)\n", surface_queue);
240 _queue_node_create(void)
242 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
244 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
250 _queue_node_delete(queue_node *node)
252 LIST_DEL(&node->item_link);
253 LIST_DEL(&node->link);
258 _queue_is_empty(queue *queue)
260 if (LIST_IS_EMPTY(&queue->head))
267 _queue_node_push_back(queue *queue, queue_node *node)
269 LIST_ADDTAIL(&node->item_link, &queue->head);
274 _queue_node_push_front(queue *queue, queue_node *node)
276 LIST_ADD(&node->item_link, &queue->head);
281 _queue_node_pop_front(queue *queue)
285 if (!queue->head.next) return NULL;
286 if (!queue->count) return NULL;
288 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
290 LIST_DELINIT(&node->item_link);
297 _queue_node_pop(queue *queue, queue_node *node)
299 LIST_DELINIT(&node->item_link);
306 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
307 tbm_surface_h surface, int *out_type)
309 queue_node *node = NULL;
312 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
316 if (type & FREE_QUEUE) {
317 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
319 if (node->surface == surface) {
321 *out_type = FREE_QUEUE;
328 if (type & DIRTY_QUEUE) {
329 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
331 if (node->surface == surface) {
333 *out_type = DIRTY_QUEUE;
340 if (type & NODE_LIST) {
341 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
342 if (node->surface == surface) {
344 *out_type = NODE_LIST;
351 TBM_ERR("fail to get the queue_node.\n");
357 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
360 if (surface_queue->free_cb) {
361 surface_queue->free_cb(surface_queue,
362 surface_queue->alloc_cb_data,
366 tbm_surface_destroy(node->surface);
369 _queue_node_delete(node);
373 _queue_init(queue *queue)
375 LIST_INITHEAD(&queue->head);
381 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
384 TBM_RETURN_IF_FAIL(cb != NULL);
386 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
388 TBM_RETURN_IF_FAIL(item != NULL);
390 LIST_INITHEAD(&item->link);
394 LIST_ADDTAIL(&item->link, list);
398 _notify_remove(struct list_head *list,
399 tbm_surface_queue_notify_cb cb, void *data)
401 queue_notify *item = NULL, *tmp;
403 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
404 if (item->cb == cb && item->data == data) {
405 LIST_DEL(&item->link);
411 TBM_ERR("Cannot find notifiy\n");
415 _notify_remove_all(struct list_head *list)
417 queue_notify *item = NULL, *tmp;
419 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
420 LIST_DEL(&item->link);
426 _notify_emit(tbm_surface_queue_h surface_queue,
427 struct list_head *list)
429 queue_notify *item = NULL, *tmp;;
432 The item->cb is the outside function of the libtbm.
433 The tbm user may/can remove the item of the list,
434 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
436 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
437 item->cb(surface_queue, item->data);
441 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
444 TBM_RETURN_IF_FAIL(cb != NULL);
446 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
448 TBM_RETURN_IF_FAIL(item != NULL);
450 LIST_INITHEAD(&item->link);
454 LIST_ADDTAIL(&item->link, list);
458 _trace_remove(struct list_head *list,
459 tbm_surface_queue_trace_cb cb, void *data)
461 queue_trace *item = NULL, *tmp;
463 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
464 if (item->cb == cb && item->data == data) {
465 LIST_DEL(&item->link);
471 TBM_ERR("Cannot find notifiy\n");
475 _trace_remove_all(struct list_head *list)
477 queue_trace *item = NULL, *tmp;
479 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
480 LIST_DEL(&item->link);
486 _trace_emit(tbm_surface_queue_h surface_queue,
487 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
489 queue_trace *item = NULL, *tmp;;
492 The item->cb is the outside function of the libtbm.
493 The tbm user may/can remove the item of the list,
494 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
496 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
497 item->cb(surface_queue, surface, trace, item->data);
501 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
503 queue_node *node = NULL;
506 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
507 if (node->type == type)
515 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
516 tbm_surface_h surface)
520 node = _queue_node_create();
521 TBM_RETURN_IF_FAIL(node != NULL);
523 tbm_surface_internal_ref(surface);
524 node->surface = surface;
526 LIST_ADDTAIL(&node->link, &surface_queue->list);
527 surface_queue->num_attached++;
528 _queue_node_push_back(&surface_queue->free_queue, node);
532 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
533 tbm_surface_h surface)
538 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
540 _queue_delete_node(surface_queue, node);
541 surface_queue->num_attached--;
546 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
547 queue_node *node, int push_back)
550 _queue_node_push_back(&surface_queue->dirty_queue, node);
552 _queue_node_push_front(&surface_queue->dirty_queue, node);
556 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
560 node = _queue_node_pop_front(&surface_queue->free_queue);
566 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
570 if (_queue_is_empty(&surface_queue->dirty_queue))
573 node = _queue_node_pop_front(&surface_queue->dirty_queue);
579 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
580 queue_node *node, int push_back)
583 _queue_node_push_back(&surface_queue->free_queue, node);
585 _queue_node_push_front(&surface_queue->free_queue, node);
589 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
591 int width, int height, int format,
592 const tbm_surface_queue_interface *impl, void *data)
594 TBM_RETURN_IF_FAIL(surface_queue != NULL);
595 TBM_RETURN_IF_FAIL(impl != NULL);
597 if (!g_surf_queue_bufmgr)
598 _init_tbm_surf_queue_bufmgr();
600 pthread_mutex_init(&surface_queue->lock, NULL);
601 pthread_cond_init(&surface_queue->free_cond, NULL);
602 pthread_cond_init(&surface_queue->dirty_cond, NULL);
604 surface_queue->queue_size = queue_size;
605 surface_queue->width = width;
606 surface_queue->height = height;
607 surface_queue->format = format;
608 surface_queue->impl = impl;
609 surface_queue->impl_data = data;
610 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
612 _queue_init(&surface_queue->free_queue);
613 _queue_init(&surface_queue->dirty_queue);
614 LIST_INITHEAD(&surface_queue->list);
616 LIST_INITHEAD(&surface_queue->destory_noti);
617 LIST_INITHEAD(&surface_queue->dequeuable_noti);
618 LIST_INITHEAD(&surface_queue->dequeue_noti);
619 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
620 LIST_INITHEAD(&surface_queue->acquirable_noti);
621 LIST_INITHEAD(&surface_queue->reset_noti);
622 LIST_INITHEAD(&surface_queue->trace_noti);
624 if (surface_queue->impl && surface_queue->impl->init)
625 surface_queue->impl->init(surface_queue);
627 LIST_ADD(&surface_queue->item_link, &g_surf_queue_bufmgr->surf_queue_list);
630 tbm_surface_queue_error_e
631 tbm_surface_queue_add_destroy_cb(
632 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
635 _tbm_surf_queue_mutex_lock();
636 _tbm_set_last_result(TBM_ERROR_NONE);
638 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
639 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
640 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
641 TBM_ERROR_INVALID_PARAMETER);
643 pthread_mutex_lock(&surface_queue->lock);
645 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
647 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
649 pthread_mutex_unlock(&surface_queue->lock);
651 _tbm_surf_queue_mutex_unlock();
653 return TBM_SURFACE_QUEUE_ERROR_NONE;
656 tbm_surface_queue_error_e
657 tbm_surface_queue_remove_destroy_cb(
658 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
661 _tbm_surf_queue_mutex_lock();
662 _tbm_set_last_result(TBM_ERROR_NONE);
664 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
665 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
667 pthread_mutex_lock(&surface_queue->lock);
669 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
671 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
673 pthread_mutex_unlock(&surface_queue->lock);
675 _tbm_surf_queue_mutex_unlock();
677 return TBM_SURFACE_QUEUE_ERROR_NONE;
680 tbm_surface_queue_error_e
681 tbm_surface_queue_add_dequeuable_cb(
682 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
685 _tbm_surf_queue_mutex_lock();
686 _tbm_set_last_result(TBM_ERROR_NONE);
688 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
689 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
690 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
691 TBM_ERROR_INVALID_PARAMETER);
693 pthread_mutex_lock(&surface_queue->lock);
695 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
697 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
699 pthread_mutex_unlock(&surface_queue->lock);
701 _tbm_surf_queue_mutex_unlock();
703 return TBM_SURFACE_QUEUE_ERROR_NONE;
706 tbm_surface_queue_error_e
707 tbm_surface_queue_remove_dequeuable_cb(
708 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
711 _tbm_surf_queue_mutex_lock();
712 _tbm_set_last_result(TBM_ERROR_NONE);
714 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
715 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
717 pthread_mutex_lock(&surface_queue->lock);
719 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
721 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
723 pthread_mutex_unlock(&surface_queue->lock);
725 _tbm_surf_queue_mutex_unlock();
727 return TBM_SURFACE_QUEUE_ERROR_NONE;
730 tbm_surface_queue_error_e
731 tbm_surface_queue_add_dequeue_cb(
732 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
735 _tbm_surf_queue_mutex_lock();
736 _tbm_set_last_result(TBM_ERROR_NONE);
738 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
739 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
740 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
741 TBM_ERROR_INVALID_PARAMETER);
743 pthread_mutex_lock(&surface_queue->lock);
745 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
747 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
749 pthread_mutex_unlock(&surface_queue->lock);
751 _tbm_surf_queue_mutex_unlock();
753 return TBM_SURFACE_QUEUE_ERROR_NONE;
756 tbm_surface_queue_error_e
757 tbm_surface_queue_remove_dequeue_cb(
758 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
761 _tbm_surf_queue_mutex_lock();
762 _tbm_set_last_result(TBM_ERROR_NONE);
764 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
765 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
767 pthread_mutex_lock(&surface_queue->lock);
769 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
771 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
773 pthread_mutex_unlock(&surface_queue->lock);
775 _tbm_surf_queue_mutex_unlock();
777 return TBM_SURFACE_QUEUE_ERROR_NONE;
780 tbm_surface_queue_error_e
781 tbm_surface_queue_add_can_dequeue_cb(
782 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
785 _tbm_surf_queue_mutex_lock();
786 _tbm_set_last_result(TBM_ERROR_NONE);
788 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
789 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
790 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
791 TBM_ERROR_INVALID_PARAMETER);
793 pthread_mutex_lock(&surface_queue->lock);
795 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
797 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
799 pthread_mutex_unlock(&surface_queue->lock);
801 _tbm_surf_queue_mutex_unlock();
803 return TBM_SURFACE_QUEUE_ERROR_NONE;
806 tbm_surface_queue_error_e
807 tbm_surface_queue_remove_can_dequeue_cb(
808 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
811 _tbm_surf_queue_mutex_lock();
812 _tbm_set_last_result(TBM_ERROR_NONE);
814 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
815 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
817 pthread_mutex_lock(&surface_queue->lock);
819 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
821 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
823 pthread_mutex_unlock(&surface_queue->lock);
825 _tbm_surf_queue_mutex_unlock();
827 return TBM_SURFACE_QUEUE_ERROR_NONE;
830 tbm_surface_queue_error_e
831 tbm_surface_queue_add_acquirable_cb(
832 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
835 _tbm_surf_queue_mutex_lock();
836 _tbm_set_last_result(TBM_ERROR_NONE);
838 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
839 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
840 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
841 TBM_ERROR_INVALID_PARAMETER);
843 pthread_mutex_lock(&surface_queue->lock);
845 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
847 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
849 pthread_mutex_unlock(&surface_queue->lock);
851 _tbm_surf_queue_mutex_unlock();
853 return TBM_SURFACE_QUEUE_ERROR_NONE;
856 tbm_surface_queue_error_e
857 tbm_surface_queue_remove_acquirable_cb(
858 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
861 _tbm_surf_queue_mutex_lock();
862 _tbm_set_last_result(TBM_ERROR_NONE);
864 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
865 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
867 pthread_mutex_lock(&surface_queue->lock);
869 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
871 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
873 pthread_mutex_unlock(&surface_queue->lock);
875 _tbm_surf_queue_mutex_unlock();
877 return TBM_SURFACE_QUEUE_ERROR_NONE;
880 tbm_surface_queue_error_e
881 tbm_surface_queue_add_trace_cb(
882 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
885 _tbm_surf_queue_mutex_lock();
886 _tbm_set_last_result(TBM_ERROR_NONE);
888 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
889 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
890 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
891 TBM_ERROR_INVALID_PARAMETER);
893 pthread_mutex_lock(&surface_queue->lock);
895 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
897 _trace_add(&surface_queue->trace_noti, trace_cb, data);
899 pthread_mutex_unlock(&surface_queue->lock);
901 _tbm_surf_queue_mutex_unlock();
903 return TBM_SURFACE_QUEUE_ERROR_NONE;
906 tbm_surface_queue_error_e
907 tbm_surface_queue_remove_trace_cb(
908 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
911 _tbm_surf_queue_mutex_lock();
912 _tbm_set_last_result(TBM_ERROR_NONE);
914 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
915 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
917 pthread_mutex_lock(&surface_queue->lock);
919 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
921 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
923 pthread_mutex_unlock(&surface_queue->lock);
925 _tbm_surf_queue_mutex_unlock();
927 return TBM_SURFACE_QUEUE_ERROR_NONE;
930 tbm_surface_queue_error_e
931 tbm_surface_queue_set_alloc_cb(
932 tbm_surface_queue_h surface_queue,
933 tbm_surface_alloc_cb alloc_cb,
934 tbm_surface_free_cb free_cb,
937 _tbm_surf_queue_mutex_lock();
938 _tbm_set_last_result(TBM_ERROR_NONE);
940 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
941 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
943 pthread_mutex_lock(&surface_queue->lock);
945 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
947 surface_queue->alloc_cb = alloc_cb;
948 surface_queue->free_cb = free_cb;
949 surface_queue->alloc_cb_data = data;
951 pthread_mutex_unlock(&surface_queue->lock);
953 _tbm_surf_queue_mutex_unlock();
955 return TBM_SURFACE_QUEUE_ERROR_NONE;
959 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
963 _tbm_surf_queue_mutex_lock();
964 _tbm_set_last_result(TBM_ERROR_NONE);
966 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
968 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
970 width = surface_queue->width;
972 _tbm_surf_queue_mutex_unlock();
978 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
982 _tbm_surf_queue_mutex_lock();
983 _tbm_set_last_result(TBM_ERROR_NONE);
985 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
987 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
989 height = surface_queue->height;
991 _tbm_surf_queue_mutex_unlock();
997 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1001 _tbm_surf_queue_mutex_lock();
1002 _tbm_set_last_result(TBM_ERROR_NONE);
1004 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1006 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1008 format = surface_queue->format;
1010 _tbm_surf_queue_mutex_unlock();
1016 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1020 _tbm_surf_queue_mutex_lock();
1021 _tbm_set_last_result(TBM_ERROR_NONE);
1023 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1025 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1027 queue_size = surface_queue->queue_size;
1029 _tbm_surf_queue_mutex_unlock();
1034 tbm_surface_queue_error_e
1035 tbm_surface_queue_add_reset_cb(
1036 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1039 _tbm_surf_queue_mutex_lock();
1040 _tbm_set_last_result(TBM_ERROR_NONE);
1042 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1043 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1044 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1045 TBM_ERROR_INVALID_PARAMETER);
1047 pthread_mutex_lock(&surface_queue->lock);
1049 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1051 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1053 pthread_mutex_unlock(&surface_queue->lock);
1055 _tbm_surf_queue_mutex_unlock();
1057 return TBM_SURFACE_QUEUE_ERROR_NONE;
1060 tbm_surface_queue_error_e
1061 tbm_surface_queue_remove_reset_cb(
1062 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1065 _tbm_surf_queue_mutex_lock();
1066 _tbm_set_last_result(TBM_ERROR_NONE);
1068 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1069 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1071 pthread_mutex_lock(&surface_queue->lock);
1073 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1075 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1077 pthread_mutex_unlock(&surface_queue->lock);
1079 _tbm_surf_queue_mutex_unlock();
1081 return TBM_SURFACE_QUEUE_ERROR_NONE;
1084 tbm_surface_queue_error_e
1085 tbm_surface_queue_enqueue(tbm_surface_queue_h
1086 surface_queue, tbm_surface_h surface)
1091 _tbm_surf_queue_mutex_lock();
1092 _tbm_set_last_result(TBM_ERROR_NONE);
1094 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1095 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1096 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1097 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1100 tbm_surface_internal_dump_buffer(surface, "enqueue");
1102 pthread_mutex_lock(&surface_queue->lock);
1104 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1106 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1107 if (node == NULL || queue_type != NODE_LIST) {
1108 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1110 pthread_mutex_unlock(&surface_queue->lock);
1112 _tbm_surf_queue_mutex_unlock();
1115 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1116 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1118 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1119 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1123 if (surface_queue->impl && surface_queue->impl->enqueue)
1124 surface_queue->impl->enqueue(surface_queue, node);
1126 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1128 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1129 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface);
1130 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1131 pthread_mutex_unlock(&surface_queue->lock);
1133 _tbm_surf_queue_mutex_unlock();
1134 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1137 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1139 if (surface_queue->enqueue_sync_count == 1) {
1140 tbm_surface_info_s info;
1143 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1144 if (ret == TBM_SURFACE_ERROR_NONE)
1145 tbm_surface_unmap(surface);
1148 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1150 pthread_mutex_unlock(&surface_queue->lock);
1151 pthread_cond_signal(&surface_queue->dirty_cond);
1153 _tbm_surf_queue_mutex_unlock();
1155 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1157 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1159 return TBM_SURFACE_QUEUE_ERROR_NONE;
1162 tbm_surface_queue_error_e
1163 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1164 surface_queue, tbm_surface_h surface)
1169 _tbm_surf_queue_mutex_lock();
1170 _tbm_set_last_result(TBM_ERROR_NONE);
1172 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1173 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1174 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1175 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1177 pthread_mutex_lock(&surface_queue->lock);
1179 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1181 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1182 if (node == NULL || queue_type != NODE_LIST) {
1183 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1185 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1186 pthread_mutex_unlock(&surface_queue->lock);
1188 _tbm_surf_queue_mutex_unlock();
1189 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1192 if (node->delete_pending) {
1193 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1195 _queue_delete_node(surface_queue, node);
1197 pthread_mutex_unlock(&surface_queue->lock);
1199 _tbm_surf_queue_mutex_unlock();
1201 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1203 return TBM_SURFACE_QUEUE_ERROR_NONE;
1206 if (surface_queue->queue_size < surface_queue->num_attached) {
1207 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1209 if (surface_queue->impl && surface_queue->impl->need_detach)
1210 surface_queue->impl->need_detach(surface_queue, node);
1212 _tbm_surface_queue_detach(surface_queue, surface);
1214 pthread_mutex_unlock(&surface_queue->lock);
1216 _tbm_surf_queue_mutex_unlock();
1218 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1220 return TBM_SURFACE_QUEUE_ERROR_NONE;
1223 if (surface_queue->impl && surface_queue->impl->release)
1224 surface_queue->impl->release(surface_queue, node);
1226 _tbm_surface_queue_release(surface_queue, node, 1);
1228 if (_queue_is_empty(&surface_queue->free_queue)) {
1229 TBM_ERR("surface_queue->free_queue is empty.\n");
1230 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1231 pthread_mutex_unlock(&surface_queue->lock);
1233 _tbm_surf_queue_mutex_unlock();
1234 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1237 node->type = QUEUE_NODE_TYPE_RELEASE;
1239 pthread_mutex_unlock(&surface_queue->lock);
1240 pthread_cond_signal(&surface_queue->free_cond);
1242 _tbm_surf_queue_mutex_unlock();
1244 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1246 return TBM_SURFACE_QUEUE_ERROR_NONE;
1249 tbm_surface_queue_error_e
1250 tbm_surface_queue_dequeue(tbm_surface_queue_h
1251 surface_queue, tbm_surface_h *surface)
1255 _tbm_surf_queue_mutex_lock();
1256 _tbm_set_last_result(TBM_ERROR_NONE);
1258 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1259 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1260 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1261 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1265 pthread_mutex_lock(&surface_queue->lock);
1267 if (_queue_is_empty(&surface_queue->free_queue)) {
1268 if (surface_queue->impl && surface_queue->impl->need_attach)
1269 surface_queue->impl->need_attach(surface_queue);
1271 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1272 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1273 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1274 pthread_mutex_unlock(&surface_queue->lock);
1275 _tbm_surf_queue_mutex_unlock();
1276 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
1280 if (surface_queue->impl && surface_queue->impl->dequeue)
1281 node = surface_queue->impl->dequeue(surface_queue);
1283 node = _tbm_surface_queue_dequeue(surface_queue);
1285 if (node == NULL || node->surface == NULL) {
1286 TBM_ERR("_queue_node_pop_front failed\n");
1287 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1288 pthread_mutex_unlock(&surface_queue->lock);
1290 _tbm_surf_queue_mutex_unlock();
1291 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1294 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1295 *surface = node->surface;
1297 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1299 pthread_mutex_unlock(&surface_queue->lock);
1301 _tbm_surf_queue_mutex_unlock();
1303 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1305 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1307 return TBM_SURFACE_QUEUE_ERROR_NONE;
1311 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1313 _tbm_surf_queue_mutex_lock();
1314 _tbm_set_last_result(TBM_ERROR_NONE);
1316 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1318 _tbm_surf_queue_mutex_unlock();
1320 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1322 _tbm_surf_queue_mutex_lock();
1324 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1326 pthread_mutex_lock(&surface_queue->lock);
1328 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1330 if (_queue_is_empty(&surface_queue->free_queue)) {
1331 if (surface_queue->impl && surface_queue->impl->need_attach)
1332 surface_queue->impl->need_attach(surface_queue);
1334 if (!_tbm_surface_queue_is_valid(surface_queue)) {
1335 TBM_ERR("surface_queue:%p is invalid", surface_queue);
1336 pthread_mutex_unlock(&surface_queue->lock);
1337 _tbm_surf_queue_mutex_unlock();
1342 if (!_queue_is_empty(&surface_queue->free_queue)) {
1343 pthread_mutex_unlock(&surface_queue->lock);
1344 _tbm_surf_queue_mutex_unlock();
1348 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1349 QUEUE_NODE_TYPE_ACQUIRE)) {
1350 _tbm_surf_queue_mutex_unlock();
1351 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1352 pthread_mutex_unlock(&surface_queue->lock);
1356 pthread_mutex_unlock(&surface_queue->lock);
1357 _tbm_surf_queue_mutex_unlock();
1361 tbm_surface_queue_error_e
1362 tbm_surface_queue_release(tbm_surface_queue_h
1363 surface_queue, tbm_surface_h surface)
1368 _tbm_surf_queue_mutex_lock();
1369 _tbm_set_last_result(TBM_ERROR_NONE);
1371 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1372 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1373 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1374 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1376 pthread_mutex_lock(&surface_queue->lock);
1378 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1380 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1381 if (node == NULL || queue_type != NODE_LIST) {
1382 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1384 pthread_mutex_unlock(&surface_queue->lock);
1386 _tbm_surf_queue_mutex_unlock();
1389 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1390 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1392 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1393 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1397 if (node->delete_pending) {
1398 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1400 _queue_delete_node(surface_queue, node);
1402 pthread_mutex_unlock(&surface_queue->lock);
1404 _tbm_surf_queue_mutex_unlock();
1406 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1408 return TBM_SURFACE_QUEUE_ERROR_NONE;
1411 if (surface_queue->queue_size < surface_queue->num_attached) {
1412 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1414 if (surface_queue->impl && surface_queue->impl->need_detach)
1415 surface_queue->impl->need_detach(surface_queue, node);
1417 _tbm_surface_queue_detach(surface_queue, surface);
1419 pthread_mutex_unlock(&surface_queue->lock);
1421 _tbm_surf_queue_mutex_unlock();
1423 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1425 return TBM_SURFACE_QUEUE_ERROR_NONE;
1428 if (surface_queue->impl && surface_queue->impl->release)
1429 surface_queue->impl->release(surface_queue, node);
1431 _tbm_surface_queue_release(surface_queue, node, 1);
1433 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1434 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1435 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1436 pthread_mutex_unlock(&surface_queue->lock);
1438 _tbm_surf_queue_mutex_unlock();
1439 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1442 node->type = QUEUE_NODE_TYPE_RELEASE;
1444 pthread_mutex_unlock(&surface_queue->lock);
1445 pthread_cond_signal(&surface_queue->free_cond);
1447 _tbm_surf_queue_mutex_unlock();
1449 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1451 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1453 return TBM_SURFACE_QUEUE_ERROR_NONE;
1456 tbm_surface_queue_error_e
1457 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1458 surface_queue, tbm_surface_h surface)
1463 _tbm_surf_queue_mutex_lock();
1464 _tbm_set_last_result(TBM_ERROR_NONE);
1466 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1467 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1468 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1469 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1471 pthread_mutex_lock(&surface_queue->lock);
1473 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1475 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1476 if (node == NULL || queue_type != NODE_LIST) {
1477 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1479 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1480 pthread_mutex_unlock(&surface_queue->lock);
1482 _tbm_surf_queue_mutex_unlock();
1483 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1486 if (surface_queue->impl && surface_queue->impl->enqueue)
1487 surface_queue->impl->enqueue(surface_queue, node);
1489 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1491 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1492 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1493 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1494 pthread_mutex_unlock(&surface_queue->lock);
1496 _tbm_surf_queue_mutex_unlock();
1497 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1500 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1502 pthread_mutex_unlock(&surface_queue->lock);
1503 pthread_cond_signal(&surface_queue->dirty_cond);
1505 _tbm_surf_queue_mutex_unlock();
1507 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1509 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1511 return TBM_SURFACE_QUEUE_ERROR_NONE;
1514 tbm_surface_queue_error_e
1515 tbm_surface_queue_acquire(tbm_surface_queue_h
1516 surface_queue, tbm_surface_h *surface)
1520 _tbm_surf_queue_mutex_lock();
1521 _tbm_set_last_result(TBM_ERROR_NONE);
1525 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1526 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1527 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1528 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1530 pthread_mutex_lock(&surface_queue->lock);
1532 if (surface_queue->impl && surface_queue->impl->acquire)
1533 node = surface_queue->impl->acquire(surface_queue);
1535 node = _tbm_surface_queue_acquire(surface_queue);
1537 if (node == NULL || node->surface == NULL) {
1538 TBM_ERR("_queue_node_pop_front failed\n");
1539 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1540 pthread_mutex_unlock(&surface_queue->lock);
1542 _tbm_surf_queue_mutex_unlock();
1543 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1546 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1548 *surface = node->surface;
1550 if (surface_queue->acquire_sync_count == 1) {
1551 tbm_surface_info_s info;
1554 TBM_ERR("start map surface:%p", *surface);
1555 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1556 TBM_ERR("end map surface:%p", *surface);
1557 if (ret == TBM_SURFACE_ERROR_NONE)
1558 tbm_surface_unmap(*surface);
1561 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1563 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1565 pthread_mutex_unlock(&surface_queue->lock);
1567 _tbm_surf_queue_mutex_unlock();
1570 tbm_surface_internal_dump_buffer(*surface, "acquire");
1572 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1574 return TBM_SURFACE_QUEUE_ERROR_NONE;
1578 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1580 _tbm_surf_queue_mutex_lock();
1581 _tbm_set_last_result(TBM_ERROR_NONE);
1583 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1585 pthread_mutex_lock(&surface_queue->lock);
1587 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1589 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1590 pthread_mutex_unlock(&surface_queue->lock);
1591 _tbm_surf_queue_mutex_unlock();
1595 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1596 QUEUE_NODE_TYPE_DEQUEUE)) {
1597 _tbm_surf_queue_mutex_unlock();
1598 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1599 pthread_mutex_unlock(&surface_queue->lock);
1603 pthread_mutex_unlock(&surface_queue->lock);
1604 _tbm_surf_queue_mutex_unlock();
1609 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1611 queue_node *node = NULL, *tmp;
1613 _tbm_surf_queue_mutex_lock();
1614 _tbm_set_last_result(TBM_ERROR_NONE);
1616 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1618 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1620 LIST_DEL(&surface_queue->item_link);
1622 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1623 _queue_delete_node(surface_queue, node);
1625 if (surface_queue->impl && surface_queue->impl->destroy)
1626 surface_queue->impl->destroy(surface_queue);
1628 _notify_emit(surface_queue, &surface_queue->destory_noti);
1630 _notify_remove_all(&surface_queue->destory_noti);
1631 _notify_remove_all(&surface_queue->dequeuable_noti);
1632 _notify_remove_all(&surface_queue->dequeue_noti);
1633 _notify_remove_all(&surface_queue->can_dequeue_noti);
1634 _notify_remove_all(&surface_queue->acquirable_noti);
1635 _notify_remove_all(&surface_queue->reset_noti);
1636 _trace_remove_all(&surface_queue->trace_noti);
1638 pthread_mutex_destroy(&surface_queue->lock);
1640 free(surface_queue);
1642 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1643 _deinit_tbm_surf_queue_bufmgr();
1645 _tbm_surf_queue_mutex_unlock();
1648 tbm_surface_queue_error_e
1649 tbm_surface_queue_reset(tbm_surface_queue_h
1650 surface_queue, int width, int height, int format)
1652 queue_node *node = NULL, *tmp;
1654 _tbm_surf_queue_mutex_lock();
1655 _tbm_set_last_result(TBM_ERROR_NONE);
1657 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1658 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1660 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1662 if (width == surface_queue->width && height == surface_queue->height &&
1663 format == surface_queue->format) {
1664 _tbm_surf_queue_mutex_unlock();
1665 return TBM_SURFACE_QUEUE_ERROR_NONE;
1668 pthread_mutex_lock(&surface_queue->lock);
1670 surface_queue->width = width;
1671 surface_queue->height = height;
1672 surface_queue->format = format;
1674 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1675 /* Destory surface and Push to free_queue */
1676 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1677 _queue_delete_node(surface_queue, node);
1679 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1680 node->delete_pending = 1;
1682 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1683 _queue_delete_node(surface_queue, node);
1685 _queue_init(&surface_queue->dirty_queue);
1686 LIST_INITHEAD(&surface_queue->list);
1690 _queue_init(&surface_queue->free_queue);
1692 surface_queue->num_attached = 0;
1694 if (surface_queue->impl && surface_queue->impl->reset)
1695 surface_queue->impl->reset(surface_queue);
1697 pthread_mutex_unlock(&surface_queue->lock);
1698 pthread_cond_signal(&surface_queue->free_cond);
1700 _tbm_surf_queue_mutex_unlock();
1702 _notify_emit(surface_queue, &surface_queue->reset_noti);
1704 return TBM_SURFACE_QUEUE_ERROR_NONE;
1707 tbm_surface_queue_error_e
1708 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1710 _tbm_surf_queue_mutex_lock();
1711 _tbm_set_last_result(TBM_ERROR_NONE);
1713 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1714 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1716 _tbm_surf_queue_mutex_unlock();
1718 _notify_emit(surface_queue, &surface_queue->reset_noti);
1720 return TBM_SURFACE_QUEUE_ERROR_NONE;
1723 tbm_surface_queue_error_e
1724 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1726 _tbm_surf_queue_mutex_lock();
1727 _tbm_set_last_result(TBM_ERROR_NONE);
1729 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1730 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1732 _tbm_surf_queue_mutex_unlock();
1734 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1736 return TBM_SURFACE_QUEUE_ERROR_NONE;
1739 tbm_surface_queue_error_e
1740 tbm_surface_queue_set_size(tbm_surface_queue_h
1741 surface_queue, int queue_size, int flush)
1743 queue_node *node = NULL, *tmp;
1745 _tbm_surf_queue_mutex_lock();
1746 _tbm_set_last_result(TBM_ERROR_NONE);
1748 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1749 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1750 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1751 TBM_ERROR_INVALID_PARAMETER);
1753 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1755 if ((surface_queue->queue_size == queue_size) && !flush) {
1756 _tbm_surf_queue_mutex_unlock();
1757 return TBM_SURFACE_QUEUE_ERROR_NONE;
1760 pthread_mutex_lock(&surface_queue->lock);
1763 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1764 /* Destory surface and Push to free_queue */
1765 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1766 _queue_delete_node(surface_queue, node);
1768 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1769 node->delete_pending = 1;
1771 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1772 _queue_delete_node(surface_queue, node);
1774 _queue_init(&surface_queue->dirty_queue);
1775 LIST_INITHEAD(&surface_queue->list);
1779 _queue_init(&surface_queue->free_queue);
1781 surface_queue->num_attached = 0;
1782 surface_queue->queue_size = queue_size;
1784 if (surface_queue->impl && surface_queue->impl->reset)
1785 surface_queue->impl->reset(surface_queue);
1787 pthread_mutex_unlock(&surface_queue->lock);
1788 pthread_cond_signal(&surface_queue->free_cond);
1790 _tbm_surf_queue_mutex_unlock();
1792 _notify_emit(surface_queue, &surface_queue->reset_noti);
1794 return TBM_SURFACE_QUEUE_ERROR_NONE;
1796 if (surface_queue->queue_size > queue_size) {
1797 int need_del = surface_queue->queue_size - queue_size;
1799 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1800 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1802 if (surface_queue->impl && surface_queue->impl->need_detach)
1803 surface_queue->impl->need_detach(surface_queue, node);
1805 _tbm_surface_queue_detach(surface_queue, node->surface);
1813 surface_queue->queue_size = queue_size;
1815 pthread_mutex_unlock(&surface_queue->lock);
1817 _tbm_surf_queue_mutex_unlock();
1819 return TBM_SURFACE_QUEUE_ERROR_NONE;
1823 tbm_surface_queue_error_e
1824 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1826 queue_node *node = NULL;
1828 _tbm_surf_queue_mutex_lock();
1829 _tbm_set_last_result(TBM_ERROR_NONE);
1831 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1832 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1834 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1836 if (surface_queue->num_attached == 0) {
1837 _tbm_surf_queue_mutex_unlock();
1838 return TBM_SURFACE_QUEUE_ERROR_NONE;
1841 pthread_mutex_lock(&surface_queue->lock);
1843 /* Destory surface in free_queue */
1844 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1845 if (surface_queue->impl && surface_queue->impl->need_detach)
1846 surface_queue->impl->need_detach(surface_queue, node);
1848 _tbm_surface_queue_detach(surface_queue, node->surface);
1852 _queue_init(&surface_queue->free_queue);
1854 pthread_mutex_unlock(&surface_queue->lock);
1855 _tbm_surf_queue_mutex_unlock();
1857 return TBM_SURFACE_QUEUE_ERROR_NONE;
1860 tbm_surface_queue_error_e
1861 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1863 queue_node *node = NULL, *tmp;
1865 _tbm_surf_queue_mutex_lock();
1866 _tbm_set_last_result(TBM_ERROR_NONE);
1868 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1869 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1871 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1873 if (surface_queue->num_attached == 0) {
1874 _tbm_surf_queue_mutex_unlock();
1875 return TBM_SURFACE_QUEUE_ERROR_NONE;
1878 pthread_mutex_lock(&surface_queue->lock);
1880 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1881 /* Destory surface and Push to free_queue */
1882 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1883 _queue_delete_node(surface_queue, node);
1885 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1886 node->delete_pending = 1;
1888 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1889 _queue_delete_node(surface_queue, node);
1891 _queue_init(&surface_queue->dirty_queue);
1892 LIST_INITHEAD(&surface_queue->list);
1896 _queue_init(&surface_queue->free_queue);
1898 surface_queue->num_attached = 0;
1900 if (surface_queue->impl && surface_queue->impl->reset)
1901 surface_queue->impl->reset(surface_queue);
1903 pthread_mutex_unlock(&surface_queue->lock);
1904 pthread_cond_signal(&surface_queue->free_cond);
1906 _tbm_surf_queue_mutex_unlock();
1908 _notify_emit(surface_queue, &surface_queue->reset_noti);
1910 return TBM_SURFACE_QUEUE_ERROR_NONE;
1913 tbm_surface_queue_error_e
1914 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1915 tbm_surface_h *surfaces, int *num)
1917 queue_node *node = NULL;
1919 _tbm_surf_queue_mutex_lock();
1920 _tbm_set_last_result(TBM_ERROR_NONE);
1922 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1923 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1924 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1925 TBM_ERROR_INVALID_PARAMETER);
1929 pthread_mutex_lock(&surface_queue->lock);
1931 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1932 if (node->delete_pending) continue;
1935 surfaces[*num] = node->surface;
1940 pthread_mutex_unlock(&surface_queue->lock);
1942 _tbm_surf_queue_mutex_unlock();
1944 return TBM_SURFACE_QUEUE_ERROR_NONE;
1947 tbm_surface_queue_error_e
1948 tbm_surface_queue_get_trace_surface_num(
1949 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1951 _tbm_surf_queue_mutex_lock();
1952 _tbm_set_last_result(TBM_ERROR_NONE);
1954 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1955 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1956 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1957 TBM_ERROR_INVALID_PARAMETER);
1961 pthread_mutex_lock(&surface_queue->lock);
1964 case TBM_SURFACE_QUEUE_TRACE_NONE:
1967 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1968 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1970 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1971 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1973 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1974 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1976 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1977 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1983 pthread_mutex_unlock(&surface_queue->lock);
1985 _tbm_surf_queue_mutex_unlock();
1987 return TBM_SURFACE_QUEUE_ERROR_NONE;
1992 } tbm_queue_default;
1995 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
1997 free(surface_queue->impl_data);
2001 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
2003 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
2004 tbm_surface_h surface;
2006 if (surface_queue->queue_size == surface_queue->num_attached)
2009 if (surface_queue->alloc_cb) {
2010 pthread_mutex_unlock(&surface_queue->lock);
2011 _tbm_surf_queue_mutex_unlock();
2012 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2013 _tbm_surf_queue_mutex_lock();
2014 pthread_mutex_lock(&surface_queue->lock);
2020 tbm_surface_internal_ref(surface);
2022 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2023 surface_queue->height,
2024 surface_queue->format,
2026 TBM_RETURN_IF_FAIL(surface != NULL);
2029 _tbm_surface_queue_attach(surface_queue, surface);
2030 tbm_surface_internal_unref(surface);
2033 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2034 NULL, /*__tbm_queue_default_init*/
2035 NULL, /*__tbm_queue_default_reset*/
2036 __tbm_queue_default_destroy,
2037 __tbm_queue_default_need_attach,
2038 NULL, /*__tbm_queue_default_enqueue*/
2039 NULL, /*__tbm_queue_default_release*/
2040 NULL, /*__tbm_queue_default_dequeue*/
2041 NULL, /*__tbm_queue_default_acquire*/
2042 NULL, /*__tbm_queue_default_need_detach*/
2046 tbm_surface_queue_create(int queue_size, int width,
2047 int height, int format, int flags)
2049 _tbm_surf_queue_mutex_lock();
2050 _tbm_set_last_result(TBM_ERROR_NONE);
2052 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2053 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2054 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2055 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2057 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2058 sizeof(struct _tbm_surface_queue));
2059 if (!surface_queue) {
2060 TBM_ERR("cannot allocate the surface_queue.\n");
2061 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2062 _tbm_surf_queue_mutex_unlock();
2066 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2068 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2069 sizeof(tbm_queue_default));
2071 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2072 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2073 free(surface_queue);
2074 _tbm_surf_queue_mutex_unlock();
2078 data->flags = flags;
2079 _tbm_surface_queue_init(surface_queue,
2081 width, height, format,
2082 &tbm_queue_default_impl, data);
2084 _tbm_surf_queue_mutex_unlock();
2086 return surface_queue;
2092 } tbm_queue_sequence;
2095 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2097 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2099 _queue_init(&data->dequeue_list);
2103 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2105 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2107 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2110 _queue_init(&data->dequeue_list);
2114 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2116 free(surface_queue->impl_data);
2120 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2122 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2123 tbm_surface_h surface;
2125 if (surface_queue->queue_size == surface_queue->num_attached)
2128 if (surface_queue->alloc_cb) {
2129 pthread_mutex_unlock(&surface_queue->lock);
2130 _tbm_surf_queue_mutex_unlock();
2131 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2132 _tbm_surf_queue_mutex_lock();
2133 pthread_mutex_lock(&surface_queue->lock);
2139 tbm_surface_internal_ref(surface);
2141 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2142 surface_queue->height,
2143 surface_queue->format,
2145 TBM_RETURN_IF_FAIL(surface != NULL);
2148 _tbm_surface_queue_attach(surface_queue, surface);
2149 tbm_surface_internal_unref(surface);
2153 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2156 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2157 queue_node *first = NULL;
2159 first = container_of(data->dequeue_list.head.next, first, item_link);
2160 if (first != node) {
2164 node->priv_flags = 0;
2166 _queue_node_pop(&data->dequeue_list, node);
2167 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2171 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2174 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2176 if (node->priv_flags) {
2177 node->priv_flags = 0;
2178 _queue_node_pop(&data->dequeue_list, node);
2181 _tbm_surface_queue_release(surface_queue, node, 1);
2185 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2188 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2191 node = _tbm_surface_queue_dequeue(surface_queue);
2193 _queue_node_push_back(&data->dequeue_list, node);
2194 node->priv_flags = 1;
2200 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2201 __tbm_queue_sequence_init,
2202 __tbm_queue_sequence_reset,
2203 __tbm_queue_sequence_destroy,
2204 __tbm_queue_sequence_need_attach,
2205 __tbm_queue_sequence_enqueue,
2206 __tbm_queue_sequence_release,
2207 __tbm_queue_sequence_dequeue,
2208 NULL, /*__tbm_queue_sequence_acquire*/
2209 NULL, /*__tbm_queue_sequence_need_dettach*/
2213 tbm_surface_queue_sequence_create(int queue_size, int width,
2214 int height, int format, int flags)
2216 _tbm_surf_queue_mutex_lock();
2217 _tbm_set_last_result(TBM_ERROR_NONE);
2219 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2220 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2221 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2222 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2224 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2225 sizeof(struct _tbm_surface_queue));
2226 if (surface_queue == NULL) {
2227 TBM_ERR("cannot allocate the surface_queue.\n");
2228 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2229 _tbm_surf_queue_mutex_unlock();
2233 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2235 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2236 sizeof(tbm_queue_sequence));
2238 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2239 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2240 free(surface_queue);
2241 _tbm_surf_queue_mutex_unlock();
2245 data->flags = flags;
2246 _tbm_surface_queue_init(surface_queue,
2248 width, height, format,
2249 &tbm_queue_sequence_impl, data);
2251 _tbm_surf_queue_mutex_unlock();
2253 return surface_queue;
2256 tbm_surface_queue_error_e
2257 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2260 _tbm_surf_queue_mutex_lock();
2261 _tbm_set_last_result(TBM_ERROR_NONE);
2263 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2264 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2266 pthread_mutex_lock(&surface_queue->lock);
2268 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2269 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2271 surface_queue->modes |= modes;
2273 pthread_mutex_unlock(&surface_queue->lock);
2275 _tbm_surf_queue_mutex_unlock();
2277 return TBM_SURFACE_QUEUE_ERROR_NONE;
2280 tbm_surface_queue_error_e
2281 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2282 unsigned int sync_count)
2284 int dequeue_num, enqueue_num;
2286 _tbm_surf_queue_mutex_lock();
2287 _tbm_set_last_result(TBM_ERROR_NONE);
2289 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2290 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2292 pthread_mutex_lock(&surface_queue->lock);
2294 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2295 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2297 if (dequeue_num + sync_count == 0)
2298 surface_queue->acquire_sync_count = enqueue_num;
2300 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2302 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2303 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2305 pthread_mutex_unlock(&surface_queue->lock);
2307 _tbm_surf_queue_mutex_unlock();
2309 return TBM_SURFACE_QUEUE_ERROR_NONE;