X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ftbm_surface_queue.c;h=b8e85eee79e1884ee06741eb0526ad95678d2751;hb=84d2f6d1cb3fc8ae8b448ca164da587b5a807327;hp=0896edcbe3a13dd8c25c004a1c237cab959bfa9c;hpb=0e03d2f9927089cbbfed11ee41106ffb055799fa;p=platform%2Fcore%2Fuifw%2Flibtbm.git diff --git a/src/tbm_surface_queue.c b/src/tbm_surface_queue.c index 0896edc..b8e85ee 100644 --- a/src/tbm_surface_queue.c +++ b/src/tbm_surface_queue.c @@ -33,6 +33,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tbm_bufmgr_int.h" #include "list.h" +#include #define FREE_QUEUE 1 #define DIRTY_QUEUE 2 @@ -46,6 +47,7 @@ void _tbm_surface_queue_mutex_unlock(void); #define TBM_SURF_QUEUE_RETURN_IF_FAIL(cond) {\ if (!(cond)) {\ TBM_ERR("'%s' failed.\n", #cond);\ + _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\ _tbm_surf_queue_mutex_unlock();\ return;\ } \ @@ -54,6 +56,7 @@ void _tbm_surface_queue_mutex_unlock(void); #define TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(cond, val) {\ if (!(cond)) {\ TBM_ERR("'%s' failed.\n", #cond);\ + _tbm_set_last_result(TBM_ERROR_INVALID_PARAMETER);\ _tbm_surf_queue_mutex_unlock();\ return val;\ } \ @@ -589,6 +592,8 @@ _tbm_surface_queue_init(tbm_surface_queue_h surface_queue, int width, int height, int format, const tbm_surface_queue_interface *impl, void *data) { + pthread_condattr_t free_attr, dirty_attr; + TBM_RETURN_IF_FAIL(surface_queue != NULL); TBM_RETURN_IF_FAIL(impl != NULL); @@ -596,8 +601,16 @@ _tbm_surface_queue_init(tbm_surface_queue_h surface_queue, _init_tbm_surf_queue_bufmgr(); pthread_mutex_init(&surface_queue->lock, NULL); - pthread_cond_init(&surface_queue->free_cond, NULL); - pthread_cond_init(&surface_queue->dirty_cond, NULL); + + pthread_condattr_init(&free_attr); + pthread_condattr_setclock(&free_attr, CLOCK_MONOTONIC); + pthread_cond_init(&surface_queue->free_cond, &free_attr); + pthread_condattr_destroy(&free_attr); + + pthread_condattr_init(&dirty_attr); + pthread_condattr_setclock(&dirty_attr, CLOCK_MONOTONIC); + pthread_cond_init(&surface_queue->dirty_cond, &dirty_attr); + pthread_condattr_destroy(&dirty_attr); surface_queue->queue_size = queue_size; surface_queue->width = width; @@ -631,6 +644,7 @@ tbm_surface_queue_add_destroy_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -656,6 +670,7 @@ tbm_surface_queue_remove_destroy_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -679,6 +694,7 @@ tbm_surface_queue_add_dequeuable_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -704,6 +720,7 @@ tbm_surface_queue_remove_dequeuable_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -727,6 +744,7 @@ tbm_surface_queue_add_dequeue_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -752,6 +770,7 @@ tbm_surface_queue_remove_dequeue_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -775,6 +794,7 @@ tbm_surface_queue_add_can_dequeue_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -800,6 +820,7 @@ tbm_surface_queue_remove_can_dequeue_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -823,6 +844,7 @@ tbm_surface_queue_add_acquirable_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -848,6 +870,7 @@ tbm_surface_queue_remove_acquirable_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -871,6 +894,7 @@ tbm_surface_queue_add_trace_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -896,6 +920,7 @@ tbm_surface_queue_remove_trace_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -921,6 +946,7 @@ tbm_surface_queue_set_alloc_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -946,6 +972,7 @@ tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue) int width; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0); @@ -964,6 +991,7 @@ tbm_surface_queue_get_height(tbm_surface_queue_h surface_queue) int height; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0); @@ -982,6 +1010,7 @@ tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue) int format; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0); @@ -1000,6 +1029,7 @@ tbm_surface_queue_get_size(tbm_surface_queue_h surface_queue) int queue_size; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0); @@ -1018,6 +1048,7 @@ tbm_surface_queue_add_reset_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1043,6 +1074,7 @@ tbm_surface_queue_remove_reset_cb( void *data) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1068,6 +1100,7 @@ tbm_surface_queue_enqueue(tbm_surface_queue_h int queue_type; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1089,10 +1122,13 @@ tbm_surface_queue_enqueue(tbm_surface_queue_h _tbm_surf_queue_mutex_unlock(); - if (!node) + if (!node) { + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE); return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE; - else + } else { + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST); return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST; + } } if (surface_queue->impl && surface_queue->impl->enqueue) @@ -1102,10 +1138,11 @@ tbm_surface_queue_enqueue(tbm_surface_queue_h if (!_queue_get_node(surface_queue, DIRTY_QUEUE, surface, NULL)) { TBM_ERR("enqueue surface(%p) but surface isn't present in the dirty_queue\n", surface); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); - return TBM_SURFACE_ERROR_INVALID_OPERATION; + return TBM_SURFACE_QUEUE_ERROR_INVALID_SEQUENCE; } node->type = QUEUE_NODE_TYPE_ENQUEUE; @@ -1141,6 +1178,7 @@ tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h int queue_type; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1155,6 +1193,7 @@ tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h if (node == NULL || queue_type != NODE_LIST) { TBM_ERR("tbm_surface_queue_cancel_dequeue::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n", node, queue_type); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); @@ -1198,9 +1237,10 @@ tbm_surface_queue_cancel_dequeue(tbm_surface_queue_h _tbm_surface_queue_release(surface_queue, node, 1); if (_queue_is_empty(&surface_queue->free_queue)) { + TBM_ERR("surface_queue->free_queue is empty.\n"); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE); pthread_mutex_unlock(&surface_queue->lock); - TBM_ERR("surface_queue->free_queue is empty.\n"); _tbm_surf_queue_mutex_unlock(); return TBM_SURFACE_QUEUE_ERROR_INVALID_SURFACE; } @@ -1224,6 +1264,7 @@ tbm_surface_queue_dequeue(tbm_surface_queue_h queue_node *node; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1237,13 +1278,6 @@ tbm_surface_queue_dequeue(tbm_surface_queue_h if (_queue_is_empty(&surface_queue->free_queue)) { if (surface_queue->impl && surface_queue->impl->need_attach) surface_queue->impl->need_attach(surface_queue); - - if (!_tbm_surface_queue_is_valid(surface_queue)) { - TBM_ERR("surface_queue:%p is invalid", surface_queue); - pthread_mutex_unlock(&surface_queue->lock); - _tbm_surf_queue_mutex_unlock(); - return TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE; - } } if (surface_queue->impl && surface_queue->impl->dequeue) @@ -1253,6 +1287,7 @@ tbm_surface_queue_dequeue(tbm_surface_queue_h if (node == NULL || node->surface == NULL) { TBM_ERR("_queue_node_pop_front failed\n"); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); @@ -1275,10 +1310,78 @@ tbm_surface_queue_dequeue(tbm_surface_queue_h return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e +tbm_surface_queue_can_dequeue_wait_timeout(tbm_surface_queue_h surface_queue, int ms_timeout) +{ + int ret; + struct timespec tp; + + _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), + TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + _tbm_surf_queue_mutex_unlock(); + + _notify_emit(surface_queue, &surface_queue->can_dequeue_noti); + + _tbm_surf_queue_mutex_lock(); + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), + TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue); + + if (_queue_is_empty(&surface_queue->free_queue)) { + if (surface_queue->impl && surface_queue->impl->need_attach) + surface_queue->impl->need_attach(surface_queue); + } + + if (!_queue_is_empty(&surface_queue->free_queue)) { + pthread_mutex_unlock(&surface_queue->lock); + _tbm_surf_queue_mutex_unlock(); + return TBM_SURFACE_QUEUE_ERROR_NONE; + } + + _tbm_surf_queue_mutex_unlock(); + + while (1) { + clock_gettime(CLOCK_MONOTONIC, &tp); + + if (ms_timeout > 1000) + tp.tv_sec += ms_timeout / 1000; + + tp.tv_nsec += (ms_timeout % 1000) * 1000000; + + if (tp.tv_nsec > 1000000000L) { + tp.tv_sec++; + tp.tv_nsec -= 1000000000L; + } + + ret = pthread_cond_timedwait(&surface_queue->free_cond, &surface_queue->lock, &tp); + if (ret) { + if (ret == ETIMEDOUT) { + TBM_ERR("surface_queue:%p can dequeue wait timeout", surface_queue); + pthread_mutex_unlock(&surface_queue->lock); + return TBM_SURFACE_QUEUE_ERROR_TIMEOUT; + } else { + TBM_INFO("surface_queue:%p timedwait error retry wait", surface_queue); + } + } else { + pthread_mutex_unlock(&surface_queue->lock); + return TBM_SURFACE_QUEUE_ERROR_NONE; + } + } +} + int tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0); @@ -1297,13 +1400,6 @@ tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait) if (_queue_is_empty(&surface_queue->free_queue)) { if (surface_queue->impl && surface_queue->impl->need_attach) surface_queue->impl->need_attach(surface_queue); - - if (!_tbm_surface_queue_is_valid(surface_queue)) { - TBM_ERR("surface_queue:%p is invalid", surface_queue); - pthread_mutex_unlock(&surface_queue->lock); - _tbm_surf_queue_mutex_unlock(); - return 0; - } } if (!_queue_is_empty(&surface_queue->free_queue)) { @@ -1312,8 +1408,7 @@ tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait) return 1; } - if (wait && _tbm_surface_queue_get_node_count(surface_queue, - QUEUE_NODE_TYPE_ACQUIRE)) { + if (wait) { _tbm_surf_queue_mutex_unlock(); pthread_cond_wait(&surface_queue->free_cond, &surface_queue->lock); pthread_mutex_unlock(&surface_queue->lock); @@ -1333,6 +1428,7 @@ tbm_surface_queue_release(tbm_surface_queue_h int queue_type; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1351,10 +1447,13 @@ tbm_surface_queue_release(tbm_surface_queue_h _tbm_surf_queue_mutex_unlock(); - if (!node) + if (!node) { + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE); return TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE; - else + } else { + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST); return TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST; + } } if (node->delete_pending) { @@ -1395,6 +1494,7 @@ tbm_surface_queue_release(tbm_surface_queue_h if (!_queue_get_node(surface_queue, FREE_QUEUE, surface, NULL)) { TBM_ERR("release surface(%p) but surface isn't present in the free_queue\n", surface); + _tbm_set_last_result(TBM_SURFACE_ERROR_INVALID_OPERATION); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); @@ -1423,6 +1523,7 @@ tbm_surface_queue_cancel_acquire(tbm_surface_queue_h int queue_type; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1437,6 +1538,7 @@ tbm_surface_queue_cancel_acquire(tbm_surface_queue_h if (node == NULL || queue_type != NODE_LIST) { TBM_ERR("tbm_surface_queue_cancel_acquire::Surface is existed in free_queue or dirty_queue node:%p, type:%d\n", node, queue_type); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_ALREADY_EXIST); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); @@ -1450,6 +1552,7 @@ tbm_surface_queue_cancel_acquire(tbm_surface_queue_h if (_queue_is_empty(&surface_queue->dirty_queue)) { TBM_ERR("enqueue surface but queue is empty node:%p\n", node); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_UNKNOWN_SURFACE); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); @@ -1477,6 +1580,7 @@ tbm_surface_queue_acquire(tbm_surface_queue_h queue_node *node; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); *surface = NULL; @@ -1494,6 +1598,7 @@ tbm_surface_queue_acquire(tbm_surface_queue_h if (node == NULL || node->surface == NULL) { TBM_ERR("_queue_node_pop_front failed\n"); + _tbm_set_last_result(TBM_SURFACE_QUEUE_ERROR_EMPTY); pthread_mutex_unlock(&surface_queue->lock); _tbm_surf_queue_mutex_unlock(); @@ -1535,6 +1640,7 @@ int tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), 0); @@ -1567,6 +1673,7 @@ tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue) queue_node *node = NULL, *tmp; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue)); @@ -1607,6 +1714,7 @@ tbm_surface_queue_reset(tbm_surface_queue_h queue_node *node = NULL, *tmp; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1662,6 +1770,7 @@ tbm_surface_queue_error_e tbm_surface_queue_notify_reset(tbm_surface_queue_h surface_queue) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1677,10 +1786,15 @@ tbm_surface_queue_error_e tbm_surface_queue_notify_dequeuable(tbm_surface_queue_h surface_queue) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + pthread_mutex_lock(&surface_queue->lock); + pthread_mutex_unlock(&surface_queue->lock); + pthread_cond_signal(&surface_queue->free_cond); + _tbm_surf_queue_mutex_unlock(); _notify_emit(surface_queue, &surface_queue->dequeuable_noti); @@ -1695,6 +1809,7 @@ tbm_surface_queue_set_size(tbm_surface_queue_h queue_node *node = NULL, *tmp; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1711,6 +1826,14 @@ tbm_surface_queue_set_size(tbm_surface_queue_h pthread_mutex_lock(&surface_queue->lock); if (flush) { + surface_queue->queue_size = queue_size; + + if (surface_queue->num_attached == 0) { + pthread_mutex_unlock(&surface_queue->lock); + _tbm_surf_queue_mutex_unlock(); + return TBM_SURFACE_QUEUE_ERROR_NONE; + } + if (surface_queue->modes & TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) { /* Destory surface and Push to free_queue */ LIST_FOR_EACH_ENTRY_SAFE(node, tmp, &surface_queue->free_queue.head, item_link) @@ -1730,7 +1853,6 @@ tbm_surface_queue_set_size(tbm_surface_queue_h _queue_init(&surface_queue->free_queue); surface_queue->num_attached = 0; - surface_queue->queue_size = queue_size; if (surface_queue->impl && surface_queue->impl->reset) surface_queue->impl->reset(surface_queue); @@ -1777,6 +1899,7 @@ tbm_surface_queue_free_flush(tbm_surface_queue_h surface_queue) queue_node *node = NULL; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1813,6 +1936,7 @@ tbm_surface_queue_flush(tbm_surface_queue_h surface_queue) queue_node *node = NULL, *tmp; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1866,6 +1990,7 @@ tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue, queue_node *node = NULL; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1893,10 +2018,42 @@ tbm_surface_queue_get_surfaces(tbm_surface_queue_h surface_queue, } tbm_surface_queue_error_e +tbm_surface_queue_get_acquirable_surfaces(tbm_surface_queue_h surface_queue, + tbm_surface_h *surfaces, int *num) +{ + queue_node *node = NULL; + + _tbm_surf_queue_mutex_lock(); + + *num = 0; + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), + TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(num != NULL, + TBM_ERROR_INVALID_PARAMETER); + + pthread_mutex_lock(&surface_queue->lock); + + LIST_FOR_EACH_ENTRY(node, &surface_queue->dirty_queue.head, item_link) { + if (surfaces) + surfaces[*num] = node->surface; + + *num = *num + 1; + } + + pthread_mutex_unlock(&surface_queue->lock); + + _tbm_surf_queue_mutex_unlock(); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + +tbm_surface_queue_error_e tbm_surface_queue_get_trace_surface_num( tbm_surface_queue_h surface_queue, tbm_surface_queue_trace trace, int *num) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -1954,11 +2111,7 @@ __tbm_queue_default_need_attach(tbm_surface_queue_h surface_queue) return; if (surface_queue->alloc_cb) { - pthread_mutex_unlock(&surface_queue->lock); - _tbm_surf_queue_mutex_unlock(); surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data); - _tbm_surf_queue_mutex_lock(); - pthread_mutex_lock(&surface_queue->lock); /* silent return */ if (!surface) @@ -1993,16 +2146,22 @@ tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width, int height, int format, int flags) { - TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL); - TBM_RETURN_VAL_IF_FAIL(width > 0, NULL); - TBM_RETURN_VAL_IF_FAIL(height > 0, NULL); - TBM_RETURN_VAL_IF_FAIL(format > 0, NULL); - _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL); tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1, sizeof(struct _tbm_surface_queue)); - TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL); + if (!surface_queue) { + TBM_ERR("cannot allocate the surface_queue.\n"); + _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY); + _tbm_surf_queue_mutex_unlock(); + return NULL; + } TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue); @@ -2010,6 +2169,7 @@ tbm_surface_queue_create(int queue_size, int width, sizeof(tbm_queue_default)); if (data == NULL) { TBM_ERR("cannot allocate the tbm_queue_default.\n"); + _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY); free(surface_queue); _tbm_surf_queue_mutex_unlock(); return NULL; @@ -2066,11 +2226,7 @@ __tbm_queue_sequence_need_attach(tbm_surface_queue_h surface_queue) return; if (surface_queue->alloc_cb) { - pthread_mutex_unlock(&surface_queue->lock); - _tbm_surf_queue_mutex_unlock(); surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data); - _tbm_surf_queue_mutex_lock(); - pthread_mutex_lock(&surface_queue->lock); /* silent return */ if (!surface) @@ -2153,16 +2309,22 @@ tbm_surface_queue_h tbm_surface_queue_sequence_create(int queue_size, int width, int height, int format, int flags) { - TBM_RETURN_VAL_IF_FAIL(queue_size > 0, NULL); - TBM_RETURN_VAL_IF_FAIL(width > 0, NULL); - TBM_RETURN_VAL_IF_FAIL(height > 0, NULL); - TBM_RETURN_VAL_IF_FAIL(format > 0, NULL); - _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); + + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(queue_size > 0, NULL); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(width > 0, NULL); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(height > 0, NULL); + TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(format > 0, NULL); tbm_surface_queue_h surface_queue = (tbm_surface_queue_h) calloc(1, sizeof(struct _tbm_surface_queue)); - TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(surface_queue != NULL, NULL); + if (surface_queue == NULL) { + TBM_ERR("cannot allocate the surface_queue.\n"); + _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY); + _tbm_surf_queue_mutex_unlock(); + return NULL; + } TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue); @@ -2170,6 +2332,7 @@ tbm_surface_queue_sequence_create(int queue_size, int width, sizeof(tbm_queue_sequence)); if (data == NULL) { TBM_ERR("cannot allocate the tbm_queue_sequence.\n"); + _tbm_set_last_result(TBM_ERROR_OUT_OF_MEMORY); free(surface_queue); _tbm_surf_queue_mutex_unlock(); return NULL; @@ -2191,6 +2354,7 @@ tbm_surface_queue_set_modes(tbm_surface_queue_h surface_queue, int modes) { _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -2216,6 +2380,7 @@ tbm_surface_queue_set_sync_count(tbm_surface_queue_h surface_queue, int dequeue_num, enqueue_num; _tbm_surf_queue_mutex_lock(); + _tbm_set_last_result(TBM_ERROR_NONE); TBM_SURF_QUEUE_RETURN_VAL_IF_FAIL(_tbm_surface_queue_is_valid(surface_queue), TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE);