From: Changyeon Lee Date: Fri, 28 Oct 2022 07:20:42 +0000 (+0900) Subject: tbm_surface_queue: add tbm_surface_queue_set_alloc_cb2 X-Git-Tag: accepted/tizen/unified/20221102.020555~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=70ed536395779e99a3fc46c45798d468fda0e483;p=platform%2Fcore%2Fuifw%2Flibtbm.git tbm_surface_queue: add tbm_surface_queue_set_alloc_cb2 surface queue infomation can be mismatched when tbm_surface_queue_reset and tbm_surface_queue_can_dequeue_wait_timeout are called in different thread. 1. tbm_surface_queue_can_dequeue_wait_timeout is called in thread1 and it wait free buffer 2. tbm_surface_queue_reset is called in thread2 3. waiting of thread1 is finished but wayland_tbm create surface with queue_info 4. _handle_tbm_surface_queue_reset_notify is called and queue_info is updated for resolving this problem, libtbm add queue infomation in alloc callback and wayland_tbm create surface with argument of alloc callback. Change-Id: Ie3274ee8380f0073445b7116c5e26cfbe86f60a2 --- diff --git a/include/tbm_surface_queue.h b/include/tbm_surface_queue.h index 3fce8e0..d067688 100644 --- a/include/tbm_surface_queue.h +++ b/include/tbm_surface_queue.h @@ -60,9 +60,12 @@ typedef struct _tbm_surface_queue *tbm_surface_queue_h; typedef void (*tbm_surface_queue_notify_cb)(tbm_surface_queue_h surface_queue, void *data); -typedef tbm_surface_h(*tbm_surface_alloc_cb)(tbm_surface_queue_h surface_queue, +typedef tbm_surface_h (*tbm_surface_alloc_cb)(tbm_surface_queue_h surface_queue, void *data); +typedef tbm_surface_h (*tbm_surface_alloc_cb2)(tbm_surface_queue_h surface_queue, + int width, int height, int format, int flags, void *data); + typedef void (*tbm_surface_free_cb)(tbm_surface_queue_h surface_queue, void *data, tbm_surface_h surface); @@ -167,6 +170,8 @@ void tbm_surface_queue_destroy(tbm_surface_queue_h surface_queue); * the tbm_surface_queue dequeue the tbm_surface returned in alloc_cb * free_cb is called when the tbm_surface_queue unreference the tbm_surface. * + * @remarks You must use either tbm_surface_queue_set_alloc_cb or tbm_surface_queue_set_alloc_cb2 + * * @param[in] surface_queue The #tbm_surface_queue_h * @param[in] alloc_cb The callback of allocate * @param[in] free_cb The callback of free @@ -181,6 +186,28 @@ tbm_surface_queue_error_e tbm_surface_queue_set_alloc_cb( tbm_surface_free_cb free_cb, void *data); +/** + * @brief Sets allocate callback to the tbm_surface_queue. + * alloc_cb2 is called when the tbm_surface_queue try to allocate the tbm_surface and + * the tbm_surface_queue dequeue the tbm_surface returned in alloc_cb2 + * free_cb is called when the tbm_surface_queue unreference the tbm_surface. + * + * @remarks You must use either tbm_surface_queue_set_alloc_cb or tbm_surface_queue_set_alloc_cb2 + * + * @param[in] surface_queue The #tbm_surface_queue_h + * @param[in] alloc_cb2 The callback of allocate + * @param[in] free_cb The callback of free + * @param[in] data The user data + * + * @return #TBM_SURFACE_QUEUE_ERROR_NONE on success, + * otherwise an error status value + */ +tbm_surface_queue_error_e tbm_surface_queue_set_alloc_cb2( + tbm_surface_queue_h surface_queue, + tbm_surface_alloc_cb2 alloc_cb2, + tbm_surface_free_cb free_cb, + void *data); + /** * @brief Gets the width of the tbm_surface_queue. * diff --git a/src/tbm_surface_queue.c b/src/tbm_surface_queue.c index ee93127..5d59296 100644 --- a/src/tbm_surface_queue.c +++ b/src/tbm_surface_queue.c @@ -146,6 +146,7 @@ struct _tbm_surface_queue { //For external buffer allocation tbm_surface_alloc_cb alloc_cb; + tbm_surface_alloc_cb2 alloc_cb2; tbm_surface_free_cb free_cb; void *alloc_cb_data; @@ -491,10 +492,18 @@ _tbm_surface_queue_need_attach(tbm_surface_queue_h surface_queue) if (surface_queue->queue_size == surface_queue->num_attached) return; - if (surface_queue->alloc_cb) { - surface = surface_queue->alloc_cb(surface_queue, surface_queue->alloc_cb_data); + if (surface_queue->alloc_cb2) { + surface = surface_queue->alloc_cb2(surface_queue, + surface_queue->width, surface_queue->height, + surface_queue->format, surface_queue->flags, + surface_queue->alloc_cb_data); + if (!surface) + return; - /* silent return */ + tbm_surface_internal_ref(surface); + } else if (surface_queue->alloc_cb){ + surface = surface_queue->alloc_cb(surface_queue, + surface_queue->alloc_cb_data); if (!surface) return; @@ -934,6 +943,14 @@ tbm_surface_queue_set_alloc_cb( TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue); + if (surface_queue->alloc_cb2) { + TBM_ERR("must use either alloc_cb or alloc_cb2"); + _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION); + pthread_mutex_unlock(&surface_queue->lock); + _tbm_surf_queue_mutex_unlock(); + return TBM_ERROR_INVALID_OPERATION; + } + surface_queue->alloc_cb = alloc_cb; surface_queue->free_cb = free_cb; surface_queue->alloc_cb_data = data; @@ -945,6 +962,42 @@ tbm_surface_queue_set_alloc_cb( return TBM_SURFACE_QUEUE_ERROR_NONE; } +tbm_surface_queue_error_e +tbm_surface_queue_set_alloc_cb2( + tbm_surface_queue_h surface_queue, + tbm_surface_alloc_cb2 alloc_cb2, + tbm_surface_free_cb free_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); + + pthread_mutex_lock(&surface_queue->lock); + + TBM_TRACE_SURFACE_QUEUE("tbm_surface_queue(%p)\n", surface_queue); + + if (surface_queue->alloc_cb) { + TBM_ERR("must use either alloc_cb or alloc_cb2"); + _tbm_set_last_result(TBM_ERROR_INVALID_OPERATION); + pthread_mutex_unlock(&surface_queue->lock); + _tbm_surf_queue_mutex_unlock(); + return TBM_ERROR_INVALID_OPERATION; + } + + surface_queue->alloc_cb2 = alloc_cb2; + surface_queue->free_cb = free_cb; + surface_queue->alloc_cb_data = data; + + pthread_mutex_unlock(&surface_queue->lock); + + _tbm_surf_queue_mutex_unlock(); + + return TBM_SURFACE_QUEUE_ERROR_NONE; +} + int tbm_surface_queue_get_width(tbm_surface_queue_h surface_queue) {