From a79ec291f05858ae09188f5edb1c692d9d9b78c4 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 27 Feb 2018 16:45:05 +0900 Subject: [PATCH 01/16] utest: add ut_tdm_output_hwc test case Change-Id: Ic4f81b512034c947143eb8ca44e0f5b4e9dd0009 --- utests/Makefile.am | 1 + utests/src/ut_tdm.h | 3 +- utests/src/ut_tdm_hwc_window.cpp | 388 --------------------------------- utests/src/ut_tdm_output_hwc.cpp | 447 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 450 insertions(+), 389 deletions(-) create mode 100644 utests/src/ut_tdm_output_hwc.cpp diff --git a/utests/Makefile.am b/utests/Makefile.am index 90b01ac..e4624ca 100644 --- a/utests/Makefile.am +++ b/utests/Makefile.am @@ -11,6 +11,7 @@ tdm_utests_SOURCES = \ src/ut_tdm_display.cpp \ src/ut_tdm_output.cpp \ src/ut_tdm_layer.cpp \ + src/ut_tdm_output_hwc.cpp \ src/ut_tdm_hwc_window.cpp \ src/ut_tdm_pp.cpp \ src/ut_tdm_capture.cpp \ diff --git a/utests/src/ut_tdm.h b/utests/src/ut_tdm.h index 0e3ff70..890f182 100644 --- a/utests/src/ut_tdm.h +++ b/utests/src/ut_tdm.h @@ -29,7 +29,8 @@ extern "C" { #define UT_TDM_ENV_ENABLE #define UT_TDM_EVENT_LOOP_ENABLE #define UT_TDM_HELPER_ENABLE -#define UT_TDM_HWC_WINDOW_ENABLE +#define UT_TDM_OUTPUT_HWC_ENABLE +//#define UT_TDM_HWC_WINDOW_ENABLE #define UT_TDM_LAYER_ENABLE #define UT_TDM_LOG_ENABLE #define UT_TDM_OUTPUT_ENABLE diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index 1c16d4e..a5a5152 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -218,29 +218,6 @@ protected: }; -/* tdm_hwc_window * tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); */ -TEST_F(TDMOutputHwc, CreateWindowFailNull) -{ - ASSERT_EQ(NULL, tdm_output_hwc_create_window(NULL, &error)); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_F(TDMOutputHwc, CreateWindowSuccessful) -{ - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - tdm_hwc_window * hw = tdm_output_hwc_create_window(outputs[i], &error); - ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_output_hwc_destroy_window(outputs[i], hw); - ASSERT_EQ(TDM_ERROR_NONE, error); - } else { - ASSERT_EQ(NULL, tdm_output_hwc_create_window(outputs[i], &error)); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} - - /* tdm_error tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window); */ TEST_F(TDMOutputHwc, DestroyWindowFailNull) { @@ -276,122 +253,6 @@ TEST_F(TDMOutputHwc, DestroyWindowSuccessful) } -/* tdm_error tdm_output_hwc_set_client_target_buffer(tdm_output *output, - tbm_surface_h target_buffer, tdm_hwc_region damage, - tdm_hwc_window *composited_wnds, uint32_t num_wnds); */ -/* TDOO: need to be fixed -TEST_F(TDMOutputHwc, SetClientTargetBufferFailNullOutput) -{ - tdm_hwc_region reg; - tbm_surface_h target_buff = CreateBufferForOutput(0); - error = tdm_output_hwc_set_client_target_buffer(NULL, target_buff, reg, NULL, 0 ); - tbm_surface_internal_destroy(target_buff); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_F(TDMOutputHwcWithoutHwcCap, SetClientTargetBufferFailNoHwc) -{ - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; - - for (int i = 0; i < output_count; i++) { - tbm_surface_h target_buff = CreateBufferForOutput(i); - ASSERT_NE(NULL, target_buff); - error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage, NULL, 0); - tbm_surface_internal_destroy(target_buff); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -TEST_F(TDMOutputHwc, SetClientTargetBufferSuccessfulSetBuff) -{ - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; - - for (int i = 0; i < output_count; i++) { - tbm_surface_h target_buff = CreateBufferForOutput(i); - ASSERT_NE(NULL, target_buff); - if (IsHwcEnable(i)) { - error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage, - NULL, 0); - tbm_surface_internal_destroy(target_buff); - ASSERT_EQ(TDM_ERROR_NONE, error); - } else { - error = tdm_output_hwc_set_client_target_buffer(outputs[i], target_buff, damage, - NULL, 0); - tbm_surface_internal_destroy(target_buff); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} - -TEST_F(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff) -{ - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; - - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - error = tdm_output_hwc_set_client_target_buffer(outputs[i], NULL, damage, - NULL, 0); - ASSERT_EQ(TDM_ERROR_NONE, error); - } else { - error = tdm_output_hwc_set_client_target_buffer(outputs[i], NULL, damage, - NULL, 0); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} -*/ - -/* tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); */ -TEST_F(TDMOutputHwc, GetTargetBufferQueueFailNullObject) -{ - tbm_surface_queue_h queue = NULL; - - queue = tdm_output_hwc_get_target_buffer_queue(NULL, &error); - ASSERT_NE(TDM_ERROR_NONE, error); - ASSERT_EQ(NULL, queue); - - queue = tdm_output_hwc_get_target_buffer_queue(NULL, NULL); - ASSERT_EQ(NULL, queue); -} - -TEST_F(TDMOutputHwcWithoutHwcCap, GetTargetBufferQueueFainNoHwc) -{ - tbm_surface_queue_h queue = NULL; - - for (int i = 0; i < output_count; i++) { - queue = tdm_output_hwc_get_target_buffer_queue(outputs[i], &error); - ASSERT_NE(TDM_ERROR_NONE, error); - ASSERT_EQ(NULL, queue); - } -} - -TEST_F(TDMOutputHwc, GetTargetBufferQueueSuccessful) -{ - tbm_surface_queue_h queue = NULL; - - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - queue = tdm_output_hwc_get_target_buffer_queue(outputs[i], &error); - tbm_surface_queue_destroy(queue); - ASSERT_EQ(TDM_ERROR_NONE, error); - ASSERT_NE(NULL, queue); - - queue = tdm_output_hwc_get_target_buffer_queue(outputs[i], NULL); - tbm_surface_queue_destroy(queue); - ASSERT_EQ(TDM_ERROR_NONE, error); - ASSERT_NE(NULL, queue); - } else { - queue = tdm_output_hwc_get_target_buffer_queue(outputs[i], &error); - ASSERT_NE(TDM_ERROR_NONE, error); - ASSERT_EQ(NULL, queue); - - queue = tdm_output_hwc_get_target_buffer_queue(outputs[i], NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - ASSERT_EQ(NULL, queue); - } - } -} - /* tbm_surface_queue_h tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); */ TEST_F(TDMHwcWindow, GetBufferQueueFailNull) { @@ -611,255 +472,6 @@ TEST_F(TDMHwcWindow, VideoGetCapabilitySuccessful) } } -/* tdm_error tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, - uint32_t *num_types); */ -/* TODO: fix the validate test later. -TEST_F(TDMOutputHwc, ValidateFailNull) -{ - uint32_t num_types; - error = tdm_output_hwc_validate(NULL, NULL, 0, &num_types); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (outputs[0]) { - error = tdm_output_hwc_validate(outputs[0], NULL, 0, NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -TEST_F(TDMOutputHwcWithoutHwcCap, ValidateFailNoHwc) -{ - uint32_t num_types; - - for (int i = 0; i < output_count; i++) { - error = tdm_output_hwc_validate(outputs[i], &num_types); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -TEST_F(TDMOutputHwc, ValidateSuccessful) -{ - uint32_t num_types; - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - error = tdm_output_hwc_validate(outputs[i], &num_types); - ASSERT_EQ(TDM_ERROR_NONE, error); - } else { - error = tdm_output_hwc_validate(outputs[i], &num_types); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} -TODO: */ - -/* tdm_error tdm_output_hwc_get_changed_composition_types(tdm_output *output, - uint32_t *num_elements, tdm_hwc_window **hwc_window, - tdm_hwc_window_composition *composition_types); */ - -TEST_F(TDMOutputHwc, GetChangedCompositionTypesFailNull) -{ - uint32_t num_elements; - - error = tdm_output_hwc_get_changed_composition_types(NULL, &num_elements, NULL, NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (outputs[0]) { - error = tdm_output_hwc_get_changed_composition_types(outputs[0], NULL, NULL, NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -TEST_F(TDMOutputHwcWithoutHwcCap, GetChangedCompositionTypesFailNoHwc) -{ - uint32_t get_num = 10; - - for (int i = 0; i < output_count; i++) { - error = tdm_output_hwc_get_changed_composition_types(outputs[i], &get_num, NULL, NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -/* TODO: fix the validate test later. -TEST_F(TDMHwcWindow, GetChangedCompositionTypesSuccessful) -{ - uint32_t validate_num; - uint32_t get_num = 0; - - tdm_hwc_window_composition *composition_types; - tdm_hwc_window **hwc_wnds; - - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_DEVICE); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - - - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - error = tdm_output_hwc_validate(outputs[i], &validate_num); - ASSERT_EQ(TDM_ERROR_NONE, error); - - error = tdm_output_hwc_get_changed_composition_types(outputs[i], &get_num, NULL, NULL); - ASSERT_EQ(TDM_ERROR_NONE, error); - - ASSERT_TRUE(get_num == validate_num); - hwc_wnds = (tdm_hwc_window **)calloc(get_num, sizeof(tdm_hwc_window *)); - composition_types = (tdm_hwc_window_composition *)calloc(get_num, sizeof(tdm_hwc_window_composition)); - - error = tdm_output_hwc_get_changed_composition_types(outputs[i], &get_num, hwc_wnds, composition_types); - - free(hwc_wnds); - free(composition_types); - - ASSERT_EQ(TDM_ERROR_NONE, error); - } else { - error = tdm_output_hwc_get_changed_composition_types(outputs[i], &get_num, NULL, NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} -*/ - -/* tdm_error tdm_output_hwc_accept_changes(tdm_output *output); */ - -TEST_F(TDMOutputHwc, AcceptChangesFailNull) -{ - error = tdm_output_hwc_accept_changes(NULL); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_F(TDMOutputHwcWithoutHwcCap, AcceptChangesFailNoHwc) -{ - for (int i = 0; i < output_count; i++) { - error = tdm_output_hwc_accept_changes(outputs[i]); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -/* TODO: fix the validate test later. -TEST_F(TDMHwcWindow, AcceptChangesSuccessful) -{ - uint32_t validate_num; - - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_DEVICE); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - error = tdm_output_hwc_validate(outputs[i], &validate_num); - ASSERT_EQ(TDM_ERROR_NONE, error); - - if (validate_num > 0) { - error = tdm_output_hwc_accept_changes(outputs[i]); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - } - } -} -*/ - -static int need_validate_handler_is_called = 0; -static void need_validate_handler(tdm_output *output) -{ - need_validate_handler_is_called = 1; -} -/* tdm_error tdm_output_hwc_set_need_validate_handler(tdm_output *output, - tdm_output_need_validate_handler hndl); */ -TEST_F(TDMOutputHwc, SetNeedValidateHandlerFailNull) -{ - error = tdm_output_hwc_set_need_validate_handler(NULL, &need_validate_handler); - ASSERT_NE(TDM_ERROR_NONE, error); - - error = tdm_output_hwc_set_need_validate_handler(outputs[0], NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - -} - -TEST_F(TDMOutputHwcWithoutHwcCap, SetNeedValidateHandlerFailNoHwc) -{ - for (int i = 0; i < output_count; i++) { - error = tdm_output_hwc_set_need_validate_handler(outputs[i], &need_validate_handler); - ASSERT_NE(TDM_ERROR_NONE, error); - } -} - -TEST_F(TDMOutputHwc, SetNeedValidateHandlerSuccessful) -{ - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - /* - * This event can't be generated form user side. - * So just check a set and double set - */ - - /* test: first set*/ - error = tdm_output_hwc_set_need_validate_handler(outputs[i], &need_validate_handler); - ASSERT_EQ(TDM_ERROR_NONE, error); - /* test: second isn't allowed*/ - error = tdm_output_hwc_set_need_validate_handler(outputs[i], &need_validate_handler); - ASSERT_NE(TDM_ERROR_NONE, error); - } else { - error = tdm_output_hwc_set_need_validate_handler(outputs[i], &need_validate_handler); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} - -/* tdm_hwc_window * tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error); */ -TEST_F(TDMOutputHwc, CreateVideoWindowFailNull) -{ - ASSERT_EQ(NULL, tdm_output_hwc_create_video_window(NULL, &error)); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_F(TDMOutputHwc, CreateVideoWindowSuccessful) -{ - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - tdm_hwc_window * hw = tdm_output_hwc_create_video_window(outputs[i], &error); - if (error != TDM_ERROR_NOT_IMPLEMENTED) { - ASSERT_EQ(TDM_ERROR_NONE, error); - ASSERT_NE(NULL, hw); - error = tdm_output_hwc_destroy_window(outputs[i], hw); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - } else { - ASSERT_EQ(NULL, tdm_output_hwc_create_video_window(outputs[i], &error)); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} - -/* tdm_output_hwc_get_video_supported_formats() */ -TEST_F(TDMOutputHwc, GetVideoSupportedFormatsFailNull) -{ - tdm_error error; - - error = tdm_output_hwc_get_video_supported_formats(NULL, NULL, NULL); - ASSERT_NE(TDM_ERROR_NONE, error); -} - -TEST_F(TDMOutputHwc, GetVideoSupportedFormatsSuccessful) -{ - tdm_error error; - const tbm_format *formats; - int count; - - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - error = tdm_output_hwc_get_video_supported_formats(outputs[i], &formats, &count); - if (error != TDM_ERROR_NOT_IMPLEMENTED) { - ASSERT_EQ(TDM_ERROR_NONE, error); - if (count > 0) - ASSERT_NE(NULL, formats); - } - } else { - error = tdm_output_hwc_get_video_supported_formats(outputs[i], &formats, &count); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } -} /* tdm_hwc_window_video_get_available_properties() */ TEST_F(TDMHwcWindow, GetAvailablePropertiesFailNullWin) diff --git a/utests/src/ut_tdm_output_hwc.cpp b/utests/src/ut_tdm_output_hwc.cpp new file mode 100644 index 0000000..1b0aa24 --- /dev/null +++ b/utests/src/ut_tdm_output_hwc.cpp @@ -0,0 +1,447 @@ +/************************************************************************** + * + * Copyright 2016 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Konstantin Drabeniuk + * Contact: Andrii Sokolenko + * Contact: Roman Marchenko + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * +**************************************************************************/ + +#include "ut_tdm.h" + +class TDMOutputHwc : public TDMOutput { +public: + TDMOutputHwc(); + void SetUp(void); + void TearDown(void); + + tdm_error error; +}; + +TDMOutputHwc::TDMOutputHwc() +{ + ; +} + +void TDMOutputHwc::SetUp(void) +{ + TDMOutput::SetUp(); +} + +void TDMOutputHwc::TearDown(void) +{ + TDMOutput::TearDown(); +} + +#ifdef UT_TDM_OUTPUT_HWC_ENABLE + +/* tdm_hwc_window * tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); */ +TEST_P(TDMOutputHwc, CreateWindowFailNull) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + ASSERT_EQ(NULL, tdm_output_hwc_create_window(NULL, &error)); + ASSERT_NE(TDM_ERROR_NONE, error); +} + +TEST_P(TDMOutputHwc, CreateWindowSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_hwc_window * hw = NULL; + + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + hw = tdm_output_hwc_create_window(outputs[o], &error); + ASSERT_EQ(TDM_ERROR_NONE, error); + error = tdm_output_hwc_destroy_window(outputs[o], hw); + ASSERT_EQ(TDM_ERROR_NONE, error); + } else { + ASSERT_EQ(NULL, tdm_output_hwc_create_window(outputs[o], &error)); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} + +/* tdm_error tdm_output_hwc_set_client_target_buffer(tdm_output *output, + tbm_surface_h target_buffer, tdm_hwc_region damage, + tdm_hwc_window *composited_wnds, uint32_t num_wnds); */ +/* TDOO: need to be fixed +TEST_P(TDMOutputHwc, SetClientTargetBufferFailNullOutput) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_hwc_region reg; + tbm_surface_h target_buff = CreateBufferForOutput(0); + error = tdm_output_hwc_set_client_target_buffer(NULL, target_buff, reg, NULL, 0 ); + tbm_surface_internal_destroy(target_buff); + ASSERT_NE(TDM_ERROR_NONE, error); +} + +TEST_P(TDMOutputHwc, SetClientTargetBufferFailNoHwc) +{ + tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + + for (int o = 0; o < output_count; o++) { + tbm_surface_h target_buff = CreateBufferForOutput(i); + ASSERT_NE(NULL, target_buff); + error = tdm_output_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); + tbm_surface_internal_destroy(target_buff); + ASSERT_NE(TDM_ERROR_NONE, error); + } +} + +TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulSetBuff) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + + for (int o = 0; o < output_count; o++) { + tbm_surface_h target_buff = CreateBufferForOutput(i); + ASSERT_NE(NULL, target_buff); + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + error = tdm_output_hwc_set_client_target_buffer(outputs[o], target_buff, damage, + NULL, 0); + tbm_surface_internal_destroy(target_buff); + ASSERT_EQ(TDM_ERROR_NONE, error); + } else { + error = tdm_output_hwc_set_client_target_buffer(outputs[o], target_buff, damage, + NULL, 0); + tbm_surface_internal_destroy(target_buff); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} + +TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + error = tdm_output_hwc_set_client_target_buffer(outputs[o], NULL, damage, + NULL, 0); + ASSERT_EQ(TDM_ERROR_NONE, error); + } else { + error = tdm_output_hwc_set_client_target_buffer(outputs[o], NULL, damage, + NULL, 0); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} +*/ + +/* tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); */ +TEST_P(TDMOutputHwc, GetTargetBufferQueueFailNullObject) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tbm_surface_queue_h queue = NULL; + + queue = tdm_output_hwc_get_target_buffer_queue(NULL, &error); + ASSERT_NE(TDM_ERROR_NONE, error); + ASSERT_EQ(NULL, queue); + + queue = tdm_output_hwc_get_target_buffer_queue(NULL, NULL); + ASSERT_EQ(NULL, queue); +} + +TEST_P(TDMOutputHwc, GetTargetBufferQueueFainNoHwc) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tbm_surface_queue_h queue = NULL; + + for (int o = 0; o < output_count; o++) { + queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], &error); + ASSERT_NE(TDM_ERROR_NONE, error); + ASSERT_EQ(NULL, queue); + } +} + +TEST_P(TDMOutputHwc, GetTargetBufferQueueSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tbm_surface_queue_h queue = NULL; + + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], &error); + tbm_surface_queue_destroy(queue); + ASSERT_EQ(TDM_ERROR_NONE, error); + ASSERT_NE(NULL, queue); + + queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], NULL); + tbm_surface_queue_destroy(queue); + ASSERT_EQ(TDM_ERROR_NONE, error); + ASSERT_NE(NULL, queue); + } else { + queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], &error); + ASSERT_NE(TDM_ERROR_NONE, error); + ASSERT_EQ(NULL, queue); + + queue = tdm_output_hwc_get_target_buffer_queue(outputs[o], NULL); + ASSERT_NE(TDM_ERROR_NONE, error); + ASSERT_EQ(NULL, queue); + } + } +} + +/* tdm_error tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, + uint32_t *num_types); */ +/* TODO: fix the validate test later. +TEST_P(TDMOutputHwc, ValidateFailNull) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t num_types; + error = tdm_output_hwc_validate(NULL, NULL, 0, &num_types); + ASSERT_NE(TDM_ERROR_NONE, error); + + if (outputs[0]) { + error = tdm_output_hwc_validate(outputs[0], NULL, 0, NULL); + ASSERT_NE(TDM_ERROR_NONE, error); + } +} + +TEST_P(TDMOutputHwc, ValidateFailNoHwc) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t num_types; + + for (int o = 0; o < output_count; o++) { + error = tdm_output_hwc_validate(outputs[o], &num_types); + ASSERT_NE(TDM_ERROR_NONE, error); + } +} + +TEST_P(TDMOutputHwc, ValidateSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t num_types; + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + error = tdm_output_hwc_validate(outputs[o], &num_types); + ASSERT_EQ(TDM_ERROR_NONE, error); + } else { + error = tdm_output_hwc_validate(outputs[o], &num_types); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} +TODO: */ + +/* tdm_error tdm_output_hwc_get_changed_composition_types(tdm_output *output, + uint32_t *num_elements, tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types); */ + +TEST_P(TDMOutputHwc, GetChangedCompositionTypesFailNull) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t num_elements; + + error = tdm_output_hwc_get_changed_composition_types(NULL, &num_elements, NULL, NULL); + ASSERT_NE(TDM_ERROR_NONE, error); + + if (outputs[0]) { + error = tdm_output_hwc_get_changed_composition_types(outputs[0], NULL, NULL, NULL); + ASSERT_NE(TDM_ERROR_NONE, error); + } +} + +TEST_P(TDMOutputHwc, GetChangedCompositionTypesFailNoHwc) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t get_num = 10; + + for (int o = 0; o < output_count; o++) { + error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); + ASSERT_NE(TDM_ERROR_NONE, error); + } +} + +/* TODO: fix the validate test later. +TEST_P(TDMHwcWindow, GetChangedCompositionTypesSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t validate_num; + uint32_t get_num = 0; + + tdm_hwc_window_composition *composition_types; + tdm_hwc_window **hwc_wnds; + + for (int i = 0; i < hwc_count; i++) { + error = tdm_hwc_window_set_composition_type(hwc_wins[o], TDM_COMPOSITION_DEVICE); + ASSERT_EQ(TDM_ERROR_NONE, error); + } + + + for (int i = 0; i < output_count; i++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + error = tdm_output_hwc_validate(outputs[o], &validate_num); + ASSERT_EQ(TDM_ERROR_NONE, error); + + error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); + ASSERT_EQ(TDM_ERROR_NONE, error); + + ASSERT_TRUE(get_num == validate_num); + hwc_wnds = (tdm_hwc_window **)calloc(get_num, sizeof(tdm_hwc_window *)); + composition_types = (tdm_hwc_window_composition *)calloc(get_num, sizeof(tdm_hwc_window_composition)); + + error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, hwc_wnds, composition_types); + + free(hwc_wnds); + free(composition_types); + + ASSERT_EQ(TDM_ERROR_NONE, error); + } else { + error = tdm_output_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} +*/ + +/* tdm_error tdm_output_hwc_accept_changes(tdm_output *output); */ + +TEST_P(TDMOutputHwc, AcceptChangesFailNull) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + error = tdm_output_hwc_accept_changes(NULL); + ASSERT_NE(TDM_ERROR_NONE, error); +} + +TEST_P(TDMOutputHwc, AcceptChangesFailNoHwc) +{ + for (int o = 0; o < output_count; o++) { + error = tdm_output_hwc_accept_changes(outputs[o]); + ASSERT_NE(TDM_ERROR_NONE, error); + } +} + +/* TODO: fix the validate test later. +TEST_P(TDMHwcWindow, AcceptChangesSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + uint32_t validate_num; + + for (int i = 0; i < hwc_count; i++) { + error = tdm_hwc_window_set_composition_type(hwc_wins[o], TDM_COMPOSITION_DEVICE); + ASSERT_EQ(TDM_ERROR_NONE, error); + } + + for (int i = 0; i < output_count; i++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + error = tdm_output_hwc_validate(outputs[o], &validate_num); + ASSERT_EQ(TDM_ERROR_NONE, error); + + if (validate_num > 0) { + error = tdm_output_hwc_accept_changes(outputs[o]); + ASSERT_EQ(TDM_ERROR_NONE, error); + } + } + } +} +*/ + +/* tdm_hwc_window * tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error); */ +TEST_P(TDMOutputHwc, CreateVideoWindowFailNull) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + ASSERT_EQ(NULL, tdm_output_hwc_create_video_window(NULL, &error)); + ASSERT_NE(TDM_ERROR_NONE, error); +} + +TEST_P(TDMOutputHwc, CreateVideoWindowSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_hwc_window *hw = NULL; + + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + hw = tdm_output_hwc_create_video_window(outputs[o], &error); + if (error != TDM_ERROR_NOT_IMPLEMENTED) { + ASSERT_EQ(TDM_ERROR_NONE, error); + ASSERT_NE(NULL, hw); + error = tdm_output_hwc_destroy_window(outputs[o], hw); + ASSERT_EQ(TDM_ERROR_NONE, error); + } + } else { + ASSERT_EQ(NULL, tdm_output_hwc_create_video_window(outputs[o], &error)); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} + +/* tdm_output_hwc_get_video_supported_formats() */ +TEST_P(TDMOutputHwc, GetVideoSupportedFormatsFailNull) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_error error; + + error = tdm_output_hwc_get_video_supported_formats(NULL, NULL, NULL); + ASSERT_NE(TDM_ERROR_NONE, error); +} + +TEST_P(TDMOutputHwc, GetVideoSupportedFormatsSuccessful) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_error error; + const tbm_format *formats; + int count; + + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + error = tdm_output_hwc_get_video_supported_formats(outputs[o], &formats, &count); + if (error != TDM_ERROR_NOT_IMPLEMENTED) { + ASSERT_EQ(TDM_ERROR_NONE, error); + if (count > 0) + ASSERT_NE(NULL, formats); + } + } else { + error = tdm_output_hwc_get_video_supported_formats(outputs[o], &formats, &count); + ASSERT_NE(TDM_ERROR_NONE, error); + } + } +} + +INSTANTIATE_TEST_CASE_P(TDMOutputHwcParams, + TDMOutputHwc, + Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE))); +#endif -- 2.7.4 From 22a7defce20cd39c32da437475e40ecf2be4230f Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Tue, 27 Feb 2018 17:25:27 +0900 Subject: [PATCH 02/16] utest: modify the TDMHwcWindow test case Change-Id: I9fb070f824ec134051f7245c923deaa989c10cdd --- utests/src/ut_tdm.h | 2 +- utests/src/ut_tdm_hwc_window.cpp | 393 +++++++++++++++------------------------ 2 files changed, 154 insertions(+), 241 deletions(-) diff --git a/utests/src/ut_tdm.h b/utests/src/ut_tdm.h index 890f182..c29a2b1 100644 --- a/utests/src/ut_tdm.h +++ b/utests/src/ut_tdm.h @@ -30,7 +30,7 @@ extern "C" { #define UT_TDM_EVENT_LOOP_ENABLE #define UT_TDM_HELPER_ENABLE #define UT_TDM_OUTPUT_HWC_ENABLE -//#define UT_TDM_HWC_WINDOW_ENABLE +#define UT_TDM_HWC_WINDOW_ENABLE #define UT_TDM_LAYER_ENABLE #define UT_TDM_LOG_ENABLE #define UT_TDM_OUTPUT_ENABLE diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index a5a5152..d18a161 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -30,223 +30,87 @@ #include "ut_tdm.h" -#ifdef UT_TDM_HWC_WINDOW_ENABLE - -class TDMOutputHwc : public ::testing::Test { -protected: - tdm_display *dpy = NULL; - tbm_bufmgr tbm_bufmgr = NULL; - int master_fd = TDM_UT_INVALID_VALUE; - /*list of connected outputs*/ - int output_count = 0; - const tdm_output_mode **preferred_mode_array = NULL; - tdm_output **outputs; - tdm_error error ; - virtual void SetEnv() - { - setenv("TDM_HWC", "1", 1); - setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DISPLAY_SERVER", "1", 1); - tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); - tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); - tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1); - tdm_config_set_string(TDM_CONFIG_KEY_GENERAL_BACKENDS, "libtdm-default.so"); - } - - void UnsetEnv() - { - unsetenv("TDM_HWC"); - unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DISPLAY_SERVER"); - } - - int IsHwcEnable(int i) - { - tdm_output_capability capabilities = (tdm_output_capability)0; - tdm_output_get_capabilities(outputs[i], &capabilities); - return capabilities & TDM_OUTPUT_CAPABILITY_HWC; - } - - tbm_surface_h CreateBufferForOutput(int i) - { - int w = preferred_mode_array[i]->hdisplay; - int h = preferred_mode_array[i]->vdisplay; - return tbm_surface_internal_create_with_flags(w, h, TBM_FORMAT_ARGB8888, TBM_BO_SCANOUT); - } - - void SetUp(void) - { - const tdm_output_mode *preferred_mode = NULL; - tdm_error error = TDM_ERROR_NONE; - int all_output_count = 0; - outputs = NULL; - - SetEnv(); - - /* FIXME: fix the error. If we initialize TBM before TDM we get fail - * in the tdm_output_set_dpms */ -#if 0 - tbm_bufmgr = tbm_bufmgr_init(-1); - ASSERT_FALSE(tbm_bufmgr == NULL); -#endif - - dpy = tdm_display_init(&error); - ASSERT_TRUE(error == TDM_ERROR_NONE); - ASSERT_FALSE(dpy == NULL); - - master_fd = tbm_drm_helper_get_master_fd(); - ASSERT_TRUE(tdm_display_get_output_count(dpy, &all_output_count) == TDM_ERROR_NONE); - - outputs = (tdm_output **)calloc(all_output_count, sizeof(tdm_output *)); - ASSERT_FALSE(NULL == outputs); +#define HWC_WIN_NUM 5 - preferred_mode_array = (const tdm_output_mode **)calloc(all_output_count, sizeof(tdm_output_mode *)); - ASSERT_FALSE(NULL == preferred_mode_array); +class TDMHwcWindow : public TDMOutput { +public: + TDMHwcWindow(); + void SetUp(void); + void TearDown(void); - output_count = 0; + tdm_error error; + tdm_hwc_window **hwc_wins; + tdm_hwc_window *video_hwc_win; + int hwc_count; +}; - for (int i = 0; i < all_output_count; i++) { - tdm_output *output = tdm_display_get_output(dpy, i, &error); - int output_modes_cnt = 0; - const tdm_output_mode *output_modes; +TDMHwcWindow::TDMHwcWindow() +{ + hwc_count = 0; + video_hwc_win = NULL; +} - if (TDM_ERROR_NONE != error || NULL == output) - continue; +void TDMHwcWindow::SetUp(void) +{ + tdm_hwc_window *hw = NULL; - tdm_output_conn_status status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED; - if (TDM_ERROR_NONE != tdm_output_get_conn_status(output, &status)) - continue; + TDMOutput::SetUp(); - if (status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) - continue; + hwc_wins = (tdm_hwc_window **)calloc(output_count * HWC_WIN_NUM, sizeof(tdm_hwc_window *)); - error = tdm_output_get_available_modes(output, &output_modes, &output_modes_cnt); - if (TDM_ERROR_NONE != error) - continue; - if (output_modes_cnt <= 0) { - continue; + //create HWC_WIN_NUM hwc_windows for each outputs + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + for (int w = 0; w < HWC_WIN_NUM; w++) { + hw = tdm_output_hwc_create_window(outputs[w], &error); + ASSERT_EQ(TDM_ERROR_NONE, error); + hwc_wins[hwc_count++] = hw; } - for(int j = 0; j < output_modes_cnt; j++) - if(output_modes[j].type & TDM_OUTPUT_MODE_TYPE_PREFERRED) - preferred_mode = &output_modes[j]; - - if (!preferred_mode) - continue; - - if (preferred_mode_array) - preferred_mode_array[output_count] = preferred_mode; - if (outputs) - outputs[output_count] = output; - output_count++; - - error = tdm_output_set_mode(output, preferred_mode); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - } - void TearDown(void) - { - tdm_display_deinit(dpy); - dpy = NULL; - tbm_bufmgr_deinit(tbm_bufmgr); - tbm_bufmgr = NULL; - if (outputs) - free(outputs); - if (preferred_mode_array) - free(preferred_mode_array); - if (master_fd > -1) { - int temp_master_fd = tbm_drm_helper_get_master_fd(); - EXPECT_EQ(temp_master_fd, -1) << "Fatal Error. Can't deinit tdm/tbm" << std::endl; - if (temp_master_fd > -1) - exit(1); - close(master_fd); - } - - UnsetEnv(); - } -}; - -class TDMOutputHwcWithoutHwcCap : public TDMOutputHwc { - void SetEnv() - { - TDMOutputHwc::SetEnv(); - setenv("TDM_HWC", "0", 1); - } -}; - -#define HWC_WIN_NUM 5 -class TDMHwcWindow : public TDMOutputHwc { -protected: - tdm_hwc_window **hwc_wins; - tdm_hwc_window *video_hwc_win; - int hwc_count; - - void SetUp(void) - { - hwc_count = 0; - video_hwc_win = NULL; - - TDMOutputHwc::SetUp(); - hwc_wins = (tdm_hwc_window **)calloc(output_count * HWC_WIN_NUM, sizeof(tdm_hwc_window *)); - - //create HWC_WIN_NUM hwc_windows for each outputs - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - for (int j = 0; j < HWC_WIN_NUM; j++) { - tdm_hwc_window * hw = tdm_output_hwc_create_window(outputs[i], &error); - ASSERT_EQ(TDM_ERROR_NONE, error); - hwc_wins[hwc_count++] = hw; - } - if (!video_hwc_win) { - video_hwc_win = tdm_output_hwc_create_video_window(outputs[i], &error); - } - } + if (!video_hwc_win) + video_hwc_win = tdm_output_hwc_create_video_window(outputs[o], &error); } } +} - void TearDown(void) - { - for (int i = 0; i < hwc_count; i++) { - tdm_output_hwc_destroy_window(outputs[0], hwc_wins[i]); - } +void TDMHwcWindow::TearDown(void) +{ + for (int w = 0; w < hwc_count; w++) + tdm_output_hwc_destroy_window(outputs[0], hwc_wins[w]); - if (video_hwc_win) - tdm_output_hwc_destroy_window(outputs[0], video_hwc_win); + if (video_hwc_win) + tdm_output_hwc_destroy_window(outputs[0], video_hwc_win); - TDMOutputHwc::TearDown(); - } + TDMOutput::TearDown(); +} -}; +#ifdef UT_TDM_HWC_WINDOW_ENABLE /* tdm_error tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window); */ -TEST_F(TDMOutputHwc, DestroyWindowFailNull) +TEST_P(TDMHwcWindow, DestroyWindowFailNull) { - for (int i = 0; i < output_count; i++) { - tdm_hwc_window * hw = NULL; - - if (IsHwcEnable(i)) { - hw = tdm_output_hwc_create_window(outputs[i], &error); - ASSERT_EQ(TDM_ERROR_NONE, error); - } - - /* test: output is NULL*/ - error = tdm_output_hwc_destroy_window(NULL, hw); - ASSERT_NE(TDM_ERROR_NONE, error); + TDM_UT_SKIP_FLAG(has_outputs); + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { /* test: hw is NULL*/ - error = tdm_output_hwc_destroy_window(outputs[i], NULL); + error = tdm_output_hwc_destroy_window(outputs[o], NULL); ASSERT_NE(TDM_ERROR_NONE, error); + } } } -TEST_F(TDMOutputHwc, DestroyWindowSuccessful) +TEST_P(TDMHwcWindow, DestroyWindowSuccessful) { - tdm_hwc_window * hw; - for (int i = 0; i < output_count; i++) { - if (IsHwcEnable(i)) { - hw = tdm_output_hwc_create_window(outputs[i], &error); + TDM_UT_SKIP_FLAG(has_outputs); + + tdm_hwc_window *hw = NULL; + + for (int o = 0; o < output_count; o++) { + if (ut_tdm_output_is_hwc_enable(outputs[o])) { + hw = tdm_output_hwc_create_window(outputs[o], &error); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_output_hwc_destroy_window(outputs[i], hw); + error = tdm_output_hwc_destroy_window(outputs[o], hw); ASSERT_EQ(TDM_ERROR_NONE, error); } } @@ -254,8 +118,10 @@ TEST_F(TDMOutputHwc, DestroyWindowSuccessful) /* tbm_surface_queue_h tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); */ -TEST_F(TDMHwcWindow, GetBufferQueueFailNull) +TEST_P(TDMHwcWindow, GetBufferQueueFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + tbm_surface_queue_h queue = NULL; queue = tdm_hwc_window_get_tbm_buffer_queue(NULL, &error); @@ -266,8 +132,10 @@ TEST_F(TDMHwcWindow, GetBufferQueueFailNull) ASSERT_EQ(NULL, queue); } -TEST_F(TDMHwcWindow, GetBufferQueueSuccessful) +TEST_P(TDMHwcWindow, GetBufferQueueSuccessful) { + TDM_UT_SKIP_FLAG(has_outputs); + tbm_surface_queue_h queue = NULL; tdm_hwc_window_info info = { 0 }; @@ -277,16 +145,16 @@ TEST_F(TDMHwcWindow, GetBufferQueueSuccessful) info.dst_pos.h = info.dst_pos.w = 256; info.transform = TDM_TRANSFORM_NORMAL; - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_info(hwc_wins[i], &info); + for (int w = 0; w < hwc_count; w++) { + error = tdm_hwc_window_set_info(hwc_wins[w], &info); ASSERT_EQ(TDM_ERROR_NONE, error); - queue = tdm_hwc_window_get_tbm_buffer_queue(hwc_wins[i], &error); + queue = tdm_hwc_window_get_tbm_buffer_queue(hwc_wins[w], &error); tbm_surface_queue_destroy(queue); ASSERT_EQ(TDM_ERROR_NONE, error); ASSERT_NE(NULL, queue); - queue = tdm_hwc_window_get_tbm_buffer_queue(hwc_wins[i], NULL); + queue = tdm_hwc_window_get_tbm_buffer_queue(hwc_wins[w], NULL); tbm_surface_queue_destroy(queue); ASSERT_NE(NULL, queue); } @@ -294,67 +162,81 @@ TEST_F(TDMHwcWindow, GetBufferQueueSuccessful) /* tdm_error tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, tdm_hwc_window_composition composition_type); */ -TEST_F(TDMHwcWindow, SetCompositionTypeFailNull) +TEST_P(TDMHwcWindow, SetCompositionTypeFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + error = tdm_hwc_window_set_composition_type(NULL, TDM_COMPOSITION_DEVICE); ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, SetCompositionTypeSuccessful) +TEST_P(TDMHwcWindow, SetCompositionTypeSuccessful) { - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_DEVICE); + TDM_UT_SKIP_FLAG(has_outputs); + + for (int w = 0; w < hwc_count; w++) { + error = tdm_hwc_window_set_composition_type(hwc_wins[w], TDM_COMPOSITION_DEVICE); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_CLIENT); + error = tdm_hwc_window_set_composition_type(hwc_wins[w], TDM_COMPOSITION_CLIENT); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_hwc_window_set_composition_type(hwc_wins[i], TDM_COMPOSITION_CURSOR); + error = tdm_hwc_window_set_composition_type(hwc_wins[w], TDM_COMPOSITION_CURSOR); ASSERT_EQ(TDM_ERROR_NONE, error); } } -TEST_F(TDMHwcWindow, SetCompositionTypeFailInvalieCompositionType) +TEST_P(TDMHwcWindow, SetCompositionTypeFailInvalieCompositionType) { - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_composition_type(hwc_wins[i], tdm_hwc_window_composition(TDM_COMPOSITION_NONE-1)); + TDM_UT_SKIP_FLAG(has_outputs); + + for (int w = 0; w < hwc_count; w++) { + error = tdm_hwc_window_set_composition_type(hwc_wins[w], tdm_hwc_window_composition(TDM_COMPOSITION_NONE-1)); ASSERT_NE(TDM_ERROR_NONE, error); } } /* tdm_error tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage); */ -TEST_F(TDMHwcWindow, SetBufferDamageFailNullHwcWindow) +TEST_P(TDMHwcWindow, SetBufferDamageFailNullHwcWindow) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; error = tdm_hwc_window_set_buffer_damage(NULL, damage); ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, SetBufferDamageFailNullDamageRects) +TEST_P(TDMHwcWindow, SetBufferDamageFailNullDamageRects) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_region damage = {.num_rects = 1, .rects = NULL}; - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_buffer_damage(hwc_wins[i], damage); + for (int w = 0; w < hwc_count; w++) { + error = tdm_hwc_window_set_buffer_damage(hwc_wins[w], damage); ASSERT_NE(TDM_ERROR_NONE, error); } } -TEST_F(TDMHwcWindow, SetBufferDamageSuccessful) +TEST_P(TDMHwcWindow, SetBufferDamageSuccessful) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_pos const rects[1] = {0}; tdm_hwc_region damage = {.num_rects = 1, .rects = rects}; - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_buffer_damage(hwc_wins[i], damage); + for (int w = 0; w < hwc_count; w++) { + error = tdm_hwc_window_set_buffer_damage(hwc_wins[w], damage); ASSERT_EQ(TDM_ERROR_NONE, error); } } /* tdm_error tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info); */ -TEST_F(TDMHwcWindow, SetInfoFailNull) +TEST_P(TDMHwcWindow, SetInfoFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_info info = { 0 }; error = tdm_hwc_window_set_info(NULL, &info); @@ -365,85 +247,102 @@ TEST_F(TDMHwcWindow, SetInfoFailNull) ASSERT_NE(TDM_ERROR_NONE, error); } } -TEST_F(TDMHwcWindow, SetInfoSuccessful) + +TEST_P(TDMHwcWindow, SetInfoSuccessful) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_info info = { 0 }; - for (int i = 0; i < hwc_count; i++) { - error = tdm_hwc_window_set_info(hwc_wins[i], &info); + for (int w = 0; w < hwc_count; w++) { + error = tdm_hwc_window_set_info(hwc_wins[w], &info); ASSERT_EQ(TDM_ERROR_NONE, error); } } /* tdm_error tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer); */ -TEST_F(TDMHwcWindow, SetBufferFailNull) +TEST_P(TDMHwcWindow, SetBufferFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + error = tdm_hwc_window_set_buffer(NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, SetBufferSuccessful) +TEST_P(TDMHwcWindow, SetBufferSuccessful) { - for (int i = 0; i < hwc_count; i++) { + TDM_UT_SKIP_FLAG(has_outputs); + + for (int w = 0; w < hwc_count; w++) { tbm_surface_h buff = tbm_surface_create(256, 256, TBM_FORMAT_ARGB8888); /* test: set*/ - error = tdm_hwc_window_set_buffer(hwc_wins[i], buff); + error = tdm_hwc_window_set_buffer(hwc_wins[w], buff); tbm_surface_destroy(buff); ASSERT_EQ(TDM_ERROR_NONE, error); /* test: reset*/ - error = tdm_hwc_window_set_buffer(hwc_wins[i], NULL); + error = tdm_hwc_window_set_buffer(hwc_wins[w], NULL); ASSERT_EQ(TDM_ERROR_NONE, error); } } /* tdm_error tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); */ -TEST_F(TDMHwcWindow, SetFlagsFailNull) +TEST_P(TDMHwcWindow, SetFlagsFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; error = tdm_hwc_window_set_flags(NULL, flag); ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, SetFlagsSuccessful) +TEST_P(TDMHwcWindow, SetFlagsSuccessful) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - for (int i = 0; i < hwc_count; i++) { + for (int w = 0; w < hwc_count; w++) { - error = tdm_hwc_window_set_flags(hwc_wins[i], flag); + error = tdm_hwc_window_set_flags(hwc_wins[w], flag); ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); } } /* tdm_error tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); */ -TEST_F(TDMHwcWindow, UnsetFlagsFailNull) +TEST_P(TDMHwcWindow, UnsetFlagsFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; error = tdm_hwc_window_unset_flags(NULL, flag); ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, UnsetFlagsSuccessful) +TEST_P(TDMHwcWindow, UnsetFlagsSuccessful) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - for (int i = 0; i < hwc_count; i++) { + for (int w = 0; w < hwc_count; w++) { - error = tdm_hwc_window_unset_flags(hwc_wins[i], flag); + error = tdm_hwc_window_unset_flags(hwc_wins[w], flag); ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); } } /* tdm_error tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, tdm_hwc_window_video_capability *video_capability); */ -TEST_F(TDMHwcWindow, VideoGetCapabilityFailNull) +TEST_P(TDMHwcWindow, VideoGetCapabilityFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_video_capability video_capability; error = tdm_hwc_window_video_get_capability(NULL, &video_capability); @@ -456,13 +355,15 @@ TEST_F(TDMHwcWindow, VideoGetCapabilityFailNull) } -TEST_F(TDMHwcWindow, VideoGetCapabilitySuccessful) +TEST_P(TDMHwcWindow, VideoGetCapabilitySuccessful) { + TDM_UT_SKIP_FLAG(has_outputs); + tdm_hwc_window_video_capability video_capability; - for (int i = 0; i < hwc_count; i++) { + for (int w = 0; w < hwc_count; w++) { /* hwc_window with TDM_COMPOSITION_CLIENT dosn't support tdm_hwc_window_video_get_capability()*/ - error = tdm_hwc_window_video_get_capability(hwc_wins[i], &video_capability); + error = tdm_hwc_window_video_get_capability(hwc_wins[w], &video_capability); ASSERT_NE(TDM_ERROR_NONE, error); if (video_hwc_win != NULL) { @@ -474,8 +375,10 @@ TEST_F(TDMHwcWindow, VideoGetCapabilitySuccessful) /* tdm_hwc_window_video_get_available_properties() */ -TEST_F(TDMHwcWindow, GetAvailablePropertiesFailNullWin) +TEST_P(TDMHwcWindow, GetAvailablePropertiesFailNullWin) { + TDM_UT_SKIP_FLAG(has_outputs); + TDM_UT_SKIP_FLAG(video_hwc_win != NULL); const tdm_prop *props; int count; @@ -490,8 +393,10 @@ TEST_F(TDMHwcWindow, GetAvailablePropertiesFailNullWin) ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, GetAvailablePropertiesSuccess) +TEST_P(TDMHwcWindow, GetAvailablePropertiesSuccess) { + TDM_UT_SKIP_FLAG(has_outputs); + TDM_UT_SKIP_FLAG(video_hwc_win != NULL); const tdm_prop *props; @@ -502,8 +407,9 @@ TEST_F(TDMHwcWindow, GetAvailablePropertiesSuccess) } /* tdm_hwc_window_video_get_property() */ -TEST_F(TDMHwcWindow, GetPropertyFailNull) +TEST_P(TDMHwcWindow, GetPropertyFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); TDM_UT_SKIP_FLAG(video_hwc_win != NULL); tdm_value value; @@ -516,8 +422,9 @@ TEST_F(TDMHwcWindow, GetPropertyFailNull) ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, GetPropertyFailWrongId) +TEST_P(TDMHwcWindow, GetPropertyFailWrongId) { + TDM_UT_SKIP_FLAG(has_outputs); TDM_UT_SKIP_FLAG(video_hwc_win != NULL); tdm_value value; @@ -528,9 +435,11 @@ TEST_F(TDMHwcWindow, GetPropertyFailWrongId) } /* tdm_hwc_window_video_set_property() */ -TEST_F(TDMHwcWindow, SetPropertyFailNull) +TEST_P(TDMHwcWindow, SetPropertyFailNull) { + TDM_UT_SKIP_FLAG(has_outputs); TDM_UT_SKIP_FLAG(video_hwc_win != NULL); + tdm_value value; int id = 1; @@ -538,8 +447,9 @@ TEST_F(TDMHwcWindow, SetPropertyFailNull) ASSERT_NE(TDM_ERROR_NONE, error); } -TEST_F(TDMHwcWindow, SetPropertyFailWrongId) +TEST_P(TDMHwcWindow, SetPropertyFailWrongId) { + TDM_UT_SKIP_FLAG(has_outputs); TDM_UT_SKIP_FLAG(video_hwc_win != NULL); tdm_value value; @@ -549,4 +459,7 @@ TEST_F(TDMHwcWindow, SetPropertyFailWrongId) ASSERT_NE(TDM_ERROR_NONE, error); } +INSTANTIATE_TEST_CASE_P(TDMHwcWindowParams, + TDMHwcWindow, + Combine(Bool(), Bool(), Values(TDM_DEFAULT_MODULE))); #endif -- 2.7.4 From bdb174af619e1150c4c23e81b096fc3ce6b850b5 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 2 Mar 2018 16:06:07 +0900 Subject: [PATCH 03/16] add tdm_client_vblank_is_waiting Change-Id: I27df05723f0544c6f063a722100b6ecdbec6c944 --- client/tdm_client.c | 12 ++++++++++++ client/tdm_client.h | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/client/tdm_client.c b/client/tdm_client.c index 4c38190..e71c691 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -1467,3 +1467,15 @@ tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, /* LCOV_EXCL_STOP */ } + +unsigned int +tdm_client_vblank_is_waiting(tdm_client_vblank *vblank) +{ + tdm_private_client_vblank *private_vblank; + + TDM_RETURN_VAL_IF_FAIL(vblank != NULL, 0); + + private_vblank = vblank; + + return (LIST_LENGTH(&private_vblank->wait_list) > 0) ? 1 : 0; +} diff --git a/client/tdm_client.h b/client/tdm_client.h index a96e4d4..4ef687b 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -409,6 +409,14 @@ tdm_client_vblank_wait(tdm_client_vblank *vblank, unsigned int interval, tdm_cli tdm_error tdm_client_vblank_wait_seq(tdm_client_vblank *vblank, unsigned int sequence, tdm_client_vblank_handler func, void *user_data); +/** + * @brief Check if the client vblank object is waiting a vblank event + * @param[in] vblank The client vblank object + * @return 1 if waiting. 0 if not waiting. + */ +unsigned int +tdm_client_vblank_is_waiting(tdm_client_vblank *vblank); + #ifdef __cplusplus } #endif -- 2.7.4 From 65a8648ffaca491aa4d16640f1633f5f0cd0b07a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 2 Mar 2018 16:38:27 +0900 Subject: [PATCH 04/16] client: add tdm_client_handle_events_timeout Change-Id: Ifebfbe10670f7f8af366e26c8ea8e172f024d6a1 --- client/tdm_client.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ client/tdm_client.h | 12 ++++++++ include/tdm_common.h | 1 + 3 files changed, 98 insertions(+) diff --git a/client/tdm_client.c b/client/tdm_client.c index e71c691..84b4c07 100644 --- a/client/tdm_client.c +++ b/client/tdm_client.c @@ -42,6 +42,7 @@ #include #include #include +#include #include @@ -570,6 +571,90 @@ tdm_client_handle_events(tdm_client *client) /* LCOV_EXCL_STOP */ } +static int +_tdm_client_poll(struct wl_display *display, short int events, int timeout) +{ + int ret; + struct pollfd pfd[1]; + + pfd[0].fd = wl_display_get_fd(display); + pfd[0].events = events; + do { + ret = poll(pfd, 1, timeout); + } while (ret == -1 && errno == EINTR); + + return ret; +} + +static tdm_error +_tdm_client_dispatch_timeout(tdm_private_client *private_client, int timeout) +{ + int ret; + struct wl_display *display = private_client->display; + + if (wl_display_prepare_read(display) == -1) + return wl_display_dispatch_pending(display); + + while (true) { + ret = wl_display_flush(display); + + if (ret != -1 || errno != EAGAIN) + break; + + if (_tdm_client_poll(display, POLLOUT, -1) == -1) { + wl_display_cancel_read(display); + TDM_ERR("_tdm_client_poll failed"); + return TDM_ERROR_OPERATION_FAILED; + } + } + + /* Don't stop if flushing hits an EPIPE; continue so we can read any + * protocol error that may have triggered it. */ + if (ret < 0 && errno != EPIPE) { + TDM_ERR("ret(%d) errno(%d)", ret, errno); + wl_display_cancel_read(display); + return TDM_ERROR_OPERATION_FAILED; + } + + ret = _tdm_client_poll(display, POLLIN, timeout); + if (ret <= 0) { + wl_display_cancel_read(display); + if (ret == 0) { + TDM_ERR("_tdm_client_poll timeout."); + return TDM_ERROR_TIMEOUT; + } else { + TDM_ERR("_tdm_client_poll failed. (ret:%d)", ret); + return TDM_ERROR_OPERATION_FAILED; + } + } + + if (wl_display_read_events(display) == -1) { + TDM_ERR("wl_display_read_events failed"); + return TDM_ERROR_OPERATION_FAILED; + } + + ret = wl_display_dispatch_pending(display); + + if (ret < 0) { + TDM_ERR("_tdm_client_dispatch_timeout failed"); + return TDM_ERROR_OPERATION_FAILED; + } + + return TDM_ERROR_NONE; +} + +tdm_error +tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout) +{ + tdm_private_client *private_client; + + TDM_RETURN_VAL_IF_FAIL(client != NULL, TDM_ERROR_INVALID_PARAMETER); + + private_client = (tdm_private_client*)client; + + return _tdm_client_dispatch_timeout(private_client, ms_timeout); +} + typedef struct _tdm_client_vblank_temp { tdm_client_vblank_handler2 func; void *user_data; diff --git a/client/tdm_client.h b/client/tdm_client.h index 4ef687b..2b9dc1e 100644 --- a/client/tdm_client.h +++ b/client/tdm_client.h @@ -117,6 +117,18 @@ tdm_error tdm_client_handle_events(tdm_client *client); /** + * @brief Handle the events of the given file descriptor with millisecond timeout + * @details + * -1: infinite. 0: return immediately. Otherwise, waiting for ms_timeout milliseconds. + * @param[in] client A TDM client object + * @param[in] ms_timeout timeout value. + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see #tdm_client_get_fd + */ +tdm_error +tdm_client_handle_events_timeout(tdm_client *client, int ms_timeout); + +/** * @brief @b Deprecated. Wait for VBLANK. * @deprecated * @details After interval vblanks, a client vblank handler will be called. diff --git a/include/tdm_common.h b/include/tdm_common.h index 4c264ed..db7e087 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -69,6 +69,7 @@ typedef enum { TDM_ERROR_DPMS_OFF = -10, /**< dpms off */ TDM_ERROR_OUTPUT_DISCONNECTED = -11, /**< output disconnected */ TDM_ERROR_PROTOCOL_ERROR = -12, /**< protocol error */ + TDM_ERROR_TIMEOUT = -13, /**< timeout */ } tdm_error; /** -- 2.7.4 From f85ee3f925ce5175638d59fa0324e7f590746668 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 28 Feb 2018 14:47:01 +0900 Subject: [PATCH 05/16] log: remove unused code Change-Id: Id0683906617148ed05423561c3bf5987ad592f37 --- common/tdm_log.c | 15 ++++++--------- include/tdm_log.h | 1 - utests/src/ut_tdm_log.cpp | 4 ---- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 3f6b560..aa3d182 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -87,23 +87,20 @@ tdm_log_enable_dlog(unsigned int enable) } EXTERN void -tdm_log_enable_debug(unsigned int enable) -{ - if (enable) - tdm_log_debug_level = TDM_LOG_LEVEL_DBG; - else - tdm_log_debug_level = TDM_LOG_LEVEL_INFO; -} - -EXTERN void tdm_log_set_debug_level(int level) { + const char *str = getenv("TDM_DEBUG_LEVEL"); + if (str) + level = str[0] - '0'; tdm_log_debug_level = level; } EXTERN void tdm_log_set_assert_level(int level) { + const char *str = getenv("TDM_ASSERT_LEVEL"); + if (str) + level = str[0] - '0'; assert_level = level; } diff --git a/include/tdm_log.h b/include/tdm_log.h index b653aa2..5a9fb65 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -66,7 +66,6 @@ enum { void tdm_log_enable_color(unsigned int enable); void tdm_log_enable_dlog(unsigned int enable); -void tdm_log_enable_debug(unsigned int enable); void tdm_log_set_debug_level(int level); void tdm_log_set_assert_level(int level); void tdm_log_set_path(const char *path); diff --git a/utests/src/ut_tdm_log.cpp b/utests/src/ut_tdm_log.cpp index 2d4e245..64f6154 100644 --- a/utests/src/ut_tdm_log.cpp +++ b/utests/src/ut_tdm_log.cpp @@ -36,7 +36,6 @@ TEST(TDMLog, logPrintf) { tdm_log_enable_color(1); tdm_log_enable_dlog(0); - tdm_log_enable_debug(1); tdm_log_set_debug_level(2); tdm_log_set_path("/tmp/tdm.log"); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest\n"); @@ -58,7 +57,6 @@ TEST(TDMLog, logDlogNone) { tdm_log_enable_color(0); tdm_log_enable_dlog(1); - tdm_log_enable_debug(0); tdm_log_set_debug_level(0); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest"); tdm_log_print(TDM_LOG_LEVEL_WRN, "utest"); @@ -69,7 +67,6 @@ TEST(TDMLog, logDlogNone) TEST(TDMLog, logDlog) { tdm_log_enable_dlog(1); - tdm_log_enable_debug(1); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest"); tdm_log_print(TDM_LOG_LEVEL_WRN, "utest"); tdm_log_print(TDM_LOG_LEVEL_INFO, "utest"); @@ -79,7 +76,6 @@ TEST(TDMLog, logDlog) TEST(TDMLog, logDlogNormal) { tdm_log_enable_dlog(1); - tdm_log_enable_debug(0); tdm_log_print(TDM_LOG_LEVEL_ERR, "utest"); tdm_log_print(TDM_LOG_LEVEL_WRN, "utest"); tdm_log_print(TDM_LOG_LEVEL_INFO, "utest"); -- 2.7.4 From 174dde585e9e9ad3f34af6160371c70e06ce090e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:18:07 +0900 Subject: [PATCH 06/16] log: add tdm_log_print_stdout Change-Id: I9ee3b16818e868f75b7bb114182f293d94a278bc --- common/tdm_log.c | 54 ++++++++++++++++++++++++++++++++++++------------------ include/tdm_log.h | 2 ++ 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index aa3d182..348ea99 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -147,20 +147,50 @@ tdm_log_set_path(const char *path) } } -EXTERN void -tdm_log_print(int level, const char *fmt, ...) +static void +_tdm_log_vprint_stdout(int level, const char *fmt, va_list ap) { - va_list arg; - if (!log_lock_init) { log_lock_init = 1; pthread_mutex_init(&log_lock, NULL); - } if (level > tdm_log_debug_level) return; + char *lvl_str[] = {"TDM_NON", "TDM_ERR", "TDM_WRN", "TDM_INF", "TDM_DBG"}; + char *color[] = {COLOR_RESET, COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_RESET}; + + pthread_mutex_lock(&log_lock); + + if (color_enable) + printf("%s", color[level]); + printf("[%s]", lvl_str[level]); + if (color_enable) + printf(COLOR_RESET); + vprintf(fmt, ap); + printf("\n"); + pthread_mutex_unlock(&log_lock); +} + + +EXTERN void +tdm_log_print_stdout(int level, const char *fmt, ...) +{ + va_list arg; + va_start(arg, fmt); + _tdm_log_vprint_stdout(level, fmt, arg); + va_end(arg); +} + +EXTERN void +tdm_log_print(int level, const char *fmt, ...) +{ + va_list arg; + + if (level > tdm_log_debug_level) + return; + if (dlog_enable) { log_priority dlog_prio; switch (level) { @@ -183,21 +213,9 @@ tdm_log_print(int level, const char *fmt, ...) __dlog_vprint(LOG_ID_SYSTEM, dlog_prio, LOG_TAG, fmt, arg); va_end(arg); } else { - char *lvl_str[] = {"TDM_NON", "TDM_ERR", "TDM_WRN", "TDM_INF", "TDM_DBG"}; - char *color[] = {COLOR_RESET, COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_RESET}; - - pthread_mutex_lock(&log_lock); - - if (color_enable) - printf("%s", color[level]); - printf("[%s]", lvl_str[level]); - if (color_enable) - printf(COLOR_RESET); va_start(arg, fmt); - vprintf(fmt, arg); + _tdm_log_vprint_stdout(level, fmt, arg); va_end(arg); - printf("\n"); - pthread_mutex_unlock(&log_lock); } assert(level > assert_level); diff --git a/include/tdm_log.h b/include/tdm_log.h index 5a9fb65..e25f685 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -69,7 +69,9 @@ void tdm_log_enable_dlog(unsigned int enable); void tdm_log_set_debug_level(int level); void tdm_log_set_assert_level(int level); void tdm_log_set_path(const char *path); +void tdm_log_print_stdout(int level, const char *fmt, ...); void tdm_log_print(int level, const char *fmt, ...); + void tdm_log_reset(void); extern unsigned int tdm_log_debug_level; -- 2.7.4 From a1cca1d19c5d26aa9dfad12d88a27d0e16cdb606 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:19:25 +0900 Subject: [PATCH 07/16] backend: add checking mandatory functions Change-Id: Ib9262959482250f95e43f7016ece3bc96581dce6 --- src/tdm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tdm.c b/src/tdm.c index b904755..fca53dd 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -728,10 +728,20 @@ _tdm_display_check_backend_functions(tdm_private_module *private_module) /* below functions should be implemented in backend side */ TDM_RETURN_VAL_IF_FAIL(func_display != NULL, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_display->display_get_capability, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_display->display_get_outputs, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_output->output_get_capability, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_output->output_get_layers, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_wait_vblank, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_set_vblank_handler, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_commit, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_set_commit_handler, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_output->output_set_mode, TDM_ERROR_BAD_MODULE); TDM_RETURN_VAL_IF_FAIL(func_layer->layer_get_capability, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_set_info, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_get_info, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_set_buffer, TDM_ERROR_BAD_MODULE); + TDM_RETURN_VAL_IF_FAIL(func_layer->layer_unset_buffer, TDM_ERROR_BAD_MODULE); ret = func_display->display_get_capability(private_module->bdata, &private_module->caps_display); if (ret != TDM_ERROR_NONE) { -- 2.7.4 From 6fff5569f6cd0ff43969a6a57ba841db6afabb92 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:20:54 +0900 Subject: [PATCH 08/16] output: correct buffer leak when calling tdm_output_commit without a handler Change-Id: I032d556d6cab02d5bed3076e91fe57ed745a6bd3 --- src/tdm_layer.c | 31 +++++++++++++++---------------- src/tdm_output.c | 3 +++ src/tdm_private.h | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index f37a948..b36f37f 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -71,7 +71,6 @@ private_output = private_layer->private_output; \ private_display = private_output->private_display -static void _tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer); static void _tdm_layer_cb_wait_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data); static void _tbm_layer_queue_acquirable_cb(tbm_surface_queue_h surface_queue, void *data); @@ -347,8 +346,8 @@ _tdm_layer_dump_buffer(tdm_layer *layer, tbm_surface_h buffer) } /* LCOV_EXCL_STOP */ -static void -_tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer) +void +tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer) { tdm_private_display *private_display; @@ -380,7 +379,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) _tdm_layer_reset_pending_data(private_layer); if (private_layer->waiting_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); + tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); private_layer->waiting_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) @@ -389,7 +388,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) } if (private_layer->committed_buffer) { - _tdm_layer_free_buffer(private_layer, 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) @@ -398,7 +397,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) } if (private_layer->showing_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); + tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); private_layer->showing_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) @@ -416,7 +415,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) { LIST_DEL(&lm->link); tdm_output_remove_commit_handler_internal(private_output, _tdm_layer_cb_output_commit, lm); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); } @@ -429,7 +428,7 @@ _tdm_layer_free_all_buffers(tdm_private_layer *private_layer) LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &clone_list, link) { LIST_DEL(&lm->link); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); } @@ -598,7 +597,7 @@ tdm_layer_committed(tdm_private_layer *private_layer, tdm_private_layer_buffer * TDM_TRACE_ASYNC_END((intptr_t)private_layer, "[LAYER] %d", tbm_bo_export(bo)); } - _tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); + tdm_layer_free_buffer(private_layer, private_layer->showing_buffer); } private_layer->showing_buffer = *committed_buffer; @@ -650,7 +649,7 @@ _tdm_layer_got_output_vblank(tdm_private_output *private_output, unsigned int se lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data); _pthread_mutex_lock(&private_display->lock); if (lm->committed_buffer) - _tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); + tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); free(lm); } @@ -704,7 +703,7 @@ wait_failed: if (lm->func) lm->func(lm->private_layer, sequence, tv_sec, tv_usec, lm->user_data); _pthread_mutex_lock(&private_display->lock); - _tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); + tdm_layer_free_buffer(lm->private_layer, lm->committed_buffer); free(lm); } @@ -876,7 +875,7 @@ tdm_layer_commit_pending_data(tdm_private_layer *private_layer) if (ret == TDM_ERROR_NONE) { if (private_layer->waiting_buffer) - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); + tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); private_layer->waiting_buffer = layer_buffer; private_layer->waiting_buffer->buffer = tdm_buffer_ref_backend(private_layer->pending_buffer); @@ -884,7 +883,7 @@ tdm_layer_commit_pending_data(tdm_private_layer *private_layer) TDM_INFO("layer(%p) waiting_buffer(%p)", private_layer, private_layer->waiting_buffer->buffer); } else - _tdm_layer_free_buffer(private_layer, layer_buffer); + tdm_layer_free_buffer(private_layer, layer_buffer); } done: @@ -1070,7 +1069,7 @@ tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_hand if (lm->func == func && lm->user_data == user_data) { LIST_DEL(&lm->link); tdm_output_remove_commit_handler_internal(private_output, _tdm_layer_cb_output_commit, lm); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); break; } @@ -1080,7 +1079,7 @@ tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_hand if (lm->func == func && lm->user_data == user_data) { LIST_DEL(&lm->link); tdm_output_remove_commit_handler_internal(private_output, _tdm_layer_cb_output_commit, lm); - _tdm_layer_free_buffer(private_layer, lm->committed_buffer); + tdm_layer_free_buffer(private_layer, lm->committed_buffer); free(lm); break; } @@ -1223,7 +1222,7 @@ tdm_layer_set_buffer_queue(tdm_layer *layer, tbm_surface_queue_h buffer_queue) } if (private_layer->waiting_buffer) { - _tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); + tdm_layer_free_buffer(private_layer, private_layer->waiting_buffer); private_layer->waiting_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) diff --git a/src/tdm_output.c b/src/tdm_output.c index f208dfe..03dcd45 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1129,6 +1129,9 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl if (!private_layer->waiting_buffer) continue; + if (private_layer->committed_buffer) + tdm_layer_free_buffer(private_layer, private_layer->committed_buffer); + private_layer->committed_buffer = private_layer->waiting_buffer; private_layer->waiting_buffer = NULL; if (tdm_debug_module & TDM_DEBUG_BUFFER) diff --git a/src/tdm_private.h b/src/tdm_private.h index 4cb34e4..43c639c 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -147,6 +147,8 @@ tdm_error tdm_layer_set_buffer_internal(tdm_private_layer *private_layer, tbm_surface_h buffer); tdm_error tdm_layer_unset_buffer_internal(tdm_private_layer *private_layer); +void +tdm_layer_free_buffer(tdm_private_layer *private_layer, tdm_private_layer_buffer *layer_buffer); tdm_error tdm_vblank_init(tdm_display *dpy); -- 2.7.4 From 182bd92fc2e8a7b9e908a28283adcc600c64c875 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:21:19 +0900 Subject: [PATCH 09/16] output: add tdm_output_has_capture_capability Change-Id: Ida5763d36449c1bb7c2734e63bdbf25eb4b0d90b --- include/tdm.h | 9 +++++++++ src/tdm_output.c | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/tdm.h b/include/tdm.h index 19d30ba..bc1f0ef 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -548,6 +548,15 @@ tdm_error tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value); /** + * @brief Check if a output object has the capture capability + * @param[in] output A output object + * @param[out] has_capability 1: has the capability, 0: not has the capability + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_output_has_capture_capability(tdm_output *output, unsigned int *has_capability); + +/** * @brief Create a capture object of a output object * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. diff --git a/src/tdm_output.c b/src/tdm_output.c index 03dcd45..15ebd81 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1473,6 +1473,31 @@ tdm_output_get_dpms(tdm_output *output, tdm_output_dpms *dpms_value) return ret; } +EXTERN tdm_error +tdm_output_has_capture_capability(tdm_output *output, unsigned int *has_capability) +{ + tdm_private_module *private_module; + + OUTPUT_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(has_capability != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_output->private_module; + + if (!(private_module->capabilities & TDM_DISPLAY_CAPABILITY_CAPTURE)) + *has_capability = 0; + else if (!(private_module->caps_capture.capabilities & TDM_CAPTURE_CAPABILITY_OUTPUT)) + *has_capability = 0; + else + *has_capability = 1; + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + EXTERN tdm_capture * tdm_output_create_capture(tdm_output *output, tdm_error *error) { -- 2.7.4 From 988dbaba7a2c25420eafa70734e22e1c49057686 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 10:14:55 +0900 Subject: [PATCH 10/16] utests: correct pointer type Change-Id: I557633d3d01b90c00005b8e1b51df0e2afc485d7 --- utests/src/ut_tdm_layer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utests/src/ut_tdm_layer.cpp b/utests/src/ut_tdm_layer.cpp index a0713be..5b8042a 100644 --- a/utests/src/ut_tdm_layer.cpp +++ b/utests/src/ut_tdm_layer.cpp @@ -75,7 +75,7 @@ void TDMLayer::SetUp(void) ASSERT_TRUE(count > 0); layer_count += count; - layers = (tdm_layer**)realloc((void*)layers, sizeof(tdm_layer*) * layer_count); + layers = (tdm_layer**)realloc(layers, sizeof(tdm_layer*) * layer_count); ASSERT_TRUE(layers != NULL); for (int l = 0; l < count; l++) { -- 2.7.4 From 77461541c237f97f3b45a5db816fc8759d25aa75 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 7 Mar 2018 11:29:11 +0900 Subject: [PATCH 11/16] package version up to 1.16.0 Change-Id: I4c0c3ba7a7e7fc5ca7b8d618bc873e4d61df53dd --- configure.ac | 2 +- doc/tdm_doc.h | 2 +- packaging/libtdm.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 04bf549..1829d04 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.60]) m4_define([tdm_major_version], [1]) -m4_define([tdm_minor_version], [15]) +m4_define([tdm_minor_version], [16]) m4_define([tdm_micro_version], [0]) m4_define([tdm_version], [tdm_major_version.tdm_minor_version.tdm_micro_version]) diff --git a/doc/tdm_doc.h b/doc/tdm_doc.h index d11256f..b7e3529 100644 --- a/doc/tdm_doc.h +++ b/doc/tdm_doc.h @@ -39,7 +39,7 @@ /** * @mainpage TDM * @author Boram Park, boram1288.park@samsung.com - * @version 1.15.0 + * @version 1.16.0 * @par Introduction * TDM stands for Tizen Display Manager. It's the display HAL layer for tizen * display server. It offers the frontend APIs(@ref tdm.h) for a frontend user diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 9ca1257..2abebe3 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.15.1 +Version: 1.16.0 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From a5be69dc815078b1132eb3291d56cd7ddb85a412 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 15:39:18 +0900 Subject: [PATCH 12/16] output: add debugging log Change-Id: I0dd4ef4067e18706257619a1cfb2f6dea79f0657 --- src/tdm_output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tdm_output.c b/src/tdm_output.c index 15ebd81..b846354 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -766,6 +766,9 @@ _tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, vblank_handler->sent_to_frontend = 1; + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("output(%d) wait_vblank: handler(%p)", vblank_handler->private_output->pipe, vblank_handler); + ret = tdm_thread_cb_call(vblank_handler->private_output, &output_vblank.base); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } -- 2.7.4 From 1ffe57e554823b255a379390e220eac050417e5a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 15:39:37 +0900 Subject: [PATCH 13/16] utests: add more tc Change-Id: I304f08c9f390acdfd4a7935be4a404afaa6e6c63 --- utests/src/ut_tdm_output.cpp | 22 ++++++++++++++++++++++ utests/src/ut_tdm_vblank.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/utests/src/ut_tdm_output.cpp b/utests/src/ut_tdm_output.cpp index 4556178..e543a55 100644 --- a/utests/src/ut_tdm_output.cpp +++ b/utests/src/ut_tdm_output.cpp @@ -1334,6 +1334,28 @@ TEST_P(TDMOutput, OutputWaitVblankFewTimesInOneVblank) } } +TEST_P(TDMOutput, OutputWaitVblankBeforeDpmsOff) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + for (int o = 0; o < output_count; o++) { + if (!ut_tdm_output_is_connected(outputs[o])) + continue; + + ASSERT_TRUE(ut_tdm_output_prepare(dpy, outputs[o]) == true); + + for (int t = 0; t < 10; t++) { + bool done = false; + + ASSERT_TRUE(tdm_output_wait_vblank(outputs[o], 1, 0, _ut_tdm_output_done_cb, &done) == TDM_ERROR_NONE); + if (t == 9) + ASSERT_TRUE(tdm_output_set_dpms(outputs[o], TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE); + while(!done) + ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE); + } + } +} + TEST_P(TDMOutput, OutputRemoveVblankHandler) { TDM_UT_SKIP_FLAG(has_outputs); diff --git a/utests/src/ut_tdm_vblank.cpp b/utests/src/ut_tdm_vblank.cpp index a4d9f8b..3b3e8e3 100644 --- a/utests/src/ut_tdm_vblank.cpp +++ b/utests/src/ut_tdm_vblank.cpp @@ -1126,6 +1126,33 @@ TEST_P(TDMVblank, VblankWaitDpmsOff) } } +TEST_P(TDMVblank, VblankWaitBeforeDpmsOff) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + ASSERT_TRUE(TestPrepareOutput() == true); + ASSERT_TRUE(TestCreateVblanks() == true); + + for (int v = 0; v < vblank_count; v++) { + unsigned int temp = 0; + tdm_error ret; + tdm_output *output = tdm_vblank_get_output(vblanks[v], &ret); + ASSERT_TRUE(ret == TDM_ERROR_NONE); + + if (!ut_tdm_output_is_connected(output)) + continue; + + ASSERT_TRUE(ut_tdm_output_unset(dpy, output) == true); + + ASSERT_TRUE(tdm_vblank_wait(vblanks[v], 0, 0, 1, _ut_tdm_vblank_cb, &temp) == TDM_ERROR_NONE); + + ASSERT_TRUE(tdm_output_set_dpms(output, TDM_OUTPUT_DPMS_OFF) == TDM_ERROR_NONE); + + while (temp == 0) + ASSERT_TRUE(tdm_display_handle_events(dpy) == TDM_ERROR_NONE); + } +} + TEST_P(TDMVblank, VblankWaitSetEnableFakeDpmsOff) { TDM_UT_SKIP_FLAG(has_outputs); -- 2.7.4 From 7941cfbc65a4abcdc1e9c45716e0561348b0ed2a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 21:35:07 +0900 Subject: [PATCH 14/16] thread: checking waiting cb_type if waiting_cb_type != cb_type->type, send cb to other thread if needed. when a thread is waiting status, if other thread tries to send the same type cb as sync, we CAN'T handle it. So we'd better make assert it to find another solution. Change-Id: I06f92b2814a3a4e0d23d9d6df3c8b17526e1175f --- src/tdm_thread.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index db910c2..ca59103 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -613,6 +613,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) struct list_head *list, *other_list; struct list_head call_list; static pid_t waiting_tid = 0; + static tdm_thread_cb_type waiting_cb_type = TDM_THREAD_CB_NONE; tdm_error ret; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); @@ -626,6 +627,10 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) assert(find_funcs[cb_base->type] != NULL); + /* When there is the previous waiting sync call, the other type sync call CAN't be handlered */ + if (waiting_tid > 0 && cb_base->sync == 1) + assert(waiting_cb_type == cb_base->type); + if (!object) { object = find_funcs[cb_base->type](private_display, cb_base->object_stamp); if (!object) { @@ -670,7 +675,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) assert(LIST_IS_EMPTY(&call_list)); - if (waiting_tid == 0) { + if (waiting_tid == 0 || waiting_cb_type != cb_base->type) { LIST_FOR_EACH_ENTRY_SAFE(cb, hh, other_list, link) { if (cb->object != object || cb->cb_type != cb_base->type || @@ -686,6 +691,7 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) if (keep_private_thread) { if (cb_base->sync) { waiting_tid = 0; + waiting_cb_type = TDM_THREAD_CB_NONE; pthread_cond_signal(&keep_private_thread->event_cond); if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("pthread broadcase"); @@ -712,6 +718,8 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) */ tdm_mutex_locked = 0; waiting_tid = caller_tid; + waiting_cb_type = cb_base->type; + pthread_cond_wait(&keep_private_thread->event_cond, &private_display->lock); tdm_mutex_locked = 1; } -- 2.7.4 From 11b7cf91cd5f44d381bab1e6d5659b9da261a82a Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 8 Mar 2018 21:41:20 +0900 Subject: [PATCH 15/16] package version up to 1.16.1 Change-Id: I2ce18aa2791e733216d174f791cf190fe6d486f1 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 2abebe3..62b46e8 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.16.0 +Version: 1.16.1 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From dd84f199e0e855ca945bae239c152fa22147af53 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 12 Mar 2018 17:13:03 +0900 Subject: [PATCH 16/16] output: seperate output-status and output-dpms change Change-Id: I0fabb65405347dab1f8604827df00be274410091 --- src/tdm.c | 3 +- src/tdm_macro.h | 3 +- src/tdm_output.c | 98 ++++++++++++++++++++++++++++++++++--------------- src/tdm_private_types.h | 16 +++++--- src/tdm_thread.c | 13 ++++--- 5 files changed, 91 insertions(+), 42 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index fca53dd..7d80016 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -194,7 +194,8 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list, link) { LIST_DEL(&h->link); - tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, h); + tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, h); + tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_STATUS, NULL, tdm_output_thread_cb_change, h); free(h); } diff --git a/src/tdm_macro.h b/src/tdm_macro.h index e681337..80be131 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -244,7 +244,8 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, - { TDM_THREAD_CB_OUTPUT_CHANGE, "output-change" }, + { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, + { TDM_THREAD_CB_OUTPUT_DPMS, "output-dpms" }, { TDM_THREAD_CB_PP_DONE, "pp-done" }, { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, diff --git a/src/tdm_output.c b/src/tdm_output.c index b846354..e6eed12 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -146,7 +146,9 @@ tdm_output_init(tdm_private_display *private_display) { tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_COMMIT, tdm_display_find_output_stamp); tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_VBLANK, tdm_display_find_output_stamp); - tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_CHANGE, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_STATUS, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_DPMS, tdm_display_find_output_stamp); + return TDM_ERROR_NONE; } @@ -226,34 +228,68 @@ INTERN void tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { tdm_private_output *private_output = object; - tdm_thread_cb_output_change *output_change = (tdm_thread_cb_output_change *)cb_base; tdm_private_output_change_handler *change_handler = user_data; + tdm_output_change_type type = TDM_OUTPUT_CHANGE_CONNECTION; + tdm_value value = {.u32 = 0 }; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); assert(change_handler->owner_tid == syscall(SYS_gettid)); + if (cb_base->type == TDM_THREAD_CB_OUTPUT_STATUS) { + tdm_thread_cb_output_status *output_status = (tdm_thread_cb_output_status *)cb_base; + type = TDM_OUTPUT_CHANGE_CONNECTION; + value.u32 = output_status->status; + } else if (cb_base->type == TDM_THREAD_CB_OUTPUT_DPMS) { + tdm_thread_cb_output_dpms *output_dpms = (tdm_thread_cb_output_dpms *)cb_base; + type = TDM_OUTPUT_CHANGE_DPMS; + value.u32 = output_dpms->dpms; + } else { + TDM_NEVER_GET_HERE(); + return; + } + _pthread_mutex_unlock(&private_display->lock); - change_handler->func(private_output, output_change->type, output_change->value, change_handler->user_data); + change_handler->func(private_output, type, value, change_handler->user_data); _pthread_mutex_lock(&private_display->lock); + } static tdm_error -_tdm_output_call_thread_cb_change(tdm_private_output *private_output, tdm_output_change_type type, tdm_value value) +_tdm_output_call_thread_cb_status(tdm_private_output *private_output, tdm_output_conn_status status) { - tdm_thread_cb_output_change output_change; + tdm_thread_cb_output_status output_status; tdm_error ret; - memset(&output_change, 0, sizeof output_change); - output_change.base.type = TDM_THREAD_CB_OUTPUT_CHANGE; - output_change.base.length = sizeof output_change; - output_change.base.object_stamp = private_output->stamp; - output_change.base.data = NULL; - output_change.base.sync = 1; - output_change.type = type; - output_change.value = value; + memset(&output_status, 0, sizeof output_status); + output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS; + output_status.base.length = sizeof output_status; + output_status.base.object_stamp = private_output->stamp; + output_status.base.data = NULL; + output_status.base.sync = 1; + output_status.status = status; - ret = tdm_thread_cb_call(private_output, &output_change.base); + ret = tdm_thread_cb_call(private_output, &output_status.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + + return TDM_ERROR_NONE; +} + +static tdm_error +_tdm_output_call_thread_cb_dpms(tdm_private_output *private_output, tdm_output_dpms dpms) +{ + tdm_thread_cb_output_dpms output_dpms; + tdm_error ret; + + memset(&output_dpms, 0, sizeof output_dpms); + output_dpms.base.type = TDM_THREAD_CB_OUTPUT_DPMS; + output_dpms.base.length = sizeof output_dpms; + output_dpms.base.object_stamp = private_output->stamp; + output_dpms.base.data = NULL; + output_dpms.base.sync = 0; + output_dpms.dpms = dpms; + + ret = tdm_thread_cb_call(private_output, &output_dpms.base); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); return TDM_ERROR_NONE; @@ -263,7 +299,6 @@ INTERN void tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void *user_data) { tdm_private_output *private_output = user_data; - tdm_value value; tdm_error ret; TDM_RETURN_IF_FAIL(private_output); @@ -278,9 +313,7 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, private_output->caps.status = status; } - value.u32 = status; - - ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_CONNECTION, value); + ret = _tdm_output_call_thread_cb_status(private_output, status); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } @@ -288,7 +321,6 @@ INTERN void tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) { tdm_private_output *private_output = user_data; - tdm_value value; tdm_error ret; TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(dpms)); @@ -297,9 +329,7 @@ tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_ private_output->waiting_dpms_change = 0; TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); - value.u32 = dpms; - - ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + ret = _tdm_output_call_thread_cb_dpms(private_output, dpms); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } @@ -332,10 +362,21 @@ tdm_output_add_change_handler(tdm_output *output, /* LCOV_EXCL_STOP */ } - ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, change_handler); + if (ret != TDM_ERROR_NONE) { + /* LCOV_EXCL_START */ + TDM_ERR("tdm_thread_cb_add failed"); + free(change_handler); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OPERATION_FAILED; + /* LCOV_EXCL_STOP */ + } + + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_STATUS, NULL, tdm_output_thread_cb_change, change_handler); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ TDM_ERR("tdm_thread_cb_add failed"); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, change_handler); free(change_handler); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OPERATION_FAILED; @@ -375,7 +416,8 @@ tdm_output_remove_change_handler(tdm_output *output, if (change_handler->func != func || change_handler->user_data != user_data) continue; - tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_DPMS, NULL, tdm_output_thread_cb_change, change_handler); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_STATUS, NULL, tdm_output_thread_cb_change, change_handler); LIST_DEL(&change_handler->link); free(change_handler); @@ -1304,10 +1346,8 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) done: if (ret == TDM_ERROR_NONE) { if (private_output->current_dpms_value != dpms_value) { - tdm_value value; private_output->current_dpms_value = dpms_value; - value.u32 = dpms_value; - _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + _tdm_output_call_thread_cb_dpms(private_output, dpms_value); TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); } } else { @@ -1448,13 +1488,11 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) /* checking with backend's value */ if (*dpms_value != private_output->current_dpms_value) { - tdm_value value; TDM_ERR("output(%d) dpms changed suddenly: %s -> %s", private_output->pipe, tdm_dpms_str(private_output->current_dpms_value), tdm_dpms_str(*dpms_value)); private_output->current_dpms_value = *dpms_value; - value.u32 = *dpms_value; - _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + _tdm_output_call_thread_cb_dpms(private_output, *dpms_value); } return ret; diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index d1c132d..a5b4423 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -449,7 +449,8 @@ typedef enum { TDM_THREAD_CB_NONE, TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, - TDM_THREAD_CB_OUTPUT_CHANGE, + TDM_THREAD_CB_OUTPUT_STATUS, + TDM_THREAD_CB_OUTPUT_DPMS, TDM_THREAD_CB_PP_DONE, TDM_THREAD_CB_CAPTURE_DONE, TDM_THREAD_CB_VBLANK_SW, @@ -461,7 +462,8 @@ typedef enum { typedef struct _tdm_thread_cb_base tdm_thread_cb_base; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; -typedef struct _tdm_thread_cb_output_change tdm_thread_cb_output_change; +typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; +typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; typedef struct _tdm_thread_cb_pp_done tdm_thread_cb_pp_done; typedef struct _tdm_thread_cb_capture_done tdm_thread_cb_capture_done; typedef struct _tdm_thread_cb_vblank_sw tdm_thread_cb_vblank_sw; @@ -483,10 +485,14 @@ struct _tdm_thread_cb_output_vblank { unsigned int tv_usec; }; -struct _tdm_thread_cb_output_change { +struct _tdm_thread_cb_output_status { tdm_thread_cb_base base; - tdm_output_change_type type; - tdm_value value; + tdm_output_conn_status status; +}; + +struct _tdm_thread_cb_output_dpms { + tdm_thread_cb_base base; + tdm_output_dpms dpms; }; struct _tdm_thread_cb_pp_done { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index ca59103..b183c59 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -437,7 +437,8 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) switch (base->type) { case TDM_THREAD_CB_OUTPUT_COMMIT: case TDM_THREAD_CB_OUTPUT_VBLANK: - case TDM_THREAD_CB_OUTPUT_CHANGE: + case TDM_THREAD_CB_OUTPUT_STATUS: + case TDM_THREAD_CB_OUTPUT_DPMS: case TDM_THREAD_CB_PP_DONE: case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: @@ -620,16 +621,18 @@ tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) TDM_RETURN_VAL_IF_FAIL(cb_base != NULL, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(cb_base->type > 0, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(cb_base->length > 0, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 0 || cb_base->sync == 1, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(cb_base->object_stamp > 0, TDM_ERROR_INVALID_PARAMETER); caller_tid = syscall(SYS_gettid); assert(find_funcs[cb_base->type] != NULL); - /* When there is the previous waiting sync call, the other type sync call CAN't be handlered */ - if (waiting_tid > 0 && cb_base->sync == 1) - assert(waiting_cb_type == cb_base->type); + /* handling only output-status as sync */ + if (cb_base->type == TDM_THREAD_CB_OUTPUT_STATUS) { + TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 1, TDM_ERROR_INVALID_PARAMETER); + } else { + TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 0, TDM_ERROR_INVALID_PARAMETER); + } if (!object) { object = find_funcs[cb_base->type](private_display, cb_base->object_stamp); -- 2.7.4