From 2da9e7de29e296079b687cade8258fc77acd12ec Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 13:53:11 +0900 Subject: [PATCH 01/16] capture: enhance debugging logs Change-Id: I54b5cc0ffb52ea8abc11b26b5763064524d960f7 --- src/tdm_capture.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index b0acba2..618fb35 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -63,7 +63,9 @@ _tdm_capture_print_list(struct list_head *list) p = str; LIST_FOR_EACH_ENTRY(b, list, link) { if (len > 0) { - int l = snprintf(p, len, " (%p)", b->buffer); + tbm_bo bo = tbm_surface_internal_get_bo(b->buffer, 0); + int flags = tbm_bo_get_flags(bo); + int l = snprintf(p, len, " (%p[bo_flags:%x])", b->buffer, flags); p += l; len -= l; } else @@ -644,6 +646,12 @@ tdm_capture_commit(tdm_capture *capture) LIST_ADDTAIL(&b->commit_link, &commit_buffer_list); } + if (tdm_debug_module & TDM_DEBUG_BUFFER) { + TDM_INFO("capture(%p) committed:", private_capture); + _tdm_capture_print_list(&private_capture->pending_buffer_list); + _tdm_capture_print_list(&private_capture->buffer_list); + } + ret = func_capture->capture_commit(private_capture->capture_module); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); -- 2.7.4 From bf8cde72bd48541c5821f7651e9c98bfaea981ca Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 10:10:22 +0900 Subject: [PATCH 02/16] buffer: enhance debugging logs Change-Id: If1fda435f672768ab0a46a1c4e0f18dcc991fad8 --- src/tdm_buffer.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index e437a58..72d9d17 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -203,6 +203,9 @@ tdm_buffer_ref_backend(tbm_surface_h buffer) buf_info->backend_ref_count++; tbm_surface_internal_ref(buffer); + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("buffer(%p) backend_ref_count(%d)", buffer, buf_info->backend_ref_count); + return buffer; } @@ -218,13 +221,17 @@ tdm_buffer_unref_backend(tbm_surface_h buffer) TDM_RETURN_IF_FAIL(buf_info != NULL); buf_info->backend_ref_count--; + + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("buffer(%p) backend_ref_count(%d)", buffer, buf_info->backend_ref_count); + if (buf_info->backend_ref_count > 0) { tbm_surface_internal_unref(buffer); return; } -// if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) -// TDM_NEVER_GET_HERE(); + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("buffer(%p) released", buffer); tbm_surface_internal_ref(buffer); LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) -- 2.7.4 From 715ed9fb56c4c3d2624690c493799a8f27a1e00c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 10:11:32 +0900 Subject: [PATCH 03/16] output: enhance debugging logs Change-Id: I01db98634347826e9a3f9b22eafa77a233d86a18 --- src/tdm_output.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/tdm_output.c b/src/tdm_output.c index bf353ce..bb2710c 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1172,8 +1172,14 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl if (!private_layer->waiting_buffer) continue; - if (private_layer->committed_buffer) + if (private_layer->committed_buffer) { tdm_layer_free_buffer(private_layer, private_layer->committed_buffer); + private_layer->committed_buffer = NULL; + if (tdm_debug_module & TDM_DEBUG_BUFFER) + TDM_INFO("layer(%p) waiting_buffer(%p) committed_buffer(%p)", + private_layer, private_layer->waiting_buffer->buffer, + private_layer->committed_buffer); + } private_layer->committed_buffer = private_layer->waiting_buffer; private_layer->waiting_buffer = NULL; -- 2.7.4 From 85de7e2c5aee819eaa922c2efd3d38fffcb24d9f Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 14:10:22 +0900 Subject: [PATCH 04/16] pp: remove unuseful pp capabilities scale and transform seems as the default pp capabilities. Change-Id: I68eff0222105f1e255210ea1ebe58a22599af32a --- include/tdm_common.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/tdm_common.h b/include/tdm_common.h index f847a77..e97170b 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -152,10 +152,8 @@ typedef enum { typedef enum { TDM_PP_CAPABILITY_SYNC = (1 << 0), /**< The pp device supports synchronous operation */ TDM_PP_CAPABILITY_ASYNC = (1 << 1), /**< The pp device supports asynchronous operation */ - TDM_PP_CAPABILITY_SCALE = (1 << 4), /**< The pp device supports scale operation */ - TDM_PP_CAPABILITY_TRANSFORM = (1 << 5), /**< The pp device supports transform operation */ - TDM_PP_CAPABILITY_SCANOUT = (1 << 6), /**< The pp device supports only scanout buffer */ - TDM_PP_CAPABILITY_NO_CSC = (1 << 7), /**< The pp device doesnt supports Color Space Conversion */ + TDM_PP_CAPABILITY_SCANOUT = (1 << 4), /**< The pp device supports only scanout buffer */ + TDM_PP_CAPABILITY_NO_CSC = (1 << 5), /**< The pp device doesn't supports Color Space Conversion */ } tdm_pp_capability; /** -- 2.7.4 From 0ca0cdc7d3caf4aa3a0f95e194e5478bf1dc92aa Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 19:46:00 +0900 Subject: [PATCH 05/16] pp: correct debugging logs Change-Id: I599a9e78919b0a0195f0ccee3c0b41544614b7fa --- src/tdm_pp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tdm_pp.c b/src/tdm_pp.c index c22fee0..bca4cd8 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -60,6 +60,7 @@ _tdm_pp_print_list(struct list_head *list) TDM_RETURN_IF_FAIL(list != NULL); + str[0] = '\0'; p = str; LIST_FOR_EACH_ENTRY(b, list, link) { if (len > 0) { -- 2.7.4 From 6e66b7b2b91efe128de1af5766a5025590f70c13 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 19:46:12 +0900 Subject: [PATCH 06/16] capture: correct debugging logs Change-Id: I00f06b8d917e135c269bc581605ea131f6f5d12a --- src/tdm_capture.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 618fb35..c3da6b7 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -60,6 +60,7 @@ _tdm_capture_print_list(struct list_head *list) TDM_RETURN_IF_FAIL(list != NULL); + str[0] = '\0'; p = str; LIST_FOR_EACH_ENTRY(b, list, link) { if (len > 0) { @@ -136,8 +137,6 @@ _tdm_capture_thread_cb_done(tdm_private_display *private_display, void *object, first_entry = container_of((&private_capture->buffer_list)->next, capture_buffer, link); if (first_entry->buffer != buffer) TDM_ERR("buffer(%p) is skipped", first_entry->buffer); - } else { - TDM_NEVER_GET_HERE(); } if ((capture_buffer = _tdm_capture_find_tbm_buffer(&private_capture->buffer_list, buffer))) { @@ -596,6 +595,7 @@ tdm_capture_attach(tdm_capture *capture, tbm_surface_h buffer) if (tdm_debug_module & TDM_DEBUG_BUFFER) { TDM_INFO("capture(%p) attached:", private_capture); + _tdm_capture_print_list(&private_capture->pending_buffer_list); _tdm_capture_print_list(&private_capture->buffer_list); } -- 2.7.4 From f7f1bfe99082ad2707be80deab70225da2d24ce4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 15:57:54 +0900 Subject: [PATCH 07/16] mutex: remove pthread_mutex_trylock We don't need to call pthread_mutex_trylock to call pthread_mutex_unlock. Just call pthread_mutex_unlock to ensure all mutexes are locked. Change-Id: Id43c9fdddaa400454f9d462430ae90ecf25615c8 --- common/tdm_log.c | 1 - src/tdm_thread.c | 1 - 2 files changed, 2 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 348ea99..4d4d500 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -224,6 +224,5 @@ tdm_log_print(int level, const char *fmt, ...) EXTERN void tdm_log_reset(void) { - pthread_mutex_trylock(&log_lock); pthread_mutex_unlock(&log_lock); } diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 29d996a..4f4626f 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -292,7 +292,6 @@ tdm_thread_deinit(tdm_private_loop *private_loop) _pthread_mutex_unlock(&private_display->lock); pthread_join(private_loop->private_thread->event_thread, NULL); - pthread_mutex_trylock(&cb_list_lock); pthread_mutex_unlock(&cb_list_lock); tdm_log_reset(); -- 2.7.4 From d37f0aa105da59dbb0601f4dbf47cbc93ae7fd0c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 15:58:12 +0900 Subject: [PATCH 08/16] tests: check return value Change-Id: I15bc563500889e26f42600a6066dd0fe884fc29f --- tools/tdm_test_client.c | 30 ++++++++++++++++++++---------- tools/tdm_test_server.c | 3 ++- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/tools/tdm_test_client.c b/tools/tdm_test_client.c index a8e7c62..11976fb 100644 --- a/tools/tdm_test_client.c +++ b/tools/tdm_test_client.c @@ -273,9 +273,12 @@ do_query(tdm_test_client *data) return; } - tdm_client_output_get_conn_status(output, &status); - tdm_client_output_get_dpms(output, &dpms); - tdm_client_output_get_refresh_rate(output, &refresh); + error = tdm_client_output_get_conn_status(output, &status); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); + error = tdm_client_output_get_dpms(output, &dpms); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); + error = tdm_client_output_get_refresh_rate(output, &refresh); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); printf("tdm_output \"%s\"\n", data->args.output_name); printf("\tstatus : %s\n", conn_str[status]); @@ -298,7 +301,8 @@ do_vblank(tdm_test_client *data) return; } - tdm_client_output_add_change_handler(output, _client_output_handler, NULL); + error = tdm_client_output_add_change_handler(output, _client_output_handler, NULL); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); vblank = tdm_client_output_create_vblank(output, &error); if (error != TDM_ERROR_NONE) { @@ -306,12 +310,18 @@ do_vblank(tdm_test_client *data) return; } - tdm_client_vblank_set_name(vblank, data->args.vblank_name); - tdm_client_vblank_set_enable_fake(vblank, data->args.enable_fake); - tdm_client_vblank_set_sync(vblank, data->args.sync); - if (data->args.fps > 0) - tdm_client_vblank_set_fps(vblank, data->args.fps); - tdm_client_vblank_set_offset(vblank, data->args.offset); + error = tdm_client_vblank_set_name(vblank, data->args.vblank_name); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); + error = tdm_client_vblank_set_enable_fake(vblank, data->args.enable_fake); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); + error = tdm_client_vblank_set_sync(vblank, data->args.sync); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); + if (data->args.fps > 0) { + error = tdm_client_vblank_set_fps(vblank, data->args.fps); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); + } + error = tdm_client_vblank_set_offset(vblank, data->args.offset); + TDM_WARNING_IF_FAIL(error == TDM_ERROR_NONE); error = tdm_client_get_fd(data->client, &fd); if (error != TDM_ERROR_NONE || fd < 0) { diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index bf5a8e2..17c0121 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -819,7 +819,8 @@ destroy(tdm_test_server *data) ret = tdm_layer_unset_buffer(l->layer); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } - tdm_layer_commit(l->layer, NULL, NULL); + ret = tdm_layer_commit(l->layer, NULL, NULL); + TDM_EXIT_IF_FAIL(ret == TDM_ERROR_NONE); } LIST_FOR_EACH_ENTRY_SAFE(p, pp, &data->pp_list, link) { -- 2.7.4 From 0a097c490e23c006da1642b060f86621cc9d7fd3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 15:58:38 +0900 Subject: [PATCH 09/16] utests: check return value Change-Id: I21868201523ec15af93d13bfc85fe17a8e770bf7 --- utests/src/ut_tdm_client.cpp | 13 ++++++++++--- utests/src/ut_tdm_helper.cpp | 17 +++-------------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/utests/src/ut_tdm_client.cpp b/utests/src/ut_tdm_client.cpp index e4b445b..b44ef46 100644 --- a/utests/src/ut_tdm_client.cpp +++ b/utests/src/ut_tdm_client.cpp @@ -104,9 +104,16 @@ void TDMClient::ServerKill(void) close(pipe_child[0]); if (pipe_child[1] >= 0) { if (server_pid > 0) { - _ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_TERMINATE_SERVER); - waitpid(server_pid, NULL, 0); - TDM_INFO("*** server terminated ***"); + bool ret = _ut_tdm_pipe_write_msg(pipe_child[1], pipe_parent[0], TDM_UT_PIPE_MSG_TERMINATE_SERVER); + if (ret) { + if (waitpid(server_pid, NULL, 0) == server_pid) + TDM_INFO("*** server terminated ***"); + else + TDM_ERR("*** failed to terminate server ***"); + } else { + if (kill(server_pid, 9) < 0) + TDM_ERR("*** failed to kill server ***"); + } } close(pipe_child[1]); } diff --git a/utests/src/ut_tdm_helper.cpp b/utests/src/ut_tdm_helper.cpp index 9684f64..b9ad342 100644 --- a/utests/src/ut_tdm_helper.cpp +++ b/utests/src/ut_tdm_helper.cpp @@ -486,28 +486,17 @@ TEST_P(TDMHelper, HelperGetDisplayInformationNullOther) TEST_P(TDMHelper, HelperCommitPerVblankEnabled) { - tdm_helper_commit_per_vblank_enabled(dpy); + ASSERT_EQ(tdm_helper_commit_per_vblank_enabled(dpy), 0); } TEST_P(TDMHelper, HelperCommitPerVblankEnabledNullOBject) { - tdm_helper_commit_per_vblank_enabled(NULL); -} - -TEST_P(TDMHelper, HelperOutputCommitPerVblankEnabled) -{ - for (int o = 0; o < output_count; o++) { - tdm_error ret; - tdm_output *output = tdm_display_get_output(dpy, o, &ret); - ASSERT_EQ(ret, TDM_ERROR_NONE); - ASSERT_NE(output, NULL); - tdm_helper_output_commit_per_vblank_enabled(output); - } + ASSERT_EQ(tdm_helper_commit_per_vblank_enabled(NULL), 0); } TEST_P(TDMHelper, HelperOutputCommitPerVblankEnabledNullObject) { - tdm_helper_output_commit_per_vblank_enabled(NULL); + ASSERT_EQ(tdm_helper_output_commit_per_vblank_enabled(NULL), -1); } #ifdef TDM_UT_TEST_WITH_PARAMS -- 2.7.4 From 866dd1e1847cabe9a61298e9650495c4af195e71 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 15:58:54 +0900 Subject: [PATCH 10/16] utests: set initialized value Change-Id: I79b87512b495d271cbe1ed266aeebf9aa8ccff6b --- utests/src/ut_tdm_hwc_window.cpp | 1 + utests/src/ut_tdm_output_hwc.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index b7f9be1..23bae31 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -47,6 +47,7 @@ public: TDMHwcWindow::TDMHwcWindow() { + error = TDM_ERROR_NONE; hwc_wins = NULL; hwc_count = 0; video_hwc_win = NULL; diff --git a/utests/src/ut_tdm_output_hwc.cpp b/utests/src/ut_tdm_output_hwc.cpp index 73bac1c..d99b0a0 100644 --- a/utests/src/ut_tdm_output_hwc.cpp +++ b/utests/src/ut_tdm_output_hwc.cpp @@ -42,7 +42,7 @@ public: TDMOutputHwc::TDMOutputHwc() { - ; + error = TDM_ERROR_NONE; } void TDMOutputHwc::SetUp(void) -- 2.7.4 From 0d873ea48bc7965683c73686cb2d77422215b743 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 19 Mar 2018 19:46:30 +0900 Subject: [PATCH 11/16] utests: show the result via a layer Change-Id: I8ca6f448a2a124f0f2925ba7a26a652ebe57b6ec --- utests/src/ut_tdm.h | 5 +- utests/src/ut_tdm_backend_capture.cpp | 635 ++++++++++++++++++++++++++-------- utests/src/ut_tdm_backend_display.cpp | 8 +- utests/src/ut_tdm_backend_pp.cpp | 418 +++++++++++++++++++--- utests/src/ut_tdm_layer.cpp | 231 ++++++------- utests/src/ut_tdm_output.cpp | 9 +- 6 files changed, 979 insertions(+), 327 deletions(-) diff --git a/utests/src/ut_tdm.h b/utests/src/ut_tdm.h index 8ffd5f2..9e4accd 100644 --- a/utests/src/ut_tdm.h +++ b/utests/src/ut_tdm.h @@ -229,15 +229,16 @@ bool ut_tdm_layer_support_scale(tdm_layer *layer); bool ut_tdm_layer_support_no_crop(tdm_layer *layer); bool ut_tdm_layer_prepare_buffer(tdm_layer *layer, tbm_surface_h *buffers, int buffer_count, bool fill); bool ut_tdm_layer_prepare_buffer_queue(tdm_layer *layer, tbm_surface_queue_h *buffer_queue); -bool ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_info_layer *info); +bool ut_tdm_layer_fill_info(tdm_layer *layer, tbm_surface_h buffer, tbm_surface_queue_h buffer_queue, tdm_info_layer *info); bool ut_tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer); +bool ut_tdm_layer_set_buffer_with_pos(tdm_layer *layer, tbm_surface_h buffer, tdm_pos *pos); unsigned int ut_tdm_layer_get_output_pipe(tdm_layer *layer); tbm_format ut_tdm_layer_find_best_format(tdm_layer *layer); bool ut_tdm_layer_is_avaiable(tdm_layer *layer); bool ut_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform transform, tdm_info_pp *info); bool ut_tdm_capture_fill_info(tdm_output *output, tbm_surface_h buffer, tdm_transform transform, - tdm_capture_type type, int frequency, tdm_info_capture *info); + tdm_capture_type type, int frequency, bool stretch, tdm_info_capture *info); /******************************************************************************/ /** testing for checking backend's basic implementation **/ diff --git a/utests/src/ut_tdm_backend_capture.cpp b/utests/src/ut_tdm_backend_capture.cpp index 6604be1..07a1033 100644 --- a/utests/src/ut_tdm_backend_capture.cpp +++ b/utests/src/ut_tdm_backend_capture.cpp @@ -50,16 +50,28 @@ public: tdm_info_capture info; tdm_output *output; + unsigned int pipe; + const tdm_output_mode *mode; + + tdm_layer *dst_layer; + int dst_zpos; + int dst_layer_index; + tdm_pos dst_pos; + + bool stream_exit; + int stream_count; TDMBackendCapture(); void SetUp(void); void TearDown(void); - bool FindFormat(tbm_format fmt); + bool FindLayer(int output_idx, tbm_format fmt, tdm_pos *punch); bool TestPrepareDefault(void); - bool TestPrepare(int output_idx, int w, int h, tbm_format fmt, tdm_transform t, tdm_capture_type c, int frequency); + bool TestPrepare(int output_idx, int w, int h, tbm_format fmt, tdm_transform t, tdm_capture_type c, int frequency, bool stretch); void TestDone(void); - void DumpBuffers(int b, char *test); + void ShowBuffer(int b, tdm_pos *pos); + void HideLayer(void); + void DumpBuffer(int b, char *test); void DestroyBuffers(void); }; @@ -75,7 +87,18 @@ TDMBackendCapture::TDMBackendCapture() for (int b = 0; b < 3; b++) buffers[b] = NULL; memset(&info, 0, sizeof info); + output = NULL; + pipe = 0; + mode = NULL; + + dst_layer = NULL; + dst_zpos = 0; + dst_layer_index = 0; + memset(&dst_pos, 0, sizeof dst_pos); + + stream_exit = false; + stream_count = 0; } void TDMBackendCapture::SetUp(void) @@ -90,6 +113,18 @@ void TDMBackendCapture::SetUp(void) if (!has_capture_cap) return; + ASSERT_EQ(tdm_display_get_capture_capabilities(dpy, &capabilities), TDM_ERROR_NONE); + ASSERT_GT(capabilities, 0); + ASSERT_EQ(tdm_display_get_capture_available_formats(dpy, &formats, &format_count), TDM_ERROR_NONE); + ASSERT_NE(formats, NULL); + ASSERT_GT(format_count, 0); + ASSERT_EQ(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align), TDM_ERROR_NONE); + ASSERT_TRUE(min_w == -1 || min_w > 0); + ASSERT_TRUE(min_h == -1 || min_h > 0); + ASSERT_TRUE(max_w == -1 || max_w > 0); + ASSERT_TRUE(max_h == -1 || max_h > 0); + ASSERT_TRUE(preferred_align == -1 || preferred_align > 0); + for (int o = 0; o < output_count; o++) { if (!ut_tdm_output_is_connected(outputs[o])) continue; @@ -115,21 +150,62 @@ void TDMBackendCapture::TearDown(void) TDMBackendDisplay::TearDown(); } -bool TDMBackendCapture::TestPrepareDefault(void) +bool TDMBackendCapture::FindLayer(int output_idx, tbm_format fmt, tdm_pos *punch) { tdm_error ret; + int count; + int primary_zpos, zpos; + tdm_layer *primary = ut_tdm_output_get_primary_layer(outputs[output_idx]); + TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(outputs[output_idx], &count) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_capabilities(dpy, &capabilities) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(capabilities > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_formats(dpy, &formats, &format_count) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(formats != NULL); - TDM_UT_RETURN_FALSE_IF_FAIL(format_count > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(min_w == -1 || min_w > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(min_h == -1 || min_h > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(max_w == -1 || max_w > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(max_h == -1 || max_h > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(preferred_align == -1 || preferred_align > 0); + dst_layer = NULL; + + for (int l = 0; l < count; l++) { + unsigned int usable; + const tbm_format *dst_formats; + int dst_format_count; + + tdm_layer *temp = tdm_output_get_layer(outputs[output_idx], l, &ret); + TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_is_usable(temp, &usable) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(temp, &dst_formats, &dst_format_count) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0); + + if (usable) { + bool found = false; + for (int f = 0; f < dst_format_count; f++) { + if (dst_formats[f] == fmt) { + found = true; + break; + } + } + if (!found) + continue; + dst_layer = temp; + dst_zpos = zpos; + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE); + break; + } + } + + if (dst_layer && (dst_zpos < primary_zpos)) { + tbm_surface_h displaying_buffer = tdm_layer_get_displaying_buffer(primary, &ret); + TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(displaying_buffer != NULL); + tdm_helper_clear_buffer_pos(displaying_buffer, punch); + } + + return true; +} + +bool TDMBackendCapture::TestPrepareDefault(void) +{ + tdm_error ret; for (int o = 0; o < output_count; o++) { if (!ut_tdm_output_is_connected(outputs[o])) @@ -140,7 +216,7 @@ bool TDMBackendCapture::TestPrepareDefault(void) TDM_UT_RETURN_FALSE_IF_FAIL(capture != NULL); TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[0], 0, false, 3, buffers) == true); - TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_capture_fill_info(outputs[o], buffers[0], TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, &info) == true); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_capture_fill_info(outputs[o], buffers[0], TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, false, &info) == true); TDM_UT_RETURN_FALSE_IF_FAIL(tdm_capture_set_info(capture, &info) == TDM_ERROR_NONE); output = outputs[o]; @@ -152,29 +228,10 @@ bool TDMBackendCapture::TestPrepareDefault(void) return (capture) ? true : false; } -bool TDMBackendCapture::FindFormat(tbm_format fmt) -{ - bool found = false; - - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_capabilities(dpy, &capabilities) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(capabilities > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_formats(dpy, &formats, &format_count) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(formats != NULL); - TDM_UT_RETURN_FALSE_IF_FAIL(format_count > 0); - - for (int f = 0; f < format_count; f++) { - if (formats[f] == fmt) { - found = true; - break; - } - } - - return found; -} - -bool TDMBackendCapture::TestPrepare(int output_idx, int w, int h, tbm_format fmt, tdm_transform t, tdm_capture_type c, int frequency) +bool TDMBackendCapture::TestPrepare(int output_idx, int w, int h, tbm_format fmt, tdm_transform t, tdm_capture_type c, int frequency, bool stretch) { tdm_error ret; + int flags = 0; TDM_UT_RETURN_FALSE_IF_FAIL(outputs != NULL); TDM_UT_RETURN_FALSE_IF_FAIL(output_count > 0); @@ -183,8 +240,6 @@ bool TDMBackendCapture::TestPrepare(int output_idx, int w, int h, tbm_format fmt TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_capabilities(dpy, &capabilities) == TDM_ERROR_NONE); TDM_UT_RETURN_FALSE_IF_FAIL(capabilities > 0); - TDM_UT_RETURN_FALSE_IF_FAIL(FindFormat(fmt) == true); - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_display_get_capture_available_size(dpy, &min_w, &min_h, &max_w, &max_h, &preferred_align) == TDM_ERROR_NONE); TDM_UT_RETURN_FALSE_IF_FAIL(min_w == -1 || min_w > 0); TDM_UT_RETURN_FALSE_IF_FAIL(min_h == -1 || min_h > 0); @@ -196,8 +251,15 @@ bool TDMBackendCapture::TestPrepare(int output_idx, int w, int h, tbm_format fmt TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE); TDM_UT_RETURN_FALSE_IF_FAIL(capture != NULL); - TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(w, h, fmt, 0, false, 3, buffers) == true); - TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_capture_fill_info(outputs[output_idx], buffers[0], t, c, frequency, &info) == true); + if (dst_layer) { + tdm_layer_capability capabilities; + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_capabilities(dst_layer, &capabilities) == TDM_ERROR_NONE); + if (capabilities & TDM_LAYER_CAPABILITY_SCANOUT) + flags |= TBM_BO_SCANOUT; + } + + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(w, h, fmt, flags, false, 3, buffers) == true); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_capture_fill_info(outputs[output_idx], buffers[0], t, c, frequency, stretch, &info) == true); TDM_UT_RETURN_FALSE_IF_FAIL(tdm_capture_set_info(capture, &info) == TDM_ERROR_NONE); output = outputs[output_idx]; @@ -215,7 +277,7 @@ void TDMBackendCapture::TestDone(void) DestroyBuffers(); } -void TDMBackendCapture::DumpBuffers(int b, char *test) +void TDMBackendCapture::DumpBuffer(int b, char *test) { char filename[256]; if (test) @@ -225,6 +287,26 @@ void TDMBackendCapture::DumpBuffers(int b, char *test) tdm_helper_dump_buffer_str(buffers[b], NULL, filename); } +void TDMBackendCapture::ShowBuffer(int b, tdm_pos *pos) +{ + ASSERT_NE(output, NULL); + ASSERT_NE(dst_layer, NULL); + + ASSERT_EQ(ut_tdm_layer_set_buffer_with_pos(dst_layer, buffers[b], pos), true); + ASSERT_EQ(tdm_output_commit(output, 0, NULL, NULL), TDM_ERROR_NONE); +} + +void TDMBackendCapture::HideLayer(void) +{ + ASSERT_NE(output, NULL); + ASSERT_NE(dst_layer, NULL); + + tdm_layer_unset_buffer(dst_layer); + tdm_output_commit(output, 0, NULL, NULL); + + dst_layer = NULL; +} + void TDMBackendCapture::DestroyBuffers(void) { for (int b = 0; b < 3; b++) { @@ -233,61 +315,91 @@ void TDMBackendCapture::DestroyBuffers(void) } } +static void +_ut_tdm_capture_fit_rect(int src_w, int src_h, int dst_w, int dst_h, tdm_pos *fit) +{ + float rw, rh; + + if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !fit) + return; + + rw = (float)src_w / dst_w; + rh = (float)src_h / dst_h; + + if (rw > rh) { + fit->w = dst_w; + fit->h = src_h / rw; + fit->x = 0; + fit->y = (dst_h - fit->h) / 2; + } else if (rw < rh) { + fit->w = src_w / rh; + fit->h = dst_h; + fit->x = (dst_w - fit->w) / 2; + fit->y = 0; + } else { + fit->w = dst_w; + fit->h = dst_h; + fit->x = 0; + fit->y = 0; + } + + if (fit->x % 2) + fit->x = fit->x - 1; +} + bool ut_tdm_capture_fill_info(tdm_output *output, tbm_surface_h buffer, tdm_transform transform, - tdm_capture_type type, int frequency, tdm_info_capture *info) + tdm_capture_type type, int frequency, bool stretch, tdm_info_capture *info) { int bw, bh; + const tdm_output_mode *mode = NULL; + + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(mode != NULL); memset(info, 0, sizeof *info); bw = bh = TDM_UT_INVALID_VALUE; tdm_helper_get_buffer_full_size(buffer, &bw, &bh); + TDM_UT_RETURN_FALSE_IF_FAIL(bw != TDM_UT_INVALID_VALUE); TDM_UT_RETURN_FALSE_IF_FAIL(bw >= tbm_surface_get_width(buffer)); TDM_UT_RETURN_FALSE_IF_FAIL(bh != TDM_UT_INVALID_VALUE); TDM_UT_RETURN_FALSE_IF_FAIL(bh >= tbm_surface_get_height(buffer)); info->dst_config.size.h = bw; info->dst_config.size.v = bh; - info->dst_config.pos.x = 0; - info->dst_config.pos.y = 0; - info->dst_config.pos.w = tbm_surface_get_width(buffer); - info->dst_config.pos.h = tbm_surface_get_height(buffer); + + if (stretch) { + info->dst_config.pos.x = 0; + info->dst_config.pos.y = 0; + info->dst_config.pos.w = tbm_surface_get_width(buffer); + info->dst_config.pos.h = tbm_surface_get_height(buffer); + } else { + _ut_tdm_capture_fit_rect(mode->hdisplay, mode->vdisplay, + tbm_surface_get_width(buffer), tbm_surface_get_height(buffer), + &info->dst_config.pos); + } + info->dst_config.format = tbm_surface_get_format(buffer); info->transform = transform; info->type = type; info->flags = 0; - if (frequency <= 0) { - const tdm_output_mode *mode = NULL; - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_mode(output, &mode) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(mode != NULL); + if (frequency <= 0) frequency = mode->vrefresh; - } info->frequency = frequency; - TDM_INFO("filling capture info done: dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) type(%s) freq(%d)", - info->dst_config.size.h, info->dst_config.size.h, - info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h, - FOURCC_STR(info->dst_config.format), - tdm_transform_str(info->transform), tdm_capture_type_str(info->type), info->frequency); + TDM_UT_INFO("filling capture info done: dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) type(%s) freq(%d)", + info->dst_config.size.h, info->dst_config.size.v, + info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h, + FOURCC_STR(info->dst_config.format), + tdm_transform_str(info->transform), tdm_capture_type_str(info->type), info->frequency); return true; } -static tbm_format test_formats[] = { - TBM_FORMAT_ARGB8888, - TBM_FORMAT_XRGB8888, - TBM_FORMAT_YUV420, - TBM_FORMAT_YVU420, - TBM_FORMAT_NV12, - TBM_FORMAT_NV21, -}; - -#define TEST_FORMAT_CNT (int)(sizeof(test_formats) / sizeof((test_formats)[0])) - TEST_P(TDMBackendCapture, CaptureDispalyGetAvaiableFormats) { const tbm_format *formats = (const tbm_format *)TDM_UT_INVALID_VALUE; @@ -367,6 +479,7 @@ TEST_P(TDMBackendCapture, CaptureDispalyGetAvaiableSizeNullOther) TEST_P(TDMBackendCapture, CaptureDestroy) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -376,6 +489,7 @@ TEST_P(TDMBackendCapture, CaptureDestroy) TEST_P(TDMBackendCapture, CaptureDestroyNullObject) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); tdm_capture_destroy(NULL); } @@ -388,6 +502,7 @@ TEST_P(TDMBackendCapture, CaptureSetInfo) TEST_P(TDMBackendCapture, CaptureSetInfoNullObject) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); tdm_info_capture info; memset(&info, 0, sizeof info); @@ -397,6 +512,7 @@ TEST_P(TDMBackendCapture, CaptureSetInfoNullObject) TEST_P(TDMBackendCapture, CaptureSetInfoNullOther) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -416,6 +532,7 @@ _ut_tdm_capture_done_cb(tdm_capture *capture, tbm_surface_h buffer, void *user_d TEST_P(TDMBackendCapture, CaptureSetDoneHandler) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -427,6 +544,7 @@ TEST_P(TDMBackendCapture, CaptureSetDoneHandler) TEST_P(TDMBackendCapture, CaptureSetDoneHandlerNullObject) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(tdm_capture_set_done_handler(NULL, _ut_tdm_capture_done_cb, NULL), TDM_ERROR_INVALID_PARAMETER); } @@ -434,6 +552,7 @@ TEST_P(TDMBackendCapture, CaptureSetDoneHandlerNullObject) TEST_P(TDMBackendCapture, CaptureSetDoneHandlerNullOther) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -445,18 +564,18 @@ TEST_P(TDMBackendCapture, CaptureSetDoneHandlerNullOther) TEST_P(TDMBackendCapture, CaptureAttach) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); for (int o = 0; o < output_count; o++) { if (!ut_tdm_output_is_connected(outputs[o])) continue; - for (int f = 0; f < TEST_FORMAT_CNT; f++) { - if (!FindFormat(test_formats[f])) - continue; + for (int f = 0; f < format_count; f++) { + FindLayer(o, formats[f], &dst_pos); - ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f], - TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1), true); + ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, false), true); for (int b = 0; b < 3; b++) ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); @@ -469,6 +588,7 @@ TEST_P(TDMBackendCapture, CaptureAttach) TEST_P(TDMBackendCapture, CaptureAttachNullObject) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); tbm_surface_h buffer = (tbm_surface_h)TDM_UT_BUFFER_SIZE; @@ -478,6 +598,7 @@ TEST_P(TDMBackendCapture, CaptureAttachNullObject) TEST_P(TDMBackendCapture, CaptureAttachNullOther) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -489,6 +610,7 @@ TEST_P(TDMBackendCapture, CaptureAttachNullOther) TEST_P(TDMBackendCapture, CaptureCommit) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -500,6 +622,7 @@ TEST_P(TDMBackendCapture, CaptureCommit) TEST_P(TDMBackendCapture, CaptureCommitNullOBject) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(tdm_capture_commit(NULL), TDM_ERROR_INVALID_PARAMETER); } @@ -507,6 +630,7 @@ TEST_P(TDMBackendCapture, CaptureCommitNullOBject) TEST_P(TDMBackendCapture, CaptureCommitDpmsOff) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); ASSERT_EQ(TestPrepareDefault(), true); @@ -519,9 +643,83 @@ TEST_P(TDMBackendCapture, CaptureCommitDpmsOff) TestDone(); } -TEST_P(TDMBackendCapture, CaptureNoScaleNoTransformNoCSC) +static void +_ut_tdm_capture_done_cb2(tdm_capture *capture, tbm_surface_h buffer, void *user_data) +{ + int *done = (int*)user_data; + if (done) + (*done)++; +} + +TEST_P(TDMBackendCapture, CaptureDestroyWithoutCommit) +{ + TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + + for (int o = 0; o < output_count; o++) { + const tdm_output_mode *mode = NULL; + int f = 0; + + if (!ut_tdm_output_is_connected(outputs[o])) + continue; + + ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); + + FindLayer(o, formats[f], &dst_pos); + + ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, false), true); + + ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, NULL), TDM_ERROR_NONE); + + for (int b = 0; b < 3; b++) + ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + + tdm_capture_destroy(capture); + capture = NULL; + + TestDone(); + } +} + +TEST_P(TDMBackendCapture, CaptureDestroyBeforeDone) +{ + TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + + for (int o = 0; o < output_count; o++) { + const tdm_output_mode *mode = NULL; + int f = 0; + + if (!ut_tdm_output_is_connected(outputs[o])) + continue; + + ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); + + FindLayer(o, formats[f], &dst_pos); + + ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, false), true); + + ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, NULL), TDM_ERROR_NONE); + + for (int b = 0; b < 3; b++) + ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + + ASSERT_EQ(tdm_capture_commit(capture), TDM_ERROR_NONE); + + tdm_capture_destroy(capture); + capture = NULL; + + TestDone(); + } +} + +TEST_P(TDMBackendCapture, CaptureOneshotLetterboxSize) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_ONESHOT); bool done; @@ -533,18 +731,29 @@ TEST_P(TDMBackendCapture, CaptureNoScaleNoTransformNoCSC) ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); - for (int f = 0; f < TEST_FORMAT_CNT; f++) { - char temp[256]; - snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(test_formats[f])); + for (int f = 0; f < format_count; f++) { + int half_size = ((mode->hdisplay <= mode->vdisplay) ? mode->hdisplay : mode->vdisplay) / 2; - if (!FindFormat(test_formats[f])) + dst_pos.x = (mode->hdisplay - half_size) / 2; + dst_pos.y = (mode->vdisplay - half_size) / 2; + dst_pos.w = half_size; + dst_pos.h = half_size; + + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(formats[f])); + + FindLayer(o, formats[f], &dst_pos); + + if (!dst_layer) { + TDM_UT_INFO("no proper layer for %c%c%c%c", FOURCC_STR(formats[f])); continue; + } - ASSERT_EQ(TestPrepare(o, mode->hdisplay, mode->vdisplay, test_formats[f], - TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1), true); + ASSERT_EQ(TestPrepare(o, half_size, half_size, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, false), true); ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb, &done), TDM_ERROR_NONE); +retry: for (int b = 0; b < 3; b++) { done = false; ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); @@ -553,17 +762,30 @@ TEST_P(TDMBackendCapture, CaptureNoScaleNoTransformNoCSC) while (!done) ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); - DumpBuffers(b, temp); +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b, &dst_pos); } + TDM_UT_ASK_YNR("* Successed to capture a output to a '%c%c%c%c' buffer as letterbox size and show? (output: %d, layer: %d)", + FOURCC_STR(formats[f]), pipe, dst_layer_index); + + + HideLayer(); + TestDone(); } } } -TEST_P(TDMBackendCapture, CaptureScaleTransformCSC) +TEST_P(TDMBackendCapture, CaptureOneshotFullSize) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_ONESHOT); bool done; @@ -575,18 +797,29 @@ TEST_P(TDMBackendCapture, CaptureScaleTransformCSC) ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); - for (int f = 0; f < TEST_FORMAT_CNT; f++) { - char temp[256]; - snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(test_formats[f])); + for (int f = 0; f < format_count; f++) { + int half_size = ((mode->hdisplay <= mode->vdisplay) ? mode->hdisplay : mode->vdisplay) / 2; + + dst_pos.x = (mode->hdisplay - half_size) / 2; + dst_pos.y = (mode->vdisplay - half_size) / 2; + dst_pos.w = half_size; + dst_pos.h = half_size; + + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(formats[f])); + + FindLayer(o, formats[f], &dst_pos); - if (!FindFormat(test_formats[f])) + if (!dst_layer) { + TDM_UT_INFO("no proper layer for %c%c%c%c", FOURCC_STR(formats[f])); continue; + } - ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f], - TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1), true); + ASSERT_EQ(TestPrepare(o, half_size, half_size, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, true), true); ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb, &done), TDM_ERROR_NONE); +retry: for (int b = 0; b < 3; b++) { done = false; ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); @@ -595,124 +828,244 @@ TEST_P(TDMBackendCapture, CaptureScaleTransformCSC) while (!done) ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); - DumpBuffers(b, temp); +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b, &dst_pos); } + TDM_UT_ASK_YNR("* Successed to capture a output to a '%c%c%c%c' buffer as full size and show? (output: %d, layer: %d)", + FOURCC_STR(formats[f]), pipe, dst_layer_index); + + + HideLayer(); + TestDone(); } } } -static void -_ut_tdm_capture_done_cb2(tdm_capture *capture, tbm_surface_h buffer, void *user_data) -{ - int *done = (int*)user_data; - if (done) - (*done)++; -} - -TEST_P(TDMBackendCapture, CaptureAttachFewTimesInOneCommit) +TEST_P(TDMBackendCapture, CaptureOneshotAttachFewTimesInOneCommit) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_ONESHOT); + + int done; for (int o = 0; o < output_count; o++) { const tdm_output_mode *mode = NULL; - int done = 0; - int f = 0; if (!ut_tdm_output_is_connected(outputs[o])) continue; ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); - char temp[256]; - snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(test_formats[f])); + for (int f = 0; f < format_count; f++) { + int half_size = ((mode->hdisplay <= mode->vdisplay) ? mode->hdisplay : mode->vdisplay) / 2; - if (!FindFormat(test_formats[f])) - continue; + dst_pos.x = (mode->hdisplay - half_size) / 2; + dst_pos.y = (mode->vdisplay - half_size) / 2; + dst_pos.w = half_size; + dst_pos.h = half_size; - ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f], - TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1), true); + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(formats[f])); - ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, &done), TDM_ERROR_NONE); + FindLayer(o, formats[f], &dst_pos); - done = 0; + if (!dst_layer) { + TDM_UT_INFO("no proper layer for %c%c%c%c", FOURCC_STR(formats[f])); + continue; + } - for (int b = 0; b < 3; b++) - ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + ASSERT_EQ(TestPrepare(o, half_size, half_size, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1, false), true); - ASSERT_EQ(tdm_capture_commit(capture), TDM_ERROR_NONE); - while (done != 3) - ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + done = 0; + ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, &done), TDM_ERROR_NONE); - for (int b = 0; b < 3; b++) - DumpBuffers(b, temp); +retry: + for (int b = 0; b < 3; b++) + ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); - TestDone(); + ASSERT_EQ(tdm_capture_commit(capture), TDM_ERROR_NONE); + + while (done != 3) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + + for (int b = 0; b < 3; b++) { +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b, &dst_pos); + } + + TDM_UT_ASK_YNR("* Successed to capture a output to a '%c%c%c%c' buffer as letterbox size and show? (output: %d, layer: %d)", + FOURCC_STR(formats[f]), pipe, dst_layer_index); + + + HideLayer(); + + TestDone(); + } } } -TEST_P(TDMBackendCapture, CaptureDestroyWithoutCommit) +static void +_ut_tdm_backend_capture_buffer_release_cb(tbm_surface_h buffer, void *user_data) +{ + TDMBackendCapture *backend_capture = (TDMBackendCapture*)user_data; + + tdm_buffer_remove_release_handler(buffer, _ut_tdm_backend_capture_buffer_release_cb, backend_capture); + + ASSERT_EQ(tdm_capture_attach(backend_capture->capture, buffer), TDM_ERROR_NONE); + ASSERT_EQ(tdm_capture_commit(backend_capture->capture), TDM_ERROR_NONE); +} + +static void +_ut_tdm_capture_stream_done_cb(tdm_capture *capture, tbm_surface_h buffer, void *user_data) +{ + TDMBackendCapture *backend_capture = (TDMBackendCapture*)user_data; + + for (int b = 0; b < 3; b++) { + if (backend_capture->buffers[b] == buffer) { +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + tdm_buffer_add_release_handler(buffer, _ut_tdm_backend_capture_buffer_release_cb, (void*)backend_capture); + backend_capture->ShowBuffer(b, &backend_capture->dst_pos); + break; + } + } + + if (--backend_capture->stream_count == 0) { + backend_capture->stream_exit = 1; + } +} + +TEST_P(TDMBackendCapture, CaptureStreamLetterboxSize) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_STREAM); for (int o = 0; o < output_count; o++) { const tdm_output_mode *mode = NULL; - int f = 0; if (!ut_tdm_output_is_connected(outputs[o])) continue; ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); - if (!FindFormat(test_formats[f])) - continue; + for (int f = 0; f < format_count; f++) { + int half_size = ((mode->hdisplay <= mode->vdisplay) ? mode->hdisplay : mode->vdisplay) / 2; - ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f], - TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1), true); + dst_pos.x = (mode->hdisplay - half_size) / 2; + dst_pos.y = (mode->vdisplay - half_size) / 2; + dst_pos.w = half_size; + dst_pos.h = half_size; - ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, NULL), TDM_ERROR_NONE); + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(formats[f])); - for (int b = 0; b < 3; b++) - ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + FindLayer(o, formats[f], &dst_pos); - tdm_capture_destroy(capture); - capture = NULL; + if (!dst_layer) { + TDM_UT_INFO("no proper layer for %c%c%c%c", FOURCC_STR(formats[f])); + continue; + } - TestDone(); + ASSERT_EQ(TestPrepare(o, half_size, half_size, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_STREAM, -1, false), true); + + ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_stream_done_cb, (void*)this), TDM_ERROR_NONE); + + for (int b = 0; b < 3; b++) + ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + +retry: + + stream_exit = false; + stream_count = 30; + + ASSERT_EQ(tdm_capture_commit(capture), TDM_ERROR_NONE); + + while (!stream_exit) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + + TDM_UT_ASK_YNR("* Successed to capture a output to a '%c%c%c%c' buffer as letterbox size and show? (output: %d, layer: %d)", + FOURCC_STR(formats[f]), pipe, dst_layer_index); + + + HideLayer(); + + TestDone(); + } } } -TEST_P(TDMBackendCapture, CaptureDestroyBeforeDone) +TEST_P(TDMBackendCapture, CaptureStreamFullSize) { TDM_UT_SKIP_FLAG(has_capture_cap); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT); + TDM_UT_SKIP_FLAG(capabilities & TDM_CAPTURE_CAPABILITY_STREAM); for (int o = 0; o < output_count; o++) { const tdm_output_mode *mode = NULL; - int f = 0; if (!ut_tdm_output_is_connected(outputs[o])) continue; ASSERT_EQ(tdm_output_get_mode(outputs[o], &mode), TDM_ERROR_NONE); - if (!FindFormat(test_formats[f])) - continue; + for (int f = 0; f < format_count; f++) { + int half_size = ((mode->hdisplay <= mode->vdisplay) ? mode->hdisplay : mode->vdisplay) / 2; - ASSERT_EQ(TestPrepare(o, TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, test_formats[f], - TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_ONESHOT, -1), true); + dst_pos.x = (mode->hdisplay - half_size) / 2; + dst_pos.y = (mode->vdisplay - half_size) / 2; + dst_pos.w = half_size; + dst_pos.h = half_size; - ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_done_cb2, NULL), TDM_ERROR_NONE); + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(formats[f])); - for (int b = 0; b < 3; b++) - ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + FindLayer(o, formats[f], &dst_pos); - ASSERT_EQ(tdm_capture_commit(capture), TDM_ERROR_NONE); + if (!dst_layer) { + TDM_UT_INFO("no proper layer for %c%c%c%c", FOURCC_STR(formats[f])); + continue; + } - tdm_capture_destroy(capture); - capture = NULL; + ASSERT_EQ(TestPrepare(o, half_size, half_size, formats[f], + TDM_TRANSFORM_NORMAL, TDM_CAPTURE_TYPE_STREAM, -1, true), true); - TestDone(); + ASSERT_EQ(tdm_capture_set_done_handler(capture, _ut_tdm_capture_stream_done_cb, (void*)this), TDM_ERROR_NONE); + + for (int b = 0; b < 3; b++) + ASSERT_EQ(tdm_capture_attach(capture, buffers[b]), TDM_ERROR_NONE); + +retry: + + stream_exit = false; + stream_count = 30; + + ASSERT_EQ(tdm_capture_commit(capture), TDM_ERROR_NONE); + + while (!stream_exit) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + + TDM_UT_ASK_YNR("* Successed to capture a output to a '%c%c%c%c' buffer as full size and show? (output: %d, layer: %d)", + FOURCC_STR(formats[f]), pipe, dst_layer_index); + + + HideLayer(); + + TestDone(); + } } } diff --git a/utests/src/ut_tdm_backend_display.cpp b/utests/src/ut_tdm_backend_display.cpp index 7fc69a4..69d7022 100644 --- a/utests/src/ut_tdm_backend_display.cpp +++ b/utests/src/ut_tdm_backend_display.cpp @@ -1378,10 +1378,16 @@ TEST_P(TDMBackendDisplay, VerifyLayerGetInfo) if (!ut_tdm_output_is_connected(outputs[o])) continue; + tbm_surface_h displaying_buffer; + tdm_error ret; tdm_info_layer info, temp; tdm_layer *layer = ut_tdm_output_get_primary_layer(outputs[o]); ASSERT_NE(layer, NULL); - ASSERT_EQ(ut_tdm_layer_fill_info(layer, -1, -1, 0, &info), true); + + displaying_buffer = tdm_layer_get_displaying_buffer(layer, &ret); + ASSERT_NE(displaying_buffer, NULL); + ASSERT_EQ(ret, TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_fill_info(layer, displaying_buffer, NULL, &info), true); ASSERT_EQ(tdm_layer_get_info(layer, &temp), TDM_ERROR_NONE); ASSERT_EQ(memcmp(&info, &temp, sizeof info), 0); } diff --git a/utests/src/ut_tdm_backend_pp.cpp b/utests/src/ut_tdm_backend_pp.cpp index 049f4ad..e65de76 100644 --- a/utests/src/ut_tdm_backend_pp.cpp +++ b/utests/src/ut_tdm_backend_pp.cpp @@ -48,13 +48,27 @@ public: tdm_info_pp info; + tdm_output *output; + unsigned int pipe; + const tdm_output_mode *mode; + + tdm_layer *dst_layer; + const tbm_format *dst_formats; + int dst_format_count; + int dst_zpos; + int dst_layer_index; + TDMBackendPP(); void SetUp(void); void TearDown(void); + bool FindLayerUnderPrimary(void); + bool FindLayerOverPrimary(void); bool PreparePP(void); bool PrepareBuffers(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t); - void DumpBuffers(int b, char *test); + void ShowBuffer(int b); + void HideLayer(void); + void DumpBuffer(int b, char *test); void DestroyBuffers(void); void DestroyPP(void); }; @@ -70,6 +84,16 @@ TDMBackendPP::TDMBackendPP() for (int b = 0; b < 3; b++) srcbuf[b] = dstbuf[b] = NULL; memset(&info, 0, sizeof info); + + output = NULL; + pipe = 0; + mode = NULL; + + dst_layer = NULL; + dst_formats = NULL; + dst_format_count = 0; + dst_zpos = 0; + dst_layer_index = 0; } void TDMBackendPP::SetUp(void) @@ -90,6 +114,18 @@ void TDMBackendPP::SetUp(void) ASSERT_TRUE(max_w == -1 || max_w > 0); ASSERT_TRUE(max_h == -1 || max_h > 0); ASSERT_TRUE(preferred_align == -1 || preferred_align > 0); + + for (int o = 0; o < output_count; o++) { + if (!ut_tdm_output_is_connected(outputs[o])) + continue; + + output = outputs[o]; + ASSERT_EQ(tdm_output_get_pipe(output, &pipe), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_output_prepare(dpy, output, false), true); + ASSERT_EQ(tdm_output_get_mode(output, &mode), TDM_ERROR_NONE); + ASSERT_NE(mode, NULL); + break; + } } void TDMBackendPP::TearDown(void) @@ -121,23 +157,122 @@ void TDMBackendPP::DestroyPP(void) bool TDMBackendPP::PrepareBuffers(int sw, int sh, tbm_format sf, int dw, int dh, tbm_format df, tdm_transform t) { - int flags = 0; + int src_flags = 0, dst_flags = 0; sw = TDM_UT_SIZE_ALIGN(sw, preferred_align); dw = TDM_UT_SIZE_ALIGN(dw, preferred_align); if (capabilities & TDM_PP_CAPABILITY_SCANOUT) - flags = TBM_BO_SCANOUT; + src_flags = dst_flags |= TBM_BO_SCANOUT; + + if (dst_layer) { + tdm_layer_capability capabilities; + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_capabilities(dst_layer, &capabilities) == TDM_ERROR_NONE); + if (capabilities & TDM_LAYER_CAPABILITY_SCANOUT) + dst_flags |= TBM_BO_SCANOUT; + } - TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(sw, sh, sf, flags, true, 3, srcbuf) == true); - TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(dw, dh, df, flags, false, 3, dstbuf) == true); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(sw, sh, sf, src_flags, true, 3, srcbuf) == true); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_buffer_create(dw, dh, df, dst_flags, false, 3, dstbuf) == true); TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_pp_fill_info(srcbuf[0], dstbuf[0], t, &info) == true); TDM_UT_RETURN_FALSE_IF_FAIL(tdm_pp_set_info(pp, &info) == TDM_ERROR_NONE); return true; } -void TDMBackendPP::DumpBuffers(int b, char *test) +bool TDMBackendPP::FindLayerUnderPrimary(void) +{ + tdm_error ret; + int count; + int primary_zpos, zpos; + tdm_layer *primary = ut_tdm_output_get_primary_layer(output); + TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE); + + for (int l = 0; l < count; l++) { + unsigned int usable; + tdm_layer *temp = tdm_output_get_layer(output, l, &ret); + TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_is_usable(temp, &usable) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE); + if (zpos < primary_zpos && usable) { + dst_layer = temp; + dst_zpos = zpos; + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE); + break; + } + } + + return true; +} + +bool TDMBackendPP::FindLayerOverPrimary(void) +{ + tdm_error ret; + int count; + int primary_zpos, zpos; + tdm_layer *primary = ut_tdm_output_get_primary_layer(output); + TDM_UT_RETURN_FALSE_IF_FAIL(primary != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_layer_count(output, &count) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(primary, &primary_zpos) == TDM_ERROR_NONE); + + for (int l = 0; l < count; l++) { + tdm_layer *temp = tdm_output_get_layer(output, l, &ret); + TDM_UT_RETURN_FALSE_IF_FAIL(temp != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(temp, &zpos) == TDM_ERROR_NONE); + if (zpos > primary_zpos) { + dst_layer = temp; + dst_zpos = zpos; + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_available_formats(dst_layer, &dst_formats, &dst_format_count) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(dst_formats != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(dst_format_count > 0); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(dst_layer, &dst_layer_index) == TDM_ERROR_NONE); + break; + } + } + + return true; + +} + +static void +_ut_tdm_backend_pp_output_commit_cb(tdm_output *output, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data) +{ + bool *done = (bool *)user_data; + if (done) + *done = true; +} + +void TDMBackendPP::ShowBuffer(int b) +{ + ASSERT_NE(output, NULL); + ASSERT_NE(dst_layer, NULL); + + bool done = false; + + ASSERT_EQ(ut_tdm_layer_set_buffer(dst_layer, dstbuf[b]), true); + ASSERT_EQ(tdm_output_commit(output, 0, _ut_tdm_backend_pp_output_commit_cb, &done), TDM_ERROR_NONE); + while (!done) { + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + } +} + +void TDMBackendPP::HideLayer(void) +{ + ASSERT_NE(output, NULL); + ASSERT_NE(dst_layer, NULL); + + tdm_layer_unset_buffer(dst_layer); + tdm_output_commit(output, 0, NULL, NULL); +} + +void TDMBackendPP::DumpBuffer(int b, char *test) { char filename[256]; if (test) @@ -202,14 +337,14 @@ ut_tdm_pp_fill_info(tbm_surface_h srcbuf, tbm_surface_h dstbuf, tdm_transform tr info->sync = 0; info->flags = 0; - TDM_INFO("src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) sync(%d) info->flags(%x)", - info->src_config.size.h, info->src_config.size.v, - info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, - FOURCC_STR(info->src_config.format), - info->dst_config.size.h, info->dst_config.size.v, - info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h, - FOURCC_STR(info->dst_config.format), - tdm_transform_str(transform), info->sync, info->flags); + TDM_UT_INFO("src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_config(%dx%d: %d,%d %dx%d: %c%c%c%c) transform(%s) sync(%d) info->flags(%x)", + info->src_config.size.h, info->src_config.size.v, + info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, + FOURCC_STR(info->src_config.format), + info->dst_config.size.h, info->dst_config.size.v, + info->dst_config.pos.x, info->dst_config.pos.y, info->dst_config.pos.w, info->dst_config.pos.h, + FOURCC_STR(info->dst_config.format), + tdm_transform_str(transform), info->sync, info->flags); return true; } @@ -382,78 +517,249 @@ TEST_P(TDMBackendPP, PPCommitNullOBject) ASSERT_EQ(tdm_pp_commit(NULL), TDM_ERROR_INVALID_PARAMETER); } -TEST_P(TDMBackendPP, PPNoScaleNoTransformNoCSC) +TEST_P(TDMBackendPP, PPConvertUnderlay) { TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy)); - bool done; - char temp[256]; - snprintf(temp, sizeof temp, "%c%c%c%c", FOURCC_STR(formats[0])); + FindLayerUnderPrimary(); - TDM_INFO("---- format(%c%c%c%c)", FOURCC_STR(formats[0])); + ASSERT_NE(dst_layer, NULL); - ASSERT_EQ(PreparePP(), true); + for (int f = 0; f < dst_format_count; f++) { + bool done; - ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[0], - TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[0], - TDM_TRANSFORM_NORMAL), true); + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f])); - ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); + ASSERT_EQ(PreparePP(), true); - for (int b = 0; b < 3; b++) { - done = false; + ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + TDM_TRANSFORM_NORMAL), true); - ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); - ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); + ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); - while (!done) - ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); +retry: + for (int b = 0; b < 3; b++) { + done = false; + + ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); + ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); - DumpBuffers(b, temp); + while (!done) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b); + } + + TDM_UT_ASK_YNR("* Successed to convert to '%c%c%c%c' buffers and show them to a underlay layer? (output: %d, layer: %d)", + FOURCC_STR(dst_formats[f]), pipe, dst_layer_index); + + DestroyPP(); + DestroyBuffers(); } +} - DestroyPP(); - DestroyBuffers(); +TEST_P(TDMBackendPP, PPConvertOverlay) +{ + TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy)); + + FindLayerOverPrimary(); + + TDM_UT_SKIP_FLAG(dst_layer != NULL); + + for (int f = 0; f < dst_format_count; f++) { + bool done; + + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f])); + + ASSERT_EQ(PreparePP(), true); + + ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + TDM_TRANSFORM_NORMAL), true); + + ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); + +retry: + for (int b = 0; b < 3; b++) { + done = false; + + ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); + ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); + + while (!done) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b); + } + + TDM_UT_ASK_YNR("* Successed to convert '%c%c%c%c' buffers and show them to a overlay layer? (output: %d, layer: %d)", + FOURCC_STR(dst_formats[f]), pipe, dst_layer_index); + + DestroyPP(); + DestroyBuffers(); + } } -TEST_P(TDMBackendPP, PPScaleTransformCSC) +TEST_P(TDMBackendPP, PPConvertScale) { TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy)); - ASSERT_EQ(PreparePP(), true); + FindLayerUnderPrimary(); - bool done; - tbm_format format1, format2; + ASSERT_NE(dst_layer, NULL); - format1 = formats[0]; - if (format_count > 1) - format2 = formats[1]; - else - format2 = formats[0]; + for (int f = 0; f < dst_format_count; f++) { + bool done; - TDM_INFO("format(%c%c%c%c) ------> format(%c%c%c%c)", FOURCC_STR(format1), FOURCC_STR(format2)); + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f])); - ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE, format1, - TDM_UT_BUFFER_SIZE * 2, TDM_UT_BUFFER_SIZE * 2, format2, - TDM_TRANSFORM_NORMAL), true); + ASSERT_EQ(PreparePP(), true); - ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); + ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + mode->hdisplay, mode->vdisplay / 2, dst_formats[f], + TDM_TRANSFORM_NORMAL), true); - for (int b = 0; b < 3; b++) { - done = false; + ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); - ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); - ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); +retry: + for (int b = 0; b < 3; b++) { + done = false; + + ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); + ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); - while (!done) - ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + while (!done) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); - DumpBuffers(b, NULL); +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d", f, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b); + } + + TDM_UT_ASK_YNR("* Successed to scale '%c%c%c%c' buffers? (output: %d, layer: %d)", + FOURCC_STR(dst_formats[f]), pipe, dst_layer_index); + + DestroyPP(); + DestroyBuffers(); } +} - DestroyBuffers(); +TEST_P(TDMBackendPP, PPConvertTransform) +{ + TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy)); + + FindLayerUnderPrimary(); + + ASSERT_NE(dst_layer, NULL); + + for (int f = 0; f < dst_format_count; f++) { + for (int t = (int)TDM_TRANSFORM_90; t <= (int)TDM_TRANSFORM_FLIPPED_270; t++) { + bool done; + + TDM_UT_INFO("* testing for %c%c%c%c", FOURCC_STR(dst_formats[f])); + + ASSERT_EQ(PreparePP(), true); + + ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[f], + (tdm_transform)t), true); + + ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); + +retry: + for (int b = 0; b < 3; b++) { + done = false; + + ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); + ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); + + while (!done) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "f%d_b%d_t%d", f, b, t); + DumpBuffer(b, temp); +#endif + ShowBuffer(b); + } + + TDM_UT_ASK_YNR("* Successed to rotate '%c%c%c%c' buffers? (transform: %s, output: %d, layer: %d)", + FOURCC_STR(dst_formats[f]), tdm_transform_str(t), pipe, dst_layer_index); + + DestroyPP(); + DestroyBuffers(); + } + } +} + +TEST_P(TDMBackendPP, PPConvertCSC) +{ + TDM_UT_SKIP_FLAG(ut_tdm_display_has_pp_capability(dpy)); + TDM_UT_SKIP_FLAG(!(capabilities & TDM_PP_CAPABILITY_NO_CSC)); + + FindLayerUnderPrimary(); + + ASSERT_NE(dst_layer, NULL); + + for (int df = 0; df < dst_format_count; df++) { + for (int sf = 0; sf < format_count; sf++) { + bool done; + + TDM_UT_INFO("* testing for format(%c%c%c%c) -> format(%c%c%c%c)", + FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df])); + + ASSERT_EQ(PreparePP(), true); + + ASSERT_EQ(PrepareBuffers(TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, formats[sf], + TDM_UT_BUFFER_SIZE, TDM_UT_BUFFER_SIZE / 2, dst_formats[df], + TDM_TRANSFORM_NORMAL), true); + + ASSERT_EQ(tdm_pp_set_done_handler(pp, _ut_tdm_pp_done_cb, &done), TDM_ERROR_NONE); + +retry: + for (int b = 0; b < 3; b++) { + done = false; + + ASSERT_EQ(tdm_pp_attach(pp, srcbuf[b], dstbuf[b]), TDM_ERROR_NONE); + ASSERT_EQ(tdm_pp_commit(pp), TDM_ERROR_NONE); + + while (!done) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + +#if 0 + char temp[256]; + snprintf(temp, sizeof temp, "sf%d_df%d_b%d", sf, df, b); + DumpBuffer(b, temp); +#endif + ShowBuffer(b); + } + + TDM_UT_ASK_YNR("* Successed to convert from '%c%c%c%c' to '%c%c%c%c'? (output: %d, layer: %d)", + FOURCC_STR(formats[sf]), FOURCC_STR(dst_formats[df]), pipe, dst_layer_index); + + DestroyPP(); + DestroyBuffers(); + } + } } + + static void _ut_tdm_pp_done_cb2(tdm_pp *pp, tbm_surface_h src, tbm_surface_h dst, void *user_data) { @@ -488,7 +794,7 @@ TEST_P(TDMBackendPP, DISABLED_PPAttachFewTimesInOneCommit) ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); for (int b = 0; b < 3; b++) - DumpBuffers(b, temp); + ShowBuffer(b); DestroyBuffers(); } diff --git a/utests/src/ut_tdm_layer.cpp b/utests/src/ut_tdm_layer.cpp index caca8eb..d178de7 100644 --- a/utests/src/ut_tdm_layer.cpp +++ b/utests/src/ut_tdm_layer.cpp @@ -284,14 +284,16 @@ ut_tdm_layer_prepare_buffer_queue(tdm_layer *layer, tbm_surface_queue_h *buffer_ } bool -ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_info_layer *info) +ut_tdm_layer_fill_info(tdm_layer *layer, tbm_surface_h buffer, tbm_surface_queue_h buffer_queue, tdm_info_layer *info) { tdm_error ret; tdm_output *output; const tdm_output_mode *mode = NULL; int count = 0; int zpos = -1; - unsigned int pipe = 0; + int bw, bh; + int w, h; + tbm_format format; output = tdm_layer_get_output(layer, &ret); TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE); @@ -306,7 +308,18 @@ ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_in TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_zpos(layer, &zpos) == TDM_ERROR_NONE); TDM_UT_RETURN_FALSE_IF_FAIL(zpos >= 0); - if (w == -1 || h == -1 || format == 0) { + if (buffer) { + tdm_helper_get_buffer_full_size(buffer, &bw, &bh); + w = tbm_surface_get_width(buffer); + h = tbm_surface_get_height(buffer); + format = tbm_surface_get_format(buffer); + } else if (buffer_queue) { + bw = w = tbm_surface_queue_get_width(buffer_queue); + bh = h = tbm_surface_queue_get_height(buffer_queue); + format = tbm_surface_queue_get_format(buffer_queue); + } else { + bw = mode->hdisplay; + bh = mode->vdisplay; w = mode->hdisplay; h = mode->vdisplay; format = ut_tdm_layer_find_best_format(layer); @@ -314,8 +327,8 @@ ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_in /* TODO: check min,max,prefered size and avaiable formats */ memset(info, 0, sizeof *info); - info->src_config.size.h = w; - info->src_config.size.v = h; + info->src_config.size.h = bw; + info->src_config.size.v = bh; info->src_config.pos.x = 0; info->src_config.pos.y = 0; info->src_config.pos.w = w; @@ -336,36 +349,96 @@ ut_tdm_layer_fill_info(tdm_layer *layer, int w, int h, tbm_format format, tdm_in info->dst_pos.h = h; info->transform = TDM_TRANSFORM_NORMAL; - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE); + return true; +} - TDM_INFO("filling output(%d) layer(%d) info done: src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_pos(%d,%d %dx%d) transform(%s)", - pipe, zpos, - info->src_config.size.h, info->src_config.size.v, - info->src_config.pos.x, info->src_config.pos.y, info->src_config.pos.w, info->src_config.pos.h, - FOURCC_STR(info->src_config.format), - info->dst_pos.x, info->dst_pos.y, info->dst_pos.w, info->dst_pos.h, - tdm_transform_str(info->transform)); +bool ut_tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) +{ + tdm_info_layer old_info, info; + + TDM_UT_RETURN_FALSE_IF_FAIL(buffer != NULL); + + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_info(layer, &old_info) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_layer_fill_info(layer, buffer, NULL, &info) == true); + + if (memcmp(&old_info, &info, sizeof info)) { + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_info(layer, &info) == TDM_ERROR_NONE); + + tdm_output *output; + tdm_error ret; + int index = -1; + unsigned int pipe = 0; + output = tdm_layer_get_output(layer, &ret); + TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(layer, &index) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE); + TDM_INFO("filling output(%d) layer(%d) info done: src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_pos(%d,%d %dx%d) transform(%s)", + pipe, index, + info.src_config.size.h, info.src_config.size.v, + info.src_config.pos.x, info.src_config.pos.y, info.src_config.pos.w, info.src_config.pos.h, + FOURCC_STR(info.src_config.format), + info.dst_pos.x, info.dst_pos.y, info.dst_pos.w, info.dst_pos.h, + tdm_transform_str(info.transform)); + } + + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_buffer(layer, buffer) == TDM_ERROR_NONE); return true; } -bool ut_tdm_layer_set_buffer(tdm_layer *layer, tbm_surface_h buffer) +bool ut_tdm_layer_set_buffer_with_pos(tdm_layer *layer, tbm_surface_h buffer, tdm_pos *pos) { tdm_info_layer old_info, info; TDM_UT_RETURN_FALSE_IF_FAIL(buffer != NULL); + TDM_UT_RETURN_FALSE_IF_FAIL(pos != NULL); + + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_info(layer, &old_info) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_layer_fill_info(layer, buffer, NULL, &info) == true); + + info.dst_pos.x = pos->x; + info.dst_pos.y = pos->y; + TDM_UT_RETURN_FALSE_IF_FAIL(info.dst_pos.w = pos->w); + TDM_UT_RETURN_FALSE_IF_FAIL(info.dst_pos.h = pos->h); + + if (memcmp(&old_info, &info, sizeof info)) { + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_info(layer, &info) == TDM_ERROR_NONE); - int bw = tbm_surface_get_width(buffer); - int bh = tbm_surface_get_height(buffer); - tbm_format bf = tbm_surface_get_format(buffer); + tdm_output *output; + tdm_error ret; + int index = -1; + unsigned int pipe = 0; + output = tdm_layer_get_output(layer, &ret); + TDM_UT_RETURN_FALSE_IF_FAIL(ret == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_index(layer, &index) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_output_get_pipe(output, &pipe) == TDM_ERROR_NONE); + TDM_INFO("filling output(%d) layer(%d) info done: src_config(%dx%d: %d,%d %dx%d: %c%c%c%c) dst_pos(%d,%d %dx%d) transform(%s)", + pipe, index, + info.src_config.size.h, info.src_config.size.v, + info.src_config.pos.x, info.src_config.pos.y, info.src_config.pos.w, info.src_config.pos.h, + FOURCC_STR(info.src_config.format), + info.dst_pos.x, info.dst_pos.y, info.dst_pos.w, info.dst_pos.h, + tdm_transform_str(info.transform)); + } + + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_buffer(layer, buffer) == TDM_ERROR_NONE); + + return true; +} + +bool ut_tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) +{ + tdm_info_layer old_info, info; + + TDM_UT_RETURN_FALSE_IF_FAIL(buffer_queue != NULL); TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_get_info(layer, &old_info) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_layer_fill_info(layer, bw, bh, bf, &info) == true); + TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_layer_fill_info(layer, NULL, buffer_queue, &info) == true); if (memcmp(&old_info, &info, sizeof info)) TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_info(layer, &info) == TDM_ERROR_NONE); - TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_buffer(layer, buffer) == TDM_ERROR_NONE); + TDM_UT_RETURN_FALSE_IF_FAIL(tdm_layer_set_buffer_queue(layer, buffer_queue) == TDM_ERROR_NONE); return true; } @@ -610,7 +683,7 @@ TEST_P(TDMLayer, LayerSetInfo) continue; tdm_info_layer info; - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], -1, -1, 0, &info), true); + ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], NULL, NULL, &info), true); ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); } } @@ -703,7 +776,6 @@ TEST_P(TDMLayer, LayerSetBuffer) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; if (ut_tdm_layer_is_cursor_layer(layers[l])) @@ -713,18 +785,10 @@ TEST_P(TDMLayer, LayerSetBuffer) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - /* set buffer & commit for 100 times */ for (int t = 0; t < 10; t++) { tbm_surface_h displaying_buffer = NULL; - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); while (displaying_buffer != buffers[next_buffer]) { ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); @@ -752,7 +816,6 @@ TEST_P(TDMLayer, LayerSetBufferFewTimeInOneCommit) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; if (ut_tdm_layer_is_cursor_layer(layers[l])) @@ -762,20 +825,13 @@ TEST_P(TDMLayer, LayerSetBufferFewTimeInOneCommit) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - /* set buffer & commit for 10 times */ for (int t = 0; t < 10; t++) { tbm_surface_h displaying_buffer = NULL; - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); if (next_buffer == 3) next_buffer = 0; - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); while (displaying_buffer != buffers[next_buffer]) { ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); @@ -837,7 +893,6 @@ TEST_P(TDMLayer, LayerUnsetBufferBeforeCommit) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; if (ut_tdm_layer_is_cursor_layer(layers[l])) @@ -849,19 +904,12 @@ TEST_P(TDMLayer, LayerUnsetBufferBeforeCommit) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - /* set buffer & commit for 10 times */ for (int t = 0; t < 10; t++) { - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); if (next_buffer == 3) next_buffer = 0; - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); if (next_buffer == 3) next_buffer = 0; } @@ -882,7 +930,6 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommit) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; if (ut_tdm_layer_is_cursor_layer(layers[l])) @@ -894,15 +941,8 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommit) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); ASSERT_EQ(tdm_layer_unset_buffer(layers[l]), TDM_ERROR_NONE); @@ -922,7 +962,6 @@ TEST_P(TDMLayer, DISABLED_LayerUnsetBufferAfterTwoCommit) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; if (ut_tdm_layer_is_cursor_layer(layers[l])) @@ -934,17 +973,10 @@ TEST_P(TDMLayer, DISABLED_LayerUnsetBufferAfterTwoCommit) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); ASSERT_EQ(tdm_layer_unset_buffer(layers[l]), TDM_ERROR_NONE); @@ -964,7 +996,6 @@ TEST_P(TDMLayer, DISABLED_LayerUnsetBufferAfterTwoCommitOneSetBuffer) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; if (ut_tdm_layer_is_cursor_layer(layers[l])) @@ -976,20 +1007,13 @@ TEST_P(TDMLayer, DISABLED_LayerUnsetBufferAfterTwoCommitOneSetBuffer) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, NULL), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer]), true); ASSERT_EQ(tdm_layer_unset_buffer(layers[l]), TDM_ERROR_NONE); @@ -1007,7 +1031,6 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDone) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; bool done; @@ -1020,16 +1043,9 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDone) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - /* set buffer & commit for 10 times */ - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); done = false; ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done), TDM_ERROR_NONE); @@ -1053,7 +1069,6 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDoneOneCommit) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; int next_buffer = 0; bool done; @@ -1066,16 +1081,9 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDoneOneCommit) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 3, true), true); - /* set info */ - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - /* set buffer & commit for 10 times */ - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); done = false; ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done), TDM_ERROR_NONE); @@ -1083,7 +1091,7 @@ TEST_P(TDMLayer, LayerUnsetBufferAfterOneCommitOneDoneOneCommit) ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); } - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[next_buffer++]), true); next_buffer = 0; ASSERT_EQ(tdm_layer_commit(layers[l], _ut_tdm_layer_commit_cb, &done), TDM_ERROR_NONE); @@ -1170,14 +1178,7 @@ TEST_P(TDMLayer, LayerRemoveCommitHandler) ASSERT_EQ(ut_tdm_layer_prepare_buffer(layers[l], buffers, 1, true), true); - /* set info */ - tdm_info_layer info; - int bw = tbm_surface_get_width(buffers[0]); - int bh = tbm_surface_get_height(buffers[0]); - tbm_format bf = tbm_surface_get_format(buffers[0]); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer(layers[l], buffers[0]), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer(layers[l], buffers[0]), true); for (int t = 0; t < 10; t++) { bool done1 = false, done2 = false, done3 = false; @@ -1328,7 +1329,6 @@ TEST_P(TDMLayer, LayerSetBufferQueue) if (!ut_tdm_layer_is_avaiable(layers[l])) continue; - tdm_info_layer info; tbm_surface_h buffer; tbm_surface_h displaying_buffer; @@ -1342,14 +1342,7 @@ TEST_P(TDMLayer, LayerSetBufferQueue) ASSERT_EQ(ut_tdm_layer_prepare_buffer_queue(layers[l], &buffer_queue), true); ASSERT_NE(buffer_queue, NULL); - /* set info */ - int bw = tbm_surface_queue_get_width(buffer_queue); - int bh = tbm_surface_queue_get_height(buffer_queue); - tbm_format bf = tbm_surface_queue_get_format(buffer_queue); - ASSERT_EQ(ut_tdm_layer_fill_info(layers[l], bw, bh, bf, &info), true); - - ASSERT_EQ(tdm_layer_set_info(layers[l], &info), TDM_ERROR_NONE); - ASSERT_EQ(tdm_layer_set_buffer_queue(layers[l], buffer_queue), TDM_ERROR_NONE); + ASSERT_EQ(ut_tdm_layer_set_buffer_queue(layers[l], buffer_queue), true); ASSERT_EQ(tdm_layer_commit(layers[l], NULL, NULL), TDM_ERROR_NONE); diff --git a/utests/src/ut_tdm_output.cpp b/utests/src/ut_tdm_output.cpp index d4bb6e1..f44109e 100644 --- a/utests/src/ut_tdm_output.cpp +++ b/utests/src/ut_tdm_output.cpp @@ -184,7 +184,6 @@ ut_tdm_output_prepare(tdm_display *dpy, tdm_output *output, bool fill) tbm_surface_h buffer = NULL; tdm_error ret; int primary_index = -1; - tdm_info_layer info; tdm_layer *layer; bool done = false; tdm_output_conn_status status; @@ -203,13 +202,7 @@ ut_tdm_output_prepare(tdm_display *dpy, tdm_output *output, bool fill) TDM_UT_RETURN_FALSE_IF_FAIL(ut_tdm_layer_prepare_buffer(layer, &buffer, 1, fill) == true); TDM_UT_RETURN_FALSE_IF_FAIL(buffer != NULL); - int bw = tbm_surface_get_width(buffer); - int bh = tbm_surface_get_height(buffer); - tbm_format bf = tbm_surface_get_format(buffer); - TDM_UT_GOTO_IF_FAIL(ut_tdm_layer_fill_info(layer, bw, bh, bf, &info) == true, failed); - - TDM_UT_GOTO_IF_FAIL(tdm_layer_set_info(layer, &info) == TDM_ERROR_NONE, failed); - TDM_UT_GOTO_IF_FAIL(tdm_layer_set_buffer(layer, buffer) == TDM_ERROR_NONE, failed); + TDM_UT_GOTO_IF_FAIL(ut_tdm_layer_set_buffer(layer, buffer) == true, failed); if (tdm_helper_output_commit_per_vblank_enabled(output)) TDM_UT_GOTO_IF_FAIL(tdm_layer_commit(layer, NULL, NULL) == TDM_ERROR_NONE, failed); -- 2.7.4 From ed57cc13684a3269b6188583aac543cf286d4b75 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 10:53:30 +0900 Subject: [PATCH 12/16] common: add description for pp, capture capability Change-Id: I3e11cb35c4a4f752282756e339e07e4f939437c0 --- include/tdm_common.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/tdm_common.h b/include/tdm_common.h index e97170b..35d5c91 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -148,6 +148,9 @@ typedef enum { /** * @brief The pp capability enumeration + * @details The scale, transform and CSC functionalities seem the default functions of PP. + * If hardware device doesn't support one of them, we'd better let a developer know + * what a backend doesn't support like TDM_PP_CAPABILITY_NO_CSC. */ typedef enum { TDM_PP_CAPABILITY_SYNC = (1 << 0), /**< The pp device supports synchronous operation */ @@ -158,6 +161,9 @@ typedef enum { /** * @brief The capture capability enumeration + * @details The scale, transform and CSC functionalities seem the default functions of capture. + * If hardware device doesn't support one of them, we'd better let a developer know + * what a backend doesn't support like TDM_PP_CAPABILITY_NO_CSC. */ typedef enum { TDM_CAPTURE_CAPABILITY_OUTPUT = (1 << 0), /**< The capture device supports to dump a output */ -- 2.7.4 From 6326a43d10302a0fa9785e9963d6d27f007d876c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 17:09:23 +0900 Subject: [PATCH 13/16] thread: sending the exit request instead of using pthread_cancel To ensure that all operations in the tdm thread are done Change-Id: I05aa6a1d187876522eeaaa2a694bdc2cc8673516 --- src/tdm_macro.h | 1 + src/tdm_private_types.h | 1 + src/tdm_thread.c | 50 ++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/tdm_macro.h b/src/tdm_macro.h index acdc9f3..14c0f7a 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -242,6 +242,7 @@ TDM_TYPE_NAME_FN(value_type) static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, + { TDM_THREAD_CB_EXIT, "exit" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index a5b4423..d71664a 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -447,6 +447,7 @@ typedef struct _tdm_capture_private_buffer { typedef enum { TDM_THREAD_CB_NONE, + TDM_THREAD_CB_EXIT, /* special type to exit the tdm-thread */ TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, TDM_THREAD_CB_OUTPUT_STATUS, diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 4f4626f..20e995f 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -46,6 +46,8 @@ struct _tdm_private_thread { pthread_cond_t event_cond; pthread_t event_thread; + unsigned int event_thread_exit; + unsigned int event_thread_joined; pid_t display_tid; pid_t thread_tid; @@ -152,6 +154,9 @@ _tdm_thread_main(void *data) TDM_INFO("server flush"); tdm_event_loop_flush(private_loop->dpy); + if (private_thread->event_thread_exit) + break; + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling in", fd); @@ -181,6 +186,22 @@ exit_thread: pthread_exit(NULL); } +static tdm_error +_tdm_thread_exit(tdm_private_loop *private_loop) +{ + tdm_thread_cb_base cb_base; + tdm_error ret; + + memset(&cb_base, 0, sizeof cb_base); + cb_base.type = TDM_THREAD_CB_EXIT; + cb_base.length = sizeof cb_base; + + ret = tdm_thread_send_cb(private_loop, &cb_base); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + return ret; +} + /* NOTE: tdm thread doesn't care about multi-thread. */ INTERN tdm_error tdm_thread_init(tdm_private_loop *private_loop) @@ -269,20 +290,20 @@ tdm_thread_deinit(tdm_private_loop *private_loop) { tdm_private_display *private_display; tdm_private_thread_cb *cb = NULL, *hh = NULL; + tdm_error ret; int i; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - for (i = 0; i < TDM_THREAD_CB_MAX; i++) - find_funcs[i] = NULL; - - if (!private_loop->private_thread) + if (!private_loop->private_thread) { + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; return; + } - if (private_loop->private_thread->sub_event_source) - tdm_event_loop_source_remove(private_loop->private_thread->sub_event_source); - - pthread_cancel(private_loop->private_thread->event_thread); + ret = _tdm_thread_exit(private_loop); + if (ret != TDM_ERROR_NONE) + pthread_cancel(private_loop->private_thread->event_thread); private_display = private_loop->dpy; @@ -291,10 +312,15 @@ tdm_thread_deinit(tdm_private_loop *private_loop) */ _pthread_mutex_unlock(&private_display->lock); pthread_join(private_loop->private_thread->event_thread, NULL); + private_loop->private_thread->event_thread_joined = 1; + TDM_INFO("Joined a TDM event thread"); pthread_mutex_unlock(&cb_list_lock); tdm_log_reset(); + if (private_loop->private_thread->sub_event_source) + tdm_event_loop_source_remove(private_loop->private_thread->sub_event_source); + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list[0], link) { _tdm_thread_free_cb(cb); } @@ -318,6 +344,9 @@ tdm_thread_deinit(tdm_private_loop *private_loop) private_loop->private_thread = NULL; keep_private_thread = NULL; + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + TDM_INFO("Finish a TDM event thread"); } @@ -442,6 +471,9 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) ret = tdm_thread_cb_call(NULL, base, 0); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); break; + case TDM_THREAD_CB_EXIT: + private_thread->event_thread_exit = 1; + break; default: break; } @@ -467,7 +499,7 @@ tdm_thread_is_running(void) { /* DON'T check TDM_MUTEX_IS_LOCKED here */ - return (keep_private_thread) ? 1 : 0; + return (keep_private_thread && !keep_private_thread->event_thread_joined) ? 1 : 0; } static void -- 2.7.4 From c2737841fe23f1ddaa73eedec7cb062bf4142cb6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 18:39:25 +0900 Subject: [PATCH 14/16] package version up to 1.16.7 Change-Id: Ifda4cc084c2bd44ba1b1e279bddb0b914ad80cfa --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 90ebc54..4009b18 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.16.6 +Version: 1.16.7 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 8a214bc399ddf657cb2d68b86cd5274acc56013d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Mar 2018 18:58:14 +0900 Subject: [PATCH 15/16] utest: remove unuseful tcs Change-Id: I84fa3d1f9839e9d70745766767a3bdc8323890fe --- utests/src/ut_tdm_env.cpp | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/utests/src/ut_tdm_env.cpp b/utests/src/ut_tdm_env.cpp index a590b68..47144ab 100644 --- a/utests/src/ut_tdm_env.cpp +++ b/utests/src/ut_tdm_env.cpp @@ -134,47 +134,11 @@ TEST_P(TDMEnv, DisplayInitDeinitWithoutBackends) { } -TEST_P(TDMEnv, DisplayInitDeinitWrongDpyBadAddress) -{ - tdm_display *dpy; - tdm_error ret; - - dpy = tdm_display_init(&ret); - ASSERT_EQ(ret, TDM_ERROR_NONE); - ASSERT_NE(dpy, NULL); - - EXPECT_EXIT({ - tdm_display *wrong_dpy = (tdm_display *)TDM_UT_INVALID_VALUE; - tdm_display_deinit(wrong_dpy); - exit(0); - }, ::testing::ExitedWithCode(0), ""); - - tdm_display_deinit(dpy); -} - TEST_P(TDMEnv, DisplayDeinitWithNULL) { tdm_display_deinit(NULL); } -TEST_P(TDMEnv, DisplayDeinitRepeatWithSameDpy) -{ - tdm_display *dpy; - tdm_error ret; - - dpy = tdm_display_init(&ret); - ASSERT_EQ(ret, TDM_ERROR_NONE); - ASSERT_NE(dpy, NULL); - - EXPECT_EXIT({ - tdm_display_deinit(dpy); - tdm_display_deinit(dpy); - exit(0); - }, ::testing::ExitedWithCode(0), ""); - - tdm_display_deinit(dpy); -} - #ifdef TDM_UT_TEST_WITH_PARAMS INSTANTIATE_TEST_CASE_P(TDMEnvParams, TDMEnv, -- 2.7.4 From 8dd61deb2ff53bfd5e01c1b37f38cc65fab5553a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 22 Mar 2018 13:44:29 +0900 Subject: [PATCH 16/16] config: fix infinite loop Change-Id: I8e74042c6cc711e64bc7f932dc2cb66be731872d --- src/tdm_config.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/tdm_config.c b/src/tdm_config.c index 703ae0a..fb361d2 100644 --- a/src/tdm_config.c +++ b/src/tdm_config.c @@ -51,6 +51,7 @@ static pthread_mutex_t g_dic_lock = PTHREAD_MUTEX_INITIALIZER; static dictionary *g_dic = NULL; +static int init_dic = 0; static int _tdm_config_check_file_owner(const char *filepath) @@ -122,19 +123,19 @@ _tdm_config_check_logs(void) pthread_mutex_lock(&g_dic_lock); } -static unsigned int +static void _tdm_config_check_init(void) { - if (g_dic) - return 1; + if (init_dic) + return; + + init_dic = 1; g_dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME); _tdm_config_check_logs(); TDM_INFO("tdm config init %s (%p)", (g_dic) ? "successed" : "failed", g_dic); - - return (g_dic) ? 1 : 0; } INTERN void @@ -149,6 +150,7 @@ tdm_config_deinit(void) iniparser_freedict(g_dic); g_dic = NULL; + init_dic = 0; TDM_INFO("tdm config deinit done"); @@ -190,7 +192,8 @@ tdm_config_get_int(const char *key, int default_value) pthread_mutex_lock(&g_dic_lock); - if (!_tdm_config_check_init()) { + _tdm_config_check_init(); + if (!g_dic) { TDM_INFO("%s = %d: default", key, default_value); pthread_mutex_unlock(&g_dic_lock); return default_value; @@ -220,7 +223,8 @@ tdm_config_get_string(const char *key, const char *default_value) pthread_mutex_lock(&g_dic_lock); - if (!_tdm_config_check_init()) { + _tdm_config_check_init(); + if (!g_dic) { TDM_INFO("%s = %s: default", key, default_value); pthread_mutex_unlock(&g_dic_lock); return default_value; @@ -246,7 +250,8 @@ tdm_config_set_int(const char *key, int value) pthread_mutex_lock(&g_dic_lock); - if (!_tdm_config_check_init()) { + _tdm_config_check_init(); + if (!g_dic) { TDM_INFO("%s = %d set failed", key, value); pthread_mutex_unlock(&g_dic_lock); return TDM_ERROR_BAD_REQUEST; @@ -272,7 +277,8 @@ tdm_config_set_string(const char *key, const char *value) pthread_mutex_lock(&g_dic_lock); - if (!_tdm_config_check_init()) { + _tdm_config_check_init(); + if (!g_dic) { TDM_INFO("%s = %s set failed", key, value); pthread_mutex_unlock(&g_dic_lock); return TDM_ERROR_BAD_REQUEST; -- 2.7.4