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 **************************************************************************/
32 #include "tbm_bufmgr_int.h"
42 #define TBM_TRACE() TBM_LOG("[TRACE] %s:%d surface:%p\n", __FUNCTION__, __LINE__, surface_queue)
43 #define TBM_LOCK() TBM_LOG("[LOCK] %s:%d surface:%p\n", __FUNCTION__, __LINE__, surface_queue)
44 #define TBM_UNLOCK() TBM_LOG("[UNLOCK] %s:%d surface:%p\n", __FUNCTION__, __LINE__, surface_queue)
52 struct list_head head;
53 struct list_head tail;
59 tbm_surface_h surface;
61 struct list_head item_link;
62 struct list_head link;
64 unsigned int priv_flags; /*for each queue*/
67 typedef struct _tbm_surface_queue_interface {
68 void (*init)(tbm_surface_queue_h queue);
69 void (*reset)(tbm_surface_queue_h queue);
70 void (*destroy)(tbm_surface_queue_h queue);
71 void (*need_attach)(tbm_surface_queue_h queue);
73 void (*enqueue)(tbm_surface_queue_h queue, queue_node* node);
74 void (*release)(tbm_surface_queue_h queue, queue_node* node);
75 queue_node* (*dequeue)(tbm_surface_queue_h queue);
76 queue_node* (*acquire)(tbm_surface_queue_h queue);
77 }tbm_surface_queue_interface;
79 struct _tbm_surface_queue {
86 struct list_head list;
88 tbm_surface_queue_notify_cb destroy_cb;
89 void *destroy_cb_data;
91 tbm_surface_queue_notify_cb dequeuable_cb;
92 void *dequeuable_cb_data;
94 tbm_surface_queue_notify_cb acquirable_cb;
95 void *acquirable_cb_data;
97 tbm_surface_queue_notify_cb reset_cb;
100 pthread_mutex_t lock;
101 pthread_cond_t free_cond;
102 pthread_cond_t dirty_cond;
104 const tbm_surface_queue_interface *impl;
108 static queue_node *_queue_node_create(void)
110 queue_node *node = (queue_node *) calloc(1, sizeof(queue_node));
111 TBM_RETURN_VAL_IF_FAIL(node != NULL, NULL);
116 static void _queue_node_delete(queue_node * node)
119 tbm_surface_destroy(node->surface);
121 LIST_DEL(&node->item_link);
122 LIST_DEL(&node->link);
126 static int _queue_is_empty(queue * queue)
128 if (queue->head.next == &queue->tail)
134 static void _queue_node_push_back(queue * queue, queue_node * node)
136 LIST_ADDTAIL(&node->item_link, &queue->tail);
141 static void _queue_node_push_front(queue * queue, queue_node * node)
143 LIST_ADD(&node->item_link, &queue->head);
148 static queue_node *_queue_node_pop_front(queue * queue)
150 queue_node *node = NULL;
152 node = LIST_ENTRY(queue_node, queue->head.next, item_link);
154 LIST_DEL(&node->item_link);
160 static queue_node *_queue_node_pop(queue * queue, queue_node* node)
162 LIST_DEL(&node->item_link);
168 static queue_node* _queue_get_node(tbm_surface_queue_h surface_queue, int type, tbm_surface_h surface, int *out_type)
170 queue_node *node = NULL;
171 queue_node *tmp = NULL;
174 type = FREE_QUEUE | DUTY_QUEUE | NODE_LIST;
178 if (type & FREE_QUEUE)
180 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) {
181 if (node->surface == surface)
183 if (out_type) *out_type = FREE_QUEUE;
189 if (type & DUTY_QUEUE)
191 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->dirty_queue.head, item_link) {
192 if (node->surface == surface)
194 if (out_type) *out_type = DUTY_QUEUE;
200 if (type & NODE_LIST)
202 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
203 if (node->surface == surface)
205 if (out_type) *out_type = NODE_LIST;
214 static void _queue_init(queue * queue)
216 LIST_INITHEAD(&queue->head);
217 LIST_INITHEAD(&queue->tail);
218 LIST_ADDTAIL(&queue->head, &queue->tail);
222 void _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
224 queue_node *node = NULL;
226 node = _queue_node_create();
227 TBM_RETURN_IF_FAIL(node != NULL);
229 tbm_surface_internal_ref(surface);
230 node->surface = surface;
232 LIST_ADDTAIL(&node->link, &surface_queue->list);
233 _queue_node_push_back(&surface_queue->free_queue, node);
236 void _tbm_surface_queue_detach(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
238 queue_node *node = NULL;
241 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
243 _queue_node_delete(node);
246 void _tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue, queue_node* node, int push_back)
249 _queue_node_push_back(&surface_queue->dirty_queue, node);
251 _queue_node_push_front(&surface_queue->dirty_queue, node);
254 queue_node* _tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue)
256 queue_node *node = NULL;
258 if (_queue_is_empty(&surface_queue->free_queue)) {
259 if (surface_queue->impl && surface_queue->impl->need_attach)
260 surface_queue->impl->need_attach(surface_queue);
262 if (_queue_is_empty(&surface_queue->free_queue)) {
267 node = _queue_node_pop_front(&surface_queue->free_queue);
272 queue_node* _tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue)
274 queue_node *node = NULL;
276 if (_queue_is_empty(&surface_queue->dirty_queue)) {
280 node = _queue_node_pop_front(&surface_queue->dirty_queue);
285 void _tbm_surface_queue_release(tbm_surface_queue_h surface_queue, queue_node* node, int push_back)
288 _queue_node_push_back(&surface_queue->free_queue, node);
290 _queue_node_push_front(&surface_queue->free_queue, node);
293 void _tbm_surface_queue_init(tbm_surface_queue_h surface_queue,
294 int width, int height, int format,
295 const tbm_surface_queue_interface* impl, void *data)
297 TBM_RETURN_IF_FAIL(surface_queue != NULL);
298 TBM_RETURN_IF_FAIL(impl != NULL);
300 memset(surface_queue, 0x00, sizeof(struct _tbm_surface_queue));
302 pthread_mutex_init(&surface_queue->lock, NULL);
303 pthread_cond_init(&surface_queue->free_cond, NULL);
304 pthread_cond_init(&surface_queue->dirty_cond, NULL);
306 surface_queue->width = width;
307 surface_queue->height = height;
308 surface_queue->format = format;
309 surface_queue->impl = impl;
310 surface_queue->impl_data = data;
312 _queue_init(&surface_queue->free_queue);
313 _queue_init(&surface_queue->dirty_queue);
314 LIST_INITHEAD(&surface_queue->list);
316 if (surface_queue->impl && surface_queue->impl->init)
317 surface_queue->impl->init(surface_queue);
320 tbm_surface_queue_error_e tbm_surface_queue_set_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data)
322 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
324 pthread_mutex_lock(&surface_queue->lock);
326 surface_queue->destroy_cb = destroy_cb;
327 surface_queue->destroy_cb_data = data;
329 pthread_mutex_unlock(&surface_queue->lock);
331 return TBM_SURFACE_QUEUE_ERROR_NONE;
334 tbm_surface_queue_error_e tbm_surface_queue_set_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, void *data)
336 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
338 pthread_mutex_lock(&surface_queue->lock);
340 surface_queue->dequeuable_cb = dequeuable_cb;
341 surface_queue->dequeuable_cb_data = data;
343 pthread_mutex_unlock(&surface_queue->lock);
345 return TBM_SURFACE_QUEUE_ERROR_NONE;
348 tbm_surface_queue_error_e tbm_surface_queue_set_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data)
350 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
352 pthread_mutex_lock(&surface_queue->lock);
354 surface_queue->acquirable_cb = acquirable_cb;
355 surface_queue->acquirable_cb_data = data;
357 pthread_mutex_unlock(&surface_queue->lock);
359 return TBM_SURFACE_QUEUE_ERROR_NONE;
362 int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue)
364 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
366 return surface_queue->width;
369 int tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue)
371 return surface_queue->height;
374 int tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue)
376 return surface_queue->format;
379 tbm_surface_queue_error_e tbm_surface_queue_set_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, void *data)
381 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
383 pthread_mutex_lock(&surface_queue->lock);
385 surface_queue->reset_cb = reset_cb;
386 surface_queue->reset_cb_data = data;
388 pthread_mutex_unlock(&surface_queue->lock);
390 return TBM_SURFACE_QUEUE_ERROR_NONE;
394 tbm_surface_queue_error_e tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
396 queue_node *node = NULL;
399 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
400 TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
402 pthread_mutex_lock(&surface_queue->lock);
404 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
405 if (node == NULL || queue_type != NODE_LIST)
407 TBM_LOG("tbm_surface_queue_enqueue::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n", node, queue_type);
408 pthread_mutex_unlock(&surface_queue->lock);
409 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
412 if (surface_queue->impl && surface_queue->impl->enqueue)
413 surface_queue->impl->enqueue(surface_queue, node);
415 _tbm_surface_queue_enqueue(surface_queue, node, 1);
417 if (_queue_is_empty(&surface_queue->dirty_queue)) {
418 pthread_mutex_unlock(&surface_queue->lock);
419 return TBM_SURFACE_QUEUE_ERROR_NONE;
422 pthread_mutex_unlock(&surface_queue->lock);
423 pthread_cond_signal(&surface_queue->dirty_cond);
425 if (surface_queue->acquirable_cb)
426 surface_queue->acquirable_cb(surface_queue, surface_queue->acquirable_cb_data);
428 return TBM_SURFACE_QUEUE_ERROR_NONE;
431 tbm_surface_queue_error_e tbm_surface_queue_dequeue(tbm_surface_queue_h surface_queue, tbm_surface_h * surface)
433 queue_node *node = NULL;
435 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
436 TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
438 pthread_mutex_lock(&surface_queue->lock);
440 if (surface_queue->impl && surface_queue->impl->dequeue)
441 node = surface_queue->impl->dequeue(surface_queue);
443 node = _tbm_surface_queue_dequeue(surface_queue);
445 if (node == NULL || node->surface == NULL) {
446 TBM_LOG("_queue_node_pop_front is failed\n");
449 pthread_mutex_unlock(&surface_queue->lock);
450 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
453 *surface = node->surface;
455 pthread_mutex_unlock(&surface_queue->lock);
457 return TBM_SURFACE_QUEUE_ERROR_NONE;
460 int tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait)
462 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
464 pthread_mutex_lock(&surface_queue->lock);
466 if (_queue_is_empty(&surface_queue->free_queue)) {
467 if (surface_queue->impl && surface_queue->impl->need_attach)
468 surface_queue->impl->need_attach(surface_queue);
471 if (_queue_is_empty(&surface_queue->free_queue)) {
473 pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock);
474 pthread_mutex_unlock(&surface_queue->lock);
478 pthread_mutex_unlock(&surface_queue->lock);
482 pthread_mutex_unlock(&surface_queue->lock);
487 tbm_surface_queue_error_e tbm_surface_queue_release(tbm_surface_queue_h surface_queue, tbm_surface_h surface)
489 queue_node *node = NULL;
492 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
493 TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
495 pthread_mutex_lock(&surface_queue->lock);
497 node = _queue_get_node(surface_queue, 0, surface, &queue_type);
498 if (node == NULL || queue_type != NODE_LIST)
500 TBM_LOG("tbm_surface_queue_release::Surface exist in free_queue or dirty_queue node:%p, queue:%d\n", node, queue_type);
501 pthread_mutex_unlock(&surface_queue->lock);
502 return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE;
505 if (surface_queue->impl && surface_queue->impl->release)
506 surface_queue->impl->release(surface_queue, node);
508 _tbm_surface_queue_release(surface_queue, node, 1);
510 if (_queue_is_empty(&surface_queue->free_queue)) {
511 pthread_mutex_unlock(&surface_queue->lock);
512 return TBM_SURFACE_QUEUE_ERROR_NONE;
515 pthread_mutex_unlock(&surface_queue->lock);
516 pthread_cond_signal(&surface_queue->free_cond);
518 if (surface_queue->dequeuable_cb)
519 surface_queue->dequeuable_cb(surface_queue, surface_queue->dequeuable_cb_data);
521 return TBM_SURFACE_QUEUE_ERROR_NONE;
524 tbm_surface_queue_error_e tbm_surface_queue_acquire(tbm_surface_queue_h surface_queue, tbm_surface_h * surface)
526 queue_node *node = NULL;
528 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
529 TBM_RETURN_VAL_IF_FAIL(surface != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE);
531 pthread_mutex_lock(&surface_queue->lock);
533 if (surface_queue->impl && surface_queue->impl->acquire)
534 node = surface_queue->impl->acquire(surface_queue);
536 node = _tbm_surface_queue_acquire(surface_queue);
538 if (node == NULL || node->surface == NULL) {
539 TBM_LOG("_queue_node_pop_front failed\n");
542 pthread_mutex_unlock(&surface_queue->lock);
543 return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE;
546 *surface = node->surface;
548 pthread_mutex_unlock(&surface_queue->lock);
550 return TBM_SURFACE_QUEUE_ERROR_NONE;
553 int tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait)
555 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0);
557 pthread_mutex_lock(&surface_queue->lock);
559 if (_queue_is_empty(&surface_queue->dirty_queue)) {
561 pthread_cond_wait(&surface_queue->dirty_cond, &surface_queue->lock);
562 pthread_mutex_unlock(&surface_queue->lock);
566 pthread_mutex_unlock(&surface_queue->lock);
570 pthread_mutex_unlock(&surface_queue->lock);
575 void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue)
577 queue_node *node = NULL, *tmp = NULL;
579 TBM_RETURN_IF_FAIL(surface_queue != NULL);
581 if (surface_queue->destroy_cb)
582 surface_queue->destroy_cb(surface_queue, surface_queue->destroy_cb_data);
584 if (surface_queue->impl && surface_queue->impl->destroy)
585 surface_queue->impl->destroy(surface_queue);
587 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link) {
588 _queue_node_delete(node);
591 pthread_mutex_destroy(&surface_queue->lock);
595 tbm_surface_queue_error_e tbm_surface_queue_reset(tbm_surface_queue_h surface_queue, int width, int height, int format)
597 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);
599 queue_node *node = NULL, *tmp = NULL;
601 if (width == surface_queue->width && height == surface_queue->height && format == surface_queue->format)
602 return TBM_SURFACE_QUEUE_ERROR_NONE;
604 pthread_mutex_lock(&surface_queue->lock);
606 surface_queue->width = width;
607 surface_queue->height = height;
608 surface_queue->format = format;
610 /* Destory surface and Push to free_queue */
611 LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->list, link)
613 _queue_node_delete(node);
617 _queue_init(&surface_queue->free_queue);
618 _queue_init(&surface_queue->dirty_queue);
619 LIST_INITHEAD(&surface_queue->list);
621 if (surface_queue->impl && surface_queue->impl->reset)
622 surface_queue->impl->reset(surface_queue);
624 pthread_mutex_unlock(&surface_queue->lock);
625 pthread_cond_signal(&surface_queue->free_cond);
627 if (surface_queue->reset_cb)
628 surface_queue->reset_cb(surface_queue, surface_queue->reset_cb_data);
630 return TBM_SURFACE_QUEUE_ERROR_NONE;
640 static void __tbm_queue_default_init(tbm_surface_queue_h surface_queue)
642 tbm_queue_default* data = surface_queue->impl_data;
643 data->num_attached = 0;
646 static void __tbm_queue_default_reset(tbm_surface_queue_h surface_queue)
648 tbm_queue_default* data = surface_queue->impl_data;
649 data->num_attached = 0;
652 static void __tbm_queue_default_destroy(tbm_surface_queue_h surface_queue)
654 free(surface_queue->impl_data);
657 static void __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue)
659 tbm_queue_default* data = surface_queue->impl_data;
660 tbm_surface_h surface;
662 if (data->queue_size == data->num_attached)
665 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
666 surface_queue->height,
667 surface_queue->format,
669 TBM_RETURN_IF_FAIL(surface != NULL);
670 _tbm_surface_queue_attach(surface_queue, surface);
671 tbm_surface_internal_unref(surface);
672 data->num_attached++;
675 static const tbm_surface_queue_interface tbm_queue_default_impl =
677 __tbm_queue_default_init,
678 __tbm_queue_default_reset,
679 __tbm_queue_default_destroy,
680 __tbm_queue_default_need_attach,
681 NULL, /*__tbm_queue_default_enqueue*/
682 NULL, /*__tbm_queue_default_release*/
683 NULL, /*__tbm_queue_default_dequeue*/
684 NULL, /*__tbm_queue_default_acquire*/
687 tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width, int height, int format, int flags)
689 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
690 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
691 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
692 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
694 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1, sizeof(struct _tbm_surface_queue));
695 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
697 tbm_queue_default *data = (tbm_queue_default *) calloc(1, sizeof(tbm_queue_default));
704 data->queue_size = queue_size;
706 _tbm_surface_queue_init(surface_queue,
707 width, height, format,
708 &tbm_queue_default_impl, data);
710 return surface_queue;
721 static void __tbm_queue_sequence_init(tbm_surface_queue_h surface_queue)
723 tbm_queue_sequence* data = surface_queue->impl_data;
725 data->num_attached = 0;
726 _queue_init(&data->dequeue_list);
729 static void __tbm_queue_sequence_reset(tbm_surface_queue_h surface_queue)
731 tbm_queue_sequence* data = surface_queue->impl_data;
733 data->num_attached = 0;
734 _queue_init(&data->dequeue_list);
737 static void __tbm_queue_sequence_destroy(tbm_surface_queue_h surface_queue)
739 free(surface_queue->impl_data);
742 static void __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue)
744 tbm_queue_sequence* data = surface_queue->impl_data;
745 tbm_surface_h surface;
747 if (data->queue_size == data->num_attached)
750 surface = tbm_surface_internal_create_with_flags(surface_queue->width,
751 surface_queue->height,
752 surface_queue->format,
754 TBM_RETURN_IF_FAIL(surface != NULL);
755 _tbm_surface_queue_attach(surface_queue, surface);
756 tbm_surface_internal_unref(surface);
757 data->num_attached++;
760 static void __tbm_queue_sequence_enqueue(tbm_surface_queue_h surface_queue, queue_node* node)
762 tbm_queue_sequence* data = surface_queue->impl_data;
763 queue_node *next = NULL;
764 queue_node *tmp = NULL;
766 node->priv_flags = 0;
768 LIST_FOR_EACH_ENTRY_SAFE(next, tmp, &data->dequeue_list.head, item_link) {
769 if (next->priv_flags) break;
770 _queue_node_pop(&data->dequeue_list, next);
771 _tbm_surface_queue_enqueue(surface_queue, next, 1);
775 static queue_node* __tbm_queue_sequence_dequeue(tbm_surface_queue_h surface_queue)
777 tbm_queue_sequence* data = surface_queue->impl_data;
778 queue_node* node = NULL;
780 node = _tbm_surface_queue_dequeue(surface_queue);
783 _queue_node_push_back(&data->dequeue_list, node);
784 node->priv_flags = 1;
790 static const tbm_surface_queue_interface tbm_queue_sequence_impl =
792 __tbm_queue_sequence_init,
793 __tbm_queue_sequence_reset,
794 __tbm_queue_sequence_destroy,
795 __tbm_queue_sequence_need_attach,
796 __tbm_queue_sequence_enqueue,
797 NULL, /*__tbm_queue_sequence_release*/
798 __tbm_queue_sequence_dequeue,
799 NULL, /*__tbm_queue_sequence_acquire*/
802 tbm_surface_queue_h tbm_surface_queue_sequence_create(int queue_size, int width, int height, int format, int flags)
804 TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL);
805 TBM_RETURN_VAL_IF_FAIL(width > 0, NULL);
806 TBM_RETURN_VAL_IF_FAIL(height > 0, NULL);
807 TBM_RETURN_VAL_IF_FAIL(format > 0, NULL);
809 tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1, sizeof(struct _tbm_surface_queue));
810 TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL);
812 tbm_queue_sequence *data = (tbm_queue_sequence *) calloc(1, sizeof(tbm_queue_sequence));
819 data->queue_size = queue_size;
821 _tbm_surface_queue_init(surface_queue,
822 width, height, format,
823 &tbm_queue_sequence_impl, data);
825 return surface_queue;