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 surface_queue->queue_size = queue_size;
1765 if (surface_queue->num_attached == 0) {
1766 pthread_mutex_unlock(&surface_queue->lock);
1767 _tbm_surf_queue_mutex_unlock();
1768 return TBM_SURFACE_QUEUE_ERROR_NONE;
1771 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1772 /* Destory surface and Push to free_queue */
1773 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1774 _queue_delete_node(surface_queue, node);
1776 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1777 node->delete_pending = 1;
1779 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1780 _queue_delete_node(surface_queue, node);
1782 _queue_init(&surface_queue->dirty_queue);
1783 LIST_INITHEAD(&surface_queue->list);
1787 _queue_init(&surface_queue->free_queue);
1789 surface_queue->num_attached = 0;
1791 if (surface_queue->impl && surface_queue->impl->reset)
1792 surface_queue->impl->reset(surface_queue);
1794 pthread_mutex_unlock(&surface_queue->lock);
1795 pthread_cond_signal(&surface_queue->free_cond);
1797 _tbm_surf_queue_mutex_unlock();
1799 _notify_emit(surface_queue, &surface_queue->reset_noti);
1801 return TBM_SURFACE_QUEUE_ERROR_NONE;
1803 if (surface_queue->queue_size > queue_size) {
1804 int need_del = surface_queue->queue_size - queue_size;
1806 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1807 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)\n", surface_queue, node->surface);
1809 if (surface_queue->impl && surface_queue->impl->need_detach)
1810 surface_queue->impl->need_detach(surface_queue, node);
1812 _tbm_surface_queue_detach(surface_queue, node->surface);
1820 surface_queue->queue_size = queue_size;
1822 pthread_mutex_unlock(&surface_queue->lock);
1824 _tbm_surf_queue_mutex_unlock();
1826 return TBM_SURFACE_QUEUE_ERROR_NONE;
1830 tbm_surface_queue_error_e
1831 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1833 queue_node *node = NULL;
1835 _tbm_surf_queue_mutex_lock();
1836 _tbm_set_last_result(TBM_ERROR_NONE);
1838 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1839 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1841 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1843 if (surface_queue->num_attached == 0) {
1844 _tbm_surf_queue_mutex_unlock();
1845 return TBM_SURFACE_QUEUE_ERROR_NONE;
1848 pthread_mutex_lock(&surface_queue->lock);
1850 /* Destory surface in free_queue */
1851 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1852 if (surface_queue->impl && surface_queue->impl->need_detach)
1853 surface_queue->impl->need_detach(surface_queue, node);
1855 _tbm_surface_queue_detach(surface_queue, node->surface);
1859 _queue_init(&surface_queue->free_queue);
1861 pthread_mutex_unlock(&surface_queue->lock);
1862 _tbm_surf_queue_mutex_unlock();
1864 return TBM_SURFACE_QUEUE_ERROR_NONE;
1867 tbm_surface_queue_error_e
1868 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
1870 queue_node *node = NULL, *tmp;
1872 _tbm_surf_queue_mutex_lock();
1873 _tbm_set_last_result(TBM_ERROR_NONE);
1875 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1876 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1878 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
1880 if (surface_queue->num_attached == 0) {
1881 _tbm_surf_queue_mutex_unlock();
1882 return TBM_SURFACE_QUEUE_ERROR_NONE;
1885 pthread_mutex_lock(&surface_queue->lock);
1887 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1888 /* Destory surface and Push to free_queue */
1889 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1890 _queue_delete_node(surface_queue, node);
1892 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1893 node->delete_pending = 1;
1895 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1896 _queue_delete_node(surface_queue, node);
1898 _queue_init(&surface_queue->dirty_queue);
1899 LIST_INITHEAD(&surface_queue->list);
1903 _queue_init(&surface_queue->free_queue);
1905 surface_queue->num_attached = 0;
1907 if (surface_queue->impl && surface_queue->impl->reset)
1908 surface_queue->impl->reset(surface_queue);
1910 pthread_mutex_unlock(&surface_queue->lock);
1911 pthread_cond_signal(&surface_queue->free_cond);
1913 _tbm_surf_queue_mutex_unlock();
1915 _notify_emit(surface_queue, &surface_queue->reset_noti);
1917 return TBM_SURFACE_QUEUE_ERROR_NONE;
1920 tbm_surface_queue_error_e
1921 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
1922 tbm_surface_h *surfaces, int *num)
1924 queue_node *node = NULL;
1926 _tbm_surf_queue_mutex_lock();
1927 _tbm_set_last_result(TBM_ERROR_NONE);
1929 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1930 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1931 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1932 TBM_ERROR_INVALID_PARAMETER);
1936 pthread_mutex_lock(&surface_queue->lock);
1938 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
1939 if (node->delete_pending) continue;
1942 surfaces[*num] = node->surface;
1947 pthread_mutex_unlock(&surface_queue->lock);
1949 _tbm_surf_queue_mutex_unlock();
1951 return TBM_SURFACE_QUEUE_ERROR_NONE;
1954 tbm_surface_queue_error_e
1955 tbm_surface_queue_get_trace_surface_num(
1956 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
1958 _tbm_surf_queue_mutex_lock();
1959 _tbm_set_last_result(TBM_ERROR_NONE);
1961 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1962 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1963 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
1964 TBM_ERROR_INVALID_PARAMETER);
1968 pthread_mutex_lock(&surface_queue->lock);
1971 case TBM_SURFACE_QUEUE_TRACE_NONE:
1974 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
1975 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
1977 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
1978 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
1980 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
1981 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
1983 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
1984 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
1990 pthread_mutex_unlock(&surface_queue->lock);
1992 _tbm_surf_queue_mutex_unlock();
1994 return TBM_SURFACE_QUEUE_ERROR_NONE;
1999 } tbm_queue_default;
2002 __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
2004 free(surface_queue->impl_data);
2008 __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
2010 tbm_queue_default *data = (tbm_queue_default *)surface_queue->impl_data;
2011 tbm_surface_h surface;
2013 if (surface_queue->queue_size == surface_queue->num_attached)
2016 if (surface_queue->alloc_cb) {
2017 pthread_mutex_unlock(&surface_queue->lock);
2018 _tbm_surf_queue_mutex_unlock();
2019 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2020 _tbm_surf_queue_mutex_lock();
2021 pthread_mutex_lock(&surface_queue->lock);
2027 tbm_surface_internal_ref(surface);
2029 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2030 surface_queue->height,
2031 surface_queue->format,
2033 TBM_RETURN_IF_FAIL(surface != NULL);
2036 _tbm_surface_queue_attach(surface_queue, surface);
2037 tbm_surface_internal_unref(surface);
2040 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2041 NULL, /*__tbm_queue_default_init*/
2042 NULL, /*__tbm_queue_default_reset*/
2043 __tbm_queue_default_destroy,
2044 __tbm_queue_default_need_attach,
2045 NULL, /*__tbm_queue_default_enqueue*/
2046 NULL, /*__tbm_queue_default_release*/
2047 NULL, /*__tbm_queue_default_dequeue*/
2048 NULL, /*__tbm_queue_default_acquire*/
2049 NULL, /*__tbm_queue_default_need_detach*/
2053 tbm_surface_queue_create(int queue_size, int width,
2054 int height, int format, int flags)
2056 _tbm_surf_queue_mutex_lock();
2057 _tbm_set_last_result(TBM_ERROR_NONE);
2059 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2060 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2061 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2062 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2064 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2065 sizeof(struct _tbm_surface_queue));
2066 if (!surface_queue) {
2067 TBM_ERR("cannot allocate the surface_queue.\n");
2068 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2069 _tbm_surf_queue_mutex_unlock();
2073 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2075 tbm_queue_default *data = (tbm_queue_default *) calloc(1,
2076 sizeof(tbm_queue_default));
2078 TBM_ERR("cannot allocate the tbm_queue_default.\n");
2079 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2080 free(surface_queue);
2081 _tbm_surf_queue_mutex_unlock();
2085 data->flags = flags;
2086 _tbm_surface_queue_init(surface_queue,
2088 width, height, format,
2089 &tbm_queue_default_impl, data);
2091 _tbm_surf_queue_mutex_unlock();
2093 return surface_queue;
2099 } tbm_queue_sequence;
2102 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2104 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2106 _queue_init(&data->dequeue_list);
2110 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2112 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2114 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2117 _queue_init(&data->dequeue_list);
2121 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2123 free(surface_queue->impl_data);
2127 __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
2129 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2130 tbm_surface_h surface;
2132 if (surface_queue->queue_size == surface_queue->num_attached)
2135 if (surface_queue->alloc_cb) {
2136 pthread_mutex_unlock(&surface_queue->lock);
2137 _tbm_surf_queue_mutex_unlock();
2138 surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data);
2139 _tbm_surf_queue_mutex_lock();
2140 pthread_mutex_lock(&surface_queue->lock);
2146 tbm_surface_internal_ref(surface);
2148 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
2149 surface_queue->height,
2150 surface_queue->format,
2152 TBM_RETURN_IF_FAIL(surface != NULL);
2155 _tbm_surface_queue_attach(surface_queue, surface);
2156 tbm_surface_internal_unref(surface);
2160 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2163 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2164 queue_node *first = NULL;
2166 first = container_of(data->dequeue_list.head.next, first, item_link);
2167 if (first != node) {
2171 node->priv_flags = 0;
2173 _queue_node_pop(&data->dequeue_list, node);
2174 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2178 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2181 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2183 if (node->priv_flags) {
2184 node->priv_flags = 0;
2185 _queue_node_pop(&data->dequeue_list, node);
2188 _tbm_surface_queue_release(surface_queue, node, 1);
2192 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2195 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2198 node = _tbm_surface_queue_dequeue(surface_queue);
2200 _queue_node_push_back(&data->dequeue_list, node);
2201 node->priv_flags = 1;
2207 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2208 __tbm_queue_sequence_init,
2209 __tbm_queue_sequence_reset,
2210 __tbm_queue_sequence_destroy,
2211 __tbm_queue_sequence_need_attach,
2212 __tbm_queue_sequence_enqueue,
2213 __tbm_queue_sequence_release,
2214 __tbm_queue_sequence_dequeue,
2215 NULL, /*__tbm_queue_sequence_acquire*/
2216 NULL, /*__tbm_queue_sequence_need_dettach*/
2220 tbm_surface_queue_sequence_create(int queue_size, int width,
2221 int height, int format, int flags)
2223 _tbm_surf_queue_mutex_lock();
2224 _tbm_set_last_result(TBM_ERROR_NONE);
2226 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2227 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2228 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2229 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2231 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2232 sizeof(struct _tbm_surface_queue));
2233 if (surface_queue == NULL) {
2234 TBM_ERR("cannot allocate the surface_queue.\n");
2235 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2236 _tbm_surf_queue_mutex_unlock();
2240 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue);
2242 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2243 sizeof(tbm_queue_sequence));
2245 TBM_ERR("cannot allocate the tbm_queue_sequence.\n");
2246 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2247 free(surface_queue);
2248 _tbm_surf_queue_mutex_unlock();
2252 data->flags = flags;
2253 _tbm_surface_queue_init(surface_queue,
2255 width, height, format,
2256 &tbm_queue_sequence_impl, data);
2258 _tbm_surf_queue_mutex_unlock();
2260 return surface_queue;
2263 tbm_surface_queue_error_e
2264 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2267 _tbm_surf_queue_mutex_lock();
2268 _tbm_set_last_result(TBM_ERROR_NONE);
2270 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2271 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2273 pthread_mutex_lock(&surface_queue->lock);
2275 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2276 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2278 surface_queue->modes |= modes;
2280 pthread_mutex_unlock(&surface_queue->lock);
2282 _tbm_surf_queue_mutex_unlock();
2284 return TBM_SURFACE_QUEUE_ERROR_NONE;
2287 tbm_surface_queue_error_e
2288 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2289 unsigned int sync_count)
2291 int dequeue_num, enqueue_num;
2293 _tbm_surf_queue_mutex_lock();
2294 _tbm_set_last_result(TBM_ERROR_NONE);
2296 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2297 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2299 pthread_mutex_lock(&surface_queue->lock);
2301 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2302 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2304 if (dequeue_num + sync_count == 0)
2305 surface_queue->acquire_sync_count = enqueue_num;
2307 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2309 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)\n",
2310 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2312 pthread_mutex_unlock(&surface_queue->lock);
2314 _tbm_surf_queue_mutex_unlock();
2316 return TBM_SURFACE_QUEUE_ERROR_NONE;