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"
42 #define TBM_SURFACE_QUEUE_MAGIC 0xBF031234
44 static pthread_mutex_t tbm_surf_queue_lock = PTHREAD_MUTEX_INITIALIZER;
45 void _tbm_surface_queue_mutex_unlock(void);
48 #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\
50 TBM_ERR("'%s' failed.", #cond);\
51 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
52 _tbm_surf_queue_mutex_unlock();\
57 #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\
59 TBM_ERR("'%s' failed.", #cond);\
60 _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\
61 _tbm_surf_queue_mutex_unlock();\
66 typedef enum _queue_node_type {
68 QUEUE_NODE_TYPE_DEQUEUE,
69 QUEUE_NODE_TYPE_ENQUEUE,
70 QUEUE_NODE_TYPE_ACQUIRE,
71 QUEUE_NODE_TYPE_RELEASE
75 struct list_head head;
80 tbm_surface_h surface;
82 struct list_head item_link;
83 struct list_head link;
87 unsigned int priv_flags; /*for each queue*/
93 struct list_head link;
95 tbm_surface_queue_notify_cb cb;
100 struct list_head link;
102 tbm_surface_queue_trace_cb cb;
106 typedef struct _tbm_surface_queue_interface {
107 void (*init)(tbm_surface_queue_h queue);
108 void (*reset)(tbm_surface_queue_h queue);
109 void (*destroy)(tbm_surface_queue_h queue);
110 void (*need_attach)(tbm_surface_queue_h queue);
112 void (*enqueue)(tbm_surface_queue_h queue, queue_node *node);
113 void (*release)(tbm_surface_queue_h queue, queue_node *node);
114 queue_node *(*dequeue)(tbm_surface_queue_h queue);
115 queue_node *(*acquire)(tbm_surface_queue_h queue);
116 void (*need_detach)(tbm_surface_queue_h queue, queue_node *node);
117 } tbm_surface_queue_interface;
119 struct _tbm_surface_queue {
130 struct list_head list;
132 struct list_head destory_noti;
133 struct list_head dequeuable_noti;
134 struct list_head dequeue_noti;
135 struct list_head can_dequeue_noti;
136 struct list_head acquirable_noti;
137 struct list_head reset_noti;
138 struct list_head trace_noti;
140 pthread_mutex_t lock;
141 pthread_cond_t free_cond;
142 pthread_cond_t dirty_cond;
144 const tbm_surface_queue_interface *impl;
147 //For external buffer allocation
148 tbm_surface_alloc_cb alloc_cb;
149 tbm_surface_alloc_cb2 alloc_cb2;
150 tbm_surface_free_cb free_cb;
154 unsigned int enqueue_sync_count;
155 unsigned int acquire_sync_count;
159 _tbm_surf_queue_mutex_lock(void)
161 pthread_mutex_lock(&tbm_surf_queue_lock);
165 _tbm_surf_queue_mutex_unlock(void)
167 pthread_mutex_unlock(&tbm_surf_queue_lock);
171 _tbm_surface_queue_magic_check(tbm_surface_queue_h surface_queue)
173 if (surface_queue->magic != TBM_SURFACE_QUEUE_MAGIC)
180 _tbm_surface_queue_is_valid(tbm_surface_queue_h surface_queue)
182 if (!surface_queue) {
183 TBM_ERR("error: surface_queue is NULL.");
187 if (!_tbm_surface_queue_magic_check(surface_queue)) {
188 TBM_ERR("error: Invalid tbm_surface_queue(%p)", surface_queue);
196 _queue_node_create(void)
198 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
200 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
206 _queue_node_delete(queue_node *node)
208 LIST_DEL(&node->item_link);
209 LIST_DEL(&node->link);
214 _queue_is_empty(queue *queue)
216 if (LIST_IS_EMPTY(&queue->head))
223 _queue_node_push_back(queue *queue, queue_node *node)
225 LIST_ADDTAIL(&node->item_link, &queue->head);
230 _queue_node_push_front(queue *queue, queue_node *node)
232 LIST_ADD(&node->item_link, &queue->head);
237 _queue_node_pop_front(queue *queue)
241 if (!queue->head.next) return NULL;
242 if (!queue->count) return NULL;
244 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
246 LIST_DELINIT(&node->item_link);
253 _queue_node_pop(queue *queue, queue_node *node)
255 LIST_DELINIT(&node->item_link);
262 _queue_get_node(tbm_surface_queue_h surface_queue, int type,
263 tbm_surface_h surface, int *out_type)
265 queue_node *node = NULL;
268 type = FREE_QUEUE | DIRTY_QUEUE | NODE_LIST;
272 if (type & FREE_QUEUE) {
273 LIST_FOR_EACH_ENTRY(node, &surface_queue->free_queue.head,
275 if (node->surface == surface) {
277 *out_type = FREE_QUEUE;
284 if (type & DIRTY_QUEUE) {
285 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head,
287 if (node->surface == surface) {
289 *out_type = DIRTY_QUEUE;
296 if (type & NODE_LIST) {
297 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
298 if (node->surface == surface) {
300 *out_type = NODE_LIST;
307 TBM_ERR("fail to get the queue_node.");
313 _queue_delete_node(tbm_surface_queue_h surface_queue, queue_node *node)
316 if (surface_queue->free_cb) {
317 surface_queue->free_cb(surface_queue,
318 surface_queue->alloc_cb_data,
322 tbm_surface_destroy(node->surface);
325 _queue_node_delete(node);
329 _queue_init(queue *queue)
331 LIST_INITHEAD(&queue->head);
337 _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb,
340 TBM_RETURN_IF_FAIL(cb != NULL);
342 queue_notify *item = (queue_notify *)calloc(1, sizeof(queue_notify));
344 TBM_RETURN_IF_FAIL(item != NULL);
346 LIST_INITHEAD(&item->link);
350 LIST_ADDTAIL(&item->link, list);
354 _notify_remove(struct list_head *list,
355 tbm_surface_queue_notify_cb cb, void *data)
357 queue_notify *item = NULL, *tmp;
359 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
360 if (item->cb == cb && item->data == data) {
361 LIST_DEL(&item->link);
367 TBM_ERR("Cannot find notifiy");
371 _notify_remove_all(struct list_head *list)
373 queue_notify *item = NULL, *tmp;
375 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
376 LIST_DEL(&item->link);
382 _notify_emit(tbm_surface_queue_h surface_queue,
383 struct list_head *list)
385 queue_notify *item = NULL, *tmp;;
388 The item->cb is the outside function of the libtbm.
389 The tbm user may/can remove the item of the list,
390 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
392 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
393 item->cb(surface_queue, item->data);
397 _trace_add(struct list_head *list, tbm_surface_queue_trace_cb cb,
400 TBM_RETURN_IF_FAIL(cb != NULL);
402 queue_trace *item = (queue_trace *)calloc(1, sizeof(queue_trace));
404 TBM_RETURN_IF_FAIL(item != NULL);
406 LIST_INITHEAD(&item->link);
410 LIST_ADDTAIL(&item->link, list);
414 _trace_remove(struct list_head *list,
415 tbm_surface_queue_trace_cb cb, void *data)
417 queue_trace *item = NULL, *tmp;
419 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
420 if (item->cb == cb && item->data == data) {
421 LIST_DEL(&item->link);
427 TBM_ERR("Cannot find notifiy");
431 _trace_remove_all(struct list_head *list)
433 queue_trace *item = NULL, *tmp;
435 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) {
436 LIST_DEL(&item->link);
442 _trace_emit(tbm_surface_queue_h surface_queue,
443 struct list_head *list, tbm_surface_h surface, tbm_surface_queue_trace trace)
445 queue_trace *item = NULL, *tmp;;
448 The item->cb is the outside function of the libtbm.
449 The tbm user may/can remove the item of the list,
450 so we have to use the LIST_FOR_EACH_ENTRY_SAFE.
452 LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link)
453 item->cb(surface_queue, surface, trace, item->data);
457 _tbm_surface_queue_get_node_count(tbm_surface_queue_h surface_queue, Queue_Node_Type type)
459 queue_node *node = NULL;
462 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
463 if (node->type == type)
471 _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue,
472 tbm_surface_h surface)
476 node = _queue_node_create();
477 TBM_RETURN_IF_FAIL(node != NULL);
479 tbm_surface_internal_ref(surface);
480 node->surface = surface;
482 LIST_ADDTAIL(&node->link, &surface_queue->list);
483 surface_queue->num_attached++;
484 _queue_node_push_back(&surface_queue->free_queue, node);
488 _tbm_surface_queue_need_attach(tbm_surface_queue_h surface_queue)
490 tbm_surface_h surface;
492 if (surface_queue->queue_size == surface_queue->num_attached)
495 if (surface_queue->alloc_cb2) {
496 surface = surface_queue->alloc_cb2(surface_queue,
497 surface_queue->width, surface_queue->height,
498 surface_queue->format, surface_queue->flags,
499 surface_queue->alloc_cb_data);
503 tbm_surface_internal_ref(surface);
504 } else if (surface_queue->alloc_cb){
505 surface = surface_queue->alloc_cb(surface_queue,
506 surface_queue->alloc_cb_data);
510 tbm_surface_internal_ref(surface);
512 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
513 surface_queue->height,
514 surface_queue->format,
515 surface_queue->flags);
516 TBM_RETURN_IF_FAIL(surface != NULL);
519 _tbm_surface_queue_attach(surface_queue, surface);
520 tbm_surface_internal_unref(surface);
524 _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue,
525 tbm_surface_h surface)
530 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
532 _queue_delete_node(surface_queue, node);
533 surface_queue->num_attached--;
538 _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue,
539 queue_node *node, int push_back)
542 _queue_node_push_back(&surface_queue->dirty_queue, node);
544 _queue_node_push_front(&surface_queue->dirty_queue, node);
548 _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
552 node = _queue_node_pop_front(&surface_queue->free_queue);
558 _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
562 if (_queue_is_empty(&surface_queue->dirty_queue))
565 node = _queue_node_pop_front(&surface_queue->dirty_queue);
571 _tbm_surface_queue_release(tbm_surface_queue_h surface_queue,
572 queue_node *node, int push_back)
575 _queue_node_push_back(&surface_queue->free_queue, node);
577 _queue_node_push_front(&surface_queue->free_queue, node);
581 _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
583 int width, int height, int format, int flags,
584 const tbm_surface_queue_interface *impl, void *data)
586 pthread_condattr_t free_attr, dirty_attr;
588 TBM_RETURN_IF_FAIL(surface_queue != NULL);
589 TBM_RETURN_IF_FAIL(impl != NULL);
591 pthread_mutex_init(&surface_queue->lock, NULL);
593 pthread_condattr_init(&free_attr);
594 pthread_condattr_setclock(&free_attr, CLOCK_MONOTONIC);
595 pthread_cond_init(&surface_queue->free_cond, &free_attr);
596 pthread_condattr_destroy(&free_attr);
598 pthread_condattr_init(&dirty_attr);
599 pthread_condattr_setclock(&dirty_attr, CLOCK_MONOTONIC);
600 pthread_cond_init(&surface_queue->dirty_cond, &dirty_attr);
601 pthread_condattr_destroy(&dirty_attr);
603 surface_queue->magic = TBM_SURFACE_QUEUE_MAGIC;
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->flags = flags;
609 surface_queue->impl = impl;
610 surface_queue->impl_data = data;
611 surface_queue->modes = TBM_SURFACE_QUEUE_MODE_NONE;
613 _queue_init(&surface_queue->free_queue);
614 _queue_init(&surface_queue->dirty_queue);
615 LIST_INITHEAD(&surface_queue->list);
617 LIST_INITHEAD(&surface_queue->destory_noti);
618 LIST_INITHEAD(&surface_queue->dequeuable_noti);
619 LIST_INITHEAD(&surface_queue->dequeue_noti);
620 LIST_INITHEAD(&surface_queue->can_dequeue_noti);
621 LIST_INITHEAD(&surface_queue->acquirable_noti);
622 LIST_INITHEAD(&surface_queue->reset_noti);
623 LIST_INITHEAD(&surface_queue->trace_noti);
625 if (surface_queue->impl && surface_queue->impl->init)
626 surface_queue->impl->init(surface_queue);
629 tbm_surface_queue_error_e
630 tbm_surface_queue_add_destroy_cb(
631 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
634 _tbm_surf_queue_mutex_lock();
635 _tbm_set_last_result(TBM_ERROR_NONE);
637 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
638 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
639 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(destroy_cb,
640 TBM_ERROR_INVALID_PARAMETER);
642 pthread_mutex_lock(&surface_queue->lock);
644 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
646 _notify_add(&surface_queue->destory_noti, destroy_cb, data);
648 pthread_mutex_unlock(&surface_queue->lock);
650 _tbm_surf_queue_mutex_unlock();
652 return TBM_SURFACE_QUEUE_ERROR_NONE;
655 tbm_surface_queue_error_e
656 tbm_surface_queue_remove_destroy_cb(
657 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb,
660 _tbm_surf_queue_mutex_lock();
661 _tbm_set_last_result(TBM_ERROR_NONE);
663 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
664 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
666 pthread_mutex_lock(&surface_queue->lock);
668 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
670 _notify_remove(&surface_queue->destory_noti, destroy_cb, data);
672 pthread_mutex_unlock(&surface_queue->lock);
674 _tbm_surf_queue_mutex_unlock();
676 return TBM_SURFACE_QUEUE_ERROR_NONE;
679 tbm_surface_queue_error_e
680 tbm_surface_queue_add_dequeuable_cb(
681 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
684 _tbm_surf_queue_mutex_lock();
685 _tbm_set_last_result(TBM_ERROR_NONE);
687 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
688 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
689 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeuable_cb,
690 TBM_ERROR_INVALID_PARAMETER);
692 pthread_mutex_lock(&surface_queue->lock);
694 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
696 _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data);
698 pthread_mutex_unlock(&surface_queue->lock);
700 _tbm_surf_queue_mutex_unlock();
702 return TBM_SURFACE_QUEUE_ERROR_NONE;
705 tbm_surface_queue_error_e
706 tbm_surface_queue_remove_dequeuable_cb(
707 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb,
710 _tbm_surf_queue_mutex_lock();
711 _tbm_set_last_result(TBM_ERROR_NONE);
713 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
714 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
716 pthread_mutex_lock(&surface_queue->lock);
718 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
720 _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data);
722 pthread_mutex_unlock(&surface_queue->lock);
724 _tbm_surf_queue_mutex_unlock();
726 return TBM_SURFACE_QUEUE_ERROR_NONE;
729 tbm_surface_queue_error_e
730 tbm_surface_queue_add_dequeue_cb(
731 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
734 _tbm_surf_queue_mutex_lock();
735 _tbm_set_last_result(TBM_ERROR_NONE);
737 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
738 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
739 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(dequeue_cb,
740 TBM_ERROR_INVALID_PARAMETER);
742 pthread_mutex_lock(&surface_queue->lock);
744 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
746 _notify_add(&surface_queue->dequeue_noti, dequeue_cb, data);
748 pthread_mutex_unlock(&surface_queue->lock);
750 _tbm_surf_queue_mutex_unlock();
752 return TBM_SURFACE_QUEUE_ERROR_NONE;
755 tbm_surface_queue_error_e
756 tbm_surface_queue_remove_dequeue_cb(
757 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeue_cb,
760 _tbm_surf_queue_mutex_lock();
761 _tbm_set_last_result(TBM_ERROR_NONE);
763 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
764 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
766 pthread_mutex_lock(&surface_queue->lock);
768 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
770 _notify_remove(&surface_queue->dequeue_noti, dequeue_cb, data);
772 pthread_mutex_unlock(&surface_queue->lock);
774 _tbm_surf_queue_mutex_unlock();
776 return TBM_SURFACE_QUEUE_ERROR_NONE;
779 tbm_surface_queue_error_e
780 tbm_surface_queue_add_can_dequeue_cb(
781 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
784 _tbm_surf_queue_mutex_lock();
785 _tbm_set_last_result(TBM_ERROR_NONE);
787 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
788 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
789 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(can_dequeue_cb,
790 TBM_ERROR_INVALID_PARAMETER);
792 pthread_mutex_lock(&surface_queue->lock);
794 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
796 _notify_add(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
798 pthread_mutex_unlock(&surface_queue->lock);
800 _tbm_surf_queue_mutex_unlock();
802 return TBM_SURFACE_QUEUE_ERROR_NONE;
805 tbm_surface_queue_error_e
806 tbm_surface_queue_remove_can_dequeue_cb(
807 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb can_dequeue_cb,
810 _tbm_surf_queue_mutex_lock();
811 _tbm_set_last_result(TBM_ERROR_NONE);
813 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
814 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
816 pthread_mutex_lock(&surface_queue->lock);
818 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
820 _notify_remove(&surface_queue->can_dequeue_noti, can_dequeue_cb, data);
822 pthread_mutex_unlock(&surface_queue->lock);
824 _tbm_surf_queue_mutex_unlock();
826 return TBM_SURFACE_QUEUE_ERROR_NONE;
829 tbm_surface_queue_error_e
830 tbm_surface_queue_add_acquirable_cb(
831 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
834 _tbm_surf_queue_mutex_lock();
835 _tbm_set_last_result(TBM_ERROR_NONE);
837 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
838 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
839 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(acquirable_cb,
840 TBM_ERROR_INVALID_PARAMETER);
842 pthread_mutex_lock(&surface_queue->lock);
844 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
846 _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data);
848 pthread_mutex_unlock(&surface_queue->lock);
850 _tbm_surf_queue_mutex_unlock();
852 return TBM_SURFACE_QUEUE_ERROR_NONE;
855 tbm_surface_queue_error_e
856 tbm_surface_queue_remove_acquirable_cb(
857 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb,
860 _tbm_surf_queue_mutex_lock();
861 _tbm_set_last_result(TBM_ERROR_NONE);
863 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
864 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
866 pthread_mutex_lock(&surface_queue->lock);
868 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
870 _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data);
872 pthread_mutex_unlock(&surface_queue->lock);
874 _tbm_surf_queue_mutex_unlock();
876 return TBM_SURFACE_QUEUE_ERROR_NONE;
879 tbm_surface_queue_error_e
880 tbm_surface_queue_add_trace_cb(
881 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
884 _tbm_surf_queue_mutex_lock();
885 _tbm_set_last_result(TBM_ERROR_NONE);
887 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
888 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
889 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(trace_cb,
890 TBM_ERROR_INVALID_PARAMETER);
892 pthread_mutex_lock(&surface_queue->lock);
894 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
896 _trace_add(&surface_queue->trace_noti, trace_cb, data);
898 pthread_mutex_unlock(&surface_queue->lock);
900 _tbm_surf_queue_mutex_unlock();
902 return TBM_SURFACE_QUEUE_ERROR_NONE;
905 tbm_surface_queue_error_e
906 tbm_surface_queue_remove_trace_cb(
907 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace_cb trace_cb,
910 _tbm_surf_queue_mutex_lock();
911 _tbm_set_last_result(TBM_ERROR_NONE);
913 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
914 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
916 pthread_mutex_lock(&surface_queue->lock);
918 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
920 _trace_remove(&surface_queue->trace_noti, trace_cb, data);
922 pthread_mutex_unlock(&surface_queue->lock);
924 _tbm_surf_queue_mutex_unlock();
926 return TBM_SURFACE_QUEUE_ERROR_NONE;
929 tbm_surface_queue_error_e
930 tbm_surface_queue_set_alloc_cb(
931 tbm_surface_queue_h surface_queue,
932 tbm_surface_alloc_cb alloc_cb,
933 tbm_surface_free_cb free_cb,
936 _tbm_surf_queue_mutex_lock();
937 _tbm_set_last_result(TBM_ERROR_NONE);
939 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
940 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
942 pthread_mutex_lock(&surface_queue->lock);
944 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
946 if (surface_queue->alloc_cb2) {
947 TBM_ERR("must use either alloc_cb or alloc_cb2");
948 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
949 pthread_mutex_unlock(&surface_queue->lock);
950 _tbm_surf_queue_mutex_unlock();
951 return TBM_ERROR_INVALID_OPERATION;
954 surface_queue->alloc_cb = alloc_cb;
955 surface_queue->free_cb = free_cb;
956 surface_queue->alloc_cb_data = data;
958 pthread_mutex_unlock(&surface_queue->lock);
960 _tbm_surf_queue_mutex_unlock();
962 return TBM_SURFACE_QUEUE_ERROR_NONE;
965 tbm_surface_queue_error_e
966 tbm_surface_queue_set_alloc_cb2(
967 tbm_surface_queue_h surface_queue,
968 tbm_surface_alloc_cb2 alloc_cb2,
969 tbm_surface_free_cb free_cb,
972 _tbm_surf_queue_mutex_lock();
973 _tbm_set_last_result(TBM_ERROR_NONE);
975 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
976 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
978 pthread_mutex_lock(&surface_queue->lock);
980 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
982 if (surface_queue->alloc_cb) {
983 TBM_ERR("must use either alloc_cb or alloc_cb2");
984 _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION);
985 pthread_mutex_unlock(&surface_queue->lock);
986 _tbm_surf_queue_mutex_unlock();
987 return TBM_ERROR_INVALID_OPERATION;
990 surface_queue->alloc_cb2 = alloc_cb2;
991 surface_queue->free_cb = free_cb;
992 surface_queue->alloc_cb_data = data;
994 pthread_mutex_unlock(&surface_queue->lock);
996 _tbm_surf_queue_mutex_unlock();
998 return TBM_SURFACE_QUEUE_ERROR_NONE;
1002 tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
1006 _tbm_surf_queue_mutex_lock();
1007 _tbm_set_last_result(TBM_ERROR_NONE);
1009 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1011 pthread_mutex_lock(&surface_queue->lock);
1013 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1015 width = surface_queue->width;
1017 pthread_mutex_unlock(&surface_queue->lock);
1019 _tbm_surf_queue_mutex_unlock();
1025 tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
1029 _tbm_surf_queue_mutex_lock();
1030 _tbm_set_last_result(TBM_ERROR_NONE);
1032 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1034 pthread_mutex_lock(&surface_queue->lock);
1036 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1038 height = surface_queue->height;
1040 pthread_mutex_unlock(&surface_queue->lock);
1042 _tbm_surf_queue_mutex_unlock();
1048 tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
1052 _tbm_surf_queue_mutex_lock();
1053 _tbm_set_last_result(TBM_ERROR_NONE);
1055 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1057 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1059 pthread_mutex_lock(&surface_queue->lock);
1061 format = surface_queue->format;
1063 pthread_mutex_unlock(&surface_queue->lock);
1065 _tbm_surf_queue_mutex_unlock();
1071 tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue)
1075 _tbm_surf_queue_mutex_lock();
1076 _tbm_set_last_result(TBM_ERROR_NONE);
1078 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1080 pthread_mutex_lock(&surface_queue->lock);
1082 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1084 queue_size = surface_queue->queue_size;
1086 pthread_mutex_unlock(&surface_queue->lock);
1088 _tbm_surf_queue_mutex_unlock();
1093 tbm_surface_queue_error_e
1094 tbm_surface_queue_add_reset_cb(
1095 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1098 _tbm_surf_queue_mutex_lock();
1099 _tbm_set_last_result(TBM_ERROR_NONE);
1101 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1102 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1103 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(reset_cb,
1104 TBM_ERROR_INVALID_PARAMETER);
1106 pthread_mutex_lock(&surface_queue->lock);
1108 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1110 _notify_add(&surface_queue->reset_noti, reset_cb, data);
1112 pthread_mutex_unlock(&surface_queue->lock);
1114 _tbm_surf_queue_mutex_unlock();
1116 return TBM_SURFACE_QUEUE_ERROR_NONE;
1119 tbm_surface_queue_error_e
1120 tbm_surface_queue_remove_reset_cb(
1121 tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb,
1124 _tbm_surf_queue_mutex_lock();
1125 _tbm_set_last_result(TBM_ERROR_NONE);
1127 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1128 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1130 pthread_mutex_lock(&surface_queue->lock);
1132 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1134 _notify_remove(&surface_queue->reset_noti, reset_cb, data);
1136 pthread_mutex_unlock(&surface_queue->lock);
1138 _tbm_surf_queue_mutex_unlock();
1140 return TBM_SURFACE_QUEUE_ERROR_NONE;
1143 tbm_surface_queue_error_e
1144 tbm_surface_queue_enqueue(tbm_surface_queue_h
1145 surface_queue, tbm_surface_h surface)
1150 _tbm_surf_queue_mutex_lock();
1151 _tbm_set_last_result(TBM_ERROR_NONE);
1153 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1154 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1155 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1156 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1159 tbm_surface_internal_dump_buffer(surface, "enqueue");
1161 pthread_mutex_lock(&surface_queue->lock);
1163 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)", surface_queue, surface);
1165 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1166 if (node == NULL || queue_type != NODE_LIST) {
1167 TBM_ERR("tbm_surface_queue_enqueue::Surface is existed in free_queue or dirty_queue node:%p, type:%d",
1169 pthread_mutex_unlock(&surface_queue->lock);
1171 _tbm_surf_queue_mutex_unlock();
1174 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1175 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1177 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1178 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1182 if (surface_queue->impl && surface_queue->impl->enqueue)
1183 surface_queue->impl->enqueue(surface_queue, node);
1185 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1187 if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) {
1188 TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue", surface);
1189 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE);
1190 pthread_mutex_unlock(&surface_queue->lock);
1192 _tbm_surf_queue_mutex_unlock();
1193 return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE;
1196 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1198 if (surface_queue->enqueue_sync_count == 1) {
1199 tbm_surface_info_s info;
1202 ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
1203 if (ret == TBM_SURFACE_ERROR_NONE)
1204 tbm_surface_unmap(surface);
1207 if (surface_queue->enqueue_sync_count > 0) surface_queue->enqueue_sync_count--;
1209 pthread_mutex_unlock(&surface_queue->lock);
1210 pthread_cond_signal(&surface_queue->dirty_cond);
1212 _tbm_surf_queue_mutex_unlock();
1214 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_ENQUEUE);
1216 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1218 return TBM_SURFACE_QUEUE_ERROR_NONE;
1221 tbm_surface_queue_error_e
1222 tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h
1223 surface_queue, tbm_surface_h surface)
1228 _tbm_surf_queue_mutex_lock();
1229 _tbm_set_last_result(TBM_ERROR_NONE);
1231 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1232 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1233 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1234 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1236 pthread_mutex_lock(&surface_queue->lock);
1238 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)", surface_queue, surface);
1240 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1241 if (node == NULL || queue_type != NODE_LIST) {
1242 TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d",
1244 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1245 pthread_mutex_unlock(&surface_queue->lock);
1247 _tbm_surf_queue_mutex_unlock();
1248 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1251 if (node->delete_pending) {
1252 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)", surface_queue, node->surface);
1254 _queue_delete_node(surface_queue, node);
1256 pthread_mutex_unlock(&surface_queue->lock);
1258 _tbm_surf_queue_mutex_unlock();
1260 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1262 return TBM_SURFACE_QUEUE_ERROR_NONE;
1265 if (surface_queue->queue_size < surface_queue->num_attached) {
1266 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)", surface_queue, node->surface);
1268 if (surface_queue->impl && surface_queue->impl->need_detach)
1269 surface_queue->impl->need_detach(surface_queue, node);
1271 _tbm_surface_queue_detach(surface_queue, surface);
1273 pthread_mutex_unlock(&surface_queue->lock);
1275 _tbm_surf_queue_mutex_unlock();
1277 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1279 return TBM_SURFACE_QUEUE_ERROR_NONE;
1282 if (surface_queue->impl && surface_queue->impl->release)
1283 surface_queue->impl->release(surface_queue, node);
1285 _tbm_surface_queue_release(surface_queue, node, 1);
1287 if (_queue_is_empty(&surface_queue->free_queue)) {
1288 TBM_ERR("surface_queue->free_queue is empty.");
1289 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1290 pthread_mutex_unlock(&surface_queue->lock);
1292 _tbm_surf_queue_mutex_unlock();
1293 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
1296 node->type = QUEUE_NODE_TYPE_RELEASE;
1298 pthread_mutex_unlock(&surface_queue->lock);
1299 pthread_cond_signal(&surface_queue->free_cond);
1301 _tbm_surf_queue_mutex_unlock();
1303 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_DEQUEUE);
1305 return TBM_SURFACE_QUEUE_ERROR_NONE;
1308 tbm_surface_queue_error_e
1309 tbm_surface_queue_dequeue(tbm_surface_queue_h
1310 surface_queue, tbm_surface_h *surface)
1314 _tbm_surf_queue_mutex_lock();
1315 _tbm_set_last_result(TBM_ERROR_NONE);
1317 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1318 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1319 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1320 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1324 pthread_mutex_lock(&surface_queue->lock);
1326 if (_queue_is_empty(&surface_queue->free_queue)) {
1327 if (surface_queue->impl && surface_queue->impl->need_attach)
1328 surface_queue->impl->need_attach(surface_queue);
1330 _tbm_surface_queue_need_attach(surface_queue);
1333 if (surface_queue->impl && surface_queue->impl->dequeue)
1334 node = surface_queue->impl->dequeue(surface_queue);
1336 node = _tbm_surface_queue_dequeue(surface_queue);
1338 if (node == NULL || node->surface == NULL) {
1339 TBM_ERR("_queue_node_pop_front failed");
1340 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1341 pthread_mutex_unlock(&surface_queue->lock);
1343 _tbm_surf_queue_mutex_unlock();
1344 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1347 node->type = QUEUE_NODE_TYPE_DEQUEUE;
1348 *surface = node->surface;
1350 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)", surface_queue, *surface);
1352 pthread_mutex_unlock(&surface_queue->lock);
1354 _tbm_surf_queue_mutex_unlock();
1356 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_DEQUEUE);
1358 _notify_emit(surface_queue, &surface_queue->dequeue_noti);
1360 return TBM_SURFACE_QUEUE_ERROR_NONE;
1363 tbm_surface_queue_error_e
1364 tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout)
1369 _tbm_surf_queue_mutex_lock();
1370 _tbm_set_last_result(TBM_ERROR_NONE);
1372 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1373 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1375 _tbm_surf_queue_mutex_unlock();
1377 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1379 _tbm_surf_queue_mutex_lock();
1381 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1382 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1384 pthread_mutex_lock(&surface_queue->lock);
1386 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1388 if (_queue_is_empty(&surface_queue->free_queue)) {
1389 if (surface_queue->impl && surface_queue->impl->need_attach)
1390 surface_queue->impl->need_attach(surface_queue);
1392 _tbm_surface_queue_need_attach(surface_queue);
1395 if (!_queue_is_empty(&surface_queue->free_queue)) {
1396 pthread_mutex_unlock(&surface_queue->lock);
1397 _tbm_surf_queue_mutex_unlock();
1398 return TBM_SURFACE_QUEUE_ERROR_NONE;
1401 _tbm_surf_queue_mutex_unlock();
1404 clock_gettime(CLOCK_MONOTONIC, &tp);
1406 if (ms_timeout >= 1000)
1407 tp.tv_sec += ms_timeout / 1000;
1409 tp.tv_nsec += (ms_timeout % 1000) * 1000000;
1411 if (tp.tv_nsec > 1000000000L) {
1413 tp.tv_nsec -= 1000000000L;
1416 ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp);
1418 if (ret == ETIMEDOUT) {
1419 TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue);
1420 pthread_mutex_unlock(&surface_queue->lock);
1421 return TBM_SURFACE_QUEUE_ERROR_TIMEOUT;
1423 TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue);
1426 if (surface_queue->impl && surface_queue->impl->need_attach)
1427 surface_queue->impl->need_attach(surface_queue);
1429 _tbm_surface_queue_need_attach(surface_queue);
1431 if (!_queue_is_empty(&surface_queue->free_queue)) {
1432 pthread_mutex_unlock(&surface_queue->lock);
1433 return TBM_SURFACE_QUEUE_ERROR_NONE;
1440 tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
1442 _tbm_surf_queue_mutex_lock();
1443 _tbm_set_last_result(TBM_ERROR_NONE);
1445 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1447 _tbm_surf_queue_mutex_unlock();
1449 _notify_emit(surface_queue, &surface_queue->can_dequeue_noti);
1451 _tbm_surf_queue_mutex_lock();
1453 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1455 pthread_mutex_lock(&surface_queue->lock);
1457 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1459 if (_queue_is_empty(&surface_queue->free_queue)) {
1460 if (surface_queue->impl && surface_queue->impl->need_attach)
1461 surface_queue->impl->need_attach(surface_queue);
1463 _tbm_surface_queue_need_attach(surface_queue);
1466 if (!_queue_is_empty(&surface_queue->free_queue)) {
1467 pthread_mutex_unlock(&surface_queue->lock);
1468 _tbm_surf_queue_mutex_unlock();
1473 _tbm_surf_queue_mutex_unlock();
1475 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
1477 if (surface_queue->impl && surface_queue->impl->need_attach)
1478 surface_queue->impl->need_attach(surface_queue);
1480 _tbm_surface_queue_need_attach(surface_queue);
1482 if (!_queue_is_empty(&surface_queue->free_queue)) {
1483 pthread_mutex_unlock(&surface_queue->lock);
1489 pthread_mutex_unlock(&surface_queue->lock);
1490 _tbm_surf_queue_mutex_unlock();
1494 tbm_surface_queue_error_e
1495 tbm_surface_queue_release(tbm_surface_queue_h
1496 surface_queue, tbm_surface_h surface)
1501 _tbm_surf_queue_mutex_lock();
1502 _tbm_set_last_result(TBM_ERROR_NONE);
1504 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1505 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1506 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1507 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1509 pthread_mutex_lock(&surface_queue->lock);
1511 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)", surface_queue, surface);
1513 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1514 if (node == NULL || queue_type != NODE_LIST) {
1515 TBM_ERR("tbm_surface_queue_release::Surface is existed in free_queue or dirty_queue node:%p, type:%d",
1517 pthread_mutex_unlock(&surface_queue->lock);
1519 _tbm_surf_queue_mutex_unlock();
1522 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1523 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1525 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1526 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1530 if (node->delete_pending) {
1531 TBM_TRACE_SURFACE_QUEUE("delete pending tbm_surface_queue(%p) surface(%p)", surface_queue, node->surface);
1533 _queue_delete_node(surface_queue, node);
1535 pthread_mutex_unlock(&surface_queue->lock);
1537 _tbm_surf_queue_mutex_unlock();
1539 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1541 return TBM_SURFACE_QUEUE_ERROR_NONE;
1544 if (surface_queue->queue_size < surface_queue->num_attached) {
1545 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)", surface_queue, node->surface);
1547 if (surface_queue->impl && surface_queue->impl->need_detach)
1548 surface_queue->impl->need_detach(surface_queue, node);
1550 _tbm_surface_queue_detach(surface_queue, surface);
1552 pthread_mutex_unlock(&surface_queue->lock);
1554 _tbm_surf_queue_mutex_unlock();
1556 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1558 return TBM_SURFACE_QUEUE_ERROR_NONE;
1561 if (surface_queue->impl && surface_queue->impl->release)
1562 surface_queue->impl->release(surface_queue, node);
1564 _tbm_surface_queue_release(surface_queue, node, 1);
1566 if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) {
1567 TBM_ERR("release surface(%p) but surface isn't present in the free_queue", surface);
1568 _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION);
1569 pthread_mutex_unlock(&surface_queue->lock);
1571 _tbm_surf_queue_mutex_unlock();
1572 return TBM_SURFACE_ERROR_INVALID_OPERATION;
1575 node->type = QUEUE_NODE_TYPE_RELEASE;
1577 pthread_mutex_unlock(&surface_queue->lock);
1578 pthread_cond_signal(&surface_queue->free_cond);
1580 _tbm_surf_queue_mutex_unlock();
1582 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_RELEASE);
1584 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1586 return TBM_SURFACE_QUEUE_ERROR_NONE;
1589 tbm_surface_queue_error_e
1590 tbm_surface_queue_cancel_acquire(tbm_surface_queue_h
1591 surface_queue, tbm_surface_h surface)
1596 _tbm_surf_queue_mutex_lock();
1597 _tbm_set_last_result(TBM_ERROR_NONE);
1599 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1600 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1601 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1602 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1604 pthread_mutex_lock(&surface_queue->lock);
1606 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)", surface_queue, surface);
1608 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
1609 if (node == NULL || queue_type != NODE_LIST) {
1610 TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d",
1612 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST);
1613 pthread_mutex_unlock(&surface_queue->lock);
1615 _tbm_surf_queue_mutex_unlock();
1616 return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST;
1619 if (surface_queue->impl && surface_queue->impl->enqueue)
1620 surface_queue->impl->enqueue(surface_queue, node);
1622 _tbm_surface_queue_enqueue(surface_queue, node, 1);
1624 if (_queue_is_empty(&surface_queue->dirty_queue)) {
1625 TBM_ERR("enqueue surface but queue is empty node:%p", node);
1626 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE);
1627 pthread_mutex_unlock(&surface_queue->lock);
1629 _tbm_surf_queue_mutex_unlock();
1630 return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE;
1633 node->type = QUEUE_NODE_TYPE_ENQUEUE;
1635 pthread_mutex_unlock(&surface_queue->lock);
1636 pthread_cond_signal(&surface_queue->dirty_cond);
1638 _tbm_surf_queue_mutex_unlock();
1640 _trace_emit(surface_queue, &surface_queue->trace_noti, surface, TBM_SURFACE_QUEUE_TRACE_CANCEL_ACQUIRE);
1642 _notify_emit(surface_queue, &surface_queue->acquirable_noti);
1644 return TBM_SURFACE_QUEUE_ERROR_NONE;
1647 tbm_surface_queue_error_e
1648 tbm_surface_queue_acquire(tbm_surface_queue_h
1649 surface_queue, tbm_surface_h *surface)
1653 _tbm_surf_queue_mutex_lock();
1654 _tbm_set_last_result(TBM_ERROR_NONE);
1658 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1659 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1660 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface != NULL,
1661 TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
1663 pthread_mutex_lock(&surface_queue->lock);
1665 if (surface_queue->impl && surface_queue->impl->acquire)
1666 node = surface_queue->impl->acquire(surface_queue);
1668 node = _tbm_surface_queue_acquire(surface_queue);
1670 if (node == NULL || node->surface == NULL) {
1671 TBM_ERR("_queue_node_pop_front failed");
1672 _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY);
1673 pthread_mutex_unlock(&surface_queue->lock);
1675 _tbm_surf_queue_mutex_unlock();
1676 return TBM_SURFACE_QUEUE_ERROR_EMPTY;
1679 node->type = QUEUE_NODE_TYPE_ACQUIRE;
1681 *surface = node->surface;
1683 if (surface_queue->acquire_sync_count == 1) {
1684 tbm_surface_info_s info;
1687 TBM_ERR("start map surface:%p", *surface);
1688 ret = tbm_surface_map(*surface, TBM_SURF_OPTION_READ, &info);
1689 TBM_ERR("end map surface:%p", *surface);
1690 if (ret == TBM_SURFACE_ERROR_NONE)
1691 tbm_surface_unmap(*surface);
1694 if (surface_queue->acquire_sync_count > 0) surface_queue->acquire_sync_count--;
1696 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) tbm_surface(%p)", surface_queue, *surface);
1698 pthread_mutex_unlock(&surface_queue->lock);
1700 _tbm_surf_queue_mutex_unlock();
1703 tbm_surface_internal_dump_buffer(*surface, "acquire");
1705 _trace_emit(surface_queue, &surface_queue->trace_noti, *surface, TBM_SURFACE_QUEUE_TRACE_ACQUIRE);
1707 return TBM_SURFACE_QUEUE_ERROR_NONE;
1711 tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
1713 _tbm_surf_queue_mutex_lock();
1714 _tbm_set_last_result(TBM_ERROR_NONE);
1716 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0);
1718 pthread_mutex_lock(&surface_queue->lock);
1720 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1722 if (!_queue_is_empty(&surface_queue->dirty_queue)) {
1723 pthread_mutex_unlock(&surface_queue->lock);
1724 _tbm_surf_queue_mutex_unlock();
1728 if (wait && _tbm_surface_queue_get_node_count(surface_queue,
1729 QUEUE_NODE_TYPE_DEQUEUE)) {
1730 _tbm_surf_queue_mutex_unlock();
1731 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
1732 pthread_mutex_unlock(&surface_queue->lock);
1736 pthread_mutex_unlock(&surface_queue->lock);
1737 _tbm_surf_queue_mutex_unlock();
1742 tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
1744 queue_node *node = NULL, *tmp;
1746 _tbm_surf_queue_mutex_lock();
1747 _tbm_set_last_result(TBM_ERROR_NONE);
1749 TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue));
1751 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1753 surface_queue->magic = 0;
1755 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1756 _queue_delete_node(surface_queue, node);
1758 if (surface_queue->impl && surface_queue->impl->destroy)
1759 surface_queue->impl->destroy(surface_queue);
1761 _notify_emit(surface_queue, &surface_queue->destory_noti);
1763 _notify_remove_all(&surface_queue->destory_noti);
1764 _notify_remove_all(&surface_queue->dequeuable_noti);
1765 _notify_remove_all(&surface_queue->dequeue_noti);
1766 _notify_remove_all(&surface_queue->can_dequeue_noti);
1767 _notify_remove_all(&surface_queue->acquirable_noti);
1768 _notify_remove_all(&surface_queue->reset_noti);
1769 _trace_remove_all(&surface_queue->trace_noti);
1771 pthread_mutex_destroy(&surface_queue->lock);
1773 free(surface_queue);
1775 _tbm_surf_queue_mutex_unlock();
1778 tbm_surface_queue_error_e
1779 tbm_surface_queue_reset(tbm_surface_queue_h
1780 surface_queue, int width, int height, int format)
1782 queue_node *node = NULL, *tmp;
1784 _tbm_surf_queue_mutex_lock();
1785 _tbm_set_last_result(TBM_ERROR_NONE);
1787 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1788 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1790 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1792 pthread_mutex_lock(&surface_queue->lock);
1794 if (width == surface_queue->width && height == surface_queue->height &&
1795 format == surface_queue->format) {
1796 pthread_mutex_unlock(&surface_queue->lock);
1797 _tbm_surf_queue_mutex_unlock();
1798 return TBM_SURFACE_QUEUE_ERROR_NONE;
1801 surface_queue->width = width;
1802 surface_queue->height = height;
1803 surface_queue->format = format;
1805 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1806 /* Destory surface and Push to free_queue */
1807 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1808 _queue_delete_node(surface_queue, node);
1810 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1811 node->delete_pending = 1;
1813 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1814 _queue_delete_node(surface_queue, node);
1816 _queue_init(&surface_queue->dirty_queue);
1817 LIST_INITHEAD(&surface_queue->list);
1821 _queue_init(&surface_queue->free_queue);
1823 surface_queue->num_attached = 0;
1825 if (surface_queue->impl && surface_queue->impl->reset)
1826 surface_queue->impl->reset(surface_queue);
1828 pthread_mutex_unlock(&surface_queue->lock);
1829 pthread_cond_signal(&surface_queue->free_cond);
1831 _tbm_surf_queue_mutex_unlock();
1833 _notify_emit(surface_queue, &surface_queue->reset_noti);
1835 return TBM_SURFACE_QUEUE_ERROR_NONE;
1838 tbm_surface_queue_error_e
1839 tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue)
1841 _tbm_surf_queue_mutex_lock();
1842 _tbm_set_last_result(TBM_ERROR_NONE);
1844 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1845 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1847 _tbm_surf_queue_mutex_unlock();
1849 _notify_emit(surface_queue, &surface_queue->reset_noti);
1851 return TBM_SURFACE_QUEUE_ERROR_NONE;
1854 tbm_surface_queue_error_e
1855 tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue)
1857 _tbm_surf_queue_mutex_lock();
1858 _tbm_set_last_result(TBM_ERROR_NONE);
1860 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1861 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1863 pthread_mutex_lock(&surface_queue->lock);
1864 pthread_mutex_unlock(&surface_queue->lock);
1865 pthread_cond_signal(&surface_queue->free_cond);
1867 _tbm_surf_queue_mutex_unlock();
1869 _notify_emit(surface_queue, &surface_queue->dequeuable_noti);
1871 return TBM_SURFACE_QUEUE_ERROR_NONE;
1874 tbm_surface_queue_error_e
1875 tbm_surface_queue_set_size(tbm_surface_queue_h
1876 surface_queue, int queue_size, int flush)
1878 queue_node *node = NULL, *tmp;
1880 _tbm_surf_queue_mutex_lock();
1881 _tbm_set_last_result(TBM_ERROR_NONE);
1883 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1884 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1885 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0,
1886 TBM_ERROR_INVALID_PARAMETER);
1888 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1890 if ((surface_queue->queue_size == queue_size) && !flush) {
1891 _tbm_surf_queue_mutex_unlock();
1892 return TBM_SURFACE_QUEUE_ERROR_NONE;
1895 pthread_mutex_lock(&surface_queue->lock);
1898 surface_queue->queue_size = queue_size;
1900 if (surface_queue->num_attached == 0) {
1901 pthread_mutex_unlock(&surface_queue->lock);
1902 _tbm_surf_queue_mutex_unlock();
1903 return TBM_SURFACE_QUEUE_ERROR_NONE;
1906 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
1907 /* Destory surface and Push to free_queue */
1908 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
1909 _queue_delete_node(surface_queue, node);
1911 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
1912 node->delete_pending = 1;
1914 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
1915 _queue_delete_node(surface_queue, node);
1917 _queue_init(&surface_queue->dirty_queue);
1918 LIST_INITHEAD(&surface_queue->list);
1922 _queue_init(&surface_queue->free_queue);
1924 surface_queue->num_attached = 0;
1926 if (surface_queue->impl && surface_queue->impl->reset)
1927 surface_queue->impl->reset(surface_queue);
1929 pthread_mutex_unlock(&surface_queue->lock);
1930 pthread_cond_signal(&surface_queue->free_cond);
1932 _tbm_surf_queue_mutex_unlock();
1934 _notify_emit(surface_queue, &surface_queue->reset_noti);
1936 return TBM_SURFACE_QUEUE_ERROR_NONE;
1938 if (surface_queue->queue_size > queue_size) {
1939 int need_del = surface_queue->queue_size - queue_size;
1941 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
1942 TBM_TRACE_SURFACE_QUEUE("deatch tbm_surface_queue(%p) surface(%p)", surface_queue, node->surface);
1944 if (surface_queue->impl && surface_queue->impl->need_detach)
1945 surface_queue->impl->need_detach(surface_queue, node);
1947 _tbm_surface_queue_detach(surface_queue, node->surface);
1955 surface_queue->queue_size = queue_size;
1957 pthread_mutex_unlock(&surface_queue->lock);
1959 _tbm_surf_queue_mutex_unlock();
1961 return TBM_SURFACE_QUEUE_ERROR_NONE;
1965 tbm_surface_queue_error_e
1966 tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue)
1968 queue_node *node = NULL;
1969 int is_guarantee_cycle = 0;
1971 _tbm_surf_queue_mutex_lock();
1972 _tbm_set_last_result(TBM_ERROR_NONE);
1974 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
1975 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
1977 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
1979 if (surface_queue->num_attached == 0) {
1980 _tbm_surf_queue_mutex_unlock();
1981 return TBM_SURFACE_QUEUE_ERROR_NONE;
1984 pthread_mutex_lock(&surface_queue->lock);
1986 /* Destory surface in free_queue */
1987 while ((node = _queue_node_pop_front(&surface_queue->free_queue))) {
1988 if (surface_queue->impl && surface_queue->impl->need_detach)
1989 surface_queue->impl->need_detach(surface_queue, node);
1991 _tbm_surface_queue_detach(surface_queue, node->surface);
1995 _queue_init(&surface_queue->free_queue);
1997 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
1998 is_guarantee_cycle = 1;
2000 pthread_mutex_unlock(&surface_queue->lock);
2001 _tbm_surf_queue_mutex_unlock();
2003 if (is_guarantee_cycle)
2004 _notify_emit(surface_queue, &surface_queue->reset_noti);
2006 return TBM_SURFACE_QUEUE_ERROR_NONE;
2009 tbm_surface_queue_error_e
2010 tbm_surface_queue_flush(tbm_surface_queue_h surface_queue)
2012 queue_node *node = NULL, *tmp;
2014 _tbm_surf_queue_mutex_lock();
2015 _tbm_set_last_result(TBM_ERROR_NONE);
2017 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2018 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2020 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
2022 pthread_mutex_lock(&surface_queue->lock);
2024 if (surface_queue->num_attached == 0) {
2025 pthread_mutex_unlock(&surface_queue->lock);
2026 _tbm_surf_queue_mutex_unlock();
2027 return TBM_SURFACE_QUEUE_ERROR_NONE;
2030 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) {
2031 /* Destory surface and Push to free_queue */
2032 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link)
2033 _queue_delete_node(surface_queue, node);
2035 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link)
2036 node->delete_pending = 1;
2038 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
2039 _queue_delete_node(surface_queue, node);
2041 _queue_init(&surface_queue->dirty_queue);
2042 LIST_INITHEAD(&surface_queue->list);
2046 _queue_init(&surface_queue->free_queue);
2048 surface_queue->num_attached = 0;
2050 if (surface_queue->impl && surface_queue->impl->reset)
2051 surface_queue->impl->reset(surface_queue);
2053 pthread_mutex_unlock(&surface_queue->lock);
2054 pthread_cond_signal(&surface_queue->free_cond);
2056 _tbm_surf_queue_mutex_unlock();
2058 _notify_emit(surface_queue, &surface_queue->reset_noti);
2060 return TBM_SURFACE_QUEUE_ERROR_NONE;
2063 tbm_surface_queue_error_e
2064 tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue,
2065 tbm_surface_h *surfaces, int *num)
2067 queue_node *node = NULL;
2069 _tbm_surf_queue_mutex_lock();
2070 _tbm_set_last_result(TBM_ERROR_NONE);
2072 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2073 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2074 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2075 TBM_ERROR_INVALID_PARAMETER);
2079 pthread_mutex_lock(&surface_queue->lock);
2081 LIST_FOR_EACH_ENTRY(node, &surface_queue->list, link) {
2082 if (node->delete_pending) continue;
2085 surfaces[*num] = node->surface;
2090 pthread_mutex_unlock(&surface_queue->lock);
2092 _tbm_surf_queue_mutex_unlock();
2094 return TBM_SURFACE_QUEUE_ERROR_NONE;
2097 tbm_surface_queue_error_e
2098 tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue,
2099 tbm_surface_h *surfaces, int *num)
2101 queue_node *node = NULL;
2103 _tbm_surf_queue_mutex_lock();
2107 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2108 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2109 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2110 TBM_ERROR_INVALID_PARAMETER);
2112 pthread_mutex_lock(&surface_queue->lock);
2114 LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) {
2116 surfaces[*num] = node->surface;
2121 pthread_mutex_unlock(&surface_queue->lock);
2123 _tbm_surf_queue_mutex_unlock();
2125 return TBM_SURFACE_QUEUE_ERROR_NONE;
2128 tbm_surface_queue_error_e
2129 tbm_surface_queue_get_trace_surface_num(
2130 tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num)
2132 _tbm_surf_queue_mutex_lock();
2133 _tbm_set_last_result(TBM_ERROR_NONE);
2135 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2136 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2137 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL,
2138 TBM_ERROR_INVALID_PARAMETER);
2142 pthread_mutex_lock(&surface_queue->lock);
2145 case TBM_SURFACE_QUEUE_TRACE_NONE:
2148 case TBM_SURFACE_QUEUE_TRACE_DEQUEUE:
2149 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2151 case TBM_SURFACE_QUEUE_TRACE_ENQUEUE:
2152 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2154 case TBM_SURFACE_QUEUE_TRACE_ACQUIRE:
2155 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ACQUIRE);
2157 case TBM_SURFACE_QUEUE_TRACE_RELEASE:
2158 *num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_RELEASE);
2164 pthread_mutex_unlock(&surface_queue->lock);
2166 _tbm_surf_queue_mutex_unlock();
2168 return TBM_SURFACE_QUEUE_ERROR_NONE;
2171 static const tbm_surface_queue_interface tbm_queue_default_impl = {
2172 NULL, /*__tbm_queue_default_init*/
2173 NULL, /*__tbm_queue_default_reset*/
2174 NULL, /*__tbm_queue_default_destroy*/
2175 NULL, /*__tbm_queue_default_need_attach*/
2176 NULL, /*__tbm_queue_default_enqueue*/
2177 NULL, /*__tbm_queue_default_release*/
2178 NULL, /*__tbm_queue_default_dequeue*/
2179 NULL, /*__tbm_queue_default_acquire*/
2180 NULL, /*__tbm_queue_default_need_detach*/
2184 tbm_surface_queue_create(int queue_size, int width,
2185 int height, int format, int flags)
2187 _tbm_surf_queue_mutex_lock();
2188 _tbm_set_last_result(TBM_ERROR_NONE);
2190 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2191 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2192 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2193 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2195 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2196 sizeof(struct _tbm_surface_queue));
2197 if (!surface_queue) {
2198 TBM_ERR("cannot allocate the surface_queue.");
2199 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2200 _tbm_surf_queue_mutex_unlock();
2204 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
2206 _tbm_surface_queue_init(surface_queue,
2208 width, height, format, flags,
2209 &tbm_queue_default_impl, NULL);
2211 _tbm_surf_queue_mutex_unlock();
2213 return surface_queue;
2218 } tbm_queue_sequence;
2221 __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
2223 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2225 _queue_init(&data->dequeue_list);
2229 __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
2231 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2233 if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE)
2236 _queue_init(&data->dequeue_list);
2240 __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
2242 free(surface_queue->impl_data);
2246 __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue,
2249 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2250 queue_node *first = NULL;
2252 first = container_of(data->dequeue_list.head.next, first, item_link);
2253 if (first != node) {
2257 node->priv_flags = 0;
2259 _queue_node_pop(&data->dequeue_list, node);
2260 _tbm_surface_queue_enqueue(surface_queue, node, 1);
2264 __tbm_queue_sequence_release(tbm_surface_queue_h surface_queue,
2267 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2269 if (node->priv_flags) {
2270 node->priv_flags = 0;
2271 _queue_node_pop(&data->dequeue_list, node);
2274 _tbm_surface_queue_release(surface_queue, node, 1);
2278 __tbm_queue_sequence_dequeue(tbm_surface_queue_h
2281 tbm_queue_sequence *data = (tbm_queue_sequence *)surface_queue->impl_data;
2284 node = _tbm_surface_queue_dequeue(surface_queue);
2286 _queue_node_push_back(&data->dequeue_list, node);
2287 node->priv_flags = 1;
2293 static const tbm_surface_queue_interface tbm_queue_sequence_impl = {
2294 __tbm_queue_sequence_init,
2295 __tbm_queue_sequence_reset,
2296 __tbm_queue_sequence_destroy,
2298 __tbm_queue_sequence_enqueue,
2299 __tbm_queue_sequence_release,
2300 __tbm_queue_sequence_dequeue,
2301 NULL, /*__tbm_queue_sequence_acquire*/
2302 NULL, /*__tbm_queue_sequence_need_dettach*/
2306 tbm_surface_queue_sequence_create(int queue_size, int width,
2307 int height, int format, int flags)
2309 _tbm_surf_queue_mutex_lock();
2310 _tbm_set_last_result(TBM_ERROR_NONE);
2312 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
2313 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL);
2314 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL);
2315 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL);
2317 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1,
2318 sizeof(struct _tbm_surface_queue));
2319 if (surface_queue == NULL) {
2320 TBM_ERR("cannot allocate the surface_queue.");
2321 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2322 _tbm_surf_queue_mutex_unlock();
2326 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)", surface_queue);
2328 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1,
2329 sizeof(tbm_queue_sequence));
2331 TBM_ERR("cannot allocate the tbm_queue_sequence.");
2332 _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY);
2333 free(surface_queue);
2334 _tbm_surf_queue_mutex_unlock();
2338 _tbm_surface_queue_init(surface_queue,
2340 width, height, format, flags,
2341 &tbm_queue_sequence_impl, data);
2343 _tbm_surf_queue_mutex_unlock();
2345 return surface_queue;
2348 tbm_surface_queue_error_e
2349 tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue,
2352 _tbm_surf_queue_mutex_lock();
2353 _tbm_set_last_result(TBM_ERROR_NONE);
2355 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2356 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2358 pthread_mutex_lock(&surface_queue->lock);
2360 if (modes == TBM_SURFACE_QUEUE_MODE_NONE)
2361 modes = TBM_SURFACE_QUEUE_MODE_NONE;
2363 surface_queue->modes |= modes;
2365 pthread_mutex_unlock(&surface_queue->lock);
2367 _tbm_surf_queue_mutex_unlock();
2369 return TBM_SURFACE_QUEUE_ERROR_NONE;
2372 tbm_surface_queue_error_e
2373 tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue,
2374 unsigned int sync_count)
2376 int dequeue_num, enqueue_num;
2378 _tbm_surf_queue_mutex_lock();
2379 _tbm_set_last_result(TBM_ERROR_NONE);
2381 TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue),
2382 TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
2384 pthread_mutex_lock(&surface_queue->lock);
2386 dequeue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_DEQUEUE);
2387 enqueue_num = _tbm_surface_queue_get_node_count(surface_queue, QUEUE_NODE_TYPE_ENQUEUE);
2389 if (dequeue_num + sync_count == 0)
2390 surface_queue->acquire_sync_count = enqueue_num;
2392 surface_queue->enqueue_sync_count = dequeue_num + sync_count;
2394 TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p) enqueue_sync_count:(%d) acquire_sync_count:(%d)",
2395 surface_queue, surface_queue->enqueue_sync_count, surface_queue->acquire_sync_count);
2397 pthread_mutex_unlock(&surface_queue->lock);
2399 _tbm_surf_queue_mutex_unlock();
2401 return TBM_SURFACE_QUEUE_ERROR_NONE;