From 46f208cfaf4d85bfdd29315ebed235f80471f750 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Fri, 12 Feb 2016 11:08:21 +0900 Subject: [PATCH] tbm_surface_queue: support multiple notify handler Next APIs will be deprecated tbm_surface_queue_set_destroy_cb() tbm_surface_queue_set_dequeuable_cb() tbm_surface_queue_set_acquirable_cb() tbm_surface_queue_set_reset_cb() Change-Id: I00ee99560f4657729112639f4b66893cac3e72d8 --- src/tbm_surface_queue.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tbm_surface_queue.h | 31 +++++++-- 2 files changed, 202 insertions(+), 7 deletions(-) diff --git a/src/tbm_surface_queue.c b/src/tbm_surface_queue.c index 5b5c5e7..f24cd01 100644 --- a/src/tbm_surface_queue.c +++ b/src/tbm_surface_queue.c @@ -64,6 +64,13 @@ typedef struct { unsigned int priv_flags; /*for each queue*/ } queue_node; +typedef struct { + struct list_head link; + + tbm_surface_queue_notify_cb cb; + void *data; +} queue_notify; + typedef struct _tbm_surface_queue_interface { void (*init)(tbm_surface_queue_h queue); void (*reset)(tbm_surface_queue_h queue); @@ -85,6 +92,11 @@ struct _tbm_surface_queue { queue dirty_queue; struct list_head list; + struct list_head destory_noti; + struct list_head dequeuable_noti; + struct list_head acquirable_noti; + struct list_head reset_noti; + tbm_surface_queue_notify_cb destroy_cb; void *destroy_cb_data; @@ -219,6 +231,54 @@ static void _queue_init(queue * queue) queue->count = 0; } +static void _notify_add(struct list_head *list, tbm_surface_queue_notify_cb cb, void* data) +{ + TBM_RETURN_IF_FAIL(cb != NULL); + + queue_notify *item = (queue_notify*)calloc(1, sizeof(queue_notify)); + TBM_RETURN_IF_FAIL(item != NULL); + + LIST_INITHEAD(&item->link); + item->cb = cb; + item->data = data; + + LIST_ADDTAIL(&item->link, list); +} + +static void _notify_remove(struct list_head *list, tbm_surface_queue_notify_cb cb, void* data) +{ + queue_notify *item = NULL, *tmp = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) { + if (item->cb == cb && item->data == data) { + LIST_DEL(&item->link); + free(item); + return; + } + } + + TBM_LOG("Cannot find notifiy\n"); +} + +static void _notify_remove_all(struct list_head *list) +{ + queue_notify *item = NULL, *tmp = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) { + LIST_DEL(&item->link); + free(item); + } +} + +static void _notify_emit(tbm_surface_queue_h surface_queue, struct list_head *list) +{ + queue_notify *item = NULL, *tmp = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(item, tmp, list, link) { + item->cb(surface_queue, item->data); + } +} + void _tbm_surface_queue_attach(tbm_surface_queue_h surface_queue, tbm_surface_h surface) { queue_node *node = NULL; @@ -313,6 +373,11 @@ void _tbm_surface_queue_init(tbm_surface_queue_h surface_queue, _queue_init(&surface_queue->dirty_queue); LIST_INITHEAD(&surface_queue->list); + LIST_INITHEAD(&surface_queue->destory_noti); + LIST_INITHEAD(&surface_queue->acquirable_noti); + LIST_INITHEAD(&surface_queue->dequeuable_noti); + LIST_INITHEAD(&surface_queue->reset_noti); + if (surface_queue->impl && surface_queue->impl->init) surface_queue->impl->init(surface_queue); } @@ -331,6 +396,32 @@ tbm_surface_queue_error_e tbm_surface_queue_set_destroy_cb(tbm_surface_queue_h s return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e tbm_surface_queue_add_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_add(&surface_queue->destory_noti, destroy_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + +tbm_surface_queue_error_e tbm_surface_queue_remove_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_remove(&surface_queue->destory_noti, destroy_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + 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) { TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -345,6 +436,32 @@ tbm_surface_queue_error_e tbm_surface_queue_set_dequeuable_cb(tbm_surface_queue_ return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e tbm_surface_queue_add_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_add(&surface_queue->dequeuable_noti, dequeuable_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + +tbm_surface_queue_error_e tbm_surface_queue_remove_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_remove(&surface_queue->dequeuable_noti, dequeuable_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + 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) { TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); @@ -359,6 +476,32 @@ tbm_surface_queue_error_e tbm_surface_queue_set_acquirable_cb(tbm_surface_queue_ return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e tbm_surface_queue_add_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_add(&surface_queue->acquirable_noti, acquirable_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + +tbm_surface_queue_error_e tbm_surface_queue_remove_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_remove(&surface_queue->acquirable_noti, acquirable_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue) { TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, 0); @@ -390,6 +533,31 @@ tbm_surface_queue_error_e tbm_surface_queue_set_reset_cb(tbm_surface_queue_h sur return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e tbm_surface_queue_add_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_add(&surface_queue->acquirable_noti, reset_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + +tbm_surface_queue_error_e tbm_surface_queue_remove_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, void *data) +{ + TBM_RETURN_VAL_IF_FAIL(surface_queue != NULL, TBM_SURFACE_QUEUE_ERROR_INVALID_QUEUE); + + pthread_mutex_lock(&surface_queue->lock); + + _notify_remove(&surface_queue->acquirable_noti, reset_cb, data); + + pthread_mutex_unlock(&surface_queue->lock); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} tbm_surface_queue_error_e tbm_surface_queue_enqueue(tbm_surface_queue_h surface_queue, tbm_surface_h surface) { @@ -422,6 +590,7 @@ tbm_surface_queue_error_e tbm_surface_queue_enqueue(tbm_surface_queue_h surface_ pthread_mutex_unlock(&surface_queue->lock); pthread_cond_signal(&surface_queue->dirty_cond); + _notify_emit(surface_queue, &surface_queue->acquirable_noti); if (surface_queue->acquirable_cb) surface_queue->acquirable_cb(surface_queue, surface_queue->acquirable_cb_data); @@ -520,6 +689,7 @@ tbm_surface_queue_error_e tbm_surface_queue_release(tbm_surface_queue_h surface_ pthread_mutex_unlock(&surface_queue->lock); pthread_cond_signal(&surface_queue->free_cond); + _notify_emit(surface_queue, &surface_queue->dequeuable_noti); if (surface_queue->dequeuable_cb) surface_queue->dequeuable_cb(surface_queue, surface_queue->dequeuable_cb_data); @@ -591,6 +761,8 @@ void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue) if (surface_queue->destroy_cb) surface_queue->destroy_cb(surface_queue, surface_queue->destroy_cb_data); + _notify_emit(surface_queue, &surface_queue->destory_noti); + if (surface_queue->impl && surface_queue->impl->destroy) surface_queue->impl->destroy(surface_queue); @@ -598,6 +770,11 @@ void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue) _queue_node_delete(node); } + _notify_remove_all(&surface_queue->destory_noti); + _notify_remove_all(&surface_queue->acquirable_noti); + _notify_remove_all(&surface_queue->dequeuable_noti); + _notify_remove_all(&surface_queue->reset_noti); + pthread_mutex_destroy(&surface_queue->lock); free(surface_queue); } @@ -634,6 +811,7 @@ tbm_surface_queue_error_e tbm_surface_queue_reset(tbm_surface_queue_h surface_qu pthread_mutex_unlock(&surface_queue->lock); pthread_cond_signal(&surface_queue->free_cond); + _notify_emit(surface_queue, &surface_queue->reset_noti); if (surface_queue->reset_cb) surface_queue->reset_cb(surface_queue, surface_queue->reset_cb_data); diff --git a/src/tbm_surface_queue.h b/src/tbm_surface_queue.h index c71992a..f1ce98c 100644 --- a/src/tbm_surface_queue.h +++ b/src/tbm_surface_queue.h @@ -63,12 +63,6 @@ int tbm_surface_queue_can_dequeue(tbm_surface_queue_h surface_queue, int wait); int tbm_surface_queue_can_acquire(tbm_surface_queue_h surface_queue, int wait); -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); - -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); - -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); - void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue); int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue); @@ -79,12 +73,35 @@ int tbm_surface_queue_get_format(tbm_surface_queue_h surface_queue); tbm_surface_queue_error_e tbm_surface_queue_reset(tbm_surface_queue_h surface_queue, int width, int height, int format); -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); +tbm_surface_queue_error_e tbm_surface_queue_add_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_reset_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb reset_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_add_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_destroy_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb destroy_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_add_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_dequeuable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb dequeuable_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_add_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data); + +tbm_surface_queue_error_e tbm_surface_queue_remove_acquirable_cb(tbm_surface_queue_h surface_queue, tbm_surface_queue_notify_cb acquirable_cb, void *data); /*The functions of queue factory*/ tbm_surface_queue_h tbm_surface_queue_create(int queue_size, int width, int height, int format, int flags); tbm_surface_queue_h tbm_surface_queue_sequence_create(int queue_size, int width, int height, int format, int flags); + +/*DEPRECATED apis*/ +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); + +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); + +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); + +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); #ifdef __cplusplus } #endif -- 2.7.4