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_QUEUE_ERROR_INVALID_SEQUENCE);
1131 pthread_mutex_unlock(&surface_queue->lock);
1133 _tbm_surf_queue_mutex_unlock();
1134 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
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();
1349 _tbm_surf_queue_mutex_unlock();
1350 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1351 pthread_mutex_unlock(&surface_queue->lock);
1355 pthread_mutex_unlock(&surface_queue->lock);
1356 _tbm_surf_queue_mutex_unlock();
1360 tbm_surface_queue_error_e
1361 tbm_surface_queue_release(tbm_surface_queue_h
1362 surface_queue, tbm_surface_h surface)
1367 _tbm_surf_queue_mutex_lock();
1368 _tbm_set_last_result(TBM_ERROR_NONE);
1370 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1371 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1372 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1373 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1375 pthread_mutex_lock(&surface_queue->lock);
1377 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1379 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1380 if (node == NULL || queue_type != NODE_LIST) {
1381 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1383 pthread_mutex_unlock(&surface_queue->lock);
1385 _tbm_surf_queue_mutex_unlock();
1388 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1389 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1391 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1392 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1396 if (node->delete_pending) {
1397 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1399 _queue_delete_node(surface_queue, node);
1401 pthread_mutex_unlock(&surface_queue->lock);
1403 _tbm_surf_queue_mutex_unlock();
1405 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1407 return TBM_SURFACE_QUEUE_ERROR_NONE;
1410 if (surface_queue->queue_size < surface_queue->num_attached) {
1411 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1413 if (surface_queue->impl && surface_queue->impl->need_detach)
1414 surface_queue->impl->need_detach(surface_queue, node);
1416 _tbm_surface_queue_detach(surface_queue, surface);
1418 pthread_mutex_unlock(&surface_queue->lock);
1420 _tbm_surf_queue_mutex_unlock();
1422 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1424 return TBM_SURFACE_QUEUE_ERROR_NONE;
1427 if (surface_queue->impl && surface_queue->impl->release)
1428 surface_queue->impl->release(surface_queue, node);
1430 _tbm_surface_queue_release(surface_queue, node, 1);
1432 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1433 TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface);
1434 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1435 pthread_mutex_unlock(&surface_queue->lock);
1437 _tbm_surf_queue_mutex_unlock();
1438 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1441 node->type = QUEUE_NODE_TYPE_RELEASE;
1443 pthread_mutex_unlock(&surface_queue->lock);
1444 pthread_cond_signal(&surface_queue->free_cond);
1446 _tbm_surf_queue_mutex_unlock();
1448 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1450 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1452 return TBM_SURFACE_QUEUE_ERROR_NONE;
1455 tbm_surface_queue_error_e
1456 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1457 surface_queue, tbm_surface_h surface)
1462 _tbm_surf_queue_mutex_lock();
1463 _tbm_set_last_result(TBM_ERROR_NONE);
1465 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1466 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1467 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1468 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1470 pthread_mutex_lock(&surface_queue->lock);
1472 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, surface);
1474 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1475 if (node == NULL || queue_type != NODE_LIST) {
1476 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n",
1478 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1479 pthread_mutex_unlock(&surface_queue->lock);
1481 _tbm_surf_queue_mutex_unlock();
1482 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1485 if (surface_queue->impl && surface_queue->impl->enqueue)
1486 surface_queue->impl->enqueue(surface_queue, node);
1488 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1490 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1491 TBM_ERR("enqueue surface but queue is empty node:%p\n", node);
1492 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1493 pthread_mutex_unlock(&surface_queue->lock);
1495 _tbm_surf_queue_mutex_unlock();
1496 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1499 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1501 pthread_mutex_unlock(&surface_queue->lock);
1502 pthread_cond_signal(&surface_queue->dirty_cond);
1504 _tbm_surf_queue_mutex_unlock();
1506 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1508 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1510 return TBM_SURFACE_QUEUE_ERROR_NONE;
1513 tbm_surface_queue_error_e
1514 tbm_surface_queue_acquire(tbm_surface_queue_h
1515 surface_queue, tbm_surface_h *surface)
1519 _tbm_surf_queue_mutex_lock();
1520 _tbm_set_last_result(TBM_ERROR_NONE);
1524 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1525 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1526 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1527 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1529 pthread_mutex_lock(&surface_queue->lock);
1531 if (surface_queue->impl && surface_queue->impl->acquire)
1532 node = surface_queue->impl->acquire(surface_queue);
1534 node = _tbm_surface_queue_acquire(surface_queue);
1536 if (node == NULL || node->surface == NULL) {
1537 TBM_ERR("_queue_node_pop_front failed\n");
1538 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1539 pthread_mutex_unlock(&surface_queue->lock);
1541 _tbm_surf_queue_mutex_unlock();
1542 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1545 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1547 *surface = node->surface;
1549 if (surface_queue->acquire_sync_count == 1) {
1550 tbm_surface_info_s info;
1553 TBM_ERR("start map surface:%p", *surface);
1554 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1555 TBM_ERR("end map surface:%p", *surface);
1556 if (ret == TBM_SURFACE_ERROR_NONE)
1557 tbm_surface_unmap(*surface);
1560 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1562 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)\n", surface_queue, *surface);
1564 pthread_mutex_unlock(&surface_queue->lock);
1566 _tbm_surf_queue_mutex_unlock();
1569 tbm_surface_internal_dump_buffer(*surface, "acquire");
1571 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1573 return TBM_SURFACE_QUEUE_ERROR_NONE;
1577 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1579 _tbm_surf_queue_mutex_lock();
1580 _tbm_set_last_result(TBM_ERROR_NONE);
1582 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1584 pthread_mutex_lock(&surface_queue->lock);
1586 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1588 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1589 pthread_mutex_unlock(&surface_queue->lock);
1590 _tbm_surf_queue_mutex_unlock();
1594 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1595 QUEUE_NODE_TYPE_DEQUEUE)) {
1596 _tbm_surf_queue_mutex_unlock();
1597 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1598 pthread_mutex_unlock(&surface_queue->lock);
1602 pthread_mutex_unlock(&surface_queue->lock);
1603 _tbm_surf_queue_mutex_unlock();
1608 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1610 queue_node *node = NULL, *tmp;
1612 _tbm_surf_queue_mutex_lock();
1613 _tbm_set_last_result(TBM_ERROR_NONE);
1615 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1617 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1619 LIST_DEL(&surface_queue->item_link);
1621 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1622 _queue_delete_node(surface_queue, node);
1624 if (surface_queue->impl && surface_queue->impl->destroy)
1625 surface_queue->impl->destroy(surface_queue);
1627 _notify_emit(surface_queue, &surface_queue->destory_noti);
1629 _notify_remove_all(&surface_queue->destory_noti);
1630 _notify_remove_all(&surface_queue->dequeuable_noti);
1631 _notify_remove_all(&surface_queue->dequeue_noti);
1632 _notify_remove_all(&surface_queue->can_dequeue_noti);
1633 _notify_remove_all(&surface_queue->acquirable_noti);
1634 _notify_remove_all(&surface_queue->reset_noti);
1635 _trace_remove_all(&surface_queue->trace_noti);
1637 pthread_mutex_destroy(&surface_queue->lock);
1639 free(surface_queue);
1641 if (LIST_IS_EMPTY(&g_surf_queue_bufmgr->surf_queue_list))
1642 _deinit_tbm_surf_queue_bufmgr();
1644 _tbm_surf_queue_mutex_unlock();
1647 tbm_surface_queue_error_e
1648 tbm_surface_queue_reset(tbm_surface_queue_h
1649 surface_queue, int width, int height, int format)
1651 queue_node *node = NULL, *tmp;
1653 _tbm_surf_queue_mutex_lock();
1654 _tbm_set_last_result(TBM_ERROR_NONE);
1656 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1657 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1659 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1661 if (width == surface_queue->width && height == surface_queue->height &&
1662 format == surface_queue->format) {
1663 _tbm_surf_queue_mutex_unlock();
1664 return TBM_SURFACE_QUEUE_ERROR_NONE;
1667 pthread_mutex_lock(&surface_queue->lock);
1669 surface_queue->width = width;
1670 surface_queue->height = height;
1671 surface_queue->format = format;
1673 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1674 /* Destory surface and Push to free_queue */
1675 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1676 _queue_delete_node(surface_queue, node);
1678 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1679 node->delete_pending = 1;
1681 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1682 _queue_delete_node(surface_queue, node);
1684 _queue_init(&surface_queue->dirty_queue);
1685 LIST_INITHEAD(&surface_queue->list);
1689 _queue_init(&surface_queue->free_queue);
1691 surface_queue->num_attached = 0;
1693 if (surface_queue->impl && surface_queue->impl->reset)
1694 surface_queue->impl->reset(surface_queue);
1696 pthread_mutex_unlock(&surface_queue->lock);
1697 pthread_cond_signal(&surface_queue->free_cond);
1699 _tbm_surf_queue_mutex_unlock();
1701 _notify_emit(surface_queue, &surface_queue->reset_noti);
1703 return TBM_SURFACE_QUEUE_ERROR_NONE;
1706 tbm_surface_queue_error_e
1707 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1709 _tbm_surf_queue_mutex_lock();
1710 _tbm_set_last_result(TBM_ERROR_NONE);
1712 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1713 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1715 _tbm_surf_queue_mutex_unlock();
1717 _notify_emit(surface_queue, &surface_queue->reset_noti);
1719 return TBM_SURFACE_QUEUE_ERROR_NONE;
1722 tbm_surface_queue_error_e
1723 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1725 _tbm_surf_queue_mutex_lock();
1726 _tbm_set_last_result(TBM_ERROR_NONE);
1728 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1729 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1731 pthread_mutex_lock(&surface_queue->lock);
1732 pthread_mutex_unlock(&surface_queue->lock);
1733 pthread_cond_signal(&surface_queue->free_cond);
1735 _tbm_surf_queue_mutex_unlock();
1737 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1739 return TBM_SURFACE_QUEUE_ERROR_NONE;
1742 tbm_surface_queue_error_e
1743 tbm_surface_queue_set_size(tbm_surface_queue_h
1744 surface_queue, int queue_size, int flush)
1746 queue_node *node = NULL, *tmp;
1748 _tbm_surf_queue_mutex_lock();
1749 _tbm_set_last_result(TBM_ERROR_NONE);
1751 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1752 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1753 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1754 TBM_ERROR_INVALID_PARAMETER);
1756 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1758 if ((surface_queue->queue_size == queue_size) && !flush) {
1759 _tbm_surf_queue_mutex_unlock();
1760 return TBM_SURFACE_QUEUE_ERROR_NONE;
1763 pthread_mutex_lock(&surface_queue->lock);
1766 surface_queue->queue_size = queue_size;
1768 if (surface_queue->num_attached == 0) {
1769 pthread_mutex_unlock(&surface_queue->lock);
1770 _tbm_surf_queue_mutex_unlock();
1771 return TBM_SURFACE_QUEUE_ERROR_NONE;
1774 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1775 /* Destory surface and Push to free_queue */
1776 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1777 _queue_delete_node(surface_queue, node);
1779 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1780 node->delete_pending = 1;
1782 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1783 _queue_delete_node(surface_queue, node);
1785 _queue_init(&surface_queue->dirty_queue);
1786 LIST_INITHEAD(&surface_queue->list);
1790 _queue_init(&surface_queue->free_queue);
1792 surface_queue->num_attached = 0;
1794 if (surface_queue->impl && surface_queue->impl->reset)
1795 surface_queue->impl->reset(surface_queue);
1797 pthread_mutex_unlock(&surface_queue->lock);
1798 pthread_cond_signal(&surface_queue->free_cond);
1800 _tbm_surf_queue_mutex_unlock();
1802 _notify_emit(surface_queue, &surface_queue->reset_noti);
1804 return TBM_SURFACE_QUEUE_ERROR_NONE;
1806 if (surface_queue->queue_size > queue_size) {
1807 int need_del = surface_queue->queue_size - queue_size;
1809 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1810 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1812 if (surface_queue->impl && surface_queue->impl->need_detach)
1813 surface_queue->impl->need_detach(surface_queue, node);
1815 _tbm_surface_queue_detach(surface_queue, node->surface);
1823 surface_queue->queue_size = queue_size;
1825 pthread_mutex_unlock(&surface_queue->lock);
1827 _tbm_surf_queue_mutex_unlock();
1829 return TBM_SURFACE_QUEUE_ERROR_NONE;
1833 tbm_surface_queue_error_e
1834 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1836 queue_node *node = NULL;
1838 _tbm_surf_queue_mutex_lock();
1839 _tbm_set_last_result(TBM_ERROR_NONE);
1841 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1842 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1844 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1846 if (surface_queue->num_attached == 0) {
1847 _tbm_surf_queue_mutex_unlock();
1848 return TBM_SURFACE_QUEUE_ERROR_NONE;
1851 pthread_mutex_lock(&surface_queue->lock);
1853 /* Destory surface in free_queue */
1854 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1855 if (surface_queue->impl && surface_queue->impl->need_detach)
1856 surface_queue->impl->need_detach(surface_queue, node);
1858 _tbm_surface_queue_detach(surface_queue, node->surface);
1862 _queue_init(&surface_queue->free_queue);
1864 pthread_mutex_unlock(&surface_queue->lock);
1865 _tbm_surf_queue_mutex_unlock();
1867 return TBM_SURFACE_QUEUE_ERROR_NONE;
1870 tbm_surface_queue_error_e
1871 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1873 queue_node *node = NULL, *tmp;
1875 _tbm_surf_queue_mutex_lock();
1876 _tbm_set_last_result(TBM_ERROR_NONE);
1878 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1879 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1881 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1883 if (surface_queue->num_attached == 0) {
1884 _tbm_surf_queue_mutex_unlock();
1885 return TBM_SURFACE_QUEUE_ERROR_NONE;
1888 pthread_mutex_lock(&surface_queue->lock);
1890 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1891 /* Destory surface and Push to free_queue */
1892 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1893 _queue_delete_node(surface_queue, node);
1895 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1896 node->delete_pending = 1;
1898 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1899 _queue_delete_node(surface_queue, node);
1901 _queue_init(&surface_queue->dirty_queue);
1902 LIST_INITHEAD(&surface_queue->list);
1906 _queue_init(&surface_queue->free_queue);
1908 surface_queue->num_attached = 0;
1910 if (surface_queue->impl && surface_queue->impl->reset)
1911 surface_queue->impl->reset(surface_queue);
1913 pthread_mutex_unlock(&surface_queue->lock);
1914 pthread_cond_signal(&surface_queue->free_cond);
1916 _tbm_surf_queue_mutex_unlock();
1918 _notify_emit(surface_queue, &surface_queue->reset_noti);
1920 return TBM_SURFACE_QUEUE_ERROR_NONE;
1923 tbm_surface_queue_error_e
1924 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1925 tbm_surface_h *surfaces, int *num)
1927 queue_node *node = NULL;
1929 _tbm_surf_queue_mutex_lock();
1930 _tbm_set_last_result(TBM_ERROR_NONE);
1932 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1933 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1934 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1935 TBM_ERROR_INVALID_PARAMETER);
1939 pthread_mutex_lock(&surface_queue->lock);
1941 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1942 if (node->delete_pending) continue;
1945 surfaces[*num] = node->surface;
1950 pthread_mutex_unlock(&surface_queue->lock);
1952 _tbm_surf_queue_mutex_unlock();
1954 return TBM_SURFACE_QUEUE_ERROR_NONE;
1957 tbm_surface_queue_error_e
1958 tbm_surface_queue_get_trace_surface_num(
1959 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1961 _tbm_surf_queue_mutex_lock();
1962 _tbm_set_last_result(TBM_ERROR_NONE);
1964 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1965 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1966 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1967 TBM_ERROR_INVALID_PARAMETER);
1971 pthread_mutex_lock(&surface_queue->lock);
1974 case TBM_SURFACE_QUEUE_TRACE_NONE:
1977 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1978 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1980 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1981 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1983 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1984 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1986 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1987 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1993 pthread_mutex_unlock(&surface_queue->lock);
1995 _tbm_surf_queue_mutex_unlock();
1997 return TBM_SURFACE_QUEUE_ERROR_NONE;
2002 } tbm_queue_default;
2005 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
2007 free(surface_queue->impl_data);
2011 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
2013 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
2014 tbm_surface_h surface;
2016 if (surface_queue->queue_size == surface_queue->num_attached)
2019 if (surface_queue->alloc_cb) {
2020 pthread_mutex_unlock(&surface_queue->lock);
2021 _tbm_surf_queue_mutex_unlock();
2022 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2023 _tbm_surf_queue_mutex_lock();
2024 pthread_mutex_lock(&surface_queue->lock);
2030 tbm_surface_internal_ref(surface);
2032 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2033 surface_queue->height,
2034 surface_queue->format,
2036 TBM_RETURN_IF_FAIL(surface != NULL);
2039 _tbm_surface_queue_attach(surface_queue, surface);
2040 tbm_surface_internal_unref(surface);
2043 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2044 NULL, /*__tbm_queue_default_init*/
2045 NULL, /*__tbm_queue_default_reset*/
2046 __tbm_queue_default_destroy,
2047 __tbm_queue_default_need_attach,
2048 NULL, /*__tbm_queue_default_enqueue*/
2049 NULL, /*__tbm_queue_default_release*/
2050 NULL, /*__tbm_queue_default_dequeue*/
2051 NULL, /*__tbm_queue_default_acquire*/
2052 NULL, /*__tbm_queue_default_need_detach*/
2056 tbm_surface_queue_create(int queue_size, int width,
2057 int height, int format, int flags)
2059 _tbm_surf_queue_mutex_lock();
2060 _tbm_set_last_result(TBM_ERROR_NONE);
2062 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2063 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2064 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2065 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2067 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2068 sizeof(struct _tbm_surface_queue));
2069 if (!surface_queue) {
2070 TBM_ERR("cannot allocate the surface_queue.\n");
2071 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2072 _tbm_surf_queue_mutex_unlock();
2076 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2078 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2079 sizeof(tbm_queue_default));
2081 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2082 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2083 free(surface_queue);
2084 _tbm_surf_queue_mutex_unlock();
2088 data->flags = flags;
2089 _tbm_surface_queue_init(surface_queue,
2091 width, height, format,
2092 &tbm_queue_default_impl, data);
2094 _tbm_surf_queue_mutex_unlock();
2096 return surface_queue;
2102 } tbm_queue_sequence;
2105 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2107 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2109 _queue_init(&data->dequeue_list);
2113 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2115 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2117 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2120 _queue_init(&data->dequeue_list);
2124 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2126 free(surface_queue->impl_data);
2130 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2132 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2133 tbm_surface_h surface;
2135 if (surface_queue->queue_size == surface_queue->num_attached)
2138 if (surface_queue->alloc_cb) {
2139 pthread_mutex_unlock(&surface_queue->lock);
2140 _tbm_surf_queue_mutex_unlock();
2141 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2142 _tbm_surf_queue_mutex_lock();
2143 pthread_mutex_lock(&surface_queue->lock);
2149 tbm_surface_internal_ref(surface);
2151 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2152 surface_queue->height,
2153 surface_queue->format,
2155 TBM_RETURN_IF_FAIL(surface != NULL);
2158 _tbm_surface_queue_attach(surface_queue, surface);
2159 tbm_surface_internal_unref(surface);
2163 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2166 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2167 queue_node *first = NULL;
2169 first = container_of(data->dequeue_list.head.next, first, item_link);
2170 if (first != node) {
2174 node->priv_flags = 0;
2176 _queue_node_pop(&data->dequeue_list, node);
2177 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2181 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2184 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2186 if (node->priv_flags) {
2187 node->priv_flags = 0;
2188 _queue_node_pop(&data->dequeue_list, node);
2191 _tbm_surface_queue_release(surface_queue, node, 1);
2195 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2198 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2201 node = _tbm_surface_queue_dequeue(surface_queue);
2203 _queue_node_push_back(&data->dequeue_list, node);
2204 node->priv_flags = 1;
2210 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2211 __tbm_queue_sequence_init,
2212 __tbm_queue_sequence_reset,
2213 __tbm_queue_sequence_destroy,
2214 __tbm_queue_sequence_need_attach,
2215 __tbm_queue_sequence_enqueue,
2216 __tbm_queue_sequence_release,
2217 __tbm_queue_sequence_dequeue,
2218 NULL, /*__tbm_queue_sequence_acquire*/
2219 NULL, /*__tbm_queue_sequence_need_dettach*/
2223 tbm_surface_queue_sequence_create(int queue_size, int width,
2224 int height, int format, int flags)
2226 _tbm_surf_queue_mutex_lock();
2227 _tbm_set_last_result(TBM_ERROR_NONE);
2229 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2230 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2231 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2232 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2234 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2235 sizeof(struct _tbm_surface_queue));
2236 if (surface_queue == NULL) {
2237 TBM_ERR("cannot allocate the surface_queue.\n");
2238 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2239 _tbm_surf_queue_mutex_unlock();
2243 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2245 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2246 sizeof(tbm_queue_sequence));
2248 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2249 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2250 free(surface_queue);
2251 _tbm_surf_queue_mutex_unlock();
2255 data->flags = flags;
2256 _tbm_surface_queue_init(surface_queue,
2258 width, height, format,
2259 &tbm_queue_sequence_impl, data);
2261 _tbm_surf_queue_mutex_unlock();
2263 return surface_queue;
2266 tbm_surface_queue_error_e
2267 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2270 _tbm_surf_queue_mutex_lock();
2271 _tbm_set_last_result(TBM_ERROR_NONE);
2273 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2274 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2276 pthread_mutex_lock(&surface_queue->lock);
2278 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2279 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2281 surface_queue->modes |= modes;
2283 pthread_mutex_unlock(&surface_queue->lock);
2285 _tbm_surf_queue_mutex_unlock();
2287 return TBM_SURFACE_QUEUE_ERROR_NONE;
2290 tbm_surface_queue_error_e
2291 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2292 unsigned int sync_count)
2294 int dequeue_num, enqueue_num;
2296 _tbm_surf_queue_mutex_lock();
2297 _tbm_set_last_result(TBM_ERROR_NONE);
2299 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2300 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2302 pthread_mutex_lock(&surface_queue->lock);
2304 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2305 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2307 if (dequeue_num + sync_count == 0)
2308 surface_queue->acquire_sync_count = enqueue_num;
2310 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2312 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2313 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2315 pthread_mutex_unlock(&surface_queue->lock);
2317 _tbm_surf_queue_mutex_unlock();
2319 return TBM_SURFACE_QUEUE_ERROR_NONE;