From 3a542008d6540197a28d82243573929a4f4873b0 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 8 Aug 2016 14:01:26 +0900 Subject: [PATCH 01/16] tpl-wayland-egl: Add tracking list of tbm_surface in order to track dequeued buffers. When tbm_surface_queue was reset, if the dequeued buffer(s) render done, don't call tbm_surface_enqueue and do wl_surface_commit directly. Change-Id: I095964f3fbb6c21f4fffc43f2682182f3cedb34a Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 109 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 72 insertions(+), 37 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 2fc074d..1be54c2 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -45,6 +45,7 @@ struct _tpl_wayland_egl_surface { tpl_bool_t reset; /* TRUE if queue reseted by external */ tpl_bool_t vblank_done; tpl_list_t *attached_buffers; /* list for tracking [ACQ]~[REL] buffers */ + tpl_list_t *dequeued_buffers; /* list for tracking [DEQ]~[ENQ] buffers */ struct wl_proxy *wl_proxy; /* wl_tbm_queue proxy */ }; @@ -316,12 +317,33 @@ static void __cb_client_window_resize_callback(struct wl_egl_window *wl_egl_window, void *private); +static TPL_INLINE void +__tpl_wayland_egl_buffer_set_reset_flag(tpl_list_t *tracking_list) +{ + tpl_wayland_egl_buffer_t *wayland_egl_buffer = NULL; + tbm_surface_h tbm_surface = NULL; + tpl_list_node_t *node = __tpl_list_get_front_node(tracking_list); + + while (node) + { + tbm_surface = (tbm_surface_h) __tpl_list_node_get_data(node); + + if (tbm_surface) + wayland_egl_buffer = + __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); + + if (wayland_egl_buffer) + wayland_egl_buffer->reset = TPL_TRUE; + + node = __tpl_list_node_next(node); + } +} + static void __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h surface_queue, void *data) { tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t*) data; - tpl_list_node_t *node = NULL; if (!wayland_egl_surface) return; @@ -331,24 +353,12 @@ __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h surface_queue, wayland_egl_surface->reset = TPL_TRUE; - /* Set the reset flag of the buffers which attaced but not released to TPL_TRUE. */ - node = __tpl_list_get_front_node(wayland_egl_surface->attached_buffers); - - while (node) - { - tbm_surface_h tbm_surface = (tbm_surface_h) __tpl_list_node_get_data(node); - tpl_wayland_egl_buffer_t *wayland_egl_buffer = NULL; - - if (!tbm_surface) break; + /* Set the reset flag of the buffers which attached but not released to TPL_TRUE. */ + __tpl_wayland_egl_buffer_set_reset_flag(wayland_egl_surface->attached_buffers); - wayland_egl_buffer = - __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); - if (!wayland_egl_buffer) break; + /* Set the reset flag of the buffers which dequeued but not enqueued to TPL_TRUE. */ + __tpl_wayland_egl_buffer_set_reset_flag(wayland_egl_surface->dequeued_buffers); - wayland_egl_buffer->reset = TPL_TRUE; - - node = __tpl_list_node_next(node); - } } static tpl_result_t @@ -379,8 +389,10 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) wayland_egl_surface->current_buffer = NULL; wayland_egl_surface->attached_buffers = __tpl_list_alloc(); - if (!wayland_egl_surface->attached_buffers) { - TPL_ERR("Failed to allcate the list of attached_buffers."); + wayland_egl_surface->dequeued_buffers = __tpl_list_alloc(); + if (!wayland_egl_surface->attached_buffers + || !wayland_egl_surface->dequeued_buffers) { + TPL_ERR("Failed to allocate tracking lists."); free(wayland_egl_surface); surface->backend.data = NULL; return TPL_ERROR_INVALID_OPERATION; @@ -504,6 +516,12 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) wayland_egl_surface->attached_buffers = NULL; } + /* the list of dequeued_buffers just does deletion */ + if (wayland_egl_surface->dequeued_buffers) { + __tpl_list_free(wayland_egl_surface->dequeued_buffers, NULL); + wayland_egl_surface->dequeued_buffers = NULL; + } + free(wayland_egl_surface); surface->backend.data = NULL; } @@ -654,6 +672,7 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t *) surface->backend.data; + tpl_wayland_egl_buffer_t *wayland_egl_buffer = NULL; tbm_surface_queue_error_e tsq_err; if (!tbm_surface_internal_is_valid(tbm_surface)) { @@ -674,21 +693,18 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, __tpl_wayland_egl_surface_wait_vblank(surface); } - tsq_err = tbm_surface_queue_enqueue(wayland_egl_surface->tbm_queue, - tbm_surface); - if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE) { - /* - * If tbm_surface_queue has not been reset, tbm_surface_queue_enqueue - * will return ERROR_NONE. Otherwise, queue has been reset - * this tbm_surface may have only one ref_count. So we need to - * unreference this tbm_surface after getting ERROR_NONE result from - * tbm_surface_queue_enqueue in order to prevent destruction. - */ + /* Stop tracking of this render_done tbm_surface. */ + __tpl_list_remove_data(wayland_egl_surface->dequeued_buffers, + (void *)tbm_surface, TPL_FIRST, NULL); - tbm_surface_internal_unref(tbm_surface); - } else { + wayland_egl_buffer = + __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); + + if (wayland_egl_buffer->reset) + { /* - * When tbm_surface_queue being reset for receiving scan-out buffer + * When tbm_surface_queue being reset for receiving + * scan-out buffer or resized buffer * tbm_surface_queue_enqueue will return error. * This error condition leads to skip frame. * @@ -699,18 +715,34 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, */ __tpl_wayland_egl_surface_commit(surface, tbm_surface, num_rects, rects); - TPL_WARN("Failed to enqeueue tbm_surface. But, commit forcibly.| tsq_err = %d", - tsq_err); return TPL_ERROR_NONE; } - /* deprecated */ + tsq_err = tbm_surface_queue_enqueue(wayland_egl_surface->tbm_queue, + tbm_surface); + if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE) { + /* + * If tbm_surface_queue has not been reset, tbm_surface_queue_enqueue + * will return ERROR_NONE. Otherwise, queue has been reset + * this tbm_surface may have only one ref_count. So we need to + * unreference this tbm_surface after getting ERROR_NONE result from + * tbm_surface_queue_enqueue in order to prevent destruction. + */ + tbm_surface_internal_unref(tbm_surface); + } else { + + TPL_ERR("Failed to enqeueue tbm_surface(%p). | tsq_err = %d", + tbm_surface, tsq_err); + return TPL_ERROR_INVALID_OPERATION; + } + tsq_err = tbm_surface_queue_acquire(wayland_egl_surface->tbm_queue, &tbm_surface); if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE) { tbm_surface_internal_ref(tbm_surface); } else { - TPL_ERR("Failed to acquire tbm_surface. | tsq_err = %d", tsq_err); + TPL_ERR("Failed to acquire tbm_surface(%p). | tsq_err = %d", + tbm_surface, tsq_err); return TPL_ERROR_INVALID_OPERATION; } @@ -892,6 +924,8 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface) wayland_egl_buffer->wl_proxy, tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); + /* Start tracking of this tbm_surface until enqueue */ + __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, (void *)tbm_surface); return tbm_surface; } @@ -948,6 +982,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface) wayland_egl_buffer, wayland_egl_buffer->wl_proxy, tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); + __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, (void *)tbm_surface); return tbm_surface; } @@ -1075,7 +1110,7 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) if (wayland_egl_buffer) { wayland_egl_surface = wayland_egl_buffer->wayland_egl_surface; - /* Stop tracking of this release tbm_surface. */ + /* Stop tracking of this released tbm_surface. */ __tpl_list_remove_data(wayland_egl_surface->attached_buffers, (void *)tbm_surface, TPL_FIRST, NULL); -- 2.7.4 From 08cf2391c9c9ebc7562bb20b529c85399bd36c4b Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Mon, 22 Aug 2016 23:30:58 +0900 Subject: [PATCH 02/16] tpl_wayland_egl: Add Null check on wayland_egl_buffer and wayland_egl_surface of __tpl_wayland_egl_surface_enqueue_buffer() Change-Id: Ice0924f4a9a068ad5962d3743538f03ce46cf766 Signed-off-by: Mun, Gwan-gyeong --- src/tpl_wayland_egl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 1be54c2..d817d7c 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -675,6 +675,8 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, tpl_wayland_egl_buffer_t *wayland_egl_buffer = NULL; tbm_surface_queue_error_e tsq_err; + if (!wayland_egl_surface) return TPL_ERROR_INVALID_PARAMETER; + if (!tbm_surface_internal_is_valid(tbm_surface)) { TPL_ERR("Failed to enqueue tbm_surface(%p) Invalid value.", tbm_surface); @@ -700,6 +702,8 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, wayland_egl_buffer = __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); + if (!wayland_egl_buffer) return TPL_ERROR_INVALID_PARAMETER; + if (wayland_egl_buffer->reset) { /* -- 2.7.4 From c76449dfa207b58dc39eb86847f4f7451214048a Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Thu, 28 Jul 2016 15:02:56 +0900 Subject: [PATCH 03/16] [sync] added dequeue/enqueue with sync interface added function - tpl_surface_dequeue_buffer_with_sync - tpl_surface_enqueue_buffer_with_damage_and_sync added parameter in backend function dequeue_buffer timeout, tbm_sync_fence_h enqueue_buffer tbm_sync_fence_h this patch dependent https://review.tizen.org/gerrit/#/c/84089/ Change-Id: I2eb7bf54c43fc75dcb73dc6a12b76eb21659eaca --- src/tpl.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tpl_gbm.c | 8 ++++++-- src/tpl_internal.h | 6 ++++-- src/tpl_surface.c | 24 ++++++++++++++++++++--- src/tpl_tbm.c | 8 ++++++-- src/tpl_wayland_egl.c | 8 ++++++-- src/tpl_wayland_vk_wsi.c | 9 +++++++-- 7 files changed, 100 insertions(+), 13 deletions(-) diff --git a/src/tpl.h b/src/tpl.h index 3365a6d..1196e26 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -63,6 +63,7 @@ #define TPL_DONT_CARE -1 #include +#include /** * Boolean variable type. * @@ -459,6 +460,26 @@ tbm_surface_h tpl_surface_dequeue_buffer(tpl_surface_t *surface); /** + * Get the buffer of the current frame for the given TPL surface. + * + * This function returns buffer of the current frame. Depending on backend, + * communication with the server might be required. + * Returned buffers can used for render target after sync_fence signaled. + * + * @param surface surface to get buffer for the current frame. + * @param timeout_ns block timeout nano seconds. + * @param sync_fence signal when buffer is valid. + * @return buffer for the current frame or NULL when timeout. + * + * @see tpl_surface_enqueue_buffer() + * @see tpl_surface_enqueue_buffer_with_damage() + * @see tpl_surface_get_swapchain_buffers() + */ +tbm_surface_h +tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, uint64_t timeout_ns, + tbm_sync_fence_h *sync_fence); + +/** * Post a given tbm_surface. * * This function request display server to post a frame. This is the @@ -505,6 +526,35 @@ tpl_surface_enqueue_buffer_with_damage(tpl_surface_t *surface, int num_rects, const int *rects); /** + * Post a given tbm_surface with region of damage. + * + * Damage information is used for reducing number of pixels composited in the + * compositor. Setting num_rects to 0 or rects to NULL means entire area is damaged. + * + * This function request display server to post a frame. + * This function is identical with tpl_surface_enqueue_buffer except delivering + * the damage information for updating. + * This function will be wait internally until signaled sync. + * + * Make sure this function is called exactly once for a frame. + * Scheduling post calls on a separate thread is recommended. + * + * @param surface surface to post a frame. + * @param tbm_surface buffer to post. + * @param num_rects the number of rectangles of the damage region. + * @param rects pointer to coordinates of rectangles. x0, y0, w0, h0, x1, y1, w1, h1... + * @param sync_fence signal when draw done. + * + * @see tpl_surface_enqueue_buffer() + * @see tpl_surface_dequeue_buffer() + * @see tpl_surface_get_swapchain_buffers() + */ +tpl_result_t +tpl_surface_enqueue_buffer_with_damage_and_sync(tpl_surface_t *surface, + tbm_surface_h tbm_surface, + int num_rects, const int *rects, + tbm_sync_fence_h sync_fence); +/** * Set frame interval of the given TPL surface. * * Frame interval ensures that only a single frame is posted within the diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c index adee701..7465f5d 100644 --- a/src/tpl_gbm.c +++ b/src/tpl_gbm.c @@ -335,7 +335,7 @@ __tpl_gbm_surface_fini(tpl_surface_t *surface) static tpl_result_t __tpl_gbm_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, - const int *rects) + const int *rects, tbm_sync_fence_h sync_fence) { tbm_bo bo; @@ -396,7 +396,8 @@ __tpl_gbm_surface_validate(tpl_surface_t *surface) } static tbm_surface_h -__tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface) +__tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, + tbm_sync_fence_h *sync_fence) { tbm_bo bo; tbm_surface_h tbm_surface = NULL; @@ -410,6 +411,9 @@ __tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface) TPL_ASSERT(surface->display); TPL_ASSERT(surface->display->native_handle); + if (sync_fence) + *sync_fence = NULL; + gbm_surface = (tpl_gbm_surface_t *)surface->backend.data; TRACE_BEGIN("WAITING FOR DEQUEUEABLE"); diff --git a/src/tpl_internal.h b/src/tpl_internal.h index 7822571..adcb48c 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -59,10 +59,12 @@ struct _tpl_surface_backend { tpl_result_t (*init)(tpl_surface_t *surface); void (*fini)(tpl_surface_t *surface); tpl_bool_t (*validate)(tpl_surface_t *surface); - tbm_surface_h (*dequeue_buffer)(tpl_surface_t *surface); + tbm_surface_h (*dequeue_buffer)(tpl_surface_t *surface, uint64_t timeout_ns, + tbm_sync_fence_h *sync_fence); tpl_result_t (*enqueue_buffer)(tpl_surface_t *surface, tbm_surface_h tbm_surface, - int num_rects, const int *rects); + int num_rects, const int *rects, + tbm_sync_fence_h sync_fence); tpl_result_t (*get_swapchain_buffers)(tpl_surface_t *surface, tbm_surface_h **buffers, int *buffer_count); diff --git a/src/tpl_surface.c b/src/tpl_surface.c index d79fd5d..a5d6c7d 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -181,6 +181,13 @@ tpl_surface_get_post_interval(tpl_surface_t *surface) tbm_surface_h tpl_surface_dequeue_buffer(tpl_surface_t *surface) { + return tpl_surface_dequeue_buffer_with_sync(surface, UINT64_MAX, NULL); +} + +tbm_surface_h +tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, uint64_t timeout_ns, + tbm_sync_fence_h *sync_fence) +{ TPL_ASSERT(surface); tbm_surface_h tbm_surface = NULL; @@ -202,7 +209,7 @@ tpl_surface_dequeue_buffer(tpl_surface_t *surface) } if (!tbm_surface) - tbm_surface = surface->backend.dequeue_buffer(surface); + tbm_surface = surface->backend.dequeue_buffer(surface, timeout_ns, sync_fence); if (tbm_surface) { /* Update size of the surface. */ @@ -222,7 +229,8 @@ tpl_surface_dequeue_buffer(tpl_surface_t *surface) tpl_result_t tpl_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface) { - return tpl_surface_enqueue_buffer_with_damage(surface, tbm_surface, 0, NULL); + return tpl_surface_enqueue_buffer_with_damage_and_sync(surface, tbm_surface, + 0, NULL, NULL); } tpl_result_t @@ -230,6 +238,16 @@ tpl_surface_enqueue_buffer_with_damage(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects) { + return tpl_surface_enqueue_buffer_with_damage_and_sync(surface, tbm_surface, + num_rects, rects, NULL); +} + +tpl_result_t +tpl_surface_enqueue_buffer_with_damage_and_sync(tpl_surface_t *surface, + tbm_surface_h tbm_surface, + int num_rects, const int *rects, + tbm_sync_fence_h sync_fence) +{ tpl_result_t ret = TPL_ERROR_NONE; if (!surface || (surface->type != TPL_SURFACE_TYPE_WINDOW)) { @@ -261,7 +279,7 @@ tpl_surface_enqueue_buffer_with_damage(tpl_surface_t *surface, tbm_surface_get_height(tbm_surface)); /* Call backend post */ - ret = surface->backend.enqueue_buffer(surface, tbm_surface, num_rects, rects); + ret = surface->backend.enqueue_buffer(surface, tbm_surface, num_rects, rects, sync_fence); TPL_OBJECT_UNLOCK(surface); TRACE_END(); diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index 6e7b696..58e55cf 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -235,7 +235,7 @@ __tpl_tbm_surface_fini(tpl_surface_t *surface) static tpl_result_t __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, - const int *rects) + const int *rects, tbm_sync_fence_h sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->display); @@ -283,7 +283,8 @@ __tpl_tbm_surface_validate(tpl_surface_t *surface) } static tbm_surface_h -__tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface) +__tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, + tbm_sync_fence_h *sync_fence) { tbm_surface_h tbm_surface = NULL; tbm_surface_queue_h tbm_queue = NULL; @@ -294,6 +295,9 @@ __tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface) TPL_ASSERT(surface->display); TPL_ASSERT(surface->display->native_handle); + if (sync_fence) + *sync_fence = NULL; + tbm_queue = (tbm_surface_queue_h)surface->native_handle; tsq_err = tbm_surface_queue_dequeue(tbm_queue, &tbm_surface); diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index d817d7c..3dd502e 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -664,7 +664,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, static tpl_result_t __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, - int num_rects, const int *rects) + int num_rects, const int *rects, tbm_sync_fence_h sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->display); @@ -869,7 +869,8 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) } static tbm_surface_h -__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface) +__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, + tbm_sync_fence_h *sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -885,6 +886,9 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface) struct wl_proxy *wl_proxy = NULL; tbm_surface_queue_error_e tsq_err = 0; + if (sync_fence) + *sync_fence = NULL; + /* Check whether the surface was resized by wayland_egl */ if (wayland_egl_surface->resized == TPL_TRUE) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *) diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index 9aadfb6..cc45c05 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -290,7 +290,8 @@ __tpl_wayland_vk_wsi_surface_fini(tpl_surface_t *surface) static tpl_result_t __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, - int num_rects, const int *rects) + int num_rects, const int *rects, + tbm_sync_fence_h sync_fence) { struct wl_surface *wl_sfc = NULL; struct wl_callback *frame_callback = NULL; @@ -364,7 +365,8 @@ __tpl_wayland_vk_wsi_surface_validate(tpl_surface_t *surface) } static tbm_surface_h -__tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface) +__tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, + uint64_t timeout_ns, tbm_sync_fence_h *sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -379,6 +381,9 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface) struct wl_proxy *wl_proxy = NULL; tbm_surface_queue_error_e tsq_err = 0; + if (sync_fence) + *sync_fence = NULL; + TPL_OBJECT_UNLOCK(surface); while (tbm_surface_queue_can_dequeue( wayland_vk_wsi_surface->tbm_queue, 0) == 0) { -- 2.7.4 From 49c4de720459d6607a4cc7d7cac76401921b88a8 Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Thu, 28 Jul 2016 16:31:45 +0900 Subject: [PATCH 04/16] tpl_wayland_vk_wsi: [sync] implement make sync timeline and send create timeline when buffer created and transfer to server and server increase timeline value create fence when buffer acquired and client wait fence before draw this patch client side need server side patch Change-Id: Ibfb4bb9dbc6bd0c7bb1fb0fbb36c1faeac7a23d7 --- src/tpl_wayland_vk_wsi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index cc45c05..cde5dae 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -9,6 +9,8 @@ #include #include +#include + #define CLIENT_QUEUE_SIZE 3 typedef struct _tpl_wayland_vk_wsi_display tpl_wayland_vk_wsi_display_t; @@ -32,6 +34,8 @@ struct _tpl_wayland_vk_wsi_buffer { tpl_display_t *display; tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface; struct wl_proxy *wl_proxy; + tbm_sync_timeline_h sync_timeline; + unsigned int sync_timestamp; }; static const struct wl_registry_listener registry_listener; @@ -351,6 +355,7 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, wl_surface_commit(wl_sfc); wl_display_flush(surface->display->native_handle); + wayland_vk_wsi_buffer->sync_timestamp++; return TPL_ERROR_NONE; } @@ -380,6 +385,7 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, (tpl_wayland_vk_wsi_display_t *)surface->display->backend.data; struct wl_proxy *wl_proxy = NULL; tbm_surface_queue_error_e tsq_err = 0; + tbm_sync_error_e sync_err; if (sync_fence) *sync_fence = NULL; @@ -409,6 +415,24 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, if ((wayland_vk_wsi_buffer = __tpl_wayland_vk_wsi_get_wayland_buffer_from_tbm_surface( tbm_surface)) != NULL) { + if (sync_fence) { + if (wayland_vk_wsi_buffer->sync_timestamp) { + /* first return -1 */ + char name[32]; + snprintf(name, 32, "%d", + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + *sync_fence = tbm_sync_fence_create(wayland_vk_wsi_buffer->sync_timeline, + name, + wayland_vk_wsi_buffer->sync_timestamp, + &sync_err); + if (*sync_fence == NULL || sync_err != TBM_SYNC_ERROR_NONE) { + TPL_ERR("Failed to create TBM sync fence!"); + /* ??? destroy and return NULL */ + } + } else { + *sync_fence = NULL; + } + } return tbm_surface; } @@ -429,6 +453,22 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, return NULL; } + /* can change signaled sync */ + if (sync_fence) + *sync_fence = NULL; + wayland_vk_wsi_buffer->sync_timeline = tbm_sync_timeline_create(&sync_err); + if (wayland_vk_wsi_buffer->sync_timeline == NULL || sync_err != TBM_SYNC_ERROR_NONE) { + TPL_ERR("Failed to create TBM sync timeline!"); + wl_proxy_destroy(wl_proxy); + tbm_surface_internal_unref(tbm_surface); + free(wayland_vk_wsi_buffer); + return NULL; + } + wayland_vk_wsi_buffer->sync_timestamp = 0; + wayland_tbm_client_set_sync_timeline(wayland_vk_wsi_display->wl_tbm_client, + (void *)wl_proxy, + wayland_vk_wsi_buffer->sync_timeline); + wl_buffer_add_listener((void *)wl_proxy, &buffer_release_listener, tbm_surface); @@ -593,6 +633,9 @@ __tpl_wayland_vk_wsi_buffer_free(tpl_wayland_vk_wsi_buffer_t wayland_tbm_client_destroy_buffer(wayland_vk_wsi_display->wl_tbm_client, (void *)wayland_vk_wsi_buffer->wl_proxy); + if (wayland_vk_wsi_buffer->sync_timeline != NULL) + tbm_sync_timeline_destroy(wayland_vk_wsi_buffer->sync_timeline); + free(wayland_vk_wsi_buffer); } -- 2.7.4 From 84e78d65185c3c4dfe009e29ba796d64c965379f Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Fri, 29 Jul 2016 12:33:06 +0900 Subject: [PATCH 05/16] tpl_wayland_vk_wsi: [sync] move buffer_release after buffer_acquire move buffer_release after buffer_acquire for vulkan's acquireNextImage spec. and insert wl_display_dispatch in enqueue_buffer's last line. if not call wl_display_dispatch it occur broken pipe. see code's comments. Change-Id: If2d1e52404c1e9425a0196392b99eba8f28b6d60 --- src/tpl_wayland_vk_wsi.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index cde5dae..03d47aa 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -357,6 +357,17 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, wl_display_flush(surface->display->native_handle); wayland_vk_wsi_buffer->sync_timestamp++; + /* + * tbm_surface insert to free queue. + * tbm_surface_can_dequeue always return true in single thread. + * __tpl_wayland_vk_wsi_surface_dequeue_buffer doesn't call wl_display_dispatch. + * wayland event queue are fulled and occur broken pipe. + * so need call wl_display_dispatch. + * need discussion wl_display_dispatch position(in dequeue or worker thread ??). + */ + tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, tbm_surface); + wl_display_dispatch(surface->display->native_handle); + return TPL_ERROR_NONE; } @@ -738,8 +749,6 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) wayland_vk_wsi_surface = wayland_vk_wsi_buffer->wayland_vk_wsi_surface; tbm_surface_internal_unref(tbm_surface); - - tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, tbm_surface); } } -- 2.7.4 From aea738a9f8d4a30d8c921466a8b4ecc8b02bdfb7 Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Fri, 29 Jul 2016 15:56:30 +0900 Subject: [PATCH 06/16] tpl_wayland_vk_wsi: [sync] wait driver's sync in enqueue (without thread) wait driver's draw done signal with sync_fd before attach/commit Change-Id: I8c85231693a4b8c5e646bb5d0ef5eca10c17515c --- src/tpl_wayland_vk_wsi.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index 03d47aa..aa88150 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -337,6 +337,15 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, return TPL_ERROR_INVALID_OPERATION; } + if (sync_fence != NULL) { + /* non worker thread mode */ + tbm_sync_error_e sync_err; + sync_err = tbm_sync_fence_wait(sync_fence, -1); + if (sync_err != TBM_SYNC_ERROR_NONE) + TPL_ERR("Failed to wait sync. | error: %d", errno); + tbm_sync_fence_destroy(sync_fence); + } + tsq_err = tbm_surface_queue_acquire(wayland_vk_wsi_surface->tbm_queue, &tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { -- 2.7.4 From 31c97918f11290c63439673b84d8747716ef2e8d Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Mon, 1 Aug 2016 14:45:07 +0900 Subject: [PATCH 07/16] tpl_wayland_vk_wsi: [sync] divide __tpl_wayland_vk_wsi_surface_enqueue_buffer added func __tpl_wayland_vk_wsi_surface_commit_buffer this func do 'attach/commit/insert free queue' buffer for worker thread Change-Id: I609c5a1e2d59e5340b5f27e1c61e6147e8189bd6 --- src/tpl_wayland_vk_wsi.c | 61 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index aa88150..c238a6d 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -13,6 +13,10 @@ #define CLIENT_QUEUE_SIZE 3 +#ifndef USE_WORKER_THREAD +#define USE_WORKER_THREAD 0 +#endif + typedef struct _tpl_wayland_vk_wsi_display tpl_wayland_vk_wsi_display_t; typedef struct _tpl_wayland_vk_wsi_surface tpl_wayland_vk_wsi_surface_t; typedef struct _tpl_wayland_vk_wsi_buffer tpl_wayland_vk_wsi_buffer_t; @@ -291,14 +295,49 @@ __tpl_wayland_vk_wsi_surface_fini(tpl_surface_t *surface) surface->backend.data = NULL; } +static void +__tpl_wayland_vk_wsi_surface_commit_buffer(tpl_surface_t *surface, + tbm_surface_h tbm_surface) +{ + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + TPL_ASSERT(surface->display->native_handle); + TPL_ASSERT(tbm_surface); + + struct wl_surface *wl_sfc = NULL; + struct wl_callback *frame_callback = NULL; + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = + (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; + tpl_wayland_vk_wsi_buffer_t *wayland_vk_wsi_buffer = + __tpl_wayland_vk_wsi_get_wayland_buffer_from_tbm_surface(tbm_surface); + TPL_ASSERT(wayland_vk_wsi_buffer); + + + wl_sfc = (struct wl_surface *)surface->native_handle; + + tbm_surface_internal_ref(tbm_surface); + wl_surface_attach(wl_sfc, (void *)wayland_vk_wsi_buffer->wl_proxy, 0, 0); + + /* TODO: num_rects and rects add to tpl_wayland_vk_wsi_buffer_t */ + wl_surface_damage(wl_sfc, 0, 0, surface->width, surface->height); + + frame_callback = wl_surface_frame(wl_sfc); + wl_callback_add_listener(frame_callback, &frame_listener, tbm_surface); + + wl_surface_commit(wl_sfc); + + wl_display_flush(surface->display->native_handle); + wayland_vk_wsi_buffer->sync_timestamp++; + + tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, tbm_surface); +} + static tpl_result_t __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects, tbm_sync_fence_h sync_fence) { - struct wl_surface *wl_sfc = NULL; - struct wl_callback *frame_callback = NULL; TPL_ASSERT(surface); TPL_ASSERT(surface->display); @@ -326,8 +365,6 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, TPL_IMAGE_DUMP(bo_handle.ptr, surface->width, surface->height, surface->dump_count++); - wl_sfc = (struct wl_surface *)surface->native_handle; - tbm_surface_internal_unref(tbm_surface); tsq_err = tbm_surface_queue_enqueue(wayland_vk_wsi_surface->tbm_queue, @@ -337,6 +374,7 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, return TPL_ERROR_INVALID_OPERATION; } +#if USE_WORKER_THREAD == 0 if (sync_fence != NULL) { /* non worker thread mode */ tbm_sync_error_e sync_err; @@ -353,18 +391,8 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, return TPL_ERROR_INVALID_OPERATION; } - tbm_surface_internal_ref(tbm_surface); - wl_surface_attach(wl_sfc, (void *)wayland_vk_wsi_buffer->wl_proxy, 0, 0); - - wl_surface_damage(wl_sfc, 0, 0, surface->width, surface->height); - - frame_callback = wl_surface_frame(wl_sfc); - wl_callback_add_listener(frame_callback, &frame_listener, tbm_surface); - - wl_surface_commit(wl_sfc); - - wl_display_flush(surface->display->native_handle); - wayland_vk_wsi_buffer->sync_timestamp++; + __tpl_wayland_vk_wsi_surface_commit_buffer(surface, tbm_surface); +#endif /* * tbm_surface insert to free queue. @@ -374,7 +402,6 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, * so need call wl_display_dispatch. * need discussion wl_display_dispatch position(in dequeue or worker thread ??). */ - tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, tbm_surface); wl_display_dispatch(surface->display->native_handle); return TPL_ERROR_NONE; -- 2.7.4 From 097ed4752eefa46f8e63e5c1afdc6f55351f2527 Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Mon, 1 Aug 2016 17:31:10 +0900 Subject: [PATCH 08/16] tpl_wayland_vk_wsi: [sync - thread] added worker thread the worker thread do wait buffer's draw done signal before attach/commit and wait buffer enqueue with pthread_condition. main thread support timeout in dequeue_buffer with worker thread.(single thread not support timeout) this patch can modify clear after libtbm support timeout(can dequeue/can acquire) Change-Id: I90fe6340c4457169073537f18c1fd7368b5b5f7b --- src/tpl_wayland_vk_wsi.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 178 insertions(+), 1 deletion(-) diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index c238a6d..1a61cdd 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -13,8 +13,14 @@ #define CLIENT_QUEUE_SIZE 3 +#define USE_WORKER_THREAD #ifndef USE_WORKER_THREAD #define USE_WORKER_THREAD 0 +#else +#include +#include +#undef USE_WORKER_THREAD +#define USE_WORKER_THREAD 1 #endif typedef struct _tpl_wayland_vk_wsi_display tpl_wayland_vk_wsi_display_t; @@ -32,6 +38,21 @@ struct _tpl_wayland_vk_wsi_display { struct _tpl_wayland_vk_wsi_surface { tbm_surface_queue_h tbm_queue; int buffer_count; + +#if USE_WORKER_THREAD == 1 + /* TODO: move thread per display or process */ + pthread_t worker_id; + tpl_bool_t worker_running; + + /* + * TODO: it can move to libtbm + * libtbm already has free queue's pthread_cond and pthread_mutex + */ + pthread_mutex_t dirty_queue_mutex; + pthread_cond_t dirty_queue_cond; + pthread_mutex_t free_queue_mutex; + pthread_cond_t free_queue_cond; +#endif }; struct _tpl_wayland_vk_wsi_buffer { @@ -40,6 +61,10 @@ struct _tpl_wayland_vk_wsi_buffer { struct wl_proxy *wl_proxy; tbm_sync_timeline_h sync_timeline; unsigned int sync_timestamp; + +#if USE_WORKER_THREAD == 1 + tbm_sync_fence_h wait_sync; +#endif }; static const struct wl_registry_listener registry_listener; @@ -318,7 +343,7 @@ __tpl_wayland_vk_wsi_surface_commit_buffer(tpl_surface_t *surface, tbm_surface_internal_ref(tbm_surface); wl_surface_attach(wl_sfc, (void *)wayland_vk_wsi_buffer->wl_proxy, 0, 0); - /* TODO: num_rects and rects add to tpl_wayland_vk_wsi_buffer_t */ + /* TODO: add num_rects and rects to tpl_wayland_vk_wsi_buffer_t */ wl_surface_damage(wl_sfc, 0, 0, surface->width, surface->height); frame_callback = wl_surface_frame(wl_sfc); @@ -329,7 +354,14 @@ __tpl_wayland_vk_wsi_surface_commit_buffer(tpl_surface_t *surface, wl_display_flush(surface->display->native_handle); wayland_vk_wsi_buffer->sync_timestamp++; +#if USE_WORKER_THREAD == 1 + pthread_mutex_lock(&wayland_vk_wsi_surface->free_queue_mutex); +#endif tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, tbm_surface); +#if USE_WORKER_THREAD == 1 + pthread_mutex_unlock(&wayland_vk_wsi_surface->free_queue_mutex); + pthread_cond_signal(&wayland_vk_wsi_surface->free_queue_cond); +#endif } static tpl_result_t @@ -367,10 +399,17 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_internal_unref(tbm_surface); +#if USE_WORKER_THREAD == 1 + wayland_vk_wsi_buffer->wait_sync = sync_fence; + pthread_mutex_lock(&wayland_vk_wsi_surface->dirty_queue_mutex); +#endif tsq_err = tbm_surface_queue_enqueue(wayland_vk_wsi_surface->tbm_queue, tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to enqeueue tbm_surface. | tsq_err = %d", tsq_err); +#if USE_WORKER_THREAD == 1 + pthread_mutex_unlock(&wayland_vk_wsi_surface->dirty_queue_mutex); +#endif return TPL_ERROR_INVALID_OPERATION; } @@ -392,6 +431,13 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, } __tpl_wayland_vk_wsi_surface_commit_buffer(surface, tbm_surface); +#else + /* + * TODO: it can move to libtbm + * libtbm already has dirty queue's pthread_cond and pthread_mutex + */ + pthread_mutex_unlock(&wayland_vk_wsi_surface->dirty_queue_mutex); + pthread_cond_signal(&wayland_vk_wsi_surface->dirty_queue_cond); #endif /* @@ -437,6 +483,7 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, if (sync_fence) *sync_fence = NULL; +#if USE_WORKER_THREAD == 0 TPL_OBJECT_UNLOCK(surface); while (tbm_surface_queue_can_dequeue( wayland_vk_wsi_surface->tbm_queue, 0) == 0) { @@ -448,9 +495,45 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, } } TPL_OBJECT_LOCK(surface); +#else + /* + * TODO: it can move to libtbm + * libtbm already has free queue's pthread_cond and pthread_mutex + */ + struct timespec abs_time; + if (timeout_ns != UINT64_MAX) { + clock_gettime(CLOCK_REALTIME, &abs_time); + abs_time.tv_sec += (timeout_ns / 1000000000L); + abs_time.tv_nsec += (timeout_ns % 1000000000L); + if (abs_time.tv_nsec >= 1000000000L) { + abs_time.tv_sec += (abs_time.tv_nsec / 1000000000L); + abs_time.tv_nsec = (abs_time.tv_nsec % 1000000000L); + } + } + pthread_mutex_lock(&wayland_vk_wsi_surface->free_queue_mutex); + while (tbm_surface_queue_can_dequeue(wayland_vk_wsi_surface->tbm_queue, 0) == 0) { + if (timeout_ns != UINT64_MAX) { + int ret; + ret = pthread_cond_timedwait(&wayland_vk_wsi_surface->free_queue_cond, + &wayland_vk_wsi_surface->free_queue_mutex, + &abs_time); + if (ret == ETIMEDOUT) { + /* timeout */ + pthread_mutex_unlock(&wayland_vk_wsi_surface->free_queue_mutex); + return NULL; + } + } else { + pthread_cond_wait(&wayland_vk_wsi_surface->free_queue_cond, + &wayland_vk_wsi_surface->free_queue_mutex); + } + } +#endif tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &tbm_surface); +#if USE_WORKER_THREAD == 1 + pthread_mutex_unlock(&wayland_vk_wsi_surface->free_queue_mutex); +#endif if (!tbm_surface) { TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d", tsq_err); @@ -595,6 +678,11 @@ release_buffer_fail: return TPL_ERROR_INVALID_OPERATION; } +#if USE_WORKER_THREAD == 1 +static void * +__tpl_wayland_vk_wsi_worker_thread_loop(void *arg); +#endif + static tpl_result_t __tpl_wayland_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, tbm_format format, int width, @@ -636,6 +724,17 @@ __tpl_wayland_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, surface->width = width; surface->height = height; +#if USE_WORKER_THREAD == 1 + pthread_mutex_init(&wayland_vk_wsi_surface->dirty_queue_mutex, NULL); + pthread_mutex_init(&wayland_vk_wsi_surface->free_queue_mutex, NULL); + pthread_cond_init(&wayland_vk_wsi_surface->dirty_queue_cond, NULL); + pthread_cond_init(&wayland_vk_wsi_surface->free_queue_cond, NULL); + + wayland_vk_wsi_surface->worker_running = 1; + pthread_create(&wayland_vk_wsi_surface->worker_id, NULL, + __tpl_wayland_vk_wsi_worker_thread_loop, surface); + +#endif return TPL_ERROR_NONE; } @@ -660,6 +759,15 @@ __tpl_wayland_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) wayland_vk_wsi_surface->tbm_queue = NULL; } +#if USE_WORKER_THREAD == 1 + wayland_vk_wsi_surface->worker_running = 0; + pthread_join(wayland_vk_wsi_surface->worker_id, NULL); + + pthread_cond_destroy(&wayland_vk_wsi_surface->free_queue_cond); + pthread_cond_destroy(&wayland_vk_wsi_surface->dirty_queue_cond); + pthread_mutex_destroy(&wayland_vk_wsi_surface->free_queue_mutex); + pthread_mutex_destroy(&wayland_vk_wsi_surface->dirty_queue_mutex); +#endif return TPL_ERROR_NONE; } @@ -791,3 +899,72 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) static const struct wl_buffer_listener buffer_release_listener = { (void *)__cb_client_buffer_release_callback, }; + +#if USE_WORKER_THREAD == 1 +static void * +__tpl_wayland_vk_wsi_worker_thread_loop(void *arg) +{ + tpl_surface_t *surface = arg; + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = + (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; + + /* + * TODO: it can change when thread per display or process model + * then need poll all surface's buffers wait sync + */ + while (wayland_vk_wsi_surface->worker_running) { + tbm_surface_queue_error_e tsq_err; + tbm_surface_h tbm_surface; + tpl_wayland_vk_wsi_buffer_t *wayland_vk_wsi_buffer; + + /* + * TODO: it can move to libtbm + * libtbm already has dirty queue's pthread_cond and pthread_mutex + * or with wait vblank in poll + */ + struct timespec abs_time; + tpl_bool_t timeout = TPL_FALSE; + + clock_gettime(CLOCK_REALTIME, &abs_time); + abs_time.tv_sec += 1; + pthread_mutex_lock(&wayland_vk_wsi_surface->dirty_queue_mutex); + while (tbm_surface_queue_can_acquire(wayland_vk_wsi_surface->tbm_queue, 0) == 0 && + timeout == TPL_FALSE) { + int ret; + ret = pthread_cond_timedwait(&wayland_vk_wsi_surface->dirty_queue_cond, + &wayland_vk_wsi_surface->dirty_queue_mutex, + &abs_time); + if (ret == ETIMEDOUT) { + timeout = TPL_TRUE; + } + } + if (timeout) { + pthread_mutex_unlock(&wayland_vk_wsi_surface->dirty_queue_mutex); + continue; + } + + tsq_err = tbm_surface_queue_acquire(wayland_vk_wsi_surface->tbm_queue, &tbm_surface); + pthread_mutex_unlock(&wayland_vk_wsi_surface->dirty_queue_mutex); + if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to acquire tbm_surface. | tsq_err = %d", tsq_err); + continue; + } + + wayland_vk_wsi_buffer = + __tpl_wayland_vk_wsi_get_wayland_buffer_from_tbm_surface(tbm_surface); + TPL_ASSERT(wayland_vk_wsi_buffer); + if (wayland_vk_wsi_buffer->wait_sync != NULL) { + tbm_sync_error_e sync_err; + sync_err = tbm_sync_fence_wait(wayland_vk_wsi_buffer->wait_sync, -1); + if (sync_err != TBM_SYNC_ERROR_NONE) + TPL_ERR("Failed to wait sync. | error: %d", errno); + tbm_sync_fence_destroy(wayland_vk_wsi_buffer->wait_sync); + wayland_vk_wsi_buffer->wait_sync = NULL; + } + + __tpl_wayland_vk_wsi_surface_commit_buffer(surface, tbm_surface); + } + + return NULL; +} +#endif -- 2.7.4 From 9f547b050595c438840fde344664fb67cb11486f Mon Sep 17 00:00:00 2001 From: "deasung.kim" Date: Wed, 24 Aug 2016 17:14:20 +0900 Subject: [PATCH 09/16] libtpl-egl: change the usage of libtbm_sync api remove tbm_sync objects and use fd tbm sync related api change reference: https://review.tizen.org/gerrit/#/c/85169/ submitted Change-Id: Ia291424c127487bed3af99759b6f37e9bd76c27a --- src/tpl.h | 4 +-- src/tpl_gbm.c | 11 +++++--- src/tpl_internal.h | 4 +-- src/tpl_surface.c | 8 +++--- src/tpl_tbm.c | 11 +++++--- src/tpl_wayland_egl.c | 11 +++++--- src/tpl_wayland_vk_wsi.c | 66 ++++++++++++++++++++---------------------------- 7 files changed, 59 insertions(+), 56 deletions(-) diff --git a/src/tpl.h b/src/tpl.h index 1196e26..585165d 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -477,7 +477,7 @@ tpl_surface_dequeue_buffer(tpl_surface_t *surface); */ tbm_surface_h tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, uint64_t timeout_ns, - tbm_sync_fence_h *sync_fence); + tbm_fd *sync_fence); /** * Post a given tbm_surface. @@ -553,7 +553,7 @@ tpl_result_t tpl_surface_enqueue_buffer_with_damage_and_sync(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects, - tbm_sync_fence_h sync_fence); + tbm_fd sync_fence); /** * Set frame interval of the given TPL surface. * diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c index 7465f5d..02242cb 100644 --- a/src/tpl_gbm.c +++ b/src/tpl_gbm.c @@ -335,7 +335,7 @@ __tpl_gbm_surface_fini(tpl_surface_t *surface) static tpl_result_t __tpl_gbm_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, - const int *rects, tbm_sync_fence_h sync_fence) + const int *rects, tbm_fd sync_fence) { tbm_bo bo; @@ -373,6 +373,11 @@ __tpl_gbm_surface_enqueue_buffer(tpl_surface_t *surface, return TPL_ERROR_INVALID_PARAMETER; } + if (sync_fence != -1) { + tbm_sync_fence_wait(sync_fence, -1); + close(sync_fence); + } + if (tbm_surface_queue_enqueue(gbm_surface->tbm_queue, tbm_surface) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("tbm_surface_queue_enqueue failed. tbm_surface_queue(%p) tbm_surface(%p)", @@ -397,7 +402,7 @@ __tpl_gbm_surface_validate(tpl_surface_t *surface) static tbm_surface_h __tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, - tbm_sync_fence_h *sync_fence) + tbm_fd *sync_fence) { tbm_bo bo; tbm_surface_h tbm_surface = NULL; @@ -412,7 +417,7 @@ __tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, TPL_ASSERT(surface->display->native_handle); if (sync_fence) - *sync_fence = NULL; + *sync_fence = -1; gbm_surface = (tpl_gbm_surface_t *)surface->backend.data; diff --git a/src/tpl_internal.h b/src/tpl_internal.h index adcb48c..f9d0f71 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -60,11 +60,11 @@ struct _tpl_surface_backend { void (*fini)(tpl_surface_t *surface); tpl_bool_t (*validate)(tpl_surface_t *surface); tbm_surface_h (*dequeue_buffer)(tpl_surface_t *surface, uint64_t timeout_ns, - tbm_sync_fence_h *sync_fence); + tbm_fd *sync_fence); tpl_result_t (*enqueue_buffer)(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects, - tbm_sync_fence_h sync_fence); + tbm_fd sync_fence); tpl_result_t (*get_swapchain_buffers)(tpl_surface_t *surface, tbm_surface_h **buffers, int *buffer_count); diff --git a/src/tpl_surface.c b/src/tpl_surface.c index a5d6c7d..c9b2c88 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -186,7 +186,7 @@ tpl_surface_dequeue_buffer(tpl_surface_t *surface) tbm_surface_h tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, uint64_t timeout_ns, - tbm_sync_fence_h *sync_fence) + tbm_fd *sync_fence) { TPL_ASSERT(surface); @@ -230,7 +230,7 @@ tpl_result_t tpl_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface) { return tpl_surface_enqueue_buffer_with_damage_and_sync(surface, tbm_surface, - 0, NULL, NULL); + 0, NULL, -1); } tpl_result_t @@ -239,14 +239,14 @@ tpl_surface_enqueue_buffer_with_damage(tpl_surface_t *surface, int num_rects, const int *rects) { return tpl_surface_enqueue_buffer_with_damage_and_sync(surface, tbm_surface, - num_rects, rects, NULL); + num_rects, rects, -1); } tpl_result_t tpl_surface_enqueue_buffer_with_damage_and_sync(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects, - tbm_sync_fence_h sync_fence) + tbm_fd sync_fence) { tpl_result_t ret = TPL_ERROR_NONE; diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index 58e55cf..1dd2207 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -235,7 +235,7 @@ __tpl_tbm_surface_fini(tpl_surface_t *surface) static tpl_result_t __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, - const int *rects, tbm_sync_fence_h sync_fence) + const int *rects, tbm_fd sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->display); @@ -264,6 +264,11 @@ __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, return TPL_ERROR_INVALID_PARAMETER; } + if (sync_fence != -1) { + tbm_sync_fence_wait(sync_fence, -1); + close(sync_fence); + } + if (tbm_surface_queue_enqueue(tbm_queue, tbm_surface) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("tbm_surface_queue_enqueue failed. tbm_queue(%p) tbm_surface(%p)", @@ -284,7 +289,7 @@ __tpl_tbm_surface_validate(tpl_surface_t *surface) static tbm_surface_h __tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, - tbm_sync_fence_h *sync_fence) + tbm_fd *sync_fence) { tbm_surface_h tbm_surface = NULL; tbm_surface_queue_h tbm_queue = NULL; @@ -296,7 +301,7 @@ __tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, TPL_ASSERT(surface->display->native_handle); if (sync_fence) - *sync_fence = NULL; + *sync_fence = -1; tbm_queue = (tbm_surface_queue_h)surface->native_handle; diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 3dd502e..25b72e7 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -664,7 +664,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, static tpl_result_t __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, - int num_rects, const int *rects, tbm_sync_fence_h sync_fence) + int num_rects, const int *rects, tbm_fd sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->display); @@ -695,6 +695,11 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, __tpl_wayland_egl_surface_wait_vblank(surface); } + if (sync_fence != -1) { + tbm_sync_fence_wait(sync_fence, -1); + close(sync_fence); + } + /* Stop tracking of this render_done tbm_surface. */ __tpl_list_remove_data(wayland_egl_surface->dequeued_buffers, (void *)tbm_surface, TPL_FIRST, NULL); @@ -870,7 +875,7 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) static tbm_surface_h __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, - tbm_sync_fence_h *sync_fence) + tbm_fd *sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -887,7 +892,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou tbm_surface_queue_error_e tsq_err = 0; if (sync_fence) - *sync_fence = NULL; + *sync_fence = -1; /* Check whether the surface was resized by wayland_egl */ if (wayland_egl_surface->resized == TPL_TRUE) { diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index 1a61cdd..fd38861 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -59,11 +59,11 @@ struct _tpl_wayland_vk_wsi_buffer { tpl_display_t *display; tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface; struct wl_proxy *wl_proxy; - tbm_sync_timeline_h sync_timeline; + tbm_fd sync_timeline; unsigned int sync_timestamp; #if USE_WORKER_THREAD == 1 - tbm_sync_fence_h wait_sync; + tbm_fd wait_sync; #endif }; @@ -368,7 +368,7 @@ static tpl_result_t __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, tbm_surface_h tbm_surface, int num_rects, const int *rects, - tbm_sync_fence_h sync_fence) + tbm_fd sync_fence) { TPL_ASSERT(surface); @@ -414,13 +414,12 @@ __tpl_wayland_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, } #if USE_WORKER_THREAD == 0 - if (sync_fence != NULL) { + if (sync_fence != -1) { /* non worker thread mode */ - tbm_sync_error_e sync_err; - sync_err = tbm_sync_fence_wait(sync_fence, -1); - if (sync_err != TBM_SYNC_ERROR_NONE) - TPL_ERR("Failed to wait sync. | error: %d", errno); - tbm_sync_fence_destroy(sync_fence); + /* TODO: set max wait time */ + if (tbm_sync_fence_wait(sync_fence, -1) != 1) + TPL_ERR("Failed to wait sync. | error: %d(%s)", errno, strerror(errno)); + close(sync_fence); } tsq_err = tbm_surface_queue_acquire(wayland_vk_wsi_surface->tbm_queue, @@ -464,7 +463,7 @@ __tpl_wayland_vk_wsi_surface_validate(tpl_surface_t *surface) static tbm_surface_h __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, - uint64_t timeout_ns, tbm_sync_fence_h *sync_fence) + uint64_t timeout_ns, tbm_fd *sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -478,10 +477,9 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, (tpl_wayland_vk_wsi_display_t *)surface->display->backend.data; struct wl_proxy *wl_proxy = NULL; tbm_surface_queue_error_e tsq_err = 0; - tbm_sync_error_e sync_err; if (sync_fence) - *sync_fence = NULL; + *sync_fence = -1; #if USE_WORKER_THREAD == 0 TPL_OBJECT_UNLOCK(surface); @@ -553,14 +551,11 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); *sync_fence = tbm_sync_fence_create(wayland_vk_wsi_buffer->sync_timeline, name, - wayland_vk_wsi_buffer->sync_timestamp, - &sync_err); - if (*sync_fence == NULL || sync_err != TBM_SYNC_ERROR_NONE) { - TPL_ERR("Failed to create TBM sync fence!"); - /* ??? destroy and return NULL */ - } + wayland_vk_wsi_buffer->sync_timestamp); + if (*sync_fence == -1) + TPL_ERR("Failed to create TBM sync fence: %d(%s)", errno, strerror(errno)); } else { - *sync_fence = NULL; + *sync_fence = -1; } } return tbm_surface; @@ -585,10 +580,10 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, /* can change signaled sync */ if (sync_fence) - *sync_fence = NULL; - wayland_vk_wsi_buffer->sync_timeline = tbm_sync_timeline_create(&sync_err); - if (wayland_vk_wsi_buffer->sync_timeline == NULL || sync_err != TBM_SYNC_ERROR_NONE) { - TPL_ERR("Failed to create TBM sync timeline!"); + *sync_fence = -1; + wayland_vk_wsi_buffer->sync_timeline = tbm_sync_timeline_create(); + if (wayland_vk_wsi_buffer->sync_timeline == -1) { + TPL_ERR("Failed to create TBM sync timeline: %d(%s)", errno, strerror(errno)); wl_proxy_destroy(wl_proxy); tbm_surface_internal_unref(tbm_surface); free(wayland_vk_wsi_buffer); @@ -788,8 +783,8 @@ __tpl_wayland_vk_wsi_buffer_free(tpl_wayland_vk_wsi_buffer_t wayland_tbm_client_destroy_buffer(wayland_vk_wsi_display->wl_tbm_client, (void *)wayland_vk_wsi_buffer->wl_proxy); - if (wayland_vk_wsi_buffer->sync_timeline != NULL) - tbm_sync_timeline_destroy(wayland_vk_wsi_buffer->sync_timeline); + if (wayland_vk_wsi_buffer->sync_timeline != -1) + close(wayland_vk_wsi_buffer->sync_timeline); free(wayland_vk_wsi_buffer); } @@ -878,7 +873,6 @@ static const struct wl_callback_listener frame_listener = { static void __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) { - tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; tpl_wayland_vk_wsi_buffer_t *wayland_vk_wsi_buffer = NULL; tbm_surface_h tbm_surface = NULL; @@ -889,11 +883,8 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) wayland_vk_wsi_buffer = __tpl_wayland_vk_wsi_get_wayland_buffer_from_tbm_surface(tbm_surface); - if (wayland_vk_wsi_buffer) { - wayland_vk_wsi_surface = wayland_vk_wsi_buffer->wayland_vk_wsi_surface; - + if (wayland_vk_wsi_buffer) tbm_surface_internal_unref(tbm_surface); - } } static const struct wl_buffer_listener buffer_release_listener = { @@ -934,9 +925,8 @@ __tpl_wayland_vk_wsi_worker_thread_loop(void *arg) ret = pthread_cond_timedwait(&wayland_vk_wsi_surface->dirty_queue_cond, &wayland_vk_wsi_surface->dirty_queue_mutex, &abs_time); - if (ret == ETIMEDOUT) { + if (ret == ETIMEDOUT) timeout = TPL_TRUE; - } } if (timeout) { pthread_mutex_unlock(&wayland_vk_wsi_surface->dirty_queue_mutex); @@ -953,13 +943,11 @@ __tpl_wayland_vk_wsi_worker_thread_loop(void *arg) wayland_vk_wsi_buffer = __tpl_wayland_vk_wsi_get_wayland_buffer_from_tbm_surface(tbm_surface); TPL_ASSERT(wayland_vk_wsi_buffer); - if (wayland_vk_wsi_buffer->wait_sync != NULL) { - tbm_sync_error_e sync_err; - sync_err = tbm_sync_fence_wait(wayland_vk_wsi_buffer->wait_sync, -1); - if (sync_err != TBM_SYNC_ERROR_NONE) - TPL_ERR("Failed to wait sync. | error: %d", errno); - tbm_sync_fence_destroy(wayland_vk_wsi_buffer->wait_sync); - wayland_vk_wsi_buffer->wait_sync = NULL; + if (wayland_vk_wsi_buffer->wait_sync != -1) { + if (tbm_sync_fence_wait(wayland_vk_wsi_buffer->wait_sync, -1) != 1) + TPL_ERR("Failed to wait sync. | error: %d(%s)", errno, strerror(errno)); + close(wayland_vk_wsi_buffer->wait_sync); + wayland_vk_wsi_buffer->wait_sync = -1; } __tpl_wayland_vk_wsi_surface_commit_buffer(surface, tbm_surface); -- 2.7.4 From 901bfcee4475d316da7680100b3f210d996402bc Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 24 Aug 2016 19:58:30 +0900 Subject: [PATCH 10/16] tpl_wayland_egl: Create tdm_vblank object directly and maintain every surfaces until destroy. tdm_vblank object decide to be maintained every tpl_wayland_egl_surface for the case where one or more surfaces are created in one display connection. Change-Id: I74a3195d1d7f6662d233edf30f43ac87902da4b5 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 71 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 25b72e7..24ba414 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -43,6 +43,7 @@ struct _tpl_wayland_egl_surface { tbm_surface_h current_buffer; tpl_bool_t resized; tpl_bool_t reset; /* TRUE if queue reseted by external */ + tdm_client_vblank *tdm_vblank; /* vblank object for each wl_surface */ tpl_bool_t vblank_done; tpl_list_t *attached_buffers; /* list for tracking [ACQ]~[REL] buffers */ tpl_list_t *dequeued_buffers; /* list for tracking [DEQ]~[ENQ] buffers */ @@ -362,6 +363,37 @@ __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h surface_queue, } static tpl_result_t +__tpl_wayland_egl_surface_create_vblank(tpl_wayland_egl_surface_t *wayland_egl_surface, + tdm_client *tdm_client) +{ + tdm_client_output *tdm_output = NULL; + tdm_error tdm_err_ret; + + TPL_ASSERT(wayland_egl_surface); + TPL_ASSERT(tdm_client); + + tdm_output = tdm_client_get_output(tdm_client, "primary", &tdm_err_ret); + if (!tdm_output) { + TPL_ERR("Failed to get tdm client output. tdm_err(%d)", tdm_err_ret); + return TPL_ERROR_INVALID_OPERATION; + } + + wayland_egl_surface->tdm_vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err_ret); + if (!wayland_egl_surface->tdm_vblank) { + TPL_ERR("Failed to create tdm vblank object. tdm_err(%d)", tdm_err_ret); + return TPL_ERROR_INVALID_OPERATION; + } + + tdm_client_vblank_set_enable_fake(wayland_egl_surface->tdm_vblank, 1); + tdm_client_vblank_set_sync(wayland_egl_surface->tdm_vblank, 0); + + TPL_LOG_B("WL_EGL", "[TDM_VBLANK_INIT] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", + wayland_egl_surface, wayland_egl_surface->tdm_vblank); + + return TPL_ERROR_NONE; +} + +static tpl_result_t __tpl_wayland_egl_surface_init(tpl_surface_t *surface) { tpl_wayland_egl_display_t *wayland_egl_display = @@ -432,23 +464,37 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) TBM_FORMAT_ARGB8888, 0); - /* Set reset_callback to tbm_quueue */ - tbm_surface_queue_add_reset_cb(wayland_egl_surface->tbm_queue, - __cb_tbm_surface_queue_reset_callback, - (void *)wayland_egl_surface); - if (!wayland_egl_surface->tbm_queue) { TPL_ERR("TBM surface queue creation failed!"); free(wayland_egl_surface); return TPL_ERROR_INVALID_OPERATION; } + /* Set reset_callback to tbm_queue */ + tbm_surface_queue_add_reset_cb(wayland_egl_surface->tbm_queue, + __cb_tbm_surface_queue_reset_callback, + (void *)wayland_egl_surface); + + surface->width = wl_egl_window->width; surface->height = wl_egl_window->height; wl_egl_window->private = surface; wl_egl_window->resize_callback = (void *)__cb_client_window_resize_callback; + /* tdm_vblank object decide to be maintained every tpl_wayland_egl_surface + for the case where the several surfaces is created in one display connection. */ + if (wayland_egl_display->tdm_client) { + tpl_result_t tpl_ret = TPL_ERROR_NONE; + tpl_ret = __tpl_wayland_egl_surface_create_vblank(wayland_egl_surface, + wayland_egl_display->tdm_client); + if (tpl_ret != TPL_ERROR_NONE) { + tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); + free(wayland_egl_surface); + return TPL_ERROR_INVALID_OPERATION; + } + } + TPL_LOG_B("WL_EGL", "[INIT] tpl_surface_t(%p) tpl_wayland_egl_surface_t(%p) tbm_queue(%p)", surface, wayland_egl_surface, wayland_egl_surface->tbm_queue); @@ -496,6 +542,12 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) wl_display_flush(wayland_egl_display->wl_dpy); wl_display_dispatch_pending(wayland_egl_display->wl_dpy); + if (wayland_egl_surface->tdm_vblank) { + TPL_LOG_B("WL_EGL", "[TDM_VBLANK_FINI] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", + wayland_egl_surface, wayland_egl_surface->tdm_vblank); + tdm_client_vblank_destroy(wayland_egl_surface->tdm_vblank); + } + TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_surface_t(%p) wl_egl_window(%p) tbm_queue(%p)", wayland_egl_surface, wl_egl_window, wayland_egl_surface->tbm_queue); tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); @@ -571,7 +623,8 @@ __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) } static void -__cb_tdm_client_wait_vblank(unsigned int sequence, unsigned int tv_sec, +__cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, + unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t *)user_data; @@ -644,13 +697,11 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, /* TPL_WAIT_VBLANK = 1 */ if (wayland_egl_display->tdm_client) { - tdm_err = tdm_client_wait_vblank(wayland_egl_display->tdm_client, /* tdm_client */ - "primary", /* name */ - 1, /* sw_timer */ + tdm_err = tdm_client_vblank_wait(wayland_egl_surface->tdm_vblank, 1, /* interval */ - 0, /* asynchronous */ __cb_tdm_client_wait_vblank, /* handler */ surface->backend.data); /* user_data */ + if (tdm_err == TDM_ERROR_NONE) wayland_egl_surface->vblank_done = TPL_FALSE; else -- 2.7.4 From f55d01e376e2df72649874caf8ea50b85eccfbd9 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 24 Aug 2016 20:04:33 +0900 Subject: [PATCH 11/16] tpl_wayland_egl: Delete unnecessary polling for tdm vblank. The necessary polling is already exist inside libtdm. Change-Id: I5cf90dd599a2bee99ac3ba0094d8d4a36a7ca8bb Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 24ba414..38b3432 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -581,37 +581,13 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) static void __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) { - int fd = -1; tdm_error tdm_err = 0; - int ret; - struct pollfd fds; - tpl_wayland_egl_display_t *wayland_egl_display = (tpl_wayland_egl_display_t*)surface->display->backend.data; tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t*)surface->backend.data; - tdm_err = tdm_client_get_fd(wayland_egl_display->tdm_client, &fd); - - if (tdm_err != TDM_ERROR_NONE || fd < 0) { - TPL_ERR("Failed to tdm_client_get_fd | tdm_err = %d", tdm_err); - } - - fds.events = POLLIN; - fds.fd = fd; - fds.revents = 0; - do { - ret = poll(&fds, 1, -1); - - if (ret < 0) { - if (errno == EBUSY) - continue; - else { - TPL_ERR("Failed to poll."); - } - } - tdm_err = tdm_client_handle_events(wayland_egl_display->tdm_client); if (tdm_err != TDM_ERROR_NONE) { @@ -619,7 +595,6 @@ __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) } } while (wayland_egl_surface->vblank_done == TPL_FALSE); - } static void -- 2.7.4 From 2a184d1f766364a2d2d1fa658823f19b3a2e74da Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Mon, 29 Aug 2016 13:51:32 +0900 Subject: [PATCH 12/16] libtpl-egl: Apply coding style and add coding style document for astyle. Change-Id: Ie39cc4244e19532bb000a16b97776575352aab69 Signed-off-by: Mun, Gwan-gyeong --- astyle-format.txt | 7 +++ src/tpl.h | 13 ++--- src/tpl_display.c | 9 ++-- src/tpl_gbm.c | 14 ++--- src/tpl_surface.c | 11 ++-- src/tpl_tbm.c | 2 +- src/tpl_wayland_egl.c | 129 +++++++++++++++++++++++++--------------------- src/tpl_wayland_vk_wsi.c | 18 ++++--- tc/src/main.c | 36 ++++++------- tc/src/tpl_test_buffer.c | 14 ++--- tc/src/tpl_test_display.c | 58 ++++++++++----------- tc/src/tpl_test_object.c | 4 +- tc/src/tpl_test_surface.c | 22 ++++---- tc/src/tpl_test_util.h | 4 +- 14 files changed, 183 insertions(+), 158 deletions(-) create mode 100644 astyle-format.txt diff --git a/astyle-format.txt b/astyle-format.txt new file mode 100644 index 0000000..ac03a2c --- /dev/null +++ b/astyle-format.txt @@ -0,0 +1,7 @@ +apply coding style with astyle + +1. To apply libtpl-egl coding style to .c code, run this command: + astyle -A4 -t4 -xT4 -p -z2 -H -k3 -W3 -xC80 -xL -n -r "./*.c" + +2. To apply libtpl-egl coding style to .h code, run this command: + astyle -A4 -t4 -xT4 -p -z2 -H -k3 -W3 -xC80 -xL -n -r "./*.h" diff --git a/src/tpl.h b/src/tpl.h index 585165d..cb48da9 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -337,7 +337,8 @@ tpl_display_get_native_handle(tpl_display_t *display); * @return TPL_ERROR_NONE is the given config is supported, TPL_ERROR otherwise. */ tpl_result_t -tpl_display_query_config(tpl_display_t *display, tpl_surface_type_t surface_type, +tpl_display_query_config(tpl_display_t *display, + tpl_surface_type_t surface_type, int red_size, int green_size, int blue_size, int alpha_size, int depth_size, int *native_visual_id, tpl_bool_t *is_slow); @@ -476,7 +477,8 @@ tpl_surface_dequeue_buffer(tpl_surface_t *surface); * @see tpl_surface_get_swapchain_buffers() */ tbm_surface_h -tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, uint64_t timeout_ns, +tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, + uint64_t timeout_ns, tbm_fd *sync_fence); /** @@ -678,10 +680,9 @@ tpl_display_get_native_pixmap_info(tpl_display_t *display, tpl_handle_t pixmap, * @return TPL_ERROR_NONE if this function is supported and the window is valid, TPL_ERROR otherwise. */ tpl_result_t -tpl_display_query_supported_buffer_count_from_native_window( - tpl_display_t *display, - tpl_handle_t window, - int *min, int *max); +tpl_display_query_supported_buffer_count_from_native_window(tpl_display_t *display, + tpl_handle_t window, + int *min, int *max); /** * Get native buffer from the given native pixmap. diff --git a/src/tpl_display.c b/src/tpl_display.c index d1d4e91..69295b0 100644 --- a/src/tpl_display.c +++ b/src/tpl_display.c @@ -164,9 +164,10 @@ tpl_display_get_native_pixmap_info(tpl_display_t *display, tpl_handle_t pixmap, } tpl_result_t -tpl_display_query_supported_buffer_count_from_native_window(tpl_display_t *display, - tpl_handle_t window, - int *min, int *max) +tpl_display_query_supported_buffer_count_from_native_window( + tpl_display_t *display, + tpl_handle_t window, + int *min, int *max) { if (!display->backend.query_window_supported_buffer_count) { TPL_ERR("Backend for display has not been initialized!"); @@ -180,7 +181,7 @@ tpl_display_query_supported_buffer_count_from_native_window(tpl_display_t *displ tbm_surface_h tpl_display_get_buffer_from_native_pixmap(tpl_display_t *display, - tpl_handle_t pixmap) + tpl_handle_t pixmap) { if (!display->backend.get_buffer_from_native_pixmap) { TPL_ERR("Backend for display has not been initialized!"); diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c index 02242cb..c95c2db 100644 --- a/src/tpl_gbm.c +++ b/src/tpl_gbm.c @@ -96,8 +96,7 @@ __tpl_gbm_display_init(tpl_display_t *display) TPL_ASSERT(display); /* Do not allow default display in gbm. */ - if (!display->native_handle) - { + if (!display->native_handle) { TPL_ERR("native_handle is NULL. Can not allow default display in gbm."); return TPL_ERROR_INVALID_PARAMETER; } @@ -248,7 +247,8 @@ __tpl_gbm_display_get_buffer_from_native_pixmap(tpl_handle_t pixmap) return NULL; } - TPL_LOG_B("GBM", "[PIXMAP] wl_resource(%p) tbm_surface(%p) bo(%d)", pixmap, tbm_surface, + TPL_LOG_B("GBM", "[PIXMAP] wl_resource(%p) tbm_surface(%p) bo(%d)", pixmap, + tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); return tbm_surface; @@ -272,8 +272,8 @@ __tpl_gbm_surface_init(tpl_surface_t *surface) if (surface->type == TPL_SURFACE_TYPE_WINDOW) { struct gbm_surface *gbm_surface = (struct gbm_surface *)surface->native_handle; - tpl_gbm_surface->tbm_queue = (tbm_surface_queue_h)gbm_tbm_get_surface_queue( - gbm_surface); + tpl_gbm_surface->tbm_queue = + (tbm_surface_queue_h)gbm_tbm_get_surface_queue(gbm_surface); if (!tpl_gbm_surface->tbm_queue) { TPL_ERR("Failed to get tbm_surface_queue from gbm_surface."); goto error; @@ -442,7 +442,7 @@ __tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, if (gbm_buffer) { TRACE_MARK("[DEQ][REUSED]BO_NAME:%d", tbm_bo_export(gbm_buffer->bo)); TPL_LOG_B("GBM", "[DEQ][R] tpl_gbm_surface_t(%p) tbm_surface(%p) bo(%d)", - gbm_surface, tbm_surface, tbm_bo_export(gbm_buffer->bo)); + gbm_surface, tbm_surface, tbm_bo_export(gbm_buffer->bo)); return tbm_surface; } @@ -468,7 +468,7 @@ __tpl_gbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, TRACE_MARK("[DEQ][NEW]BO_NAME:%d", tbm_bo_export(gbm_buffer->bo)); TPL_LOG_B("GBM", "[DEQ][N] tpl_gbm_surface_t(%p) tbm_surface(%p) bo(%d)", - gbm_surface, tbm_surface, tbm_bo_export(bo)); + gbm_surface, tbm_surface, tbm_bo_export(bo)); return tbm_surface; } diff --git a/src/tpl_surface.c b/src/tpl_surface.c index c9b2c88..d6ad51d 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -141,7 +141,8 @@ tpl_surface_validate(tpl_surface_t *surface) TPL_OBJECT_UNLOCK(surface); - TPL_LOG_F("tpl_surface_t(%p) valid [%s]", surface, was_valid?"TRUE":"FALSE"); + TPL_LOG_F("tpl_surface_t(%p) valid [%s]", surface, + was_valid ? "TRUE" : "FALSE"); return was_valid; } @@ -185,7 +186,8 @@ tpl_surface_dequeue_buffer(tpl_surface_t *surface) } tbm_surface_h -tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, uint64_t timeout_ns, +tpl_surface_dequeue_buffer_with_sync(tpl_surface_t *surface, + uint64_t timeout_ns, tbm_fd *sync_fence) { TPL_ASSERT(surface); @@ -279,7 +281,8 @@ tpl_surface_enqueue_buffer_with_damage_and_sync(tpl_surface_t *surface, tbm_surface_get_height(tbm_surface)); /* Call backend post */ - ret = surface->backend.enqueue_buffer(surface, tbm_surface, num_rects, rects, sync_fence); + ret = surface->backend.enqueue_buffer(surface, tbm_surface, num_rects, rects, + sync_fence); TPL_OBJECT_UNLOCK(surface); TRACE_END(); @@ -399,6 +402,6 @@ tpl_surface_set_frontbuffer_mode(tpl_surface_t *surface, tpl_bool_t set) TPL_OBJECT_UNLOCK(surface); TPL_LOG_F("tpl_surface_t(%p) frontbuffer_mode [%s]", - surface, set?"ACTIVATED":"DEACTIVATED"); + surface, set ? "ACTIVATED" : "DEACTIVATED"); return ret; } diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index 1dd2207..a375008 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -245,7 +245,7 @@ __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, TPL_IGNORE(rects); if (!tbm_surface_internal_is_valid(tbm_surface)) { - TPL_ERR("Failed to enqueue tbm_surface(%p) Invalid value.",tbm_surface); + TPL_ERR("Failed to enqueue tbm_surface(%p) Invalid value.", tbm_surface); return TPL_ERROR_INVALID_PARAMETER; } diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 38b3432..54e6769 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -150,17 +150,14 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) goto free_wl_display; } - if (env == NULL || atoi(env)) - { + if (env == NULL || atoi(env)) { TPL_LOG_B("WL_EGL", "[INIT] ENABLE wait vblank."); wayland_egl_display->tdm_client = tdm_client_create(&tdm_err); if (!wayland_egl_display->tdm_client) { TPL_ERR("tdm client initialization failed! tdm_err=%d", tdm_err); goto free_wl_display; } - } - else - { + } else { TPL_LOG_B("WL_EGL", "[INIT] DISABLE wait vblank."); wayland_egl_display->tdm_client = NULL; } @@ -173,7 +170,7 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) } TPL_LOG_B("WL_EGL", "[INIT] tpl_wayland_egl_display_t(%p) wl_tbm_client(%p)", - wayland_egl_display, wayland_egl_display->wl_tbm_client); + wayland_egl_display, wayland_egl_display->wl_tbm_client); return TPL_ERROR_NONE; @@ -325,8 +322,7 @@ __tpl_wayland_egl_buffer_set_reset_flag(tpl_list_t *tracking_list) tbm_surface_h tbm_surface = NULL; tpl_list_node_t *node = __tpl_list_get_front_node(tracking_list); - while (node) - { + while (node) { tbm_surface = (tbm_surface_h) __tpl_list_node_get_data(node); if (tbm_surface) @@ -344,7 +340,8 @@ static void __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h surface_queue, void *data) { - tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t*) data; + tpl_wayland_egl_surface_t *wayland_egl_surface = + (tpl_wayland_egl_surface_t *)data; if (!wayland_egl_surface) return; @@ -363,7 +360,8 @@ __cb_tbm_surface_queue_reset_callback(tbm_surface_queue_h surface_queue, } static tpl_result_t -__tpl_wayland_egl_surface_create_vblank(tpl_wayland_egl_surface_t *wayland_egl_surface, +__tpl_wayland_egl_surface_create_vblank(tpl_wayland_egl_surface_t + *wayland_egl_surface, tdm_client *tdm_client) { tdm_client_output *tdm_output = NULL; @@ -378,7 +376,8 @@ __tpl_wayland_egl_surface_create_vblank(tpl_wayland_egl_surface_t *wayland_egl_s return TPL_ERROR_INVALID_OPERATION; } - wayland_egl_surface->tdm_vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err_ret); + wayland_egl_surface->tdm_vblank = + tdm_client_output_create_vblank(tdm_output, &tdm_err_ret); if (!wayland_egl_surface->tdm_vblank) { TPL_ERR("Failed to create tdm vblank object. tdm_err(%d)", tdm_err_ret); return TPL_ERROR_INVALID_OPERATION; @@ -387,8 +386,9 @@ __tpl_wayland_egl_surface_create_vblank(tpl_wayland_egl_surface_t *wayland_egl_s tdm_client_vblank_set_enable_fake(wayland_egl_surface->tdm_vblank, 1); tdm_client_vblank_set_sync(wayland_egl_surface->tdm_vblank, 0); - TPL_LOG_B("WL_EGL", "[TDM_VBLANK_INIT] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", - wayland_egl_surface, wayland_egl_surface->tdm_vblank); + TPL_LOG_B("WL_EGL", + "[TDM_VBLANK_INIT] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", + wayland_egl_surface, wayland_egl_surface->tdm_vblank); return TPL_ERROR_NONE; } @@ -486,8 +486,9 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) for the case where the several surfaces is created in one display connection. */ if (wayland_egl_display->tdm_client) { tpl_result_t tpl_ret = TPL_ERROR_NONE; - tpl_ret = __tpl_wayland_egl_surface_create_vblank(wayland_egl_surface, - wayland_egl_display->tdm_client); + tpl_ret = + __tpl_wayland_egl_surface_create_vblank(wayland_egl_surface, + wayland_egl_display->tdm_client); if (tpl_ret != TPL_ERROR_NONE) { tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); free(wayland_egl_surface); @@ -495,10 +496,12 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) } } - TPL_LOG_B("WL_EGL", "[INIT] tpl_surface_t(%p) tpl_wayland_egl_surface_t(%p) tbm_queue(%p)", - surface, wayland_egl_surface, + TPL_LOG_B("WL_EGL", + "[INIT] tpl_surface_t(%p) tpl_wayland_egl_surface_t(%p) tbm_queue(%p)", + surface, wayland_egl_surface, wayland_egl_surface->tbm_queue); - TPL_LOG_B("WL_EGL", "[INIT] tpl_wayland_egl_surface_t(%p) wl_egl_window(%p) (%dx%d)", + TPL_LOG_B("WL_EGL", + "[INIT] tpl_wayland_egl_surface_t(%p) wl_egl_window(%p) (%dx%d)", wayland_egl_surface, wl_egl_window, surface->width, surface->height); return TPL_ERROR_NONE; @@ -543,12 +546,14 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) wl_display_dispatch_pending(wayland_egl_display->wl_dpy); if (wayland_egl_surface->tdm_vblank) { - TPL_LOG_B("WL_EGL", "[TDM_VBLANK_FINI] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", + TPL_LOG_B("WL_EGL", + "[TDM_VBLANK_FINI] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", wayland_egl_surface, wayland_egl_surface->tdm_vblank); tdm_client_vblank_destroy(wayland_egl_surface->tdm_vblank); } - TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_surface_t(%p) wl_egl_window(%p) tbm_queue(%p)", + TPL_LOG_B("WL_EGL", + "[FINI] tpl_wayland_egl_surface_t(%p) wl_egl_window(%p) tbm_queue(%p)", wayland_egl_surface, wl_egl_window, wayland_egl_surface->tbm_queue); tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); wayland_egl_surface->tbm_queue = NULL; @@ -583,9 +588,9 @@ __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) { tdm_error tdm_err = 0; tpl_wayland_egl_display_t *wayland_egl_display = - (tpl_wayland_egl_display_t*)surface->display->backend.data; + (tpl_wayland_egl_display_t *)surface->display->backend.data; tpl_wayland_egl_surface_t *wayland_egl_surface = - (tpl_wayland_egl_surface_t*)surface->backend.data; + (tpl_wayland_egl_surface_t *)surface->backend.data; do { tdm_err = tdm_client_handle_events(wayland_egl_display->tdm_client); @@ -599,10 +604,11 @@ __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) static void __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, - unsigned int sequence, unsigned int tv_sec, - unsigned int tv_usec, void *user_data) + unsigned int sequence, unsigned int tv_sec, + unsigned int tv_usec, void *user_data) { - tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t *)user_data; + tpl_wayland_egl_surface_t *wayland_egl_surface = + (tpl_wayland_egl_surface_t *)user_data; wayland_egl_surface->vblank_done = TPL_TRUE; TRACE_MARK("TDM_CLIENT_VBLACK"); } @@ -662,16 +668,17 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wl_display_flush(wayland_egl_display->wl_dpy); - TPL_LOG_B("WL_EGL", "[COMMIT] wl_surface(%p) wl_egl_window(%p)(%dx%d) wl_buffer(%p)", + TPL_LOG_B("WL_EGL", + "[COMMIT] wl_surface(%p) wl_egl_window(%p)(%dx%d) wl_buffer(%p)", wl_egl_window->surface, wl_egl_window, wl_egl_window->width, wl_egl_window->height, wayland_egl_buffer->wl_proxy); /* Start tracking of this tbm_surface until release_cb called. */ - __tpl_list_push_back(wayland_egl_surface->attached_buffers, (void *)tbm_surface); + __tpl_list_push_back(wayland_egl_surface->attached_buffers, + (void *)tbm_surface); /* TPL_WAIT_VBLANK = 1 */ - if (wayland_egl_display->tdm_client) - { + if (wayland_egl_display->tdm_client) { tdm_err = tdm_client_vblank_wait(wayland_egl_surface->tdm_vblank, 1, /* interval */ __cb_tdm_client_wait_vblank, /* handler */ @@ -713,8 +720,8 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); TPL_LOG_B("WL_EGL", - "[ENQ] tpl_wayland_egl_surface_t(%p) tbm_queue(%p) tbm_surface(%p) bo(%d)", - wayland_egl_surface, wayland_egl_surface->tbm_queue, + "[ENQ] tpl_wayland_egl_surface_t(%p) tbm_queue(%p) tbm_surface(%p) bo(%d)", + wayland_egl_surface, wayland_egl_surface->tbm_queue, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); if (wayland_egl_surface->vblank_done == TPL_FALSE) { @@ -735,8 +742,7 @@ __tpl_wayland_egl_surface_enqueue_buffer(tpl_surface_t *surface, if (!wayland_egl_buffer) return TPL_ERROR_INVALID_PARAMETER; - if (wayland_egl_buffer->reset) - { + if (wayland_egl_buffer->reset) { /* * When tbm_surface_queue being reset for receiving * scan-out buffer or resized buffer @@ -813,7 +819,8 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) int num = 0, i; tpl_result_t ret = TPL_ERROR_NONE; - wayland_egl_display = (tpl_wayland_egl_display_t *)surface->display->backend.data; + wayland_egl_display = (tpl_wayland_egl_display_t *) + surface->display->backend.data; wayland_egl_surface = (tpl_wayland_egl_surface_t *)surface->backend.data; wl_display_dispatch_pending(wayland_egl_display->wl_dpy); @@ -821,21 +828,20 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) return TPL_ERROR_NONE; tbm_surface_queue_get_surfaces(wayland_egl_surface->tbm_queue, buffers, &num); - if (num == 0) - { + if (num == 0) { TPL_ERR("tbm_queue(%p) has no buffer", wayland_egl_surface->tbm_queue); return TPL_ERROR_INVALID_OPERATION; } queue = wl_display_create_queue(wayland_egl_display->wl_dpy); - if (!queue) - { + if (!queue) { TPL_ERR("failed to create new wl_display queue."); return TPL_ERROR_INVALID_OPERATION; } - for (i=0; iwl_proxy) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, queue); } @@ -845,7 +851,7 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) * - buffer_attached_with_fd * - active * - deactive - * + * * When wayland_egl_surface->wl_proxy( == wl_tbm_queue ) could not receive * any events, tpl_surface cannot get a buffer. * So, we have to manage event queue about wl_tbm_queue along with wl_buffer. @@ -856,10 +862,10 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) wl_display_dispatch_pending(wayland_egl_display->wl_dpy); - if (tbm_surface_queue_can_dequeue(wayland_egl_surface->tbm_queue, 0)) - { - for (i=0; itbm_queue, 0)) { + for (i = 0; i < num; i++) { + wayland_egl_buffer = + __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(buffers[i]); if (wayland_egl_buffer && wayland_egl_buffer->wl_proxy) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, NULL); } @@ -875,7 +881,7 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) TRACE_BEGIN("WAITING FOR DEQUEUEABLE"); TPL_OBJECT_UNLOCK(surface); while (tbm_surface_queue_can_dequeue( - wayland_egl_surface->tbm_queue, 0) == 0) { + wayland_egl_surface->tbm_queue, 0) == 0) { /* Application sent all buffers to the server. Wait for server response. */ if (wl_display_dispatch_queue(wayland_egl_display->wl_dpy, queue) == -1) { ret = TPL_ERROR_INVALID_OPERATION; @@ -886,8 +892,9 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) TPL_OBJECT_LOCK(surface); TRACE_END(); - for (i=0; iwl_proxy) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, NULL); } @@ -900,7 +907,8 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) } static tbm_surface_h -__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, +__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, + uint64_t timeout_ns, tbm_fd *sync_fence) { TPL_ASSERT(surface); @@ -957,14 +965,15 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TRACE_MARK("[DEQ][REUSED]BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); TRACE_ASYNC_BEGIN((int)wayland_egl_buffer, "[DEQ]~[ENQ] BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); - TPL_LOG_B("WL_EGL", - "[DEQ][R] tpl_wayland_surface_t(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)", - wayland_egl_surface, - wayland_egl_buffer->wl_proxy, + TPL_LOG_B("WL_EGL", + "[DEQ][R] tpl_wayland_surface_t(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)", + wayland_egl_surface, + wayland_egl_buffer->wl_proxy, tbm_surface, tbm_bo_export(wayland_egl_buffer->bo)); /* Start tracking of this tbm_surface until enqueue */ - __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, (void *)tbm_surface); + __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, + (void *)tbm_surface); return tbm_surface; } @@ -1017,11 +1026,12 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TRACE_ASYNC_BEGIN((int)wayland_egl_buffer, "[DEQ]~[ENQ] BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); TPL_LOG_B("WL_EGL", - "[DEQ][N] tpl_wayland_egl_buffer_t(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)", - wayland_egl_buffer, wayland_egl_buffer->wl_proxy, tbm_surface, - tbm_bo_export(wayland_egl_buffer->bo)); + "[DEQ][N] tpl_wayland_egl_buffer_t(%p) wl_buffer(%p) tbm_surface(%p) bo(%d)", + wayland_egl_buffer, wayland_egl_buffer->wl_proxy, tbm_surface, + tbm_bo_export(wayland_egl_buffer->bo)); - __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, (void *)tbm_surface); + __tpl_list_push_back(wayland_egl_surface->dequeued_buffers, + (void *)tbm_surface); return tbm_surface; } @@ -1138,8 +1148,7 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) proxy, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); - if (tbm_surface_internal_is_valid(tbm_surface)) - { + if (tbm_surface_internal_is_valid(tbm_surface)) { tpl_wayland_egl_surface_t *wayland_egl_surface = NULL; tpl_wayland_egl_buffer_t *wayland_egl_buffer = NULL; diff --git a/src/tpl_wayland_vk_wsi.c b/src/tpl_wayland_vk_wsi.c index fd38861..e9469ae 100644 --- a/src/tpl_wayland_vk_wsi.c +++ b/src/tpl_wayland_vk_wsi.c @@ -463,7 +463,8 @@ __tpl_wayland_vk_wsi_surface_validate(tpl_surface_t *surface) static tbm_surface_h __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, - uint64_t timeout_ns, tbm_fd *sync_fence) + uint64_t timeout_ns, + tbm_fd *sync_fence) { TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -509,7 +510,8 @@ __tpl_wayland_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, } } pthread_mutex_lock(&wayland_vk_wsi_surface->free_queue_mutex); - while (tbm_surface_queue_can_dequeue(wayland_vk_wsi_surface->tbm_queue, 0) == 0) { + while (tbm_surface_queue_can_dequeue(wayland_vk_wsi_surface->tbm_queue, + 0) == 0) { if (timeout_ns != UINT64_MAX) { int ret; ret = pthread_cond_timedwait(&wayland_vk_wsi_surface->free_queue_cond, @@ -919,12 +921,13 @@ __tpl_wayland_vk_wsi_worker_thread_loop(void *arg) clock_gettime(CLOCK_REALTIME, &abs_time); abs_time.tv_sec += 1; pthread_mutex_lock(&wayland_vk_wsi_surface->dirty_queue_mutex); - while (tbm_surface_queue_can_acquire(wayland_vk_wsi_surface->tbm_queue, 0) == 0 && - timeout == TPL_FALSE) { + while ((tbm_surface_queue_can_acquire(wayland_vk_wsi_surface->tbm_queue, + 0) == 0) && + (timeout == TPL_FALSE)) { int ret; ret = pthread_cond_timedwait(&wayland_vk_wsi_surface->dirty_queue_cond, - &wayland_vk_wsi_surface->dirty_queue_mutex, - &abs_time); + &wayland_vk_wsi_surface->dirty_queue_mutex, + &abs_time); if (ret == ETIMEDOUT) timeout = TPL_TRUE; } @@ -933,7 +936,8 @@ __tpl_wayland_vk_wsi_worker_thread_loop(void *arg) continue; } - tsq_err = tbm_surface_queue_acquire(wayland_vk_wsi_surface->tbm_queue, &tbm_surface); + tsq_err = tbm_surface_queue_acquire(wayland_vk_wsi_surface->tbm_queue, + &tbm_surface); pthread_mutex_unlock(&wayland_vk_wsi_surface->dirty_queue_mutex); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to acquire tbm_surface. | tsq_err = %d", tsq_err); diff --git a/tc/src/main.c b/tc/src/main.c index 241dca7..896bdad 100644 --- a/tc/src/main.c +++ b/tc/src/main.c @@ -116,7 +116,7 @@ __LOG_ERR( const char *func, int line, const char *fmt, ... ) /* wayland native related */ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, - const char *interface, uint32_t version) + const char *interface, uint32_t version) { TPLNativeWnd *that = (TPLNativeWnd *)(data); @@ -133,7 +133,7 @@ registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, void registry_handle_global_remove(void *data, struct wl_registry *registry, - uint32_t name) + uint32_t name) { } @@ -143,21 +143,21 @@ const struct wl_registry_listener registry_listener_ = { }; shell_surface_handle_ping(void *data, struct wl_shell_surface *shell_surface, - uint32_t serial) + uint32_t serial) { wl_shell_surface_pong(shell_surface, serial); } void shell_surface_handle_popup_done(void *data, - struct wl_shell_surface *shell_surface) + struct wl_shell_surface *shell_surface) { } void shell_surface_handle_configure(void *data, - struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, - int32_t height) + struct wl_shell_surface *shell_surface, uint32_t edges, int32_t width, + int32_t height) { TPLNativeWnd *that = (TPLNativeWnd *)(data); that->width = width; @@ -202,7 +202,7 @@ finish: bool tpl_test_native_wnd_initialize( TPLNativeWnd *wnd, int x, int y, int width, - int height ) + int height ) { bool res = false; @@ -239,7 +239,7 @@ tpl_test_native_wnd_initialize( TPLNativeWnd *wnd, int x, int y, int width, wl_shell_surface_set_toplevel(wnd->shell_surface); if (wnd->shell_surface) { wl_shell_surface_add_listener(wnd->shell_surface, &shell_surface_listener_, - wnd); + wnd); } wl_shell_surface_set_title(wnd->shell_surface, "tpl_testtest"); @@ -341,16 +341,16 @@ print_usage( char *name ) fprintf( stderr, "Options:\n" ); fprintf( stderr, " -w Set width size of the window default: %d\n", - g_option.wnd_w ); + g_option.wnd_w ); fprintf( stderr, " -h Set height size of the window default: %d\n", - g_option.wnd_h ); + g_option.wnd_h ); fprintf( stderr, " -t Specify the test case number default: %d\n", - g_option.tc_num ); + g_option.tc_num ); fprintf( stderr, " -a Run all test cases default: %s\n", - g_option.all ? "true" : "false" ); + g_option.all ? "true" : "false" ); fprintf( stderr, " -l Show TC name default: %s\n", - g_option.show_names ? "true" : "false" ); + g_option.show_names ? "true" : "false" ); fprintf( stderr, "\n" ); exit( 1 ); } @@ -479,10 +479,10 @@ main( int argc, char **argv ) if ( !wnd ) goto finish; res = tpl_test_native_wnd_initialize( wnd, - g_option.wnd_x, - g_option.wnd_y, - g_option.wnd_w, - g_option.wnd_h ); + g_option.wnd_x, + g_option.wnd_y, + g_option.wnd_w, + g_option.wnd_h ); if ( !res ) goto finish; printf( "-------------------tpl test begin!!!-----------------------------------\n"); @@ -508,7 +508,7 @@ main( int argc, char **argv ) //printf( "----------------------------------------------\n\n" ); if ( tpl_test[tc_num].name ) printf( "[%4d] %-50s", tc_num, - tpl_test[tc_num].name ); + tpl_test[tc_num].name ); else printf( "[%4d] No test name\n", tc_num ); if ( tpl_test[tc_num].run ) { diff --git a/tc/src/tpl_test_buffer.c b/tc/src/tpl_test_buffer.c index 1c411dd..aa6d1ea 100644 --- a/tc/src/tpl_test_buffer.c +++ b/tc/src/tpl_test_buffer.c @@ -22,7 +22,7 @@ bool tpl_buffer_map_unmap_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display , (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -46,7 +46,7 @@ bool tpl_buffer_map_unmap_test(TPLNativeWnd *wnd ) //int size = tpl_buf->width * tpl_buf->height * tpl_buf->depth; int size = wnd->width * wnd->height ; LOG("INFO", LOG_LEVEL_LOW , "width=%d,height=%d,size=%d\n", wnd->width , - wnd->height , size); + wnd->height , size); ptr = tpl_buffer_map(wnd->tpl_buf, size); if (ptr == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_buffer_map"); @@ -86,7 +86,7 @@ bool tpl_buffer_lock_unlock_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -172,7 +172,7 @@ bool tpl_buffer_get_arg_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -283,7 +283,7 @@ bool tpl_buffer_create_native_buffer_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -338,7 +338,7 @@ bool tpl_buffer_abnormal_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -405,7 +405,7 @@ bool tpl_buffer_stress_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display , (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; diff --git a/tc/src/tpl_test_display.c b/tc/src/tpl_test_display.c index e7ccd88..4a3e45e 100644 --- a/tc/src/tpl_test_display.c +++ b/tc/src/tpl_test_display.c @@ -41,7 +41,7 @@ bool tpl_display_bind_client_display_test(TPLNativeWnd *wnd) // bind display handle tpl_bool_t result = false; result = tpl_display_bind_client_display_handle(wnd->tpl_display, - (tpl_handle_t)wnd->dpy); + (tpl_handle_t)wnd->dpy); if (result == false) { LOG("ERRO", LOG_LEVEL_HIGH , " failed:tpl_display_bind_client_display_handle"); ret = false; @@ -51,10 +51,10 @@ bool tpl_display_bind_client_display_test(TPLNativeWnd *wnd) // unbind display handle result = false; result = tpl_display_unbind_client_display_handle(wnd->tpl_display, - (tpl_handle_t)wnd->dpy); + (tpl_handle_t)wnd->dpy); if (result == false) { LOG("ERRO", LOG_LEVEL_HIGH , - " failed:tpl_display_unbind_client_display_handle"); + " failed:tpl_display_unbind_client_display_handle"); ret = false; goto finish; } @@ -83,7 +83,7 @@ bool tpl_display_get_arg_test (TPLNativeWnd *wnd) //tpl_display_get_backend_type tpl_backend_type_t backend_type = tpl_display_get_backend_type( - wnd->tpl_display); + wnd->tpl_display); if (backend_type != TPL_BACKEND_WAYLAND) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_display_get_backend_type"); ret = false; @@ -123,14 +123,14 @@ bool tpl_display_query_config_test (TPLNativeWnd *wnd) //query config tpl_bool_t result = false; result = tpl_display_query_config(wnd->tpl_display, - TPL_SURFACE_TYPE_WINDOW, - 8, - 8, - 8, - 8, - 32, - NULL, - NULL); + TPL_SURFACE_TYPE_WINDOW, + 8, + 8, + 8, + 8, + 32, + NULL, + NULL); if (result == false ) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_display_query_config"); ret = false; @@ -138,14 +138,14 @@ bool tpl_display_query_config_test (TPLNativeWnd *wnd) } result = tpl_display_query_config(wnd->tpl_display, - TPL_SURFACE_TYPE_WINDOW, - 8, - 8, - 8, - 8, - 24, - NULL, - NULL); + TPL_SURFACE_TYPE_WINDOW, + 8, + 8, + 8, + 8, + 24, + NULL, + NULL); if (result == false ) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_display_query_config"); ret = false; @@ -153,14 +153,14 @@ bool tpl_display_query_config_test (TPLNativeWnd *wnd) } result = tpl_display_query_config(wnd->tpl_display, - TPL_SURFACE_TYPE_WINDOW, - 0, - 8, - 8, - 8, - 24, - NULL, - NULL); + TPL_SURFACE_TYPE_WINDOW, + 0, + 8, + 8, + 8, + 24, + NULL, + NULL); if (result != false ) { //unmatched case LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_display_query_config"); ret = false; @@ -252,7 +252,7 @@ bool tpl_display_abnormal_test (TPLNativeWnd *wnd) tpl_display_get_native_handle(NULL); tpl_display_filter_config(NULL, NULL, 0); tpl_display_query_config(NULL, TPL_SURFACE_TYPE_PIXMAP, 0, 8, 8, 8, 24, NULL, - NULL); + NULL); finish: diff --git a/tc/src/tpl_test_object.c b/tc/src/tpl_test_object.c index 1f6eb81..527099d 100644 --- a/tc/src/tpl_test_object.c +++ b/tc/src/tpl_test_object.c @@ -22,7 +22,7 @@ bool tpl_object_get_type_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -87,7 +87,7 @@ bool tpl_object_userdata_test(TPLNativeWnd *wnd ) //2. set userdate tpl_object_set_user_data((tpl_object_t *)wnd->tpl_display, (void *)wnd->dpy, - NULL); + NULL); //3.get userdate void *get_dpy = NULL; diff --git a/tc/src/tpl_test_surface.c b/tc/src/tpl_test_surface.c index bc6fd48..1752b83 100644 --- a/tc/src/tpl_test_surface.c +++ b/tc/src/tpl_test_surface.c @@ -20,7 +20,7 @@ bool tpl_surface_create_test(TPLNativeWnd *wnd) //2.tpl_surface_create tpl_surface_t *tpl_surf = NULL; tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -51,7 +51,7 @@ bool tpl_surface_get_arg_test(TPLNativeWnd *wnd) //2.tpl_surface_create tpl_surface_t *tpl_surf = NULL; tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -104,7 +104,7 @@ bool tpl_surface_frame_test(TPLNativeWnd *wnd) //2.tpl_surface_create tpl_surface_t *tpl_surf = NULL; tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -149,7 +149,7 @@ bool tpl_surface_get_buffer_test(TPLNativeWnd *wnd ) //2.tpl_surface_create tpl_surface_t *tpl_surf = NULL; tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -209,7 +209,7 @@ bool tpl_surface_post_test(TPLNativeWnd *wnd ) //2.tpl_surface_create tpl_surface_t *tpl_surf = NULL; tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -233,7 +233,7 @@ bool tpl_surface_post_test(TPLNativeWnd *wnd ) //int size = tpl_buf->width * tpl_buf->height * tpl_buf->depth; int size = wnd->width * wnd->height ; LOG("INFO", LOG_LEVEL_LOW , "width=%d,height=%d,size=%d", wnd->width , - wnd->height , size); + wnd->height , size); ptr = tpl_buffer_map(wnd->tpl_buf, size); if (ptr == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_buffer_map"); @@ -309,11 +309,11 @@ bool tpl_surface_abnormal_test(TPLNativeWnd *wnd) //abnormal test wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(NULL, NULL, TPL_SURFACE_TYPE_WINDOW, - TPL_FORMAT_ARGB8888); + TPL_FORMAT_ARGB8888); wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, 10, - TPL_FORMAT_ARGB8888); + TPL_FORMAT_ARGB8888); wnd->tpl_surf = tpl_surface_create(wnd->tpl_display, (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_INVALID); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_INVALID); /* if(tpl_surf != NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "abnormal test failed:%s",__func__); @@ -364,7 +364,7 @@ bool tpl_surface_stress_test(TPLNativeWnd *wnd ) //2.tpl_surface_create wnd->tpl_surf = NULL; wnd->tpl_surf = tpl_surface_create(wnd->tpl_display , (tpl_handle_t)wnd->wnd, - TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; @@ -387,7 +387,7 @@ bool tpl_surface_stress_test(TPLNativeWnd *wnd ) tpl_buffer_t *buf_array[STRESS_NUM] = {0}; for (index = 0; index < STRESS_NUM; index++) { surf_array[index] = tpl_surface_create(wnd->tpl_display , - (tpl_handle_t)wnd->wnd, TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); + (tpl_handle_t)wnd->wnd, TPL_SURFACE_TYPE_WINDOW, TPL_FORMAT_ARGB8888); if (wnd->tpl_surf == NULL) { LOG("ERRO", LOG_LEVEL_HIGH , "failed:tpl_surface_create"); ret = false; diff --git a/tc/src/tpl_test_util.h b/tc/src/tpl_test_util.h index 298300e..763db7c 100644 --- a/tc/src/tpl_test_util.h +++ b/tc/src/tpl_test_util.h @@ -203,9 +203,9 @@ GfxUtilTimer *tpl_test_util_timer_copy( GfxUtilTimer *src, const char *func, int line, const char *msg ); void tpl_test_util_timer_list_clear( void ); void tpl_test_util_timer_begin( GfxUtilTimer *timer, const char *func, - int line, const char *msg ); + int line, const char *msg ); void tpl_test_util_timer_end( GfxUtilTimer *timer, const char *func, int line, - const char *msg ); + const char *msg ); #else # define __TPL_TIMER_GLOBAL_BEGIN( ... ) { ; } # define __TPL_TIMER_GLOBAL_END( ... ) { ; } -- 2.7.4 From 6255ab1e3cc4771457c474f678d6ce8d59f1534a Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 29 Aug 2016 19:54:07 +0900 Subject: [PATCH 13/16] tpl_wayland_egl: Change the name 'wayland_egl_surface->wl_proxy' to 'wayland_egl_surface->wl_tbm_queue'. Change-Id: Ia6bafcaa31d9652238e03307ba5a1bb590f47feb Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 54e6769..e2ddf07 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -47,7 +47,7 @@ struct _tpl_wayland_egl_surface { tpl_bool_t vblank_done; tpl_list_t *attached_buffers; /* list for tracking [ACQ]~[REL] buffers */ tpl_list_t *dequeued_buffers; /* list for tracking [DEQ]~[ENQ] buffers */ - struct wl_proxy *wl_proxy; /* wl_tbm_queue proxy */ + struct wl_proxy *wl_tbm_queue; /* wl_tbm_queue proxy */ }; struct _tpl_wayland_egl_buffer { @@ -448,10 +448,11 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) * The activate/decactivate events is sent from the display server * at the no-comoposite mode and the composite mode. */ - wayland_egl_surface->wl_proxy = (struct wl_proxy *) - wayland_tbm_client_get_wl_tbm_queue(wayland_egl_display->wl_tbm_client, - wl_egl_window->surface); - if (!wayland_egl_surface->wl_proxy) { + wayland_egl_surface->wl_tbm_queue = + (struct wl_proxy *)wayland_tbm_client_get_wl_tbm_queue( + wayland_egl_display->wl_tbm_client, + wl_egl_window->surface); + if (!wayland_egl_surface->wl_tbm_queue) { TPL_ERR("Failed to get tbm_queue from wayland_tbm_client."); return TPL_ERROR_INVALID_OPERATION; } @@ -488,7 +489,7 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) tpl_result_t tpl_ret = TPL_ERROR_NONE; tpl_ret = __tpl_wayland_egl_surface_create_vblank(wayland_egl_surface, - wayland_egl_display->tdm_client); + wayland_egl_display->tdm_client); if (tpl_ret != TPL_ERROR_NONE) { tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); free(wayland_egl_surface); @@ -846,19 +847,19 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, queue); } - /* wayland_egl_surface->wl_proxy has to receive below wayland events. + /* wayland_egl_surface->wl_tbm_queue has to receive below wayland events. * - buffer_attached_with_id * - buffer_attached_with_fd * - active * - deactive * - * When wayland_egl_surface->wl_proxy( == wl_tbm_queue ) could not receive + * When wayland_egl_surface->wl_tbm_queue( == wl_tbm_queue ) could not receive * any events, tpl_surface cannot get a buffer. * So, we have to manage event queue about wl_tbm_queue along with wl_buffer. */ - if (wayland_egl_surface->wl_proxy) - wl_proxy_set_queue(wayland_egl_surface->wl_proxy, queue); + if (wayland_egl_surface->wl_tbm_queue) + wl_proxy_set_queue(wayland_egl_surface->wl_tbm_queue, queue); wl_display_dispatch_pending(wayland_egl_display->wl_dpy); @@ -870,8 +871,8 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, NULL); } - if (wayland_egl_surface->wl_proxy) - wl_proxy_set_queue(wayland_egl_surface->wl_proxy, NULL); + if (wayland_egl_surface->wl_tbm_queue) + wl_proxy_set_queue(wayland_egl_surface->wl_tbm_queue, NULL); wl_event_queue_destroy(queue); @@ -899,16 +900,15 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, NULL); } - if (wayland_egl_surface->wl_proxy) - wl_proxy_set_queue(wayland_egl_surface->wl_proxy, NULL); + if (wayland_egl_surface->wl_tbm_queue) + wl_proxy_set_queue(wayland_egl_surface->wl_tbm_queue, NULL); wl_event_queue_destroy(queue); return ret; } static tbm_surface_h -__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, - uint64_t timeout_ns, +__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, tbm_fd *sync_fence) { TPL_ASSERT(surface); @@ -930,8 +930,8 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, /* Check whether the surface was resized by wayland_egl */ if (wayland_egl_surface->resized == TPL_TRUE) { - struct wl_egl_window *wl_egl_window = (struct wl_egl_window *) - surface->native_handle; + struct wl_egl_window *wl_egl_window = + (struct wl_egl_window *)surface->native_handle; int width, height, format; width = wl_egl_window->width; height = wl_egl_window->height; @@ -985,8 +985,9 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, return NULL; } - wl_proxy = (struct wl_proxy *)wayland_tbm_client_create_buffer( - wayland_egl_display->wl_tbm_client, tbm_surface); + wl_proxy = + (struct wl_proxy *)wayland_tbm_client_create_buffer( + wayland_egl_display->wl_tbm_client, tbm_surface); if (!wl_proxy) { TPL_ERR("Failed to create TBM client buffer!"); tbm_surface_internal_unref(tbm_surface); -- 2.7.4 From c7dfda9662f4c327afbb5b657feb7cb0c8c19e59 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 29 Aug 2016 19:30:21 +0900 Subject: [PATCH 14/16] tpl_wayland_egl: Add wl_proxy to wayland_egl_display about wayland_tbm_client for handling some events. - The separated events will be processed like below. [wayland_egl_surface->wl_tbm_queue] : process 'ACTIVE' and 'DEACTIVE' [wayland_egl_display->wl_tbm] : process 'buffer_attached_with_id' and 'buffer_attached_with_fd' - Related reference : wayland-tbm https://review.tizen.org/gerrit/#/c/85406/ https://review.tizen.org/gerrit/#/c/85407/ Change-Id: Ic22ce21c753916cfa7e66f5ad3a67b8e24013df5 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index e2ddf07..f5a4b69 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -34,6 +34,7 @@ typedef struct _tpl_wayland_egl_buffer tpl_wayland_egl_buffer_t; struct _tpl_wayland_egl_display { tbm_bufmgr bufmgr; struct wayland_tbm_client *wl_tbm_client; + struct wl_proxy *wl_tbm; /* wayland_tbm_client proxy */ tdm_client *tdm_client; struct wl_display *wl_dpy; }; @@ -150,6 +151,13 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) goto free_wl_display; } + wayland_egl_display->wl_tbm = + wayland_tbm_client_get_wl_tbm(wayland_egl_display->wl_tbm_client); + if (!wayland_egl_display->wl_tbm) { + TPL_ERR("Failed to get wl_tbm from wayland_tbm_client."); + goto free_wl_display; + } + if (env == NULL || atoi(env)) { TPL_LOG_B("WL_EGL", "[INIT] ENABLE wait vblank."); wayland_egl_display->tdm_client = tdm_client_create(&tdm_err); @@ -176,6 +184,16 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) free_wl_display: if (wayland_egl_display) { + if (wayland_egl_display->wl_tbm_client) + wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + if (wayland_egl_display->tdm_client) + tdm_client_destroy(wayland_egl_display->tdm_client); + + wayland_egl_display->wl_tbm_client = NULL; + wayland_egl_display->tdm_client = NULL; + wayland_egl_display->wl_tbm = NULL; + wayland_egl_display->wl_dpy = NULL; + free(wayland_egl_display); display->backend.data = NULL; } @@ -194,11 +212,15 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_display_t(%p) wl_tbm_client(%p)", wayland_egl_display, wayland_egl_display->wl_tbm_client); - wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + if (wayland_egl_display->wl_tbm_client) + wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); if (wayland_egl_display->tdm_client) tdm_client_destroy(wayland_egl_display->tdm_client); + wayland_egl_display->wl_tbm_client = NULL; + wayland_egl_display->tdm_client = NULL; + wayland_egl_display->wl_tbm = NULL; wayland_egl_display->wl_dpy = NULL; free(wayland_egl_display); } @@ -847,20 +869,28 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) wl_proxy_set_queue(wayland_egl_buffer->wl_proxy, queue); } - /* wayland_egl_surface->wl_tbm_queue has to receive below wayland events. + /* wayland_egl_display->wl_tbm has to receive below wayland events. * - buffer_attached_with_id * - buffer_attached_with_fd + * + * wayland_egl_surface->wl_tbm_queue has to receive below wayland events. * - active * - deactive * - * When wayland_egl_surface->wl_tbm_queue( == wl_tbm_queue ) could not receive - * any events, tpl_surface cannot get a buffer. - * So, we have to manage event queue about wl_tbm_queue along with wl_buffer. + * When wayland_egl_surface->wl_tbm_queue + * or wayland_egl_display->wl_tbm( == wayland_tbm_client) + * could not receive any events, tpl_surface cannot get a buffer. + * + * So, we have to manage event queue about [wl_tbm_queue, wayland_tbm_client] + * along with wl_buffer. */ if (wayland_egl_surface->wl_tbm_queue) wl_proxy_set_queue(wayland_egl_surface->wl_tbm_queue, queue); + if (wayland_egl_display->wl_tbm) + wl_proxy_set_queue(wayland_egl_display->wl_tbm, queue); + wl_display_dispatch_pending(wayland_egl_display->wl_dpy); if (tbm_surface_queue_can_dequeue(wayland_egl_surface->tbm_queue, 0)) { @@ -874,6 +904,9 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) if (wayland_egl_surface->wl_tbm_queue) wl_proxy_set_queue(wayland_egl_surface->wl_tbm_queue, NULL); + if (wayland_egl_display->wl_tbm) + wl_proxy_set_queue(wayland_egl_display->wl_tbm, NULL); + wl_event_queue_destroy(queue); return TPL_ERROR_NONE; @@ -903,12 +936,16 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) if (wayland_egl_surface->wl_tbm_queue) wl_proxy_set_queue(wayland_egl_surface->wl_tbm_queue, NULL); + if (wayland_egl_display->wl_tbm) + wl_proxy_set_queue(wayland_egl_display->wl_tbm, NULL); + wl_event_queue_destroy(queue); return ret; } static tbm_surface_h -__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, +__tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, + uint64_t timeout_ns, tbm_fd *sync_fence) { TPL_ASSERT(surface); -- 2.7.4 From 3a6e7b4da6d3d563f0219d82c5eac4b04133bfd4 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Mon, 29 Aug 2016 23:25:36 +0900 Subject: [PATCH 15/16] tpl_wayland_egl: Fix build warning Change-Id: I0c40d3d40e7c9f6fefbf5e641a81732488ac69a8 Signed-off-by: Mun, Gwan-gyeong --- src/tpl_wayland_egl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index f5a4b69..597defc 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -152,7 +152,8 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) } wayland_egl_display->wl_tbm = - wayland_tbm_client_get_wl_tbm(wayland_egl_display->wl_tbm_client); + (struct wl_proxy *)wayland_tbm_client_get_wl_tbm( + wayland_egl_display->wl_tbm_client); if (!wayland_egl_display->wl_tbm) { TPL_ERR("Failed to get wl_tbm from wayland_tbm_client."); goto free_wl_display; -- 2.7.4 From 650f6e64cbde6f14eab9675d9b2c4381abe78945 Mon Sep 17 00:00:00 2001 From: "Mun, Gwan-gyeong" Date: Tue, 30 Aug 2016 22:16:16 +0900 Subject: [PATCH 16/16] libtpl-egl: add checking of tpl_object validation feature tpl_object check(validation check) supports magic-number mode and finding hash mode. Change-Id: Ic885930bc6cda0d885250f8cd19371eacb5a1186 Signed-off-by: Mun, Gwan-gyeong --- Makefile | 3 +++ packaging/libtpl-egl.spec | 7 +++++- src/tpl.c | 15 ++++++++++++- src/tpl_internal.h | 43 ++++++++++++++++++++++++++++++++++-- src/tpl_object.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index ccdb8f2..e18a35a 100644 --- a/Makefile +++ b/Makefile @@ -52,6 +52,9 @@ ifneq ($(call is-feature-enabled,pngdump),) CFLAGS += `pkg-config --cflags libpng` LDFLAGS += `pkg-config --libs libpng` endif +ifneq ($(call is-feature-enabled,object_hash_check),) + CFLAGS += -DOBJECT_HASH_CHECK +endif ifneq ($(call is-feature-enabled,arm_atomic_operation),) CFLAGS += -DARM_ATOMIC_OPERATION diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index e993c70..bf2b968 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -11,8 +11,9 @@ #TPL FEATURE OPTION %define ENABLE_TTRACE 0 %define ENABLE_DLOG 0 -%define ENABLE_DEFAULT_LOG 0 +%define ENABLE_DEFAULT_LOG 0 %define ENABLE_PNG_DUMP 0 +%define ENABLE_OBJECT_HASH_CHECK 1 #WAYLAND-EGL VERSION MACROS %define WL_EGL_VERSION 1.0.0 @@ -149,6 +150,10 @@ TPL_OPTIONS=${TPL_OPTIONS}-default_log TPL_OPTIONS=${TPL_OPTIONS}-pngdump %endif +%if "%{ENABLE_OBJECT_HASH_CHECK}" == "1" +TPL_OPTIONS=${TPL_OPTIONS}-object_hash_check +%endif + %ifarch %arm aarch64 TPL_OPTIONS=${TPL_OPTIONS}-arm_atomic_operation %endif diff --git a/src/tpl.c b/src/tpl.c index 46fa3bc..4f2ab38 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -25,8 +25,17 @@ __tpl_runtime_init() return TPL_ERROR_NONE; } +static void __attribute__((constructor)) +__tpl_init(void) +{ + TPL_DEBUG("[libtpl-egl] loaded"); +#ifdef OBJECT_HASH_CHECK + __tpl_object_hash_init(); +#endif +} + static void __attribute__((destructor)) -__tpl_runtime_fini() +__tpl_runtime_fini(void) { if (runtime != NULL) { int i; @@ -39,6 +48,10 @@ __tpl_runtime_fini() free(runtime); runtime = NULL; } + +#ifdef OBJECT_HASH_CHECK + __tpl_object_hash_shutdown(); +#endif } /* Begin: OS dependent function definition */ diff --git a/src/tpl_internal.h b/src/tpl_internal.h index f9d0f71..6231c87 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -15,10 +15,34 @@ #include #include -#define TPL_OBJECT_BUCKET_BITS 5 - +#define TPL_OBJECT_BUCKET_BITS 5 #define TPL_OBJECT_LOCK(object) __tpl_object_lock((tpl_object_t *)(object)) #define TPL_OBJECT_UNLOCK(object) __tpl_object_unlock((tpl_object_t *)(object)) +#define TPL_OBJECT_MAGIC 0xe0b9ec75 +#define TPL_OBJECT_MAGIC_FREED 0xe0bf6eed +#define TPL_OBJECT(x) ((tpl_object_t *)(x)) + +#ifdef OBJECT_HASH_CHECK +# define TPL_OBJECT_HASH_FIND(x) __tpl_object_hash_find(TPL_OBJECT(x)) +# define TPL_OBJECT_CHECK(x) \ + do { \ + if (!TPL_OBJECT(x))return; \ + else if ((tpl_obj_hash_check) && (!TPL_OBJECT_HASH_FIND(x))) return;\ + else if ((TPL_OBJECT(x)->magic != (int)TPL_OBJECT_MAGIC)) return; \ + } while (0) +# define TPL_OBJECT_CHECK_RETURN(x, ret) \ + do { \ + if (!TPL_OBJECT(x))return ret; \ + else if ((tpl_obj_hash_check) && (!TPL_OBJECT_HASH_FIND(x))) return ret;\ + else if ((TPL_OBJECT(x)->magic != (int)TPL_OBJECT_MAGIC)) return ret; \ + } while (0) +#else +# define TPL_OBJECT_CHECK(x) do {if ((!TPL_OBJECT(x)) || (TPL_OBJECT(x)->magic != (int)TPL_OBJECT_MAGIC)) return;} while (0) +# define TPL_OBJECT_CHECK_RETURN(x, ret) do {if ((!TPL_OBJECT(x)) || (TPL_OBJECT(x)->magic != (int)TPL_OBJECT_MAGIC)) return ret;} while (0) +#endif + +#define TPL_OBJECT_TYPE_CHECK(x, tp) do {if ((TPL_OBJECT(x)->type) != (tpl_object_type_t)(tp)) { TPL_ERR("Object type check failed"); return;} } while (0) +#define TPL_OBJECT_TYPE_CHECK_RETURN(x, tp, ret) do {if ((TPL_OBJECT(x)->type) != (tpl_object_type_t)(tp)) { TPL_ERR("Object type check failed"); return ret;} } while (0) typedef struct _tpl_runtime tpl_runtime_t; typedef struct _tpl_display_backend tpl_display_backend_t; @@ -75,6 +99,7 @@ struct _tpl_surface_backend { }; struct _tpl_object { + int magic; tpl_object_type_t type; tpl_util_atomic_uint reference; tpl_free_func_t free; @@ -212,4 +237,18 @@ void __tpl_hashlist_do_for_all_nodes(tpl_hlist_t *list, void (*cb_func)(void *)); void *__tpl_hashlist_lookup(tpl_hlist_t *list, size_t key); +#ifdef OBJECT_HASH_CHECK +/* object hash check global variable */ +extern tpl_bool_t tpl_obj_hash_check; +extern tpl_hlist_t *tpl_obj_hash; +/* object hash check functions */ +void __tpl_object_hash_init(void); +void __tpl_object_hash_shutdown(void); +static TPL_INLINE tpl_object_t * +__tpl_object_hash_find(tpl_object_t *object) +{ + return (tpl_object_t *)__tpl_hashlist_lookup(tpl_obj_hash, (size_t)object); +} +#endif + #endif /* TPL_INTERNAL_H */ diff --git a/src/tpl_object.c b/src/tpl_object.c index ce1c419..cf66cb0 100644 --- a/src/tpl_object.c +++ b/src/tpl_object.c @@ -1,12 +1,50 @@ #include "tpl_internal.h" #include +#ifdef OBJECT_HASH_CHECK +tpl_bool_t tpl_obj_hash_check = TPL_FALSE; +tpl_hlist_t *tpl_obj_hash = NULL; + +void +__tpl_object_hash_init(void) +{ + char *val; + tpl_obj_hash_check = TPL_FALSE; + + val = getenv("TPL_OBJECT_HASH_CHECK"); + if ((val) && (!strcmp(val, "1")) && (!tpl_obj_hash)) { + tpl_obj_hash_check = TPL_TRUE; + tpl_obj_hash = __tpl_hashlist_create(); + } +} + +void +__tpl_object_hash_shutdown(void) +{ + if (tpl_obj_hash) { + __tpl_hashlist_destroy(&tpl_obj_hash); + tpl_obj_hash = NULL; + } + tpl_obj_hash_check = TPL_FALSE; +} +#endif + tpl_bool_t __tpl_object_is_valid(tpl_object_t *object) { if (NULL == object) return TPL_FALSE; +#ifdef OBJECT_HASH_CHECK + if ((tpl_obj_hash_check == TPL_TRUE) && (!__tpl_object_hash_find(object))) + return TPL_FALSE; + else if (object->magic != (int)TPL_OBJECT_MAGIC) + return TPL_FALSE; +#else + if (object->magic != (int)TPL_OBJECT_MAGIC) + return TPL_FALSE; +#endif + return (__tpl_util_atomic_get(&object->reference) != 0); } @@ -17,6 +55,17 @@ __tpl_object_init(tpl_object_t *object, tpl_object_type_t type, TPL_ASSERT(object); TPL_ASSERT(type >= 0 && type < TPL_OBJECT_MAX); + object->magic = (int)TPL_OBJECT_MAGIC; +#ifdef OBJECT_HASH_CHECK + if (tpl_obj_hash_check) { + tpl_result_t ret; + ret = __tpl_hashlist_insert(tpl_obj_hash, (size_t)object, (void *)object); + if (TPL_ERROR_NONE != ret) { + TPL_ERR("__tpl_hashlist_insert failed. list(%p), object(%p)", + tpl_obj_hash, object); + } + } +#endif object->type = type; object->free = free_func; tpl_util_map_pointer_init(&object->user_data_map, TPL_OBJECT_BUCKET_BITS, @@ -37,6 +86,12 @@ __tpl_object_fini(tpl_object_t *object) { TPL_ASSERT(object); + object->magic = (int)TPL_OBJECT_MAGIC_FREED; +#ifdef OBJECT_HASH_CHECK + if (tpl_obj_hash_check) + __tpl_hashlist_delete(tpl_obj_hash, (size_t)object); +#endif + if (pthread_mutex_destroy(&object->mutex) != 0) { TPL_ERR("tpl_object_t pthread_mutex_destroy failed."); return TPL_ERROR_INVALID_OPERATION; -- 2.7.4