From 782d100ad830459baaee9f46b179fd4998e80607 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 3 Apr 2018 16:26:13 +0900 Subject: [PATCH 01/16] add plantuml, dot files Change-Id: I99569149d5b46722426a97e8f59e39fa3db526bc --- doc/tdm_header.txt | 109 ++++++++++++++++++++++++++++++++++++++++++++ doc/tdm_thread.txt | 40 ++++++++++++++++ doc/tdm_thread_deadlock.txt | 40 ++++++++++++++++ 3 files changed, 189 insertions(+) create mode 100644 doc/tdm_header.txt create mode 100644 doc/tdm_thread.txt create mode 100644 doc/tdm_thread_deadlock.txt diff --git a/doc/tdm_header.txt b/doc/tdm_header.txt new file mode 100644 index 0000000..59c3cef --- /dev/null +++ b/doc/tdm_header.txt @@ -0,0 +1,109 @@ +#dot -Tpng a.dot -o a.png + +digraph G +{ + compound=true; + nodesep=0.2; + ranksep=0.5; + node [fontname=Courier,fontsize=10,width=0,height=0,shape=box]; + + { + node [fontname=Courier,fontsize=10,shape=plaintext,color=white]; + edge [style=invis]; + Lv0 -> Lv1 -> Lv2 -> Lv3 -> Lv4 -> Lv5 -> Lv6; + } + + { + rank=same; + Lv0; + "tdm_common.h"; + } + + { + rank=same; + Lv1; + + "tdm_types.h"; + "tdm_client_types.h"; + } + + { + rank=same; + Lv2; + + "tdm_list.h"; + "tdm_log.h"; + "tdm_helper.h"; + "tdm.h"; + "tdm_backend.h"; + "tdm_client.h"; + } + + { + rank=same; + Lv3; + + "tdm_private_types.h"; + } + + { + rank=same; + Lv4; + + "tdm_config.h"; + "tdm_thread.h"; + } + + + { + rank=same; + Lv5; + + "tdm_macro.h"; + } + + + { + rank=same; + Lv6; + + "tdm_private.h"; + } + + "tdm_list.h" [style="filled",fillcolor=gold]; + "tdm_log.h" [style="filled",fillcolor=gold]; + "tdm_helper.h" [style="filled",fillcolor=gold]; + + "tdm_private.h" [style="filled",fillcolor=grey]; + "tdm_private_types.h" [style="filled",fillcolor=grey]; + "tdm_config.h" [style="filled",fillcolor=grey]; + "tdm_macro.h" [style="filled",fillcolor=grey]; + "tdm_thread.h" [style="filled",fillcolor=grey]; + + "tdm_backend.h" [style="filled",fillcolor=darkorchid1]; + "tdm.h" [style="filled",fillcolor=cornflowerblue]; + + "tdm_client.h" [style="filled",fillcolor= skyblue]; + + "tdm_client_types.h" -> "tdm_common.h"; + "tdm_client.h" -> "tdm_client_types.h"; + "tdm_types.h" -> "tdm_common.h"; + "tdm.h" -> "tdm_types.h"; + "tdm_helper.h" -> "tdm_types.h"; + "tdm_backend.h" -> "tdm_types.h"; + "tdm_macro.h" -> "tdm_private_types.h"; + "tdm_macro.h" -> "tdm_thread.h"; + "tdm_thread.h" -> "tdm_private_types.h"; + "tdm_private_types.h" -> "tdm_types.h"; + "tdm_private_types.h" -> "tdm_list.h"; + "tdm_private_types.h" -> "tdm_log.h"; + "tdm_private_types.h" -> "tdm_backend.h"; + "tdm_config.h" -> "tdm_private_types.h"; + "tdm_private.h" -> "tdm_private_types.h"; + "tdm_private.h" -> "tdm_macro.h"; + "tdm_private.h" -> "tdm_helper.h"; + "tdm_private.h" -> "tdm_config.h"; + "tdm_private.h" -> "tdm_thread.h"; + + "tdm_private_types.h" -> "tdm.h"; +} diff --git a/doc/tdm_thread.txt b/doc/tdm_thread.txt new file mode 100644 index 0000000..5e6f28f --- /dev/null +++ b/doc/tdm_thread.txt @@ -0,0 +1,40 @@ +@startuml + +hide footbox + +participant "E20 main thread" as main +participant "tdm thread" as sub + +== an asynchronous event == +sub <-- : an asynchronous event +activate sub + sub -> sub: calling thread callbacks in tdm-thread + activate sub + deactivate sub + main <-- sub: sending an asynchronous event +deactivate sub +activate main +main -> main: calling thread callbacks in main-thread +activate main +deactivate main +deactivate main + +== a synchronous event == +sub <-- : a synchronous event +activate sub + sub -> sub: calling thread callbacks in tdm-thread + activate sub + deactivate sub + sub --> main: sending a synchronous event + activate main + sub -> sub: pthread_cond_wait + activate sub + main -> main: calling thread callbacks in main-thread + activate main + deactivate main + main --> sub: pthread_cond_signal + deactivate sub + deactivate main +deactivate sub + +@enduml diff --git a/doc/tdm_thread_deadlock.txt b/doc/tdm_thread_deadlock.txt new file mode 100644 index 0000000..3a01697 --- /dev/null +++ b/doc/tdm_thread_deadlock.txt @@ -0,0 +1,40 @@ +@startuml + +hide footbox + +participant "E20 main thread" as main +participant "tdm thread" as sub + +sub <-- : a synchronous event +activate sub +--> main: a synchronous event +activate main +sub -> sub: calling thread callbacks in tdm-thread +activate sub +deactivate sub +sub --> main: sending a synchronous event +sub -> sub: pthread_cond_wait +activate sub +main -> main: calling thread callbacks in main-thread +activate main +deactivate main +main --> sub: sending a synchronous event +main -> main: pthread_cond_wait +activate main +deactivate sub +deactivate main +deactivate main +deactivate sub + +... (DEADLOCK) ... +note over main, sub + * 만약 main-thread, tdm-thread에서 동시에 synchronous event가 발생되게 되면 deadlock발생됨 + - 양쪽에서 모두 pthread_cond_wait에서 대기 + * sync event는 한쪽 thread에서만 발생되도록 보장되어야 함. + - tdm-thread -> main-thread방향으로만 sync event전달만 허용 + * sync event의 종류 + - backend에서 스스로 발생되는 event들만 가능 + - output status변경중에 connection/disconnection, virtual output creation/destruction +end note + +@enduml -- 2.7.4 From 04ab8db6936dfb9a5d1f91a7ab3ccf78f13d0af0 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 3 Apr 2018 16:46:34 +0900 Subject: [PATCH 02/16] config: not export tdm_config function to backend Change-Id: I2c8d162912c0971e6be5443c18535df81055eca7 --- include/tdm_backend.h | 22 ---------------------- src/tdm_config.h | 38 ++++++++++++++++++++++++++++++++++++-- src/tdm_private.h | 3 +++ 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 970cbc4..0416a90 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -1443,28 +1443,6 @@ tdm_event_loop_source_timer_update(tdm_event_loop_source *source, unsigned int m void tdm_event_loop_source_remove(tdm_event_loop_source *source); -/** - * @brief Get the ini value with given key - * @details - * @param[in] key The given key - * @param[in] default_value The default value - * @return the value of given key if success. Otherwise, default_value. - * @see #tdm_config_get_string - */ -int -tdm_config_get_int(const char *key, int default_value); - -/** - * @brief Get the ini value with given key - * @details - * @param[in] key The given key - * @param[in] default_value The default value - * @return the value of given key if success. Otherwise, default_value. - * @see #tdm_config_get_int - */ -const char * -tdm_config_get_string(const char *key, const char *default_value); - /** * @brief Trigger a 'need to validate' event. diff --git a/src/tdm_config.h b/src/tdm_config.h index b6a34ba..73eeb9f 100644 --- a/src/tdm_config.h +++ b/src/tdm_config.h @@ -49,11 +49,45 @@ extern "C" { * @brief The config header file for a frontend library */ -void -tdm_config_deinit(void); +/** + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_string + */ +int +tdm_config_get_int(const char *key, int default_value); + +/** + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_int + */ +const char * +tdm_config_get_string(const char *key, const char *default_value); +/** + * @brief Set the ini value with given key + * @details + * @param[in] key The given key + * @param[in] value The value + * @return TDM_ERROR_NONE if success. Otherwise, error value. + */ tdm_error tdm_config_set_int(const char *key, int value); + +/** + * @brief Set the ini value with given key + * @details + * @param[in] key The given key + * @param[in] value The value + * @return TDM_ERROR_NONE if success. Otherwise, error value. + */ tdm_error tdm_config_set_string(const char *key, const char *value); diff --git a/src/tdm_private.h b/src/tdm_private.h index 9b1951d..40f9e79 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -238,6 +238,9 @@ tdm_error tdm_display_enable_fps(tdm_private_display *private_display, int enable); void +tdm_config_deinit(void); + +void tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len); #ifdef __cplusplus -- 2.7.4 From 46142c8a75ff9d1008abab34f090d79600658ba7 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 3 Apr 2018 17:04:00 +0900 Subject: [PATCH 03/16] doc: fix carriage return Change-Id: I850997b73174ff25e60b59c33e52b0b8cb89d1bc --- doc/tdm_thread.txt | 80 ++++++++++++++++++++++----------------------- doc/tdm_thread_deadlock.txt | 71 ++++++++++++++++++---------------------- 2 files changed, 71 insertions(+), 80 deletions(-) diff --git a/doc/tdm_thread.txt b/doc/tdm_thread.txt index 5e6f28f..71bf7a3 100644 --- a/doc/tdm_thread.txt +++ b/doc/tdm_thread.txt @@ -1,40 +1,40 @@ -@startuml - -hide footbox - -participant "E20 main thread" as main -participant "tdm thread" as sub - -== an asynchronous event == -sub <-- : an asynchronous event -activate sub - sub -> sub: calling thread callbacks in tdm-thread - activate sub - deactivate sub - main <-- sub: sending an asynchronous event -deactivate sub -activate main -main -> main: calling thread callbacks in main-thread -activate main -deactivate main -deactivate main - -== a synchronous event == -sub <-- : a synchronous event -activate sub - sub -> sub: calling thread callbacks in tdm-thread - activate sub - deactivate sub - sub --> main: sending a synchronous event - activate main - sub -> sub: pthread_cond_wait - activate sub - main -> main: calling thread callbacks in main-thread - activate main - deactivate main - main --> sub: pthread_cond_signal - deactivate sub - deactivate main -deactivate sub - -@enduml +@startuml + +hide footbox + +participant "E20 main thread" as main +participant "tdm thread" as sub + +== an asynchronous event == +sub <-- : an asynchronous event +activate sub +sub -> sub: calling thread callbacks in tdm-thread +activate sub +deactivate sub +main <-- sub: sending an asynchronous event +deactivate sub +activate main +main -> main: calling thread callbacks in main-thread +activate main +deactivate main +deactivate main + +== a synchronous event == +sub <-- : a synchronous event +activate sub +sub -> sub: calling thread callbacks in tdm-thread +activate sub +deactivate sub +sub --> main: sending a synchronous event +activate main +sub -> sub: pthread_cond_wait +activate sub +main -> main: calling thread callbacks in main-thread +activate main +deactivate main +main --> sub: pthread_cond_signal +deactivate sub +deactivate main +deactivate sub + +@enduml diff --git a/doc/tdm_thread_deadlock.txt b/doc/tdm_thread_deadlock.txt index 3a01697..85cca6f 100644 --- a/doc/tdm_thread_deadlock.txt +++ b/doc/tdm_thread_deadlock.txt @@ -1,40 +1,31 @@ -@startuml - -hide footbox - -participant "E20 main thread" as main -participant "tdm thread" as sub - -sub <-- : a synchronous event -activate sub ---> main: a synchronous event -activate main -sub -> sub: calling thread callbacks in tdm-thread -activate sub -deactivate sub -sub --> main: sending a synchronous event -sub -> sub: pthread_cond_wait -activate sub -main -> main: calling thread callbacks in main-thread -activate main -deactivate main -main --> sub: sending a synchronous event -main -> main: pthread_cond_wait -activate main -deactivate sub -deactivate main -deactivate main -deactivate sub - -... (DEADLOCK) ... -note over main, sub - * 만약 main-thread, tdm-thread에서 동시에 synchronous event가 발생되게 되면 deadlock발생됨 - - 양쪽에서 모두 pthread_cond_wait에서 대기 - * sync event는 한쪽 thread에서만 발생되도록 보장되어야 함. - - tdm-thread -> main-thread방향으로만 sync event전달만 허용 - * sync event의 종류 - - backend에서 스스로 발생되는 event들만 가능 - - output status변경중에 connection/disconnection, virtual output creation/destruction -end note - -@enduml +@startuml + +hide footbox + +participant "E20 main thread" as main +participant "tdm thread" as sub + +sub <-- : a synchronous event +activate sub +--> main: a synchronous event +activate main +sub -> sub: calling thread callbacks in tdm-thread +activate sub +deactivate sub +sub --> main: sending a synchronous event +sub -> sub: pthread_cond_wait +activate sub +main -> main: calling thread callbacks in main-thread +activate main +deactivate main +main --> sub: sending a synchronous event +main -> main: pthread_cond_wait +activate main +deactivate sub +deactivate main +deactivate main +deactivate sub + +... (DEADLOCK) ... + +@enduml -- 2.7.4 From aa70cc4a91cfcc516231964af272bbe6299d9490 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 3 Apr 2018 17:04:40 +0900 Subject: [PATCH 04/16] doc: update dot file Change-Id: I6cfe80a55147c2bf9ef22b4e095c2c2607dc43b0 --- doc/tdm_header.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/tdm_header.txt b/doc/tdm_header.txt index 59c3cef..37be79c 100644 --- a/doc/tdm_header.txt +++ b/doc/tdm_header.txt @@ -98,7 +98,7 @@ digraph G "tdm_private_types.h" -> "tdm_list.h"; "tdm_private_types.h" -> "tdm_log.h"; "tdm_private_types.h" -> "tdm_backend.h"; - "tdm_config.h" -> "tdm_private_types.h"; + "tdm_config.h" -> "tdm_common.h"; "tdm_private.h" -> "tdm_private_types.h"; "tdm_private.h" -> "tdm_macro.h"; "tdm_private.h" -> "tdm_helper.h"; -- 2.7.4 From 96d1f3519412969af72a04bc4ebf811911310011 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 3 Apr 2018 17:24:03 +0900 Subject: [PATCH 05/16] event_loop: destroy clients before destroying display Change-Id: I6e143aa8446d6cd1e3c5567604dac227b647d6fe --- src/tdm_event_loop.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index 2e7fbbd..b7de4ab 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -162,6 +162,10 @@ tdm_event_loop_deinit(tdm_private_display *private_display) tdm_event_loop_source_remove(source); } +#if WAYLAND_VERSION_MAJOR >= 1 && WAYLAND_VERSION_MINOR >= 15 + wl_display_destroy_clients(private_display->private_loop->wl_display); +#endif + wl_display_destroy(private_display->private_loop->wl_display); free(private_display->private_loop); -- 2.7.4 From 929734f3059260852503ec3f34304e471d31b23d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 6 Apr 2018 16:38:59 +0900 Subject: [PATCH 06/16] utests: add excluding coverage comments Change-Id: I8533054065c261c059294bc3f8101f64d1623ab3 --- utests/src/ut_tdm.h | 4 +++ utests/src/ut_tdm_backend_capture.cpp | 3 ++ utests/src/ut_tdm_backend_display.cpp | 4 +++ utests/src/ut_tdm_backend_env.cpp | 4 +++ utests/src/ut_tdm_backend_pp.cpp | 4 +++ utests/src/ut_tdm_buffer.cpp | 4 +++ utests/src/ut_tdm_client.cpp | 67 +++++++++++++++++++++++++++++------ utests/src/ut_tdm_display.cpp | 24 ++++++++++++- utests/src/ut_tdm_env.cpp | 4 +++ utests/src/ut_tdm_event_loop.cpp | 4 +++ utests/src/ut_tdm_helper.cpp | 4 +++ utests/src/ut_tdm_hwc_window.cpp | 6 +++- utests/src/ut_tdm_layer.cpp | 4 +++ utests/src/ut_tdm_log.cpp | 3 ++ utests/src/ut_tdm_main.cpp | 6 +++- utests/src/ut_tdm_output.cpp | 6 +++- utests/src/ut_tdm_output_hwc.cpp | 4 +++ utests/src/ut_tdm_vblank.cpp | 24 ++++++++++++- 18 files changed, 163 insertions(+), 16 deletions(-) diff --git a/utests/src/ut_tdm.h b/utests/src/ut_tdm.h index 63662e1..b7265fa 100644 --- a/utests/src/ut_tdm.h +++ b/utests/src/ut_tdm.h @@ -18,6 +18,8 @@ extern "C" { #include } +/* LCOV_EXCL_START */ + #include "tdm.h" #include "tdm_helper.h" #include "tdm_config.h" @@ -255,4 +257,6 @@ char ut_tdm_backend_getchar(void); } \ } while (0) +/* LCOV_EXCL_STOP */ + #endif // _UT_TDM_H_ diff --git a/utests/src/ut_tdm_backend_capture.cpp b/utests/src/ut_tdm_backend_capture.cpp index 07a1033..8eca5d6 100644 --- a/utests/src/ut_tdm_backend_capture.cpp +++ b/utests/src/ut_tdm_backend_capture.cpp @@ -30,6 +30,7 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ class TDMBackendCapture : public TDMBackendDisplay { public: @@ -1078,3 +1079,5 @@ INSTANTIATE_TEST_CASE_P(TDMBackendCaptureParams, TDMBackendCapture, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_backend_display.cpp b/utests/src/ut_tdm_backend_display.cpp index b0afa59..a5dd08e 100644 --- a/utests/src/ut_tdm_backend_display.cpp +++ b/utests/src/ut_tdm_backend_display.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + #define TDM_UT_BACKEND_TEST_CNT 20 TDMBackendBasic::TDMBackendBasic() @@ -1427,3 +1429,5 @@ INSTANTIATE_TEST_CASE_P(TDMBackendDisplayParams, TDMBackendDisplay, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_backend_env.cpp b/utests/src/ut_tdm_backend_env.cpp index 4c9bbbf..72a7f92 100644 --- a/utests/src/ut_tdm_backend_env.cpp +++ b/utests/src/ut_tdm_backend_env.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + bool enable_porting_debug = false; void TDMBackendEnv::SetUp(void) @@ -77,3 +79,5 @@ INSTANTIATE_TEST_CASE_P(TDMBackendEnvParams, TDMBackendEnv, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_backend_pp.cpp b/utests/src/ut_tdm_backend_pp.cpp index 794046c..d7545ac 100644 --- a/utests/src/ut_tdm_backend_pp.cpp +++ b/utests/src/ut_tdm_backend_pp.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + class TDMBackendPP : public TDMBackendDisplay { public: @@ -854,3 +856,5 @@ INSTANTIATE_TEST_CASE_P(TDMBackendPPParams, TDMBackendPP, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_buffer.cpp b/utests/src/ut_tdm_buffer.cpp index 10ec508..ec03dba 100644 --- a/utests/src/ut_tdm_buffer.cpp +++ b/utests/src/ut_tdm_buffer.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + class TDMBuffer : public TDMDisplay { public: @@ -293,3 +295,5 @@ INSTANTIATE_TEST_CASE_P(TDMBufferParams, TDMBuffer, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_client.cpp b/utests/src/ut_tdm_client.cpp index b44ef46..e72510a 100644 --- a/utests/src/ut_tdm_client.cpp +++ b/utests/src/ut_tdm_client.cpp @@ -38,6 +38,8 @@ #include "ut_tdm.h" #include "tdm_client.h" +/* LCOV_EXCL_START */ + enum { TDM_UT_PIPE_MSG_NONE, TDM_UT_PIPE_MSG_REPLY, @@ -452,25 +454,31 @@ TEST_P(TDMClient, ClientGetFdNullOther) ASSERT_EQ(tdm_client_get_fd(client, NULL), TDM_ERROR_INVALID_PARAMETER); } +static void +_ut_tdm_client_vblank_cb(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + bool *done = (bool *)user_data; + if (done) + *done = true; +} + /* tdm_client_handle_events_timeout */ -TEST_P(TDMClient, DISABLED_ClientHandleEvent) +TEST_P(TDMClient, ClientHandleEvent) { + bool done = false; + ASSERT_EQ(PrepareClient(), true); -// ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE); -} + ASSERT_EQ(tdm_client_wait_vblank(client, NULL, 1, 1, 0, _ut_tdm_client_vblank_cb, &done), TDM_ERROR_NONE); + ASSERT_EQ(done, false); -TEST_P(TDMClient, ClientHandleEventNullObject) -{ - ASSERT_EQ(tdm_client_handle_events_timeout(NULL, 3000), TDM_ERROR_INVALID_PARAMETER); + while (!done) + ASSERT_EQ(tdm_client_handle_events(client), TDM_ERROR_NONE); } -static void -_ut_tdm_client_vblank_cb(unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) +TEST_P(TDMClient, ClientHandleEventNullObject) { - bool *done = (bool *)user_data; - if (done) - *done = true; + ASSERT_EQ(tdm_client_handle_events(NULL), TDM_ERROR_INVALID_PARAMETER); } /* tdm_client_wait_vblank, deprecated */ @@ -1315,6 +1323,41 @@ TEST_P(TDMClient, ClientVblankWaitSetEnableFakeDpmsOff) ASSERT_EQ(tdm_client_output_get_dpms(output, &dpms), TDM_ERROR_NONE); } +/* tdm_client_vblank_wait */ +TEST_P(TDMClient, ClientVblankIsWaiting) +{ + bool done; + unsigned int waiting; + + ASSERT_EQ(PrepareClient(), true); + ASSERT_EQ(PrepareOutput(), true); + ASSERT_EQ(PrepareVblank(), true); + + done = false; + ASSERT_EQ(tdm_client_vblank_wait(vblank, 1, _ut_tdm_client_vblank_cb2, &done), TDM_ERROR_NONE); + + waiting = tdm_client_vblank_is_waiting(vblank); + ASSERT_EQ(waiting, 1); + + start = tdm_helper_get_time(); + while (!done) + ASSERT_EQ(tdm_client_handle_events_timeout(client, 3000), TDM_ERROR_NONE); + end = tdm_helper_get_time(); + + /* "+ vrefresh_interval" consider the delay of socket communication between kernel and platform */ + ASSERT_LT((end - start), (vrefresh_interval + vrefresh_interval)); + + waiting = tdm_client_vblank_is_waiting(vblank); + ASSERT_EQ(waiting, 0); +} + +/* tdm_client_vblank_wait */ +TEST_P(TDMClient, ClientVblankIsWaitingNullObject) +{ + unsigned int waiting = tdm_client_vblank_is_waiting(NULL); + ASSERT_EQ(waiting, 0); +} + #ifdef TDM_UT_TEST_WITH_PARAMS INSTANTIATE_TEST_CASE_P(TDMClientParams, TDMClient, @@ -1324,3 +1367,5 @@ INSTANTIATE_TEST_CASE_P(TDMClientParams, TDMClient, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_display.cpp b/utests/src/ut_tdm_display.cpp index 1548a5e..2476999 100644 --- a/utests/src/ut_tdm_display.cpp +++ b/utests/src/ut_tdm_display.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + TDMDisplay::TDMDisplay() { dpy = NULL; @@ -368,6 +370,24 @@ TEST_P(TDMDisplay, DisplayGetOutputWrongIndex) ASSERT_EQ(output, NULL); } +TEST_P(TDMDisplay, DisplayFindOutput) +{ + tdm_output *output; + int count = TDM_UT_INVALID_VALUE; + tdm_error ret; + + ASSERT_EQ(tdm_display_get_output_count(dpy, &count), TDM_ERROR_NONE); + ASSERT_GT(count, 0); + + output = tdm_display_find_output(dpy, "primary", &ret); + ASSERT_EQ(ret, TDM_ERROR_NONE); + ASSERT_NE(output, NULL); + + output = tdm_display_find_output(dpy, "invalid", &ret); + ASSERT_EQ(ret, TDM_ERROR_NONE); + ASSERT_EQ(output, NULL); +} + TEST_P(TDMDisplay, DisplayCreatePp) { tdm_pp *pp; @@ -474,4 +494,6 @@ INSTANTIATE_TEST_CASE_P(TDMDisplayParams, INSTANTIATE_TEST_CASE_P(TDMDisplayParams, TDMDisplay, Values(TDM_DEFAULT_MODULE)); -#endif \ No newline at end of file +#endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_env.cpp b/utests/src/ut_tdm_env.cpp index 25915aa..e773e39 100644 --- a/utests/src/ut_tdm_env.cpp +++ b/utests/src/ut_tdm_env.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + void TDMEnv::SetUp(void) { const char *test_backend; @@ -152,3 +154,5 @@ INSTANTIATE_TEST_CASE_P(TDMEnvParams, TDMEnv, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_event_loop.cpp b/utests/src/ut_tdm_event_loop.cpp index 3fffecb..d7f5b6a 100644 --- a/utests/src/ut_tdm_event_loop.cpp +++ b/utests/src/ut_tdm_event_loop.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + class TDMEventLoop : public TDMDisplay { public: @@ -218,3 +220,5 @@ INSTANTIATE_TEST_CASE_P(TDMEventLoopParams, TDMEventLoop, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_helper.cpp b/utests/src/ut_tdm_helper.cpp index b9ad342..5aa34b1 100644 --- a/utests/src/ut_tdm_helper.cpp +++ b/utests/src/ut_tdm_helper.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + class TDMHelper : public TDMOutput { public: @@ -508,3 +510,5 @@ INSTANTIATE_TEST_CASE_P(TDMHelperParams, TDMHelper, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index 23bae31..12be19c 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + #define HWC_WIN_NUM 5 class TDMHwcWindow : public TDMOutput @@ -468,4 +470,6 @@ INSTANTIATE_TEST_CASE_P(TDMHwcWindowParams, INSTANTIATE_TEST_CASE_P(TDMHwcWindowParams, TDMHwcWindow, Values(TDM_DEFAULT_MODULE)); -#endif \ No newline at end of file +#endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_layer.cpp b/utests/src/ut_tdm_layer.cpp index d178de7..d1eb318 100644 --- a/utests/src/ut_tdm_layer.cpp +++ b/utests/src/ut_tdm_layer.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + #define BORDER_SIZE 20 class TDMLayer : public TDMOutput @@ -1500,3 +1502,5 @@ INSTANTIATE_TEST_CASE_P(TDMLayerParams, TDMLayer, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_log.cpp b/utests/src/ut_tdm_log.cpp index e8fee79..e399742 100644 --- a/utests/src/ut_tdm_log.cpp +++ b/utests/src/ut_tdm_log.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + TEST(TDMLog, logPrintf) { tdm_log_enable_color(1); @@ -86,3 +88,4 @@ TEST(TDMLog, logDlogUnknownLevel) tdm_log_print(TDM_UT_INVALID_VALUE, "utest"); } +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_main.cpp b/utests/src/ut_tdm_main.cpp index 8ed5556..bc1b1bc 100644 --- a/utests/src/ut_tdm_main.cpp +++ b/utests/src/ut_tdm_main.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + int tdm_debug_module; int main(int argc, char **argv) @@ -61,4 +63,6 @@ int main(int argc, char **argv) #endif return AllTestSuccess; -} \ No newline at end of file +} + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_output.cpp b/utests/src/ut_tdm_output.cpp index 227b3e2..2559517 100644 --- a/utests/src/ut_tdm_output.cpp +++ b/utests/src/ut_tdm_output.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + static void _ut_tdm_output_change_cb(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data); static void _ut_tdm_output_change_cb2(tdm_output *output, tdm_output_change_type type, tdm_value value, void *user_data); @@ -1708,4 +1710,6 @@ INSTANTIATE_TEST_CASE_P(TDMOutputParams, INSTANTIATE_TEST_CASE_P(TDMOutputParams, TDMOutput, Values(TDM_DEFAULT_MODULE)); -#endif \ No newline at end of file +#endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_output_hwc.cpp b/utests/src/ut_tdm_output_hwc.cpp index d99b0a0..e84860d 100644 --- a/utests/src/ut_tdm_output_hwc.cpp +++ b/utests/src/ut_tdm_output_hwc.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + class TDMOutputHwc : public TDMOutput { public: @@ -449,3 +451,5 @@ INSTANTIATE_TEST_CASE_P(TDMOutputHwcParams, TDMOutputHwc, Values(TDM_DEFAULT_MODULE)); #endif + +/* LCOV_EXCL_END */ \ No newline at end of file diff --git a/utests/src/ut_tdm_vblank.cpp b/utests/src/ut_tdm_vblank.cpp index b9ae767..5a6584c 100644 --- a/utests/src/ut_tdm_vblank.cpp +++ b/utests/src/ut_tdm_vblank.cpp @@ -30,6 +30,8 @@ #include "ut_tdm.h" +/* LCOV_EXCL_START */ + static void _ut_tdm_vblank_create_cb(tdm_vblank *vblank, void *user_data); static void _ut_tdm_vblank_create_cb2(tdm_vblank *vblank, void *user_data); @@ -1409,6 +1411,24 @@ TEST_P(TDMVblank, DISABLED_VblankWaitBeforeDpmsOff) /* wait vblank -> dpms off -> then? (vblank handler is called? or not?) */ } +TEST_P(TDMVblank, VblankWaitTimeout) +{ + TDM_UT_SKIP_FLAG(has_outputs); + + ASSERT_EQ(TestPrepareOutput(), true); + ASSERT_EQ(TestCreateVblanks(), true); + + if (vblank_count > 0) { + tdm_vblank *vblank = vblanks[0]; + unsigned int cur_seq = 0; + + ASSERT_EQ(tdm_vblank_wait(vblank, 0, 0, 1, _ut_tdm_vblank_cb, &cur_seq), TDM_ERROR_NONE); + usleep(1200000); + while (cur_seq == 0) + ASSERT_EQ(ut_tdm_display_handle_events(dpy), TDM_ERROR_NONE); + } +} + #ifdef TDM_UT_TEST_WITH_PARAMS INSTANTIATE_TEST_CASE_P(TDMVblankParams, TDMVblank, @@ -1417,4 +1437,6 @@ INSTANTIATE_TEST_CASE_P(TDMVblankParams, INSTANTIATE_TEST_CASE_P(TDMVblankParams, TDMVblank, Values(TDM_DEFAULT_MODULE)); -#endif \ No newline at end of file +#endif + +/* LCOV_EXCL_END */ \ No newline at end of file -- 2.7.4 From 44b1aa829d5b6c774925b596c6161a630aa3f4d4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 6 Apr 2018 16:40:25 +0900 Subject: [PATCH 07/16] common: add excluding coverage comments Change-Id: I3608620a3fd494a1416dfb53df057241e074f114 --- src/tdm_backend.c | 4 ++++ src/tdm_display.c | 2 ++ src/tdm_hwc_window.c | 49 +++---------------------------------------------- src/tdm_macro.h | 2 ++ src/tdm_output.c | 42 ++---------------------------------------- 5 files changed, 13 insertions(+), 86 deletions(-) diff --git a/src/tdm_backend.c b/src/tdm_backend.c index 238d085..8be51f0 100644 --- a/src/tdm_backend.c +++ b/src/tdm_backend.c @@ -131,6 +131,7 @@ tdm_backend_register_func_layer(tdm_display *dpy, tdm_func_layer *func_layer) return TDM_ERROR_NONE; } +/* LCOV_EXCL_START */ EXTERN tdm_error tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func_hwc_window) { @@ -155,6 +156,7 @@ tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func return TDM_ERROR_NONE; } +/* LCOV_EXCL_STOP */ EXTERN tdm_error tdm_backend_register_func_pp(tdm_display *dpy, tdm_func_pp *func_pp) @@ -204,6 +206,7 @@ tdm_backend_register_func_capture(tdm_display *dpy, return TDM_ERROR_NONE; } +/* LCOV_EXCL_START */ /* backend operates itself types */ static tdm_private_output* _look_for_frontend_hwc_output(tdm_output *backend_output) @@ -247,3 +250,4 @@ tdm_backend_trigger_need_validate_event(tdm_output *output) return TDM_ERROR_NONE; } +/* LCOV_EXCL_STOP */ diff --git a/src/tdm_display.c b/src/tdm_display.c index d2fcde4..9f66167 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -61,6 +61,7 @@ private_module = (tdm_private_module*)module; \ private_display = private_module->private_display; +/* LCOV_EXCL_START */ INTERN tdm_error tdm_display_enable_debug_module(const char*modules) { @@ -346,6 +347,7 @@ tdm_display_enable_fps(tdm_private_display *private_display, int enable) return TDM_ERROR_NONE; } +/* LCOV_EXCL_STOP */ EXTERN tdm_error tdm_display_get_capabilities(tdm_display *dpy, diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index c3619ed..8ef8042 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -39,6 +39,8 @@ #include "tdm_private.h" +/* LCOV_EXCL_START */ + #define COUNT_MAX 10 #define HWC_WINDOW_FUNC_ENTRY() \ @@ -86,13 +88,11 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); if (error) *error = TDM_ERROR_NOT_IMPLEMENTED; return NULL; - /* LCOV_EXCL_STOP */ } queue = func_hwc_window->hwc_window_get_tbm_buffer_queue(private_hwc_window->hwc_window_backend, error); @@ -119,11 +119,9 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_set_composition_type) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_set_composition_type(private_hwc_window->hwc_window_backend, composition_type); @@ -149,11 +147,9 @@ tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region dama func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_set_buffer_damage) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_set_buffer_damage(private_hwc_window->hwc_window_backend, damage); @@ -181,11 +177,9 @@ tdm_hwc_window_set_info(tdm_hwc_window *hwc_window, tdm_hwc_window_info *info) func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_set_info) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } if (info->src_config.format) @@ -220,23 +214,19 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) _pthread_mutex_lock(&private_display->lock); if ((tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) && buffer) { - /* LCOV_EXCL_START */ char str[TDM_PATH_LEN]; static int i; snprintf(str, TDM_PATH_LEN, "window_%d_%03d", private_output->index, i++); tdm_helper_dump_buffer_str(buffer, tdm_debug_dump_dir, str); - /* LCOV_EXCL_STOP */ } private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_set_buffer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_set_buffer(private_hwc_window->hwc_window_backend, buffer); @@ -260,11 +250,9 @@ tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window) func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_unset_buffer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_unset_buffer(private_hwc_window->hwc_window_backend); @@ -289,11 +277,9 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, if (!is_video) { if (!func_output->output_hwc_create_window) { - /* LCOV_EXCL_START */ if (error) *error = TDM_ERROR_BAD_MODULE; return NULL; - /* LCOV_EXCL_STOP */ } hwc_window_backend = func_output->output_hwc_create_window( @@ -305,11 +291,9 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, } } else { if (!func_output->output_hwc_create_video_window) { - /* LCOV_EXCL_START */ if (error) *error = TDM_ERROR_NOT_IMPLEMENTED; return NULL; - /* LCOV_EXCL_STOP */ } hwc_window_backend = func_output->output_hwc_create_video_window( @@ -323,13 +307,11 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window)); if (!private_hwc_window) { - /* LCOV_EXCL_START */ TDM_ERR("failed: alloc memory"); func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend); if (error) *error = TDM_ERROR_OUT_OF_MEMORY; return NULL; - /* LCOV_EXCL_STOP */ } LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list); @@ -384,11 +366,9 @@ tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_set_flags) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags); @@ -412,11 +392,9 @@ tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_unset_flags) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags); @@ -461,21 +439,17 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_get_layer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend, &ret); if (!layer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("no assigned layer!!"); return TDM_ERROR_INVALID_PARAMETER; - /* LCOV_EXCL_STOP */ } private_layer = (tdm_private_layer*)layer; @@ -487,36 +461,28 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler else ret = tdm_layer_unset_buffer_internal(private_layer); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: layer set buffer(window)"); - /* LCOV_EXCL_STOP */ return ret; } ret = func_hwc_window->hwc_window_get_info(private_hwc_window->hwc_window_backend, &window_info); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: commit layer(window)"); - /* LCOV_EXCL_STOP */ return ret; } info_layer = (tdm_info_layer *)&window_info; ret = tdm_layer_set_info_internal(private_layer, info_layer); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: layer set info(window)"); - /* LCOV_EXCL_STOP */ return ret; } hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler)); if (!hwc_window_commit_handler) { - /* LCOV_EXCL_START */ TDM_ERR("failed: alloc memory"); return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ } hwc_window_commit_handler->private_hwc_window = private_hwc_window; @@ -525,10 +491,8 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, hwc_window_commit_handler); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: commit layer(window)"); free(hwc_window_commit_handler); - /* LCOV_EXCL_STOP */ return ret; } @@ -554,11 +518,9 @@ tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_video_get_capability) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend, @@ -587,11 +549,9 @@ tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_video_get_available_properties) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend, @@ -619,11 +579,9 @@ tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_video_get_property) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend, @@ -649,11 +607,9 @@ tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, func_hwc_window = &private_module->func_hwc_window; if (!func_hwc_window->hwc_window_video_set_property) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend, @@ -663,3 +619,4 @@ tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, return ret; } +/* LCOV_EXCL_STOP */ \ No newline at end of file diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 00af3ef..a84b82a 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -103,6 +103,7 @@ extern "C" { #define TDM_OUTPUT_DPMS_VSYNC_IS_OFF(dpms) ((dpms) & TDM_OUTPUT_DPMS_VSYNC_OFF_MASK) /* strtostr *****************************************************************/ +/* LCOV_EXCL_START */ static inline char* strtostr(char *buf, int len, char *str, char *delim) { @@ -117,6 +118,7 @@ strtostr(char *buf, int len, char *str, char *delim) snprintf(buf, len, "%s", str); return str + len - 1; } +/* LCOV_EXCL_STOP */ /* EXTERN, INTERN, DEPRECATED ***********************************************/ #undef EXTERN diff --git a/src/tdm_output.c b/src/tdm_output.c index 6543b7d..9b9d200 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1563,6 +1563,7 @@ tdm_output_create_capture(tdm_output *output, tdm_error *error) return capture; } +/* LCOV_EXCL_START */ EXTERN tdm_hwc_window * tdm_output_hwc_create_window(tdm_output *output, tdm_error *error) { @@ -1575,11 +1576,9 @@ tdm_output_hwc_create_window(tdm_output *output, tdm_error *error) if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 0, error); else { - /* LCOV_EXCL_START */ TDM_ERR("output(%p) not support HWC", private_output); if (error) *error = TDM_ERROR_BAD_REQUEST; - /* LCOV_EXCL_STOP */ } _pthread_mutex_unlock(&private_display->lock); @@ -1599,11 +1598,9 @@ tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error) if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 1, error); else { - /* LCOV_EXCL_START */ TDM_ERR("output(%p) not support HWC", private_output); if (error) *error = TDM_ERROR_BAD_REQUEST; - /* LCOV_EXCL_STOP */ } _pthread_mutex_unlock(&private_display->lock); @@ -1653,11 +1650,9 @@ tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, func_output = &private_module->func_output; if (!func_output->output_hwc_validate) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } if (num_wnds == 0) { @@ -1670,10 +1665,8 @@ tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *)); if (!composited_wnds_backend) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ } composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds; @@ -1747,20 +1740,16 @@ tdm_output_hwc_get_changed_composition_types(tdm_output *output, func_output = &private_module->func_output; if (!func_output->output_hwc_get_changed_composition_types) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_output->output_hwc_get_changed_composition_types(private_output->output_backend, num_elements, hwc_window, composition_types); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); return ret; - /* LCOV_EXCL_STOP */ } if (hwc_window == NULL || composition_types == NULL) { @@ -1773,13 +1762,11 @@ tdm_output_hwc_get_changed_composition_types(tdm_output *output, private_hwc_window = _tdm_output_find_private_hwc_window(private_output, hwc_window[i]); if (private_hwc_window == NULL) { - /* LCOV_EXCL_START */ TDM_ERR("failed! This should never happen!"); func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window[i]); *num_elements = 0; _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OPERATION_FAILED; - /* LCOV_EXCL_STOP */ } hwc_window[i] = (tdm_hwc_window*)private_hwc_window; @@ -1810,11 +1797,9 @@ tdm_output_hwc_accept_changes(tdm_output *output) func_output = &private_module->func_output; if (!func_output->output_hwc_validate) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_output->output_hwc_accept_changes(private_output->output_backend); @@ -1847,11 +1832,9 @@ tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error) func_output = &private_module->func_output; if (!func_output->output_hwc_get_target_buffer_queue) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return NULL; - /* LCOV_EXCL_STOP */ } queue = func_output->output_hwc_get_target_buffer_queue(private_output->output_backend, error); @@ -1878,24 +1861,20 @@ tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target } if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) { - /* LCOV_EXCL_START */ char str[TDM_PATH_LEN]; static int i; snprintf(str, TDM_PATH_LEN, "target_window_%d_%03d", private_output->index, i++); tdm_helper_dump_buffer_str(target_buffer, tdm_debug_dump_dir, str); - /* LCOV_EXCL_STOP */ } private_module = private_output->private_module; func_output = &private_module->func_output; if (!func_output->output_hwc_set_client_target_buffer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_output->output_hwc_set_client_target_buffer(private_output->output_backend, target_buffer, damage); @@ -1925,11 +1904,9 @@ tdm_output_hwc_unset_client_target_buffer(tdm_output *output) func_output = &private_module->func_output; if (!func_output->output_hwc_unset_client_target_buffer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_output->output_hwc_unset_client_target_buffer(private_output->output_backend); @@ -1979,31 +1956,25 @@ tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_ta func_output = &private_module->func_output; if (!func_output->output_hwc_get_client_target_buffer_layer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } layer = func_output->output_hwc_get_client_target_buffer_layer(private_output->output_backend, &ret); if (!layer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("no assigned layer!!"); return TDM_ERROR_INVALID_PARAMETER; - /* LCOV_EXCL_STOP */ } private_layer = (tdm_private_layer*)layer; if (!func_output->output_hwc_get_client_target_buffer) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_ERR("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } buffer = func_output->output_hwc_get_client_target_buffer(private_output->output_backend, @@ -2013,10 +1984,8 @@ tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_ta else ret = tdm_layer_unset_buffer_internal(private_layer); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: layer set info(window)"); _pthread_mutex_unlock(&private_display->lock); - /* LCOV_EXCL_STOP */ return ret; } @@ -2036,10 +2005,8 @@ tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_ta ret = tdm_layer_set_info_internal(private_layer, &private_output->target_buffer_info); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: layer set info(window)"); _pthread_mutex_unlock(&private_display->lock); - /* LCOV_EXCL_STOP */ return ret; } @@ -2048,11 +2015,9 @@ tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_ta output_hwc_target_buffer_commit_handler = calloc(1, sizeof(tdm_private_output_hwc_target_buffer_commit_handler)); if (!output_hwc_target_buffer_commit_handler) { - /* LCOV_EXCL_START */ TDM_ERR("failed: alloc memory"); _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ } output_hwc_target_buffer_commit_handler->private_output = private_output; @@ -2061,11 +2026,9 @@ tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_ta ret = tdm_layer_commit_internal(private_layer, _tdm_output_hwc_layer_commit_handler, output_hwc_target_buffer_commit_handler); if (ret != TDM_ERROR_NONE) { - /* LCOV_EXCL_START */ TDM_ERR("failed: commit layer(target buffer)"); free(output_hwc_target_buffer_commit_handler); _pthread_mutex_unlock(&private_display->lock); - /* LCOV_EXCL_STOP */ return ret; } @@ -2091,11 +2054,9 @@ tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format func_output = &private_module->func_output; if (!func_output->output_hwc_get_video_supported_formats) { - /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; - /* LCOV_EXCL_STOP */ } ret = func_output->output_hwc_get_video_supported_formats( @@ -2232,3 +2193,4 @@ tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int return TDM_ERROR_NONE; } +/* LCOV_EXCL_STOP */ -- 2.7.4 From c5d34acb3cd217e269f9215b2fa64d8a7b4b55d6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 6 Apr 2018 16:42:06 +0900 Subject: [PATCH 08/16] buffer: remove unuseful function the behavior of tdm_buffer_remove_release_handler_internal is not clear. even if commit is failed, the buffer release function seems to need to be called. Change-Id: Idbf92ea109272d5556680ed87212095126d8b1cf --- src/tdm_buffer.c | 20 -------------------- src/tdm_capture.c | 6 ------ src/tdm_pp.c | 8 -------- src/tdm_private.h | 2 -- 4 files changed, 36 deletions(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 81716b5..97857b4 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -170,26 +170,6 @@ tdm_buffer_remove_release_handler(tbm_surface_h buffer, } } -INTERN void -tdm_buffer_remove_release_handler_internal(tbm_surface_h buffer) -{ - tdm_buffer_info *buf_info; - tdm_buffer_func_info *func_info = NULL, *next = NULL; - - TDM_RETURN_IF_FAIL(buffer != NULL); - - buf_info = tdm_buffer_get_info(buffer); - TDM_RETURN_IF_FAIL(buf_info != NULL); - - LIST_FOR_EACH_ENTRY_SAFE(func_info, next, &buf_info->release_funcs, link) { - - LIST_DEL(&func_info->link); - free(func_info); - - return; - } -} - EXTERN tbm_surface_h tdm_buffer_ref_backend(tbm_surface_h buffer) { diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 4b58fbd..1fd5bb4 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -663,12 +663,6 @@ tdm_capture_commit(tdm_capture *capture) if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ - /* Not to call the user release handler when failed. - * Do we have to call this function here really? - * User better use set_done_handler to know when pp is done. Using - * buffer_release_handler is not good. - */ - tdm_buffer_remove_release_handler_internal(b->buffer); _pthread_mutex_unlock(&private_display->lock); tdm_buffer_unref_backend(b->buffer); diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 1a0e91e..a53531a 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -573,14 +573,6 @@ tdm_pp_commit(tdm_pp *pp) continue; if (ret != TDM_ERROR_NONE) { - /* Not to call the user release handler when failed. - * Do we have to call this function here really? - * User better use set_done_handler to know when pp is done. Using - * buffer_release_handler is not good. - */ - tdm_buffer_remove_release_handler_internal(b->src); - tdm_buffer_remove_release_handler_internal(b->dst); - _pthread_mutex_unlock(&private_display->lock); tdm_buffer_unref_backend(b->src); tdm_buffer_unref_backend(b->dst); diff --git a/src/tdm_private.h b/src/tdm_private.h index 40f9e79..22c984c 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -187,8 +187,6 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture); /* utility buffer functions for private */ tdm_buffer_info* tdm_buffer_get_info(tbm_surface_h buffer); -void -tdm_buffer_remove_release_handler_internal(tbm_surface_h buffer); /* event functions for private */ tdm_error -- 2.7.4 From 3ad3e82dc0bc043697fc72d34c5cf7d051b69af4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 9 Apr 2018 20:43:57 +0900 Subject: [PATCH 09/16] common: remove unuseful variable Change-Id: I1f47f58fb65b5b18f08e64b790e11c4c195e1c32 --- src/tdm.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 15840f4..1a84fc0 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -477,19 +477,17 @@ tdm_display_update_output(tdm_private_module *private_module, return TDM_ERROR_NONE; } -static tdm_output ** +static void _tdm_display_set_main_first(tdm_output **outputs, int index) { tdm_output *output_tmp = NULL; if (index == 0) - return outputs; + return; output_tmp = outputs[0]; outputs[0] = outputs[index]; outputs[index] = output_tmp; - - return outputs; } static tdm_output ** @@ -497,7 +495,6 @@ _tdm_display_get_ordered_outputs(tdm_private_module *private_module, int *count) { tdm_func_display *func_display = &private_module->func_display; tdm_output **outputs = NULL; - tdm_output **new_outputs = NULL; tdm_output *output_dsi = NULL; tdm_output *output_lvds = NULL; tdm_output *output_hdmia = NULL; @@ -580,32 +577,28 @@ _tdm_display_get_ordered_outputs(tdm_private_module *private_module, int *count) if (output_connected_count == 0) { /* hdmi > dsi > lvds > else */ if (output_hdmia != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmia); + _tdm_display_set_main_first(outputs, index_hdmia); else if (output_hdmib != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmib); + _tdm_display_set_main_first(outputs, index_hdmib); else if (output_dsi != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_dsi); + _tdm_display_set_main_first(outputs, index_dsi); else if (output_lvds != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_lvds); - else - new_outputs = outputs; + _tdm_display_set_main_first(outputs, index_lvds); } else { /* (output_connected_count > 1) */ /* dsi > lvds > hdmi > else */ if (output_dsi != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_dsi); + _tdm_display_set_main_first(outputs, index_dsi); else if (output_lvds != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_lvds); + _tdm_display_set_main_first(outputs, index_lvds); else if (output_hdmia != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmia); + _tdm_display_set_main_first(outputs, index_hdmia); else if (output_hdmib != NULL) - new_outputs = _tdm_display_set_main_first(outputs, index_hdmib); - else - new_outputs = outputs; + _tdm_display_set_main_first(outputs, index_hdmib); } - private_module->outputs = new_outputs; + private_module->outputs = outputs; - return new_outputs; + return outputs; failed_get_outputs: free(outputs); -- 2.7.4 From e3bf909bf70dabcee8bb28a68fdb75b1a93fc671 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 9 Apr 2018 20:44:18 +0900 Subject: [PATCH 10/16] common: fix syntax error Change-Id: Ib6c52268e151511ba4aef5f15a84ac2adcba993b --- src/tdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tdm.c b/src/tdm.c index 1a84fc0..08a9136 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -883,7 +883,7 @@ static tdm_error _tdm_display_load_modules(tdm_private_display *private_display) { const char *module_names; - tdm_error ret = 0; + tdm_error ret = TDM_ERROR_NONE; char temp[TDM_PATH_LEN]; char *arg; char *end; -- 2.7.4 From d6ada65f4863702f6d7d5c1080b408e332fb8923 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 9 Apr 2018 21:15:59 +0900 Subject: [PATCH 11/16] common: remove unuseful condition output_get_capability can't be null at this function. checking null is already done in other function. Change-Id: I737ab197eba4763cc6afbfd65d8b8e8183c4a122 --- src/tdm.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 08a9136..be3d0bf 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -528,11 +528,6 @@ _tdm_display_get_ordered_outputs(tdm_private_module *private_module, int *count) tdm_caps_output caps; memset(&caps, 0, sizeof(tdm_caps_output)); - if (!func_output->output_get_capability) { - TDM_ERR("no output_get_capability()"); - goto failed_get_outputs; - } - ret = func_output->output_get_capability(outputs[i], &caps); if (ret != TDM_ERROR_NONE) { TDM_ERR("output_get_capability() failed"); -- 2.7.4 From 547570439aa623b2f46197c3362e65f0af93dec1 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 9 Apr 2018 21:18:37 +0900 Subject: [PATCH 12/16] display: find the correct output To find a primary output, we have to check the connection status first. If there is no connected output, this function will return the first output. Change-Id: If386dcabc6524ce81a1f08c87082342a259278f3 --- src/tdm_display.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/src/tdm_display.c b/src/tdm_display.c index 9f66167..45ccdf2 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -634,18 +634,50 @@ tdm_display_find_output(tdm_display *dpy, const char *name, tdm_error *error) { tdm_private_module *private_module = NULL; tdm_private_output *private_output = NULL; + tdm_private_output *mode_setted_output = NULL; + tdm_private_output *connected_output = NULL; + unsigned int find_primary = 0; DISPLAY_FUNC_ENTRY_ERROR(); - if (!strncasecmp(name, "primary", 7) || !strncasecmp(name, "default", 7)) { - return tdm_display_get_output(dpy, 0, error); - } + if (!strncasecmp(name, "primary", 7) || !strncasecmp(name, "default", 7)) + find_primary = 1; _pthread_mutex_lock(&private_display->lock); if (error) *error = TDM_ERROR_NONE; + if (find_primary) { + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_CONNECTED && !connected_output) + connected_output = private_output; + else if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_MODE_SETTED && !mode_setted_output) + mode_setted_output = private_output; + } + } + + if (mode_setted_output) { + _pthread_mutex_unlock(&private_display->lock); + return mode_setted_output; + } + + if (connected_output) { + _pthread_mutex_unlock(&private_display->lock); + return connected_output; + } + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (private_output->index == 0) { + _pthread_mutex_unlock(&private_display->lock); + return private_output; + } + } + } + } + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { if (strncmp(private_output->caps.model, name, TDM_NAME_LEN)) -- 2.7.4 From ff24c59c2316df5e88162fb202df293873f60c17 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 11 Apr 2018 08:52:09 +0900 Subject: [PATCH 13/16] hwc: add omitted unlocks Change-Id: I7631a2a6d9549a5361a05de2ccdc3a65b0452b6c --- src/tdm_hwc_window.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 8ef8042..25692b3 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -462,6 +462,7 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler ret = tdm_layer_unset_buffer_internal(private_layer); if (ret != TDM_ERROR_NONE) { TDM_ERR("failed: layer set buffer(window)"); + _pthread_mutex_unlock(&private_display->lock); return ret; } @@ -469,6 +470,7 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler &window_info); if (ret != TDM_ERROR_NONE) { TDM_ERR("failed: commit layer(window)"); + _pthread_mutex_unlock(&private_display->lock); return ret; } @@ -476,12 +478,14 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler ret = tdm_layer_set_info_internal(private_layer, info_layer); if (ret != TDM_ERROR_NONE) { TDM_ERR("failed: layer set info(window)"); + _pthread_mutex_unlock(&private_display->lock); return ret; } hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler)); if (!hwc_window_commit_handler) { TDM_ERR("failed: alloc memory"); + _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_OUT_OF_MEMORY; } @@ -493,6 +497,7 @@ tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler if (ret != TDM_ERROR_NONE) { TDM_ERR("failed: commit layer(window)"); free(hwc_window_commit_handler); + _pthread_mutex_unlock(&private_display->lock); return ret; } -- 2.7.4 From 7590648039833576048af41891ca3eccc2ed57b9 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Wed, 11 Apr 2018 13:22:34 +0900 Subject: [PATCH 14/16] package version up to 1.16.13 Change-Id: Icacee006b6aad474889c50a0b615bd432db69e0c --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 493b7b7..c7855e4 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.16.12 +Version: 1.16.13 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 08707fc90dc3c6adccea7a958ed6a58604990aee Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 30 Mar 2018 20:08:55 +0900 Subject: [PATCH 15/16] hwc: redesign the hwc change the frontend apis for hwc change the backend apis for hwc remove the useless codes Change-Id: I7571dfb817140ebc25a3bbff77dffb7edae2ff35 --- include/tdm.h | 444 +++++++++++----------------- include/tdm_backend.h | 476 +++++++++++++----------------- include/tdm_common.h | 10 - include/tdm_types.h | 56 ++-- src/Makefile.am | 1 + src/tdm.c | 163 ++++++++--- src/tdm_backend.c | 71 ++--- src/tdm_hwc.c | 550 ++++++++++++++++++++++++++++++++++ src/tdm_hwc_window.c | 491 +++++++++---------------------- src/tdm_macro.h | 2 +- src/tdm_output.c | 615 +-------------------------------------- src/tdm_private.h | 17 +- src/tdm_private_types.h | 56 ++-- src/tdm_thread.c | 2 +- utests/Makefile.am | 2 - utests/src/ut_tdm_hwc_window.cpp | 159 ++-------- utests/src/ut_tdm_output_hwc.cpp | 142 ++++----- 17 files changed, 1377 insertions(+), 1880 deletions(-) create mode 100644 src/tdm_hwc.c diff --git a/include/tdm.h b/include/tdm.h index 0f9bf5d..7beccd0 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -567,199 +567,14 @@ tdm_capture * tdm_output_create_capture(tdm_output *output, tdm_error *error); /** - * @brief Creates a new window on the given display. + * @brief Get a hwc associated with a output object. * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object - * @since 2.0.0 - */ -tdm_hwc_window * -tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); - -/** - * @brief Creates a new video window on the given output. - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object - * @since 2.0.0 - */ -tdm_hwc_window * -tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error); - -/** - * @brief Destroys the given window. - * @param[in] output A output object - * @param[in] window the pointer of the window to destroy - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window); - -/** - * @brief Set the client(relative to the TDM) target buffer - * @details Sets the buffer which will receive the output of client composition. - * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE - * will be composited into this buffer prior to the call to tdm_output_commit(), - * and windows not marked as TDM_COMPOSITION_CLIENT and - * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the - * device. - * - * The buffer handle provided may be null if no windows are being composited by - * the client. This must not result in an error (unless an invalid display - * handle is also provided). - * - * The damage parameter describes a buffer damage region as defined in the - * description of tdm_hwc_window_set_buffer_damage(). - * - * List of composited hwc_windows (hwc_windows which buffers are presented on #target_buffer) - * should be passed along with #target_buffer to allow tdm to make the smooth transition - * from a DEVICE type to a CLIENT type. - * - * Should be called before tdm_output_commit() if any of the layers are marked as - * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are - * so marked, then it is not necessary to call this function. It is not necessary - * to call tdm_output_hwc_validate() after changing the target through this function. - * @param[in] output A output object - * @param[in] target_buffer The new target buffer - * @param[in] damage The buffer damage region - * @param[in] composited_wnds The array of composited hwc_wnds - * @param[in] num_wnds The size of #composited_wnds array - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage); - -/** - * @brief Unset the client(relative to the TDM) target buffer - * @details TODO - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_unset_client_target_buffer(tdm_output *output); - -/** - * @brief Commit changes for a target_window - * @details After all change of a window object are applied, a user commit handler - * will be called. - * @param[in] hwc_window A window object - * @param[in] func A user commit handler - * @param[in] user_data The user data - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data); - -/** - * @brief Validate the output - * @details Instructs the device to inspect all of the layer state and - * determine if there are any composition type changes necessary before - * presenting the output. Permitted changes are described in the definition - * of tdm_hwc_window_composition_t above. - * @param[in] output A output object - * @param[out] num_types The number of composition type changes required by - * the device; if greater than 0, the client must either set and validate new - * types, or call tdm_output_hwc_accept_changes() to accept the changes returned by - * tdm_output_hwc_get_changed_composition_types(); must be the same as the number of - * changes returned by tdm_output_hwc_get_changed_composition_types (see the - * declaration of that function for more information); pointer will be non-NULL - * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A hwc object * @since 2.0.0 */ -tdm_error -tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, - uint32_t *num_types); - -/** - * @brief Set the 'need to validate' handler for the 'output' - * - * @details During backend's work it may need to ask for the revalidation - * (make client (E20) do tdm_output_hwc_validate() again), so a 'hndl' will - * be called as such need happen. Only one handler per output is supported. - * - * @param[in] output The output object a hndl is going to be registered for. - * @param[in] hndl The handler which will be called on the 'need to validate' event. - * - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_set_need_validate_handler(tdm_output *output, - tdm_output_need_validate_handler hndl); - -/** - * @brief Get changed composition types - * @details Retrieves the windows for which the device requires a different - * composition type than had been set prior to the last call to tdm_output_hwc_validate(). - * The client will either update its state with these types and call - * tdm_output_hwc_accept_changes, or will set new types and attempt to validate the - * display again. - * windows and types may be NULL to retrieve the number of elements which - * will be returned. The number of elements returned must be the same as the - * value returned in num_types from the last call to tdm_output_hwc_validate(). - * @param[in] output A output object - * @param[out] num_elements If windows or types were NULL, the number of layers - * and types which would have been returned; if both were non-NULL, the - * number of elements returned in layers and types, which must not exceed - * the value stored in num_elements prior to the call; pointer will be - * non-NULL - * @param[in] output A output object - * @param[out] windows An array of windows - * @param[out] composition_types An array of composition types, each corresponding - * to an element of windows - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -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); - -/** - * @brief Accepts the changes required by the device - * @details Accepts the changes required by the device from the previous - * tdm_output_hwc_validate() call (which may be queried using - * tdm_output_get_chaged_composition_types()) and revalidates the display. This - * function is equivalent to requesting the changed types from - * tdm_output_get_chaged_composition_types(), setting those types on the - * corresponding windows, and then calling tdm_output_hwc_validate again. - * After this call it must be valid to present this display. Calling this after - * tdm_output_hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but - * should have no other effect. - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_output_hwc_accept_changes(tdm_output *output); - -/** - * @brief Get a target buffer queue - * @details Buffers from target buffer queue will receive the output of - * client composition. Window marked as TDM_COMPOSITION_CLIENT or - * TDM_COMPOSITION_DEVICE_CANDIDATE will be composited into this buffers - * prior to the call to tdm_output_commit(). - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A buffer queue - * @since 2.0.0 - */ -tbm_surface_queue_h -tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); - -/** - * @brief Get the supported format array for video hwc windows of a output object. - * @param[in] output A output object - * @param[out] formats The available format array - * @param[out] count The count of formats - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_output_hwc_get_video_supported_formats(tdm_layer *layer, const tbm_format **formats, - int *count); +tdm_hwc * +tdm_output_get_hwc(tdm_output *output, tdm_error *error); /** * @brief Get a output object of a layer object @@ -1000,6 +815,173 @@ tdm_error tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags); /** + * @brief Creates a new window on the given hwc. + * @param[in] hwc A hwc object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A created window object + * @since 2.0.0 + */ +tdm_hwc_window * +tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error); + +/** + * @brief Get the supported format array for hwc windows of a hwc object. + * @param[in] hwc A output hwc + * @param[out] formats The available format array + * @param[out] count The count of formats + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count); + +/** + * @brief Get the available property array of a hwc object. + * @param[in] hwc A hwc + * @param[out] props The available property array + * @param[out] count The count of properties + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count); + +/** + * @brief Get a target buffer queue + * @details Buffers from target buffer queue will receive the output of + * client composition. Window marked as TDM_COMPOSITION_CLIENT or + * TDM_COMPOSITION_DEVICE_CANDIDATE will be composited into this buffers + * prior to the call to tdm_output_commit(). + * @param[in] output A output object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A buffer queue + * @since 2.0.0 + */ +tbm_surface_queue_h +tdm_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error); + +/** + * @brief Set the client(relative to the TDM) target buffer + * @details Sets the buffer which will receive the output of client composition. + * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE + * will be composited into this buffer prior to the call to tdm_output_commit(), + * and windows not marked as TDM_COMPOSITION_CLIENT and + * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the + * device. + * + * The buffer handle provided may be null if no windows are being composited by + * the client. This must not result in an error (unless an invalid display + * handle is also provided). + * + * The damage parameter describes a buffer damage region as defined in the + * description of tdm_hwc_window_set_buffer_damage(). + * + * List of composited hwc_windows (hwc_windows which buffers are presented on #target_buffer) + * should be passed along with #target_buffer to allow tdm to make the smooth transition + * from a DEVICE type to a CLIENT type. + * + * Should be called before tdm_output_commit() if any of the layers are marked as + * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are + * so marked, then it is not necessary to call this function. It is not necessary + * to call tdm_hwc_validate() after changing the target through this function. + * @param[in] hwc A output hwc + * @param[in] target_buffer The new target buffer + * @param[in] damage The buffer damage region + * @param[in] composited_wnds The array of composited hwc_wnds + * @param[in] num_wnds The size of #composited_wnds array + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_region damage); + +/** + * @brief Validate the output + * @details Instructs the device to inspect all of the layer state and + * determine if there are any composition type changes necessary before + * presenting the output. Permitted changes are described in the definition + * of tdm_hwc_window_composition_t above. + * @param[in] output A output object + * @param[out] num_types The number of composition type changes required by + * the device; if greater than 0, the client must either set and validate new + * types, or call tdm_hwc_accept_changes() to accept the changes returned by + * tdm_hwc_get_changed_composition_types(); must be the same as the number of + * changes returned by tdm_hwc_get_changed_composition_types (see the + * declaration of that function for more information); pointer will be non-NULL + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, + uint32_t *num_types); + +/** + * @brief Get changed composition types + * @details Retrieves the windows for which the device requires a different + * composition type than had been set prior to the last call to tdm_hwc_validate(). + * The client will either update its state with these types and call + * tdm_hwc_accept_changes, or will set new types and attempt to validate the + * display again. + * windows and types may be NULL to retrieve the number of elements which + * will be returned. The number of elements returned must be the same as the + * value returned in num_types from the last call to tdm_hwc_validate(). + * @param[in] output A output object + * @param[out] num_elements If windows or types were NULL, the number of layers + * and types which would have been returned; if both were non-NULL, the + * number of elements returned in layers and types, which must not exceed + * the value stored in num_elements prior to the call; pointer will be + * non-NULL + * @param[in] output A output object + * @param[out] windows An array of windows + * @param[out] composition_types An array of composition types, each corresponding + * to an element of windows + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types); + +/** + * @brief Accepts the changes required by the device + * @details Accepts the changes required by the device from the previous + * tdm_hwc_validate() call (which may be queried using + * tdm_hwc_get_chaged_composition_types()) and revalidates the display. This + * function is equivalent to requesting the changed types from + * tdm_hwc_get_chaged_composition_types(), setting those types on the + * corresponding windows, and then calling tdm_hwc_validate again. + * After this call it must be valid to present this display. Calling this after + * tdm_hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but + * should have no other effect. + * @param[in] output A output object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ +tdm_error +tdm_hwc_accept_changes(tdm_hwc *hwc); + +/** + * @brief Commit changes for a hwc + * @details After all change of a window object are applied, a user commit handler + * will be called. + * @param[in] hwc A hwc object + * @param[in] sync 0: asynchronous, 1:synchronous + * @param[in] func A user commit handler + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_data); + +/** + * @brief Destroys the given window. + * @param[in] output A output object + * @param[in] window the pointer of the window to destroy + * @since 2.0.0 + */ +void +tdm_hwc_window_destroy(tdm_hwc_window *hwc_window); + +/** * @brief Get a buffer queue for the window object * @details These buffers are used to composite by hardware a client content in * the nocomp mode. @@ -1009,11 +991,11 @@ tdm_layer_get_buffer_flags(tdm_layer *layer, unsigned int *flags); * @since 2.0.0 */ tbm_surface_queue_h -tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); +tdm_hwc_window_get_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); /** * @brief Sets the desired composition type of the given window. - * @details During tdm_output_hwc_validate(), the device may request changes to + * @details During tdm_hwc_validate(), the device may request changes to * the composition types of any of the layers as described in the definition * of tdm_hwc_window_composition_t above. * @param[in] hwc_window A window object @@ -1047,7 +1029,7 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, * @since 2.0.0 */ tdm_error -tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage); +tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage); /** * @brief Set the information to a window object @@ -1077,94 +1059,24 @@ tdm_error tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer); /** - * @brief Unset a TBM buffer to a window object - * @details A TBM buffer will be applied when the output object of a layer - * object is committed. - * @param[in] hwc_window A window object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @return #TDM_ERROR_BUSY if #hwc_window can't be updated right now, this - * can happen if #hwc_window is involved in the smooth transition from - * DEVICE to CLIENT, this shouldn't be interpreted like some critical error. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window); - -/** - * @brief Set a flags to a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); - -/** - * @brief Unset a flags from a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); - -/** - * @brief Commit changes for a window object - * @details After all change of a window object are applied, a user commit handler - * will be called. - * @param[in] hwc_window A window object - * @param[in] func A user commit handler - * @param[in] user_data The user data - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data); - -/** - * @brief Get the available property array of a video hwc window object. - * @param[in] hwc window A video hwc window object - * @param[out] props The available property array - * @param[out] count The count of properties - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ -tdm_error -tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, - const tdm_prop **props, int *count); - -/** * @brief Get the property which has a given id. - * @param[in] hwc window A video hwc window object + * @param[in] hwc window A hwc window object * @param[in] id The property id * @param[out] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error -tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, uint32_t id, - tdm_value *value); +tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, uint32_t id, tdm_value *value); /** * @brief Set the property which has a given id. - * @param[in] hwc window A video hwc window object + * @param[in] hwc window A hwc window object * @param[in] id The property id * @param[in] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error -tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, uint32_t id, - tdm_value value); - -/** - * @brief Get the window video capability - * @param[in] hwc_window A window object - * @param[out] video_capability A hwc window video capability - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ -tdm_error -tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability); +tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, uint32_t id, tdm_value value); /** * @brief Destroy a pp object diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 0416a90..d43d73c 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -541,176 +541,12 @@ typedef struct _tdm_func_output { tdm_error (*output_set_dpms_async)(tdm_output *output, tdm_output_dpms dpms_value); /** - * @brief Creates a new window on the given display. + * @brief Get a hwc object of a output object * @param[in] output A output object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object - * @since 2.0.0 - */ - tdm_hwc_window *(*output_hwc_create_window)(tdm_output *output, tdm_error *error); - - /** - * @brief Destroys the given window. - * @param[in] output A output object - * @param[in] window the pointer of the window to destroy - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_destroy_window)(tdm_output *output, tdm_hwc_window *hwc_window); - - /** - * @brief Set the client(relative to the TDM) target buffer - * @details Sets the buffer which will receive the output of client composition. - * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE - * will be composited into this buffer prior to the call to output_commit(), - * and windows not marked as TDM_COMPOSITION_CLIENT and - * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the - * device. - * - * The buffer handle provided may be null if no windows are being composited by - * the client. This must not result in an error (unless an invalid display - * handle is also provided). - * - * The damage parameter describes a buffer damage region as defined in the - * description of hwc_window_set_buffer_damage(). - * - * List of composited hwc_windows (hwc_windows which buffers are presented on #target_buffer) - * will be passed along with #target_buffer to allow tdm to make the smooth transition - * from a DEVICE type to a CLIENT type. - * - * Will be called before output_commit() if any of the layers are marked as - * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are - * so marked, then it is not necessary to call this function. It is not necessary - * to call output_hwc_validate() after changing the target through this function. - * @param[in] output A output object - * @param[in] target The new target buffer - * @param[in] damage The buffer damage region - * @param[in] composited_wnds The array of composited hwc_wnds - * @param[in] num_wnds The size of #composited_wnds array - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_set_client_target_buffer)(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage); - - /** - * @brief Unset the client(relative to the TDM) target buffer - * @details TODO - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_unset_client_target_buffer)(tdm_output *output); - - /** - * @brief Get the layer associated with the client target buffer - * @details TODO: - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A layer object. - * @since 2.0.0 - */ - tdm_layer *(*output_hwc_get_client_target_buffer_layer)(tdm_output *output, tdm_error *error); - - /** - * @brief Get the buffer which is set to the client target buffer - * @details TODO: - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A layer object. - * @since 2.0.0 - */ - tbm_surface_h (*output_hwc_get_client_target_buffer)(tdm_output *output, tdm_error *error); - - /** - * @brief Validate the output - * @details Instructs the device to inspect all of the layer state and - * determine if there are any composition type changes necessary before - * presenting the output. Permitted changes are described in the definition - * of tdm_composition_t above. - * @param[in] output A output object - * @param[out] num_types The number of composition type changes required by - * the device; if greater than 0, the client must either set and validate new - * types, or call output_hwc_accept_changes() to accept the changes returned by - * output_hwc_get_changed_composition_types(); must be the same as the number of - * changes returned by output_hwc_get_changed_composition_types (see the - * declaration of that function for more information); pointer will be non-NULL - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_validate)(tdm_output *output, tdm_hwc_window **composited_wnds, uint32_t num_wnds, - uint32_t *num_types); - - /** - * @brief Get changed composition types - * @details Retrieves the windows for which the device requires a different - * composition type than had been set prior to the last call to output_hwc_validate(). - * The client will either update its state with these types and call - * output_hwc_accept_changes, or will set new types and attempt to validate the - * display again. - * layers and types may be NULL to retrieve the number of elements which - * will be returned. The number of elements returned must be the same as the - * value returned in num_types from the last call to output_hwc_validate(). - * @param[in] output A output object - * @param[out] num_elements If windows or types were NULL, the number of layers - * and types which would have been returned; if both were non-NULL, the - * number of elements returned in layers and types, which must not exceed - * the value stored in num_elements prior to the call; pointer will be - * non-NULL - * @param[out] windows An array of windows - * @param[out] composition_types An array of composition types, each - * corresponding to an element of windows - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 + * @return A hwc object */ - tdm_error (*output_hwc_get_changed_composition_types)(tdm_output *output, - uint32_t *num_elements, - tdm_hwc_window **hwc_window, - tdm_hwc_window_composition *composition_types); - /** - * @brief Accepts the changes required by the device - * @details Accepts the changes required by the device from the previous - * output_hwc_validate() call (which may be queried using - * output_get_chaged_composition_types()) and revalidates the display. This - * function is equivalent to requesting the changed types from - * output_get_chaged_composition_types(), setting those types on the - * corresponding windows, and then calling output_hwc_validate again. - * After this call it must be valid to present this display. Calling this after - * output_hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but - * should have no other effect. - * @param[in] output A output object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * @since 2.0.0 - */ - tdm_error (*output_hwc_accept_changes)(tdm_output *output); - - /** - * @brief Get a target buffer queue - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A buffer queue - * @since 2.0.0 - */ - tbm_surface_queue_h (*output_hwc_get_target_buffer_queue)(tdm_output *output, - tdm_error *error); - - /** - * @brief Get the supported format array for video hwc windows of a output object. - * @param[in] output A output object - * @param[out] formats The available format array - * @param[out] count The count of formats - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*output_hwc_get_video_supported_formats)(tdm_layer *layer, - const tbm_format **formats, int *count); - - /** - * @brief Creates a new video window on the given output. - * @param[in] output A output object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A created window object. If the video abilities isn't accessed return NULL - * @since 2.0.0 - */ - tdm_hwc_window *(*output_hwc_create_video_window)(tdm_output *output, tdm_error *error); + tdm_hwc *(*output_get_hwc)(tdm_output *output, tdm_error *error); void (*reserved5)(void); void (*reserved6)(void); @@ -847,23 +683,190 @@ typedef struct _tdm_func_layer { void (*reserved7)(void); } tdm_func_layer; +typedef struct _tdm_func_hwc { + /** + * @brief Create a new window on the given hwc. + * @param[in] hwc A hwc object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A created window object + * @since 2.0.0 + */ + tdm_hwc_window *(*hwc_create_window)(tdm_hwc *hwc, tdm_error *error); + + /** + * @brief Get the supported format array for the hwc windows of a hwc object. + * @param[in] hwc A hwc object + * @param[out] formats The available format array + * @param[out] count The count of formats + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_get_supported_formats)(tdm_hwc *hwc, const tbm_format **formats, + int *count); + + + /** + * @brief Get the available property array of a hwc object. + * @param[in] hwc A hwc object + * @param[out] props The available property array + * @param[out] count The count of properties + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_get_available_properties)(tdm_hwc *hwc, const tdm_prop **props, + int *count); + + /** + * @brief Get a target buffer queue + * @param[in] hwc A hwc object + * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. + * @return A buffer queue + * @since 2.0.0 + */ + tbm_surface_queue_h (*hwc_get_client_target_buffer_queue)(tdm_hwc *hwc, + tdm_error *error); + + /** + * @brief Set the client(relative to the TDM) target buffer + * @details Sets the buffer which will receive the hwc of client composition. + * Window marked as TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE + * will be composited into this buffer prior to the call to hwc_commit(), + * and windows not marked as TDM_COMPOSITION_CLIENT and + * TDM_COMPOSITION_DEVICE_CANDIDATE should be composited with this buffer by the + * device. + * + * The buffer handle provided may be null if no windows are being composited by + * the client. This must not result in an error (unless an invalid display + * handle is also provided). + * + * The damage parameter describes a buffer damage region as defined in the + * description of hwc_window_set_buffer_damage(). + * + * Will be called before hwc_commit() if any of the layers are marked as + * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. If no layers are + * so marked, then it is not necessary to call this function. It is not necessary + * to call hwc_validate() after changing the target through this function. + * @param[in] hwc A hwc object + * @param[in] target The new target buffer + * @param[in] damage The buffer damage region + * @param[in] composited_wnds The array of composited hwc_wnds + * @param[in] num_wnds The size of #composited_wnds array + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_set_client_target_buffer)(tdm_hwc *hwc, + tbm_surface_h target_buffer, + tdm_region damage); + + /** + * @brief Validate the hwc + * @details Instructs the device to inspect all of the layer state and + * determine if there are any composition type changes necessary before + * presenting the hwc. Permitted changes are described in the definition + * of tdm_composition_t above. + * @param[in] hwc A hwc object + * @param[out] num_types The number of composition type changes required by + * the device; if greater than 0, the client must either set and validate new + * types, or call hwc_accept_changes() to accept the changes returned by + * hwc_get_changed_composition_types(); must be the same as the number of + * changes returned by hwc_get_changed_composition_types (see the + * declaration of that function for more information); pointer will be non-NULL + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_validate)(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, + uint32_t num_wnds, uint32_t *num_types); + + /** + * @brief Get changed composition types + * @details Retrieves the windows for which the device requires a different + * composition type than had been set prior to the last call to hwc_validate(). + * The client will either update its state with these types and call + * hwc_accept_changes, or will set new types and attempt to validate the + * display again. + * layers and types may be NULL to retrieve the number of elements which + * will be returned. The number of elements returned must be the same as the + * value returned in num_types from the last call to hwc_validate(). + * @param[in] hwc A hwc object + * @param[out] num_elements If windows or types were NULL, the number of layers + * and types which would have been returned; if both were non-NULL, the + * number of elements returned in layers and types, which must not exceed + * the value stored in num_elements prior to the call; pointer will be + * non-NULL + * @param[out] windows An array of windows + * @param[out] composition_types An array of composition types, each + * corresponding to an element of windows + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_get_changed_composition_types)(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types); + /** + * @brief Accepts the changes required by the device + * @details Accepts the changes required by the device from the previous + * hwc_validate() call (which may be queried using + * hwc_get_chaged_composition_types()) and revalidates the display. This + * function is equivalent to requesting the changed types from + * hwc_get_chaged_composition_types(), setting those types on the + * corresponding windows, and then calling hwc_validate again. + * After this call it must be valid to present this display. Calling this after + * hwc_validate() returns 0 changes must succeed with TDM_ERROR_NONE, but + * should have no other effect. + * @param[in] hwc A hwc object + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @since 2.0.0 + */ + tdm_error (*hwc_accept_changes)(tdm_hwc *hwc); + + /** + * @brief Commit changes for a output object + * @param[in] hwc A hwc object + * @param[in] sync 0: asynchronous, 1:synchronous + * @param[in] user_data The user data + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see hwc_set_commit_handler, tdm_hwc_commit_handler + * @remark + * When this function is called, a backend module @b SHOULD apply the all + * changes of the given output object to screen as well as the layer changes + * of this output. + * If this function returns TDM_ERROR_NONE, a backend module @b SHOULD call + * a user commit handler with the user data of this function after all + * changes of the given output object are applied. + */ + tdm_error (*hwc_commit)(tdm_hwc *hwc, int sync, void *user_data); + + /** + * @brief Set a user commit handler + * @param[in] hwc A hwc object + * @param[in] func A user commit handler + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ + tdm_error (*hwc_set_commit_handler)(tdm_output *hwc, tdm_hwc_commit_handler func); +} tdm_func_hwc; + /** * @brief The window functions for a backend module. * @since 2.0.0 */ -typedef struct _tdm_func_window { +typedef struct _tdm_func_hwc_window { + /** + * @brief Destroys the given window. + * @param[in] window the pointer of the window to destroy + * @since 2.0.0 + */ + void (*hwc_window_destroy)(tdm_hwc_window *hwc_window); + /** * @brief Get a buffer queue for the window object * @param[in] hwc_window A window object * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. * @return A buffer queue */ - tbm_surface_queue_h (*hwc_window_get_tbm_buffer_queue)(tdm_hwc_window *hwc_window, - tdm_error *error); + tbm_surface_queue_h (*hwc_window_get_buffer_queue)(tdm_hwc_window *hwc_window, + tdm_error *error); /** * @brief Sets the desired composition type of the given window. - * @details During output_hwc_validate(), the device may request changes to + * @details During hwc_validate(), the device may request changes to * the composition types of any of the layers as described in the definition * of tdm_hwc_window_composition_t above. * @param[in] hwc_window A window object @@ -877,7 +880,7 @@ typedef struct _tdm_func_window { * @brief Set the buffer damage * @details Provides the region of the source buffer which has been modified * since the last frame. This region does not need to be validated before - * calling output_commit(). + * calling hwc_commit(). * Once set through this function, the damage region remains the same until a * subsequent call to this function. * If damage.num_rects > 0, then it may be assumed that any portion of the source @@ -894,11 +897,11 @@ typedef struct _tdm_func_window { * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ tdm_error (*hwc_window_set_buffer_damage)(tdm_hwc_window *hwc_window, - tdm_hwc_region damage); + tdm_region damage); /** * @brief Set the information to a window object - * @details The information will be applied when the output object + * @details The information will be applied when the hwc object * of a layer object is committed. * @param[in] hwc_window A window object * @param[in] info The geometry information @@ -918,7 +921,7 @@ typedef struct _tdm_func_window { /** * @brief Set a TDM buffer to a window object - * @details A TDM buffer will be applied when the output object + * @details A TDM buffer will be applied when the hwc object * of a layer object is committed. * @param[in] hwc_window A window object * @param[in] buffer A TDM buffer @@ -932,104 +935,24 @@ typedef struct _tdm_func_window { tbm_surface_h buffer); /** - * @brief Unset a TDM buffer to a window object - * @details A TDM buffer will be applied when the output object - * of a layer object is committed. - * @param[in] hwc_window A window object - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - * - * Implementation should return #TDM_ERROR_BUSY if #hwc_window can't - * be updated right now, this won't be interpreted like some critical - * error. - */ - tdm_error (*hwc_window_unset_buffer)(tdm_hwc_window *hwc_window); - - /** - * @brief Get a buffer which is set to a window object - * @details A TDM buffer will be applied when the output object - * of a layer object is committed. - * @param[in] hwc_window A window object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A buffer which is @b assigend to a window object - * - * Implementation should return #TDM_ERROR_BUSY if #hwc_window can't - * be updated right now, this won't be interpreted like some critical - * error. - */ - tbm_surface_h (*hwc_window_get_buffer)(tdm_hwc_window *hwc_window, - tdm_error *error); - - /** - * @brief Get a layer associated with a window object - * @param[in] hwc_window A window object - * @param[out] error #TDM_ERROR_NONE if success. Otherwise, error value. - * @return A layer which is @b assigend to a window object - * @remark - * A backend module @b SHOULD implement this function. The backend should - * return the tdm_layer assoicated with a hwc_window which must be assigend - * hw overlay.\n - */ - tdm_layer *(*hwc_window_get_layer)(tdm_hwc_window *hwc_window, - tdm_error *error); - - /** - * @brief Set a flags to a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_set_flags)(tdm_hwc_window *hwc_window, - tdm_hwc_window_flag flags); - - /** - * @brief Unset a flags from a window object - * @param[in] hwc_window A window object - * @param[in] flags A hwc_window flags - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_unset_flags)(tdm_hwc_window *hwc_window, - tdm_hwc_window_flag flags); - - /** - * @brief Get the window video capability - * @param[in] hwc_window A window object - * @param[out] video_capability A hwc window video capability - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_video_get_capability)(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability); - - /** - * @brief Get the available property array of a video hwc window object. - * @param[in] hwc window A video hwc window object - * @param[out] props The available property array - * @param[out] count The count of properties + * @brief Set the property which has a given id. + * @param[in] hwc window A hwc window object + * @param[in] id The property id + * @param[in] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ - tdm_error (*hwc_window_video_get_available_properties)( - tdm_hwc_window *hwc_window, - const tdm_prop **props, int *count); + tdm_error (*hwc_window_set_property)(tdm_hwc_window *hwc_window, + uint32_t id, tdm_value value); /** * @brief Get the property which has a given id. - * @param[in] hwc window A video hwc window object + * @param[in] hwc window A hwc window object * @param[in] id The property id * @param[out] value The value * @return #TDM_ERROR_NONE if success. Otherwise, error value. */ - tdm_error (*hwc_window_video_get_property)(tdm_hwc_window *hwc_window, - uint32_t id, tdm_value *value); - - /** - * @brief Set the property which has a given id. - * @param[in] hwc window A video hwc window object - * @param[in] id The property id - * @param[in] value The value - * @return #TDM_ERROR_NONE if success. Otherwise, error value. - */ - tdm_error (*hwc_window_video_set_property)(tdm_hwc_window *hwc_window, - uint32_t id, tdm_value value); - + tdm_error (*hwc_window_get_property)(tdm_hwc_window *hwc_window, + uint32_t id, tdm_value *value); } tdm_func_hwc_window; /** @@ -1443,16 +1366,27 @@ tdm_event_loop_source_timer_update(tdm_event_loop_source *source, unsigned int m void tdm_event_loop_source_remove(tdm_event_loop_source *source); +/** + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_string + */ +int +tdm_config_get_int(const char *key, int default_value); /** - * @brief Trigger a 'need to validate' event. - * @param[in] output The output the event should be triggered for. - * @note The global display lock has to be locked before the call to this function. - * @see #tdm_output_hwc_set_need_validate_handler - * @since 2.0.0 + * @brief Get the ini value with given key + * @details + * @param[in] key The given key + * @param[in] default_value The default value + * @return the value of given key if success. Otherwise, default_value. + * @see #tdm_config_get_int */ -tdm_error -tdm_backend_trigger_need_validate_event(tdm_output *output); +const char * +tdm_config_get_string(const char *key, const char *default_value); #ifdef __cplusplus } diff --git a/include/tdm_common.h b/include/tdm_common.h index ef5ee15..328f837 100644 --- a/include/tdm_common.h +++ b/include/tdm_common.h @@ -137,16 +137,6 @@ typedef enum { } tdm_layer_capability; /** - * @brief The hwc window capability enumeration - * @since 2.0.0 - */ -typedef enum { - TDM_HWC_WINDOW_VIDEO_CAPABILITY_SCALE = (1 << 1), /**< if a hwc window video has scale capability */ - TDM_HWC_WINDOW_VIDEO_CAPABILITY_TRANSFORM = (1 << 2), /**< if a hwc window video has transform capability */ - TDM_HWC_WINDOW_VIDEO_CAPABILITY_SCANOUT = (1 << 3), /**< if a hwc_window video allows a scanout buffer only */ -} tdm_hwc_window_video_capability; - -/** * @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 diff --git a/include/tdm_types.h b/include/tdm_types.h index 68f3096..32f544d 100644 --- a/include/tdm_types.h +++ b/include/tdm_types.h @@ -115,6 +115,15 @@ typedef struct _tdm_info_layer { } tdm_info_layer; /** + * @brief The region structure + * @since 2.0.0 + */ +typedef struct _tdm_region { + unsigned int num_rects; + tdm_pos const *rects; +} tdm_region; + +/** * @brief The hwc window info structure * @since 2.0.0 */ @@ -124,11 +133,6 @@ typedef struct _tdm_hwc_window_info { tdm_transform transform; } tdm_hwc_window_info; -typedef struct _tdm_hwc_region { - unsigned int num_rects; - tdm_pos const *rects; -} tdm_hwc_region; - /** * @brief The pp info structre */ @@ -173,18 +177,18 @@ typedef enum { */ TDM_COMPOSITION_CLIENT = 1, - /** Set by the client before tdm_output_hwc_validate(). + /** Set by the client before tdm_hwc_validate(). * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to + * Upon tdm_hwc_validate(), the device may request a change from this type to * TDM_COMPOSITION_DEVICE or TDM_COMPOSITION_CLIENT. */ TDM_COMPOSITION_DEVICE_CANDIDATE = 2, - /** Set by the HWC after tdm_output_hwc_validate(). + /** Set by the HWC after tdm_hwc_validate(). * * The device will handle the composition of this window through a hardware * overlay or other similar means. * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to + * Upon tdm_hwc_validate(), the device may request a change from this type to * TDM_COMPOSITION_CLIENT or TDM_COMPOSITION_DEVICE_CANDIDATE. */ TDM_COMPOSITION_DEVICE = 3, @@ -192,9 +196,9 @@ typedef enum { * asynchronously through layer_set_cursor_position. If this functionality is not * supported on a layer that the client sets to TDM_COMPOSITION_CURSOR, the * device must request that the composition type of that layer is changed to - * TDM_COMPOSITION_CLIENT upon the next call to tdm_output_hwc_validate(). + * TDM_COMPOSITION_CLIENT upon the next call to tdm_hwc_validate(). * - * Upon tdm_output_hwc_validate(), the device may request a change from this type to + * Upon tdm_hwc_validate(), the device may request a change from this type to * either TDM_COMPOSITION_DEVICE or TDM_COMPOSITION_CLIENT. Changing to * TDM_COMPOSITION_DEVICE will prevent the use of layer_set_cursor_position but * still permit the device to composite the layer. */ @@ -236,7 +240,13 @@ typedef void tdm_output; typedef void tdm_layer; /** - * @brief The tdm window object + * @brief The tdm hwc object + * @since 2.0.0 + */ +typedef void tdm_hwc; + +/** + * @brief The tdm hwc window object * @since 2.0.0 */ typedef void tdm_hwc_window; @@ -290,20 +300,6 @@ typedef void (*tdm_layer_commit_handler)(tdm_layer *layer, unsigned int sequence void *user_data); /** - * @brief The hwc_window commit handler - */ -typedef void (*tdm_hwc_window_commit_handler)(tdm_hwc_window *hwc_window, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); - -/** - * @brief The output target_buffer commit handler - */ -typedef void (*tdm_output_hwc_target_buffer_commit_handler)(tdm_output *output, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data); - -/** * @brief The done handler of a pp object */ typedef void (*tdm_pp_done_handler)(tdm_pp *pp, tbm_surface_h src, @@ -321,10 +317,12 @@ typedef void (*tdm_capture_done_handler)(tdm_capture *capture, typedef void (*tdm_vblank_create_handler)(tdm_vblank *vblank, void *user_data); /** - * @brief The 'need to validate' handler of an output object - * @since 2.0.0 + * @brief The hwc commit handler + * @see hwc_set_commit_handler() function of #tdm_func_hwc */ -typedef void (*tdm_output_need_validate_handler)(tdm_output *output); +typedef void (*tdm_hwc_commit_handler)(tdm_hwc *hwc, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, + void *user_data); #ifdef __cplusplus } diff --git a/src/Makefile.am b/src/Makefile.am index 7ec1cd4..f9616e4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ libtdm_la_SOURCES = \ tdm_display.c \ tdm_output.c \ tdm_layer.c \ + tdm_hwc.c \ tdm_hwc_window.c \ tdm_pp.c \ tdm_capture.c \ diff --git a/src/tdm.c b/src/tdm.c index be3d0bf..bc59c3c 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -97,6 +97,44 @@ tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp return NULL; } +tdm_private_hwc * +tdm_display_find_private_hwc(tdm_private_display *private_display, tdm_hwc *hwc_backend) +{ + tdm_private_module *private_module = NULL; + tdm_private_output *private_output = NULL; + tdm_private_hwc *private_hwc = NULL; + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (!private_output->private_hwc) continue; + private_hwc = private_output->private_hwc; + if (private_hwc->hwc_backend == hwc_backend) + return private_hwc; + } + } + + return NULL; +} + +INTERN void * +tdm_display_find_hwc_stamp(tdm_private_display *private_display, double stamp) +{ + tdm_private_module *private_module = NULL; + tdm_private_output *private_output = NULL; + tdm_private_hwc *private_hwc = NULL; + + LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { + LIST_FOR_EACH_ENTRY(private_output, &private_module->output_list, link) { + if (!private_output->private_hwc) continue; + private_hwc = private_output->private_hwc; + if (private_hwc->stamp == stamp) + return private_hwc; + } + } + + return NULL; +} + static void _tdm_display_destroy_caps_pp(tdm_caps_pp *caps_pp) { @@ -164,10 +202,12 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) { tdm_private_display *private_display = private_output->private_display; tdm_private_layer *l = NULL, *ll = NULL; + tdm_private_hwc *private_hwc = NULL; tdm_private_hwc_window *hw = NULL, *hww = NULL; tdm_private_capture *c = NULL, *cc = NULL; tdm_private_output_vblank_handler *v = NULL, *vv = NULL; tdm_private_output_commit_handler *om = NULL, *omm = NULL; + tdm_private_hwc_commit_handler *hm = NULL, *hmm = NULL; tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; tdm_private_output_change_handler *h = NULL, *hh = NULL; @@ -186,9 +226,17 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) free(om); } - LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { - LIST_DEL(&lm->link); - free(lm); + if (private_output->private_hwc) { + private_hwc = private_output->private_hwc; + LIST_FOR_EACH_ENTRY_SAFE(hm, hmm, &private_hwc->hwc_commit_handler_list, link) { + LIST_DEL(&hm->link); + free(hm); + } + } else { + LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { + LIST_DEL(&lm->link); + free(lm); + } } LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->pending_commit_handler_list, link) { @@ -218,21 +266,20 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) } LIST_FOR_EACH_ENTRY_SAFE(c, cc, &private_output->capture_list, link) - tdm_capture_destroy_internal(c); - - LIST_FOR_EACH_ENTRY_SAFE(hw, hww, &private_output->hwc_window_list, link) - tdm_hwc_window_destroy_internal(hw); - - LIST_FOR_EACH_ENTRY_SAFE(l, ll, &private_output->layer_list, link) - _tdm_display_destroy_private_layer(l); + tdm_capture_destroy_internal(c); + + if (private_output->private_hwc) { + private_hwc = private_output->private_hwc; + LIST_FOR_EACH_ENTRY_SAFE(hw, hww, &private_hwc->hwc_window_list, link) + tdm_hwc_window_destroy_internal(hw); + free(private_hwc); + } else { + LIST_FOR_EACH_ENTRY_SAFE(l, ll, &private_output->layer_list, link) + _tdm_display_destroy_private_layer(l); + } _tdm_display_destroy_caps_output(&private_output->caps); - tdm_thread_cb_remove(private_output, TDM_THREAD_CB_NEED_VALIDATE, NULL, - tdm_output_need_validate_handler_thread, NULL); - tdm_event_loop_source_remove(private_output->need_validate.event_source); - close(private_output->need_validate.event_fd); - /* when destroying output, vblank objects are also destroyed. vblank checks * if output object is valid. So delete the output's link at last. */ @@ -405,6 +452,8 @@ tdm_display_update_output(tdm_private_module *private_module, tdm_func_output *func_output = &private_module->func_output; tdm_private_output *private_output = NULL; tdm_layer **layers = NULL; + tdm_private_hwc *private_hwc = NULL; + tdm_hwc *hwc; int layer_count = 0, i; tdm_error ret; @@ -426,53 +475,82 @@ tdm_display_update_output(tdm_private_module *private_module, private_output->pipe = pipe; private_output->index = pipe; - LIST_INITHEAD(&private_output->layer_list); - LIST_INITHEAD(&private_output->hwc_window_list); LIST_INITHEAD(&private_output->capture_list); LIST_INITHEAD(&private_output->vblank_handler_list); LIST_INITHEAD(&private_output->output_commit_handler_list); - LIST_INITHEAD(&private_output->layer_commit_handler_list); LIST_INITHEAD(&private_output->pending_commit_handler_list); LIST_INITHEAD(&private_output->change_handler_list); - private_output->need_validate.event_fd = -1; - if (func_output->output_set_status_handler) { func_output->output_set_status_handler(private_output->output_backend, tdm_output_cb_status, private_output); private_output->regist_change_cb = 1; } - } - - /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" - * because we have to get new modes. - */ - if (need_new_caps) { - _tdm_display_destroy_caps_output(&private_output->caps); ret = _tdm_display_update_caps_output(private_module, pipe, output_backend, &private_output->caps); TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) private_output->current_mode = NULL; - } - layers = func_output->output_get_layers(output_backend, &layer_count, &ret); - if (ret != TDM_ERROR_NONE) { - free(layers); - return ret; + /* get the tdm_hwc object */ + if (private_output->caps.capabilities&TDM_OUTPUT_CAPABILITY_HWC) { + hwc = func_output->output_get_hwc(output_backend, &ret); + TDM_RETURN_VAL_IF_FAIL(hwc != NULL, ret); + + private_hwc = calloc(1, sizeof(tdm_private_hwc)); + TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_OUT_OF_MEMORY); + + private_hwc->private_module = private_module; + private_hwc->private_output = private_output; + private_hwc->hwc_backend = hwc; + private_hwc->index = pipe; + private_hwc->stamp = tdm_helper_get_time(); + while (tdm_display_find_hwc_stamp(private_module->private_display, private_hwc->stamp)) + private_hwc->stamp++; + + LIST_INITHEAD(&private_hwc->hwc_window_list); + LIST_INITHEAD(&private_hwc->hwc_commit_handler_list); + + private_output->private_hwc = private_hwc; + } else { + LIST_INITHEAD(&private_output->layer_list); + LIST_INITHEAD(&private_output->layer_commit_handler_list); + } + } else { + /* need_new_caps will be true only in case of "disconnected -> connected" and "connected -> disconnected" + * because we have to get new modes. + */ + if (need_new_caps) { + _tdm_display_destroy_caps_output(&private_output->caps); + + ret = _tdm_display_update_caps_output(private_module, pipe, output_backend, &private_output->caps); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + if (private_output->caps.status == TDM_OUTPUT_CONN_STATUS_DISCONNECTED) + private_output->current_mode = NULL; + } } - for (i = 0; i < layer_count; i++) { - ret = _tdm_display_update_layer(private_output, layers[i], i); + /* do not use the layer object when the tdm_output has the hwc capability */ + if ((private_output->caps.capabilities&TDM_OUTPUT_CAPABILITY_HWC) == 0) { + layers = func_output->output_get_layers(output_backend, &layer_count, &ret); if (ret != TDM_ERROR_NONE) { free(layers); return ret; } - } - free(layers); + for (i = 0; i < layer_count; i++) { + ret = _tdm_display_update_layer(private_output, layers[i], i); + if (ret != TDM_ERROR_NONE) { + free(layers); + return ret; + } + } + + free(layers); + } return TDM_ERROR_NONE; } @@ -1005,6 +1083,10 @@ tdm_display_init(tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed_load; + ret = tdm_hwc_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_load; + ret = tdm_pp_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; @@ -1054,15 +1136,6 @@ tdm_display_init(tdm_error *error) private_display->init_count = 1; g_private_display = private_display; - tdm_private_module *b = NULL; - tdm_private_output *o = NULL; - LIST_FOR_EACH_ENTRY(b, &private_display->module_list, link) { - LIST_FOR_EACH_ENTRY(o, &b->output_list, link) { - if (o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - tdm_output_need_validate_event_init(o); - } - } - /* the COMMIT_PER_VBLANK functionality is ability of an output to support * several operational modes (commit_per_vblank modes) related to tdm_commit; * this functionality can be turned off which means a default mode */ diff --git a/src/tdm_backend.c b/src/tdm_backend.c index 8be51f0..13ea24c 100644 --- a/src/tdm_backend.c +++ b/src/tdm_backend.c @@ -133,6 +133,31 @@ tdm_backend_register_func_layer(tdm_display *dpy, tdm_func_layer *func_layer) /* LCOV_EXCL_START */ EXTERN tdm_error +tdm_backend_register_func_hwc(tdm_display *dpy, tdm_func_hwc *func_hwc) +{ + tdm_backend_module *module; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); + + BACKEND_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(func_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); + + assert(private_display->current_module); + + module = private_display->current_module->module_data; + /* FIX ME: + Temporarily, we set the version of hwc window to 1.1 for the development. + Originally the hwc window version is 2.0. */ + if (_check_abi_version(module, 1, 1) < 0) + return TDM_ERROR_BAD_MODULE; + + private_display->current_module->func_hwc = *func_hwc; + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error tdm_backend_register_func_hwc_window(tdm_display *dpy, tdm_func_hwc_window *func_hwc_window) { tdm_backend_module *module; @@ -205,49 +230,3 @@ tdm_backend_register_func_capture(tdm_display *dpy, return TDM_ERROR_NONE; } - -/* LCOV_EXCL_START */ -/* backend operates itself types */ -static tdm_private_output* -_look_for_frontend_hwc_output(tdm_output *backend_output) -{ - tdm_private_output *frontend_output = NULL, *o = NULL; - tdm_private_display *private_display = tdm_display_get(); - tdm_private_module *private_module = NULL; - - LIST_FOR_EACH_ENTRY(private_module, &private_display->module_list, link) { - LIST_FOR_EACH_ENTRY(o, &private_module->output_list, link) { - if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) - continue; - - if (o->output_backend == backend_output) { - frontend_output = o; - return frontend_output; - } - } - } - - return NULL; -} - -EXTERN tdm_error -tdm_backend_trigger_need_validate_event(tdm_output *output) -{ - tdm_private_output *private_output; - uint64_t value; - int res; - - private_output = _look_for_frontend_hwc_output(output); - TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); - - value = 1; - - /* do not lock the global display lock here */ - - res = write(private_output->need_validate.event_fd, &value, sizeof(value)); - if (res < 0) - return TDM_ERROR_OPERATION_FAILED; - - return TDM_ERROR_NONE; -} -/* LCOV_EXCL_STOP */ diff --git a/src/tdm_hwc.c b/src/tdm_hwc.c new file mode 100644 index 0000000..115197c --- /dev/null +++ b/src/tdm_hwc.c @@ -0,0 +1,550 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2018 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: SooChan Lim , + * Boram Park , + * Changyeon Lee , + * Sangjin Lee + * + * 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. + * +**************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tdm_private.h" + +#define HWC_FUNC_ENTRY() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_VAL_IF_FAIL(hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_hwc = (tdm_private_hwc*)hwc; \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_display = private_output->private_display + +#define HWC_FUNC_ENTRY_ERROR() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ + private_hwc = (tdm_private_hwc*)hwc; \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ + private_display = private_output->private_display + +#define HWC_FUNC_ENTRY_VOID_RETURN() \ + tdm_private_display *private_display; \ + tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ + tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ + TDM_RETURN_IF_FAIL(hwc != NULL); \ + private_hwc = (tdm_private_hwc*)hwc; \ + private_output = private_hwc->private_output; \ + TDM_RETURN_IF_FAIL(private_output != NULL); \ + private_display = private_output->private_display + + +static tdm_private_hwc_window * +_tdm_hwc_find_private_hwc_window(tdm_private_hwc *private_hwc, tdm_hwc_window *hwc_window_backend) +{ + tdm_private_hwc_window *private_hwc_window = NULL; + + LIST_FOR_EACH_ENTRY(private_hwc_window, &private_hwc->hwc_window_list, link) { + if (private_hwc_window->hwc_window_backend == hwc_window_backend) + return private_hwc_window; + } + + return NULL; +} + +static void +_tdm_hwc_thread_cb_commit(tdm_private_display *private_display, void *object, + tdm_thread_cb_base *cb_base, void *user_data) +{ + tdm_thread_cb_hwc_commit *hwc_commit = (tdm_thread_cb_hwc_commit *)cb_base; + tdm_private_hwc_commit_handler *hwc_commit_handler = hwc_commit->base.data; + tdm_private_hwc *private_hwc = object; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + if (!hwc_commit_handler) + return; + + assert(hwc_commit_handler->owner_tid == syscall(SYS_gettid)); + + tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler, + _tdm_hwc_thread_cb_commit, NULL); + + LIST_DEL(&hwc_commit_handler->link); + + if (tdm_debug_module & TDM_DEBUG_COMMIT) { + TDM_INFO("----------------------------------------- hwc(%d) committed", private_hwc->index); + TDM_INFO("handler(%p)", hwc_commit_handler); + } + + if (hwc_commit_handler->func) { + _pthread_mutex_unlock(&private_display->lock); + hwc_commit_handler->func(private_hwc, + hwc_commit->sequence, + hwc_commit->tv_sec, + hwc_commit->tv_usec, + hwc_commit_handler->user_data); + _pthread_mutex_lock(&private_display->lock); + } + + free(hwc_commit_handler); + + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("-----------------------------------------..."); +} + +static void +_tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + tdm_private_hwc_commit_handler *hwc_commit_handler = user_data; + tdm_private_hwc *private_hwc; + tdm_thread_cb_hwc_commit hwc_commit; + tdm_error ret; + + if (hwc_commit_handler) + private_hwc = hwc_commit_handler->private_hwc; + else + private_hwc = tdm_display_find_private_hwc(tdm_display_get(), hwc_backend); + + memset(&hwc_commit, 0, sizeof hwc_commit); + hwc_commit.base.type = TDM_THREAD_CB_HWC_COMMIT; + hwc_commit.base.length = sizeof hwc_commit; + hwc_commit.base.object_stamp = private_hwc->stamp; + hwc_commit.base.data = hwc_commit_handler; + hwc_commit.base.sync = 0; + hwc_commit.sequence = sequence; + hwc_commit.tv_sec = tv_sec; + hwc_commit.tv_usec = tv_usec; + + ret = tdm_thread_cb_call(private_hwc, &hwc_commit.base, 1); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +INTERN tdm_error +tdm_hwc_init(tdm_private_display *private_display) +{ + tdm_thread_cb_set_find_func(TDM_THREAD_CB_HWC_COMMIT, tdm_display_find_hwc_stamp); + + return TDM_ERROR_NONE; +} + +EXTERN tdm_hwc_window * +tdm_hwc_create_window(tdm_hwc *hwc, tdm_error *error) +{ + tdm_hwc_window *hwc_window = NULL; + + HWC_FUNC_ENTRY_ERROR(); + + _pthread_mutex_lock(&private_display->lock); + + hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_hwc, error); + + _pthread_mutex_unlock(&private_display->lock); + + return hwc_window; +} + +EXTERN tdm_error +tdm_hwc_get_supported_formats(tdm_hwc *hwc, const tbm_format **formats, int *count) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_output->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_supported_formats) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_get_supported_formats(private_hwc->hwc_backend, formats, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_get_available_properties(tdm_hwc *hwc, const tdm_prop **props, int *count) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_output->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_available_properties) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_get_available_properties(private_hwc->hwc_backend, props, count); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tbm_surface_queue_h +tdm_hwc_get_client_target_buffer_queue(tdm_hwc *hwc, tdm_error *error) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tbm_surface_queue_h queue = NULL; + + HWC_FUNC_ENTRY_ERROR(); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_client_target_buffer_queue) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return NULL; + /* LCOV_EXCL_STOP */ + } + + queue = func_hwc->hwc_get_client_target_buffer_queue(private_hwc->hwc_backend, error); + + _pthread_mutex_unlock(&private_display->lock); + + return queue; +} + +EXTERN tdm_error +tdm_hwc_set_client_target_buffer(tdm_hwc *hwc, tbm_surface_h target_buffer, tdm_region damage) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + + HWC_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) { + /* LCOV_EXCL_START */ + char str[TDM_PATH_LEN]; + static int i; + snprintf(str, TDM_PATH_LEN, "target_window_%03d", i++); + tdm_helper_dump_buffer_str(target_buffer, tdm_debug_dump_dir, str); + /* LCOV_EXCL_STOP */ + } + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_set_client_target_buffer) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_set_client_target_buffer(private_hwc->hwc_backend, target_buffer, damage); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + + +EXTERN tdm_error +tdm_hwc_validate(tdm_hwc *hwc, tdm_hwc_window **composited_wnds, uint32_t num_wnds, uint32_t *num_types) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tdm_private_hwc_window **composited_wnds_frontend = NULL; + tdm_hwc_window **composited_wnds_backend = NULL; + int i; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_validate) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + if (num_wnds == 0) { + ret = func_hwc->hwc_validate(private_hwc->hwc_backend, NULL, 0, num_types); + + _pthread_mutex_unlock(&private_display->lock); + return ret; + } + + composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *)); + if (!composited_wnds_backend) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + + composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds; + + for (i = 0; i < num_wnds; i++) + composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend; + + ret = func_hwc->hwc_validate(private_hwc->hwc_backend, composited_wnds_backend, + num_wnds, num_types); + + free(composited_wnds_backend); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, uint32_t *num_elements, + tdm_hwc_window **hwc_window, + tdm_hwc_window_composition *composition_types) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tdm_private_hwc_window * private_hwc_window = NULL; + int i = 0; + + HWC_FUNC_ENTRY(); + + TDM_RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_get_changed_composition_types) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_get_changed_composition_types(private_hwc->hwc_backend, + num_elements, hwc_window, composition_types); + if (ret != TDM_ERROR_NONE) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + return ret; + /* LCOV_EXCL_STOP */ + } + + if (hwc_window == NULL || composition_types == NULL) { + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + for (i = 0; i < *num_elements; i++) { + private_hwc_window = _tdm_hwc_find_private_hwc_window(private_hwc, hwc_window[i]); + if (private_hwc_window == NULL) { + /* LCOV_EXCL_START */ + TDM_ERR("failed! This should never happen!"); + tdm_hwc_window_destroy_internal(private_hwc_window); + *num_elements = 0; + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OPERATION_FAILED; + /* LCOV_EXCL_STOP */ + } + + hwc_window[i] = (tdm_hwc_window*)private_hwc_window; + } + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_accept_changes(tdm_hwc *hwc) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + + HWC_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_validate) { + /* LCOV_EXCL_START */ + _pthread_mutex_unlock(&private_display->lock); + TDM_WRN("not implemented!!"); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + + ret = func_hwc->hwc_accept_changes(private_hwc->hwc_backend); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + +EXTERN tdm_error +tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_data) +{ + tdm_private_module *private_module; + tdm_func_hwc *func_hwc = NULL; + tdm_private_hwc_commit_handler *hwc_commit_handler = NULL; + + HWC_FUNC_ENTRY(); + + _pthread_mutex_lock(&private_display->lock); + + private_module = private_hwc->private_module; + func_hwc = &private_module->func_hwc; + + if (!func_hwc->hwc_commit) { + /* LCOV_EXCL_START */ + TDM_WRN("not implemented!!"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NOT_IMPLEMENTED; + /* LCOV_EXCL_STOP */ + } + +//TODO: I am not sure yet whether we have to check the dpms at hwc_commit. +#if 0 + /* check if the dpms is off */ + if (TDM_OUTPUT_DPMS_VSYNC_IS_OFF(private_output->current_dpms_value)) { + TDM_ERR("hwc(%d) dpms: %s", private_hwc->index, + tdm_dpms_str(private_output->current_dpms_value)); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_DPMS_OFF; + } +#endif + + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("hwc(%d) commit", private_hwc->index); + + if (!private_hwc->regist_commit_cb) { + private_hwc->regist_commit_cb = 1; + ret = func_hwc->hwc_set_commit_handler(private_hwc->hwc_backend, _tdm_hwc_cb_commit); + /* LCOV_EXCL_START */ + if (ret != TDM_ERROR_NONE) { + private_hwc->regist_commit_cb = 0; + TDM_ERR("hwc(%d) fail to set hwc_set_commit_handler", private_hwc->index); + _pthread_mutex_unlock(&private_display->lock); + return ret; + /* LCOV_EXCL_STOP */ + } + } + + hwc_commit_handler = calloc(1, sizeof(tdm_private_hwc_commit_handler)); + if (!hwc_commit_handler) { + /* LCOV_EXCL_START */ + TDM_ERR("failed: alloc memory"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OUT_OF_MEMORY; + /* LCOV_EXCL_STOP */ + } + + ret = tdm_thread_cb_add(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler, + _tdm_hwc_thread_cb_commit, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + free(hwc_commit_handler); + return ret; + } + + LIST_ADDTAIL(&hwc_commit_handler->link, &private_hwc->hwc_commit_handler_list); + hwc_commit_handler->private_hwc = private_hwc; + hwc_commit_handler->func = func; + hwc_commit_handler->user_data = user_data; + hwc_commit_handler->owner_tid = syscall(SYS_gettid); + + ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler); + TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); + + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)", + private_hwc->index, hwc_commit_handler, func, user_data); + + _pthread_mutex_unlock(&private_display->lock); + + return ret; + +commit_failed: + /* LCOV_EXCL_START */ + if (hwc_commit_handler) { + tdm_thread_cb_remove(private_hwc, TDM_THREAD_CB_HWC_COMMIT, hwc_commit_handler, + _tdm_hwc_thread_cb_commit, NULL); + LIST_DEL(&hwc_commit_handler->link); + free(hwc_commit_handler); + } + + _pthread_mutex_unlock(&private_display->lock); + + return ret; + /* LCOV_EXCL_STOP */ +} \ No newline at end of file diff --git a/src/tdm_hwc_window.c b/src/tdm_hwc_window.c index 25692b3..78df88d 100644 --- a/src/tdm_hwc_window.c +++ b/src/tdm_hwc_window.c @@ -2,14 +2,12 @@ * * libtdm * - * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * Copyright 2018 Samsung Electronics co., Ltd. All Rights Reserved. * - * Contact: Eunchul Kim , - * JinYoung Jeon , - * Taeheon Kim , - * YoungJun Cho , - * SooChan Lim , - * Boram Park + * Contact: SooChan Lim , + * Boram Park , + * Changyeon Lee , + * Sangjin Lee * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -46,35 +44,148 @@ #define HWC_WINDOW_FUNC_ENTRY() \ tdm_private_display *private_display; \ tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ tdm_private_hwc_window *private_hwc_window; \ tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); \ private_hwc_window = (tdm_private_hwc_window*)hwc_window; \ - private_output = private_hwc_window->private_output; \ + private_hwc = private_hwc_window->private_hwc; \ + TDM_RETURN_VAL_IF_FAIL(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER); \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); \ private_display = private_output->private_display #define HWC_WINDOW_FUNC_ENTRY_ERROR() \ tdm_private_display *private_display; \ tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ tdm_private_hwc_window *private_hwc_window; \ tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ private_hwc_window = (tdm_private_hwc_window*)hwc_window; \ - private_output = private_hwc_window->private_output; \ + private_hwc = private_hwc_window->private_hwc; \ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_hwc != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ + private_output = private_hwc->private_output; \ + TDM_RETURN_VAL_IF_FAIL_WITH_ERROR(private_output != NULL, TDM_ERROR_INVALID_PARAMETER, NULL); \ private_display = private_output->private_display #define HWC_WINDOW_FUNC_ENTRY_VOID_RETURN() \ tdm_private_display *private_display; \ tdm_private_output *private_output; \ + tdm_private_hwc *private_hwc; \ tdm_private_hwc_window *private_hwc_window; \ tdm_error ret = TDM_ERROR_NONE; /* default TDM_ERROR_NONE */\ TDM_RETURN_IF_FAIL(hwc_window != NULL); \ private_hwc_window = (tdm_private_hwc_window*)hwc_window; \ - private_output = private_hwc_window->private_output; \ + private_hwc = private_hwc_window->private_hwc; \ + TDM_RETURN_IF_FAIL(private_hwc != NULL); \ + private_output = private_hwc->private_output; \ + TDM_RETURN_IF_FAIL(private_output != NULL); \ private_display = private_output->private_display -tbm_surface_queue_h -tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) + +INTERN tdm_hwc_window * +tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error) +{ + tdm_private_output *private_output = private_hwc->private_output; + tdm_private_module *private_module = private_output->private_module; + tdm_func_hwc *func_hwc = &private_module->func_hwc; + tdm_private_hwc_window *private_hwc_window = NULL; + tdm_hwc_window *hwc_window_backend = NULL; + tdm_error ret = TDM_ERROR_NONE; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); + + if (!func_hwc->hwc_create_window) { + /* LCOV_EXCL_START */ + if (error) + *error = TDM_ERROR_BAD_MODULE; + return NULL; + /* LCOV_EXCL_STOP */ + } + + private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window)); + if (!private_hwc_window) { + /* LCOV_EXCL_START */ + TDM_ERR("failed: alloc memory"); + if (error) + *error = TDM_ERROR_OUT_OF_MEMORY; + return NULL; + /* LCOV_EXCL_STOP */ + } + + hwc_window_backend = func_hwc->hwc_create_window(private_hwc->hwc_backend, &ret); + if (ret != TDM_ERROR_NONE) { + free(private_hwc_window); + if (error) + *error = ret; + return NULL; + } + + LIST_ADD(&private_hwc_window->link, &private_hwc->hwc_window_list); + + private_hwc_window->private_hwc = private_hwc; + private_hwc_window->hwc_window_backend = hwc_window_backend; + + TDM_DBG("hwc_window(%p) create", private_hwc_window); + + if (error) + *error = TDM_ERROR_NONE; + + return private_hwc_window; +} + +INTERN void +tdm_hwc_window_destroy_internal(tdm_private_hwc_window *private_hwc_window) +{ + tdm_private_output *private_output; + tdm_private_module *private_module; + tdm_private_hwc *private_hwc; + tdm_func_hwc_window *func_hwc_window; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + if (!private_hwc_window) + return; + + private_hwc = private_hwc_window->private_hwc; + private_output = private_hwc->private_output; + private_module = private_output->private_module; + func_hwc_window = &private_module->func_hwc_window; + + LIST_DEL(&private_hwc_window->link); + + func_hwc_window = &private_module->func_hwc_window; + func_hwc_window->hwc_window_destroy(private_hwc_window->hwc_window_backend); + + free(private_hwc_window); +} + +EXTERN void +tdm_hwc_window_destroy(tdm_hwc_window *hwc_window) +{ + tdm_private_display *private_display; + tdm_private_output *private_output; + tdm_private_hwc *private_hwc; + tdm_private_hwc_window *private_hwc_window; + + if (!hwc_window) + return; + + private_hwc_window = (tdm_private_hwc_window *)hwc_window; + private_hwc = private_hwc_window->private_hwc; + private_output = private_hwc->private_output; + private_display = private_output->private_display; + + _pthread_mutex_lock(&private_display->lock); + + tdm_hwc_window_destroy_internal(hwc_window); + + _pthread_mutex_unlock(&private_display->lock); +} + +EXTERN tbm_surface_queue_h +tdm_hwc_window_get_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -87,7 +198,8 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; - if (!func_hwc_window->hwc_window_get_tbm_buffer_queue) { + if (!func_hwc_window->hwc_window_get_buffer_queue) { + /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); if (error) @@ -95,7 +207,7 @@ tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error return NULL; } - queue = func_hwc_window->hwc_window_get_tbm_buffer_queue(private_hwc_window->hwc_window_backend, error); + queue = func_hwc_window->hwc_window_get_buffer_queue(private_hwc_window->hwc_window_backend, error); _pthread_mutex_unlock(&private_display->lock); @@ -132,7 +244,7 @@ tdm_hwc_window_set_composition_type(tdm_hwc_window *hwc_window, } EXTERN tdm_error -tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage) +tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -237,339 +349,7 @@ tdm_hwc_window_set_buffer(tdm_hwc_window *hwc_window, tbm_surface_h buffer) } EXTERN tdm_error -tdm_hwc_window_unset_buffer(tdm_hwc_window *hwc_window) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_unset_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_unset_buffer(private_hwc_window->hwc_window_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -INTERN tdm_hwc_window * -tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, - tdm_error *error) -{ - tdm_private_display *private_display = private_output->private_display; - tdm_private_module *private_module = private_output->private_module; - tdm_func_output *func_output = &private_module->func_output; - tdm_private_hwc_window *private_hwc_window = NULL; - tdm_hwc_window *hwc_window_backend = NULL; - tdm_error ret = TDM_ERROR_NONE; - - TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), NULL); - - if (!is_video) { - if (!func_output->output_hwc_create_window) { - if (error) - *error = TDM_ERROR_BAD_MODULE; - return NULL; - } - - hwc_window_backend = func_output->output_hwc_create_window( - private_output->output_backend, &ret); - if (ret != TDM_ERROR_NONE) { - if (error) - *error = ret; - return NULL; - } - } else { - if (!func_output->output_hwc_create_video_window) { - if (error) - *error = TDM_ERROR_NOT_IMPLEMENTED; - return NULL; - } - - hwc_window_backend = func_output->output_hwc_create_video_window( - private_output->output_backend, &ret); - if (ret != TDM_ERROR_NONE) { - if (error) - *error = ret; - return NULL; - } - } - - private_hwc_window = calloc(1, sizeof(tdm_private_hwc_window)); - if (!private_hwc_window) { - TDM_ERR("failed: alloc memory"); - func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window_backend); - if (error) - *error = TDM_ERROR_OUT_OF_MEMORY; - return NULL; - } - - LIST_ADD(&private_hwc_window->link, &private_output->hwc_window_list); - - private_hwc_window->private_display = private_display; - private_hwc_window->private_output = private_output; - private_hwc_window->hwc_window_backend = hwc_window_backend; - - TDM_DBG("hwc_window(%p) create", private_hwc_window); - - if (error) - *error = TDM_ERROR_NONE; - - return private_hwc_window; -} - -INTERN tdm_error -tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window) -{ - tdm_private_output *private_output; - tdm_private_module *private_module; - tdm_func_output *func_output; - - TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); - - if (!private_hwc_window) - return TDM_ERROR_OPERATION_FAILED; - - private_output = private_hwc_window->private_output; - private_module = private_output->private_module; - - LIST_DEL(&private_hwc_window->link); - - func_output = &private_module->func_output; - func_output->output_hwc_destroy_window(private_output->output_backend, private_hwc_window->hwc_window_backend); - - free(private_hwc_window); - return TDM_ERROR_NONE; -} - -EXTERN tdm_error -tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_set_flags) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_set_flags(private_hwc_window->hwc_window_backend, flags); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_unset_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_unset_flags) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_unset_flags(private_hwc_window->hwc_window_backend, flags); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -static void -_tdm_hwc_window_layer_commit_handler(tdm_layer *layer, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - tdm_private_hwc_window_commit_handler *hwc_window_commit_handler = (tdm_private_hwc_window_commit_handler *)user_data; - tdm_hwc_window_commit_handler func = hwc_window_commit_handler->func; - tdm_hwc_window *hwc_window = (tdm_hwc_window *)hwc_window_commit_handler->private_hwc_window; - void *data = hwc_window_commit_handler->user_data; - - func(hwc_window, sequence, tv_sec, tv_usec, data); - - free(hwc_window_commit_handler); -} - -tdm_error -tdm_hwc_window_commit(tdm_hwc_window *hwc_window, tdm_hwc_window_commit_handler func, void *user_data) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - tdm_private_hwc_window_commit_handler *hwc_window_commit_handler; - tdm_layer *layer = NULL; - tdm_private_layer *private_layer; - tdm_info_layer *info_layer; - tdm_hwc_window_info window_info; - tbm_surface_h buffer; - - HWC_WINDOW_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_get_layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - layer = func_hwc_window->hwc_window_get_layer(private_hwc_window->hwc_window_backend, - &ret); - if (!layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("no assigned layer!!"); - return TDM_ERROR_INVALID_PARAMETER; - } - - private_layer = (tdm_private_layer*)layer; - - buffer = func_hwc_window->hwc_window_get_buffer(private_hwc_window->hwc_window_backend, - &ret); - if (buffer) - ret = tdm_layer_set_buffer_internal(private_layer, buffer); - else - ret = tdm_layer_unset_buffer_internal(private_layer); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set buffer(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - ret = func_hwc_window->hwc_window_get_info(private_hwc_window->hwc_window_backend, - &window_info); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: commit layer(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - info_layer = (tdm_info_layer *)&window_info; - ret = tdm_layer_set_info_internal(private_layer, info_layer); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set info(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - hwc_window_commit_handler = calloc(1, sizeof(tdm_private_hwc_window_commit_handler)); - if (!hwc_window_commit_handler) { - TDM_ERR("failed: alloc memory"); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - } - - hwc_window_commit_handler->private_hwc_window = private_hwc_window; - hwc_window_commit_handler->func = func; - hwc_window_commit_handler->user_data = user_data; - - ret = tdm_layer_commit_internal(private_layer, _tdm_hwc_window_layer_commit_handler, hwc_window_commit_handler); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: commit layer(window)"); - free(hwc_window_commit_handler); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_video_get_capability(tdm_hwc_window *hwc_window, - tdm_hwc_window_video_capability *video_capability) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(video_capability != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_video_get_capability) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_video_get_capability(private_hwc_window->hwc_window_backend, - video_capability); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_video_get_available_properties(tdm_hwc_window *hwc_window, - const tdm_prop **props, int *count) -{ - tdm_private_module *private_module; - tdm_func_hwc_window *func_hwc_window = NULL; - - HWC_WINDOW_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(props != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_hwc_window = &private_module->func_hwc_window; - - if (!func_hwc_window->hwc_window_video_get_available_properties) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_hwc_window->hwc_window_video_get_available_properties(private_hwc_window->hwc_window_backend, - props, count); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, - unsigned int id, tdm_value *value) +tdm_hwc_window_get_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value *value) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -583,14 +363,14 @@ tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; - if (!func_hwc_window->hwc_window_video_get_property) { + if (!func_hwc_window->hwc_window_get_property) { + /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; } - ret = func_hwc_window->hwc_window_video_get_property(private_hwc_window->hwc_window_backend, - id, value); + ret = func_hwc_window->hwc_window_get_property(private_hwc_window->hwc_window_backend, id, value); _pthread_mutex_unlock(&private_display->lock); @@ -598,8 +378,7 @@ tdm_hwc_window_video_get_property(tdm_hwc_window *hwc_window, } EXTERN tdm_error -tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, - unsigned int id, tdm_value value) +tdm_hwc_window_set_property(tdm_hwc_window *hwc_window, unsigned int id, tdm_value value) { tdm_private_module *private_module; tdm_func_hwc_window *func_hwc_window = NULL; @@ -611,14 +390,14 @@ tdm_hwc_window_video_set_property(tdm_hwc_window *hwc_window, private_module = private_output->private_module; func_hwc_window = &private_module->func_hwc_window; - if (!func_hwc_window->hwc_window_video_set_property) { + if (!func_hwc_window->hwc_window_set_property) { + /* LCOV_EXCL_START */ _pthread_mutex_unlock(&private_display->lock); TDM_WRN("not implemented!!"); return TDM_ERROR_NOT_IMPLEMENTED; } - ret = func_hwc_window->hwc_window_video_set_property(private_hwc_window->hwc_window_backend, - id, value); + ret = func_hwc_window->hwc_window_set_property(private_hwc_window->hwc_window_backend, id, value); _pthread_mutex_unlock(&private_display->lock); diff --git a/src/tdm_macro.h b/src/tdm_macro.h index a84b82a..5b8f861 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -253,7 +253,7 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, { TDM_THREAD_CB_VBLANK_CREATE, "vblank-create" }, - { TDM_THREAD_CB_NEED_VALIDATE, "need-validate" }, + { TDM_THREAD_CB_HWC_COMMIT, "hwc-commit" }, }; TDM_TYPE_NAME_FN(cb_type) diff --git a/src/tdm_output.c b/src/tdm_output.c index 9b9d200..ee760c1 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -127,20 +127,6 @@ _tdm_output_vblank_timeout_update(tdm_private_output *private_output, int ms_del } } -static tdm_private_hwc_window * -_tdm_output_find_private_hwc_window(tdm_private_output *private_output, - tdm_hwc_window *hwc_window_backend) -{ - tdm_private_hwc_window *private_hwc_window = NULL; - - LIST_FOR_EACH_ENTRY(private_hwc_window, &private_output->hwc_window_list, link) { - if (private_hwc_window->hwc_window_backend == hwc_window_backend) - return private_hwc_window; - } - - return NULL; -} - INTERN tdm_error tdm_output_init(tdm_private_display *private_display) { @@ -1563,614 +1549,29 @@ tdm_output_create_capture(tdm_output *output, tdm_error *error) return capture; } -/* LCOV_EXCL_START */ -EXTERN tdm_hwc_window * -tdm_output_hwc_create_window(tdm_output *output, tdm_error *error) +EXTERN tdm_hwc * +tdm_output_get_hwc(tdm_output *output, tdm_error *error) { - tdm_hwc_window *hwc_window = NULL; + tdm_private_hwc *private_hwc = NULL; OUTPUT_FUNC_ENTRY_ERROR(); _pthread_mutex_lock(&private_display->lock); - if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 0, error); - else { - TDM_ERR("output(%p) not support HWC", private_output); + private_hwc = private_output->private_hwc; + if (!private_hwc) { if (error) *error = TDM_ERROR_BAD_REQUEST; - } - - _pthread_mutex_unlock(&private_display->lock); - - return hwc_window; -} - -EXTERN tdm_hwc_window * -tdm_output_hwc_create_video_window(tdm_output *output, tdm_error *error) -{ - tdm_hwc_window *hwc_window = NULL; - - OUTPUT_FUNC_ENTRY_ERROR(); - - _pthread_mutex_lock(&private_display->lock); - - if (private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC) - hwc_window = (tdm_hwc_window *)tdm_hwc_window_create_internal(private_output, 1, error); - else { - TDM_ERR("output(%p) not support HWC", private_output); - if (error) - *error = TDM_ERROR_BAD_REQUEST; - } - - _pthread_mutex_unlock(&private_display->lock); - - return hwc_window; -} - -EXTERN tdm_error -tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window) -{ - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(hwc_window != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - ret = tdm_hwc_window_destroy_internal(hwc_window); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_validate(tdm_output *output, tdm_hwc_window **composited_wnds, - uint32_t num_wnds, uint32_t *num_types) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - tdm_private_hwc_window **composited_wnds_frontend = NULL; - tdm_hwc_window **composited_wnds_backend = NULL; - int i; - - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(num_types != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_validate) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - if (num_wnds == 0) { - ret = func_output->output_hwc_validate(private_output->output_backend, NULL, 0, num_types); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; - } - - composited_wnds_backend = calloc(num_wnds, sizeof(tdm_hwc_window *)); - if (!composited_wnds_backend) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - } - - composited_wnds_frontend = (tdm_private_hwc_window **)composited_wnds; - - for (i = 0; i < num_wnds; i++) - composited_wnds_backend[i] = composited_wnds_frontend[i]->hwc_window_backend; - - ret = func_output->output_hwc_validate(private_output->output_backend, composited_wnds_backend, num_wnds, num_types); - - free(composited_wnds_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_set_need_validate_handler(tdm_output *output, - tdm_output_need_validate_handler hndl) -{ - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(hndl != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - /* there's no reason to allow this */ - if (private_output->need_validate.hndl) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OPERATION_FAILED; - } - - private_output->need_validate.hndl = hndl; - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN 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) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - tdm_private_hwc_window * private_hwc_window = NULL; - int i = 0; - - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(num_elements != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_changed_composition_types) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_get_changed_composition_types(private_output->output_backend, - num_elements, hwc_window, composition_types); - if (ret != TDM_ERROR_NONE) { - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - if (hwc_window == NULL || composition_types == NULL) { - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; - } - - for (i = 0; i < *num_elements; i++) { - - private_hwc_window = _tdm_output_find_private_hwc_window(private_output, hwc_window[i]); - - if (private_hwc_window == NULL) { - TDM_ERR("failed! This should never happen!"); - func_output->output_hwc_destroy_window(private_output->output_backend, hwc_window[i]); - *num_elements = 0; - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OPERATION_FAILED; - } - - hwc_window[i] = (tdm_hwc_window*)private_hwc_window; - } - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -tdm_error -tdm_output_hwc_accept_changes(tdm_output *output) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_validate) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_accept_changes(private_output->output_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -tbm_surface_queue_h -tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - tbm_surface_queue_h queue = NULL; - - OUTPUT_FUNC_ENTRY_ERROR(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - if (error) - *error = TDM_ERROR_BAD_REQUEST; - _pthread_mutex_unlock(&private_display->lock); - return NULL; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_target_buffer_queue) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); return NULL; } - queue = func_output->output_hwc_get_target_buffer_queue(private_output->output_backend, error); - - _pthread_mutex_unlock(&private_display->lock); - - return queue; -} - -EXTERN tdm_error -tdm_output_hwc_set_client_target_buffer(tdm_output *output, tbm_surface_h target_buffer, tdm_hwc_region damage) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - if (tdm_debug_dump & TDM_DUMP_FLAG_WINDOW) { - char str[TDM_PATH_LEN]; - static int i; - snprintf(str, TDM_PATH_LEN, "target_window_%d_%03d", - private_output->index, i++); - tdm_helper_dump_buffer_str(target_buffer, tdm_debug_dump_dir, str); - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_set_client_target_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_set_client_target_buffer(private_output->output_backend, target_buffer, damage); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -EXTERN tdm_error -tdm_output_hwc_unset_client_target_buffer(tdm_output *output) -{ - tdm_private_module *private_module; - tdm_func_output *func_output = NULL; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_unset_client_target_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_unset_client_target_buffer(private_output->output_backend); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -static void -_tdm_output_hwc_layer_commit_handler(tdm_layer *layer, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, - void *user_data) -{ - tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler = (tdm_private_output_hwc_target_buffer_commit_handler *)user_data; - tdm_output_hwc_target_buffer_commit_handler func = output_hwc_target_buffer_commit_handler->func; - tdm_output *output = (tdm_output *)output_hwc_target_buffer_commit_handler->private_output; - void *data = output_hwc_target_buffer_commit_handler->user_data; - - func(output, sequence, tv_sec, tv_usec, data); - - free(output_hwc_target_buffer_commit_handler); -} - -tdm_error -tdm_output_hwc_commit_client_target_buffer(tdm_output *output, tdm_output_hwc_target_buffer_commit_handler func, void *user_data) -{ - tdm_private_module *private_module; - tdm_func_output *func_output; - tdm_private_output_hwc_target_buffer_commit_handler *output_hwc_target_buffer_commit_handler; - tdm_layer *layer = NULL; - tdm_private_layer *private_layer; - const tdm_output_mode *mode; - tbm_surface_h buffer; - - OUTPUT_FUNC_ENTRY(); - - _pthread_mutex_lock(&private_display->lock); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_BAD_REQUEST; - } - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_client_target_buffer_layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - layer = func_output->output_hwc_get_client_target_buffer_layer(private_output->output_backend, - &ret); - if (!layer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("no assigned layer!!"); - return TDM_ERROR_INVALID_PARAMETER; - } - - private_layer = (tdm_private_layer*)layer; - - if (!func_output->output_hwc_get_client_target_buffer) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - buffer = func_output->output_hwc_get_client_target_buffer(private_output->output_backend, - &ret); - if (buffer) - ret = tdm_layer_set_buffer_internal(private_layer, buffer); - else - ret = tdm_layer_unset_buffer_internal(private_layer); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set info(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - if (private_output->need_set_target_info) { - mode = private_output->current_mode; - private_output->target_buffer_info.src_config.size.h = mode->hdisplay; - private_output->target_buffer_info.src_config.size.v = mode->vdisplay; - private_output->target_buffer_info.src_config.pos.x = 0; - private_output->target_buffer_info.src_config.pos.y = 0; - private_output->target_buffer_info.src_config.pos.w = mode->hdisplay; - private_output->target_buffer_info.src_config.pos.h = mode->vdisplay; - private_output->target_buffer_info.dst_pos.x = 0; - private_output->target_buffer_info.dst_pos.y = 0; - private_output->target_buffer_info.dst_pos.w = mode->hdisplay; - private_output->target_buffer_info.dst_pos.h = mode->vdisplay; - private_output->target_buffer_info.transform = TDM_TRANSFORM_NORMAL; - - ret = tdm_layer_set_info_internal(private_layer, &private_output->target_buffer_info); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: layer set info(window)"); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - private_output->need_set_target_info = 0; - } - - output_hwc_target_buffer_commit_handler = calloc(1, sizeof(tdm_private_output_hwc_target_buffer_commit_handler)); - if (!output_hwc_target_buffer_commit_handler) { - TDM_ERR("failed: alloc memory"); - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_OUT_OF_MEMORY; - } - - output_hwc_target_buffer_commit_handler->private_output = private_output; - output_hwc_target_buffer_commit_handler->func = func; - output_hwc_target_buffer_commit_handler->user_data = user_data; - - ret = tdm_layer_commit_internal(private_layer, _tdm_output_hwc_layer_commit_handler, output_hwc_target_buffer_commit_handler); - if (ret != TDM_ERROR_NONE) { - TDM_ERR("failed: commit layer(target buffer)"); - free(output_hwc_target_buffer_commit_handler); - _pthread_mutex_unlock(&private_display->lock); - return ret; - } - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -tdm_error -tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format **formats, - int *count) -{ - tdm_private_module *private_module; - tdm_func_output *func_output; - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(formats != NULL, TDM_ERROR_INVALID_PARAMETER); - TDM_RETURN_VAL_IF_FAIL(count != NULL, TDM_ERROR_INVALID_PARAMETER); - - _pthread_mutex_lock(&private_display->lock); - - private_module = private_output->private_module; - func_output = &private_module->func_output; - - if (!func_output->output_hwc_get_video_supported_formats) { - _pthread_mutex_unlock(&private_display->lock); - TDM_WRN("not implemented!!"); - return TDM_ERROR_NOT_IMPLEMENTED; - } - - ret = func_output->output_hwc_get_video_supported_formats( - private_output->output_backend, formats, count); - - _pthread_mutex_unlock(&private_display->lock); - - return ret; -} - -static int -_is_hwc_output_still_existed(tdm_private_output *private_output) -{ - tdm_private_module *private_module = private_output->private_module; - tdm_private_output *o = NULL; - - LIST_FOR_EACH_ENTRY(o, &private_module->output_list, link) { - if (!(o->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) - continue; - - if (o == private_output) - goto exist; - } - - return 0; - -exist: - return 1; -} - -/* gets called on behalf of the ecore-main-loop thread */ -INTERN void -tdm_output_need_validate_handler_thread(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) -{ - tdm_private_output *private_output = object; - - TDM_RETURN_IF_FAIL(private_output != NULL); - - _pthread_mutex_lock(&private_display->lock); - - /* as we get 'private_output' within an event, an output this 'private_output' - * points to can be destroyed already */ - if (!_is_hwc_output_still_existed(private_output)) { - _pthread_mutex_unlock(&private_display->lock); - return; - } + if (error) + *error = TDM_ERROR_NONE; _pthread_mutex_unlock(&private_display->lock); - TDM_INFO("tdm-backend asks for revalidation for the output:%p.", private_output); - - if (private_output->need_validate.hndl) - private_output->need_validate.hndl((tdm_output*)private_output); -} - -/* gets called on behalf of the tdm-thread */ -static tdm_error -_need_validate_handler(int fd, tdm_event_loop_mask mask, void *user_data) -{ - tdm_thread_cb_need_validate ev; - tdm_private_output *private_output; - tdm_error ret; - uint64_t value; - - private_output = (tdm_private_output *)user_data; - - if (read(private_output->need_validate.event_fd, &value, sizeof(value)) < 0) { - TDM_ERR("error while trying to read from a need_validate.event_fd fd."); - return TDM_ERROR_OPERATION_FAILED; - } - - memset(&ev, 0, sizeof ev); - ev.base.type = TDM_THREAD_CB_NEED_VALIDATE; - ev.base.length = sizeof ev; - ev.base.object_stamp = private_output->stamp; - ev.base.data = NULL; - ev.base.sync = 0; - - ret = tdm_thread_cb_call(private_output, &ev.base, 1); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - TDM_INFO("tdm-thread: get a 'need to revalidate' event for the ouptut:%p.", private_output); - - /* who cares about this? */ - return TDM_ERROR_NONE; -} - -INTERN tdm_error -tdm_output_need_validate_event_init(tdm_output *output) -{ - int fd; - - OUTPUT_FUNC_ENTRY(); - - TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); - - if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_HWC)) { - TDM_ERR("output(%p) not support HWC", private_output); - return TDM_ERROR_BAD_REQUEST; - } - - /* build in eventfd fds into event_loop listened & handled by the tdm-thread */ - fd = eventfd(0, 0); - TDM_WARNING_IF_FAIL(fd >= 0); - - private_output->need_validate.event_source = tdm_event_loop_add_fd_handler(private_display, - fd, TDM_EVENT_LOOP_READABLE, _need_validate_handler, private_output, &ret); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - private_output->need_validate.event_fd = fd; - - TDM_INFO("register an output:%p for the revalidation, event_fd:%d.", private_output, fd); - - return ret; + return private_hwc; } INTERN tdm_error diff --git a/src/tdm_private.h b/src/tdm_private.h index 22c984c..5e1ed84 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -93,6 +93,11 @@ tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp tdm_private_output * tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend); +void * +tdm_display_find_hwc_stamp(tdm_private_display *private_display, double stamp); +tdm_private_hwc * +tdm_display_find_private_hwc(tdm_private_display *private_display, tdm_hwc *hwc_backend); + tdm_error tdm_output_init(tdm_private_display *private_display); @@ -104,8 +109,6 @@ tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data); -tdm_error -tdm_output_cb_need_validate(tdm_private_output *private_output); void tdm_output_vblank_print_wait_information(tdm_private_output *private_output, void *user_data); @@ -118,10 +121,6 @@ tdm_error tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value); tdm_error -tdm_output_need_validate_event_init(tdm_output *output); -void -tdm_output_need_validate_handler_thread(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); -tdm_error tdm_output_choose_commit_per_vblank_mode(tdm_private_output *private_output, int mode); void @@ -168,9 +167,11 @@ tdm_pp_create_internal(tdm_private_module *private_module, tdm_error *error); void tdm_pp_destroy_internal(tdm_private_pp *private_pp); -tdm_hwc_window * -tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, tdm_error *error); tdm_error +tdm_hwc_init(tdm_private_display *private_display); +tdm_hwc_window * +tdm_hwc_window_create_internal(tdm_private_hwc *private_hwc, tdm_error *error); +void tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window); tdm_error diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 980ebfe..37adf72 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -100,6 +100,7 @@ typedef struct _tdm_private_module tdm_private_module; typedef struct _tdm_private_display tdm_private_display; typedef struct _tdm_private_output tdm_private_output; typedef struct _tdm_private_layer tdm_private_layer; +typedef struct _tdm_private_hwc tdm_private_hwc; typedef struct _tdm_private_hwc_window tdm_private_hwc_window; typedef struct _tdm_private_pp tdm_private_pp; typedef struct _tdm_private_capture tdm_private_capture; @@ -110,8 +111,7 @@ typedef struct _tdm_private_output_change_handler tdm_private_output_change_hand typedef struct _tdm_private_output_commit_handler tdm_private_output_commit_handler; typedef struct _tdm_private_output_vblank_handler tdm_private_output_vblank_handler; typedef struct _tdm_private_layer_commit_handler tdm_private_layer_commit_handler; -typedef struct _tdm_private_hwc_window_commit_handler tdm_private_hwc_window_commit_handler; -typedef struct _tdm_private_output_hwc_target_buffer_window_commit_handler tdm_private_output_hwc_target_buffer_commit_handler; +typedef struct _tdm_private_hwc_commit_handler tdm_private_hwc_commit_handler; typedef struct _tdm_private_layer_buffer tdm_private_layer_buffer; @@ -130,6 +130,7 @@ struct _tdm_private_module { tdm_func_display func_display; tdm_func_output func_output; tdm_func_layer func_layer; + tdm_func_hwc func_hwc; tdm_func_hwc_window func_hwc_window; tdm_func_pp func_pp; tdm_func_capture func_capture; @@ -196,7 +197,6 @@ struct _tdm_private_output { int regist_dpms_cb; struct list_head layer_list; - struct list_head hwc_window_list; struct list_head capture_list; struct list_head vblank_handler_list; struct list_head output_commit_handler_list; @@ -214,13 +214,6 @@ struct _tdm_private_output { void **layers_ptr; - struct { - /* look at the tdm_output_set_need_revalidate_handler() declaration for the details */ - tdm_output_need_validate_handler hndl; - int event_fd; - tdm_event_loop_source *event_source; - } need_validate; - tdm_info_layer target_buffer_info; /* layer_info for the target_buffer */ /* calling a output commit per a vblank */ @@ -232,6 +225,7 @@ struct _tdm_private_output { /* hwc */ int need_set_target_info; + tdm_private_hwc *private_hwc; }; struct _tdm_private_layer { @@ -271,14 +265,30 @@ struct _tdm_private_layer { unsigned int fps_count; }; -struct _tdm_private_hwc_window { +struct _tdm_private_hwc { struct list_head link; + tdm_private_module *private_module; + int index; + double stamp; - tdm_private_display *private_display; tdm_private_output *private_output; + struct list_head hwc_window_list; + struct list_head hwc_commit_handler_list; + + int regist_commit_cb; + + tdm_hwc *hwc_backend; +}; + +struct _tdm_private_hwc_window { + struct list_head link; + + tdm_private_module *private_module; + + tdm_private_hwc *private_hwc; tdm_hwc_window *hwc_window_backend; }; @@ -394,16 +404,14 @@ struct _tdm_private_output_commit_handler { pid_t owner_tid; }; -struct _tdm_private_hwc_window_commit_handler { - tdm_private_hwc_window *private_hwc_window; - tdm_hwc_window_commit_handler func; - void *user_data; -}; +struct _tdm_private_hwc_commit_handler { + struct list_head link; -struct _tdm_private_output_hwc_target_buffer_window_commit_handler { - tdm_private_output *private_output; - tdm_output_hwc_target_buffer_commit_handler func; + tdm_private_hwc *private_hwc; + tdm_hwc_commit_handler func; void *user_data; + + pid_t owner_tid; }; struct _tdm_private_layer_commit_handler { @@ -458,7 +466,7 @@ typedef enum { TDM_THREAD_CB_CAPTURE_DONE, TDM_THREAD_CB_VBLANK_SW, TDM_THREAD_CB_VBLANK_CREATE, - TDM_THREAD_CB_NEED_VALIDATE, + TDM_THREAD_CB_HWC_COMMIT, TDM_THREAD_CB_MAX, } tdm_thread_cb_type; @@ -471,7 +479,7 @@ 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; typedef struct _tdm_thread_cb_vblank_create tdm_thread_cb_vblank_create; -typedef struct _tdm_thread_cb_need_validate tdm_thread_cb_need_validate; +typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_hwc_commit; struct _tdm_thread_cb_base { tdm_thread_cb_type type; @@ -518,10 +526,6 @@ struct _tdm_thread_cb_vblank_create { double vblank_stamp; }; -struct _tdm_thread_cb_need_validate { - tdm_thread_cb_base base; -}; - struct argument_details { char type; int nullable; diff --git a/src/tdm_thread.c b/src/tdm_thread.c index ea891a2..997d772 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -459,7 +459,7 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: case TDM_THREAD_CB_VBLANK_CREATE: - case TDM_THREAD_CB_NEED_VALIDATE: + case TDM_THREAD_CB_HWC_COMMIT: /* this event comes from other thread. so we don't need to propagate this to other thread */ ret = tdm_thread_cb_call(NULL, base, 0); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); diff --git a/utests/Makefile.am b/utests/Makefile.am index 7c22473..7aed5c8 100644 --- a/utests/Makefile.am +++ b/utests/Makefile.am @@ -11,8 +11,6 @@ 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_client.cpp \ src/ut_tdm_backend_env.cpp \ src/ut_tdm_backend_display.cpp \ diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index 12be19c..fb1b190 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -43,7 +43,6 @@ public: tdm_error error; tdm_hwc_window **hwc_wins; - tdm_hwc_window *video_hwc_win; int hwc_count; }; @@ -67,13 +66,10 @@ void TDMHwcWindow::SetUp(void) 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); + hw = tdm_hwc_create_window(outputs[w], &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[o], &error); } } } @@ -81,26 +77,16 @@ void TDMHwcWindow::SetUp(void) 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); + tdm_hwc_window_destroy(hwc_wins[w]); TDMOutput::TearDown(); } -/* tdm_error tdm_output_hwc_destroy_window(tdm_output *output, tdm_hwc_window *hwc_window); */ +/* void tdm_hwc_window_destroy(tdm_hwc_window *hwc_window); */ +/* TEST_P(TDMHwcWindow, DestroyWindowFailNull) { - 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[o], NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } - } + tdm_hwc_window_destroy(NULL); } TEST_P(TDMHwcWindow, DestroyWindowSuccessful) @@ -111,27 +97,27 @@ TEST_P(TDMHwcWindow, DestroyWindowSuccessful) 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); + hw = tdm_hwc_create_window(outputs[o], &error); ASSERT_EQ(TDM_ERROR_NONE, error); - error = tdm_output_hwc_destroy_window(outputs[o], hw); + error = tdm_hwc_window_destroy(outputs[o], hw); ASSERT_EQ(TDM_ERROR_NONE, error); } } } +*/ - -/* tbm_surface_queue_h tdm_hwc_window_get_tbm_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); */ +/* tbm_surface_queue_h tdm_hwc_window_get_buffer_queue(tdm_hwc_window *hwc_window, tdm_error *error); */ 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); + queue = tdm_hwc_window_get_buffer_queue(NULL, &error); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); - queue = tdm_hwc_window_get_tbm_buffer_queue(NULL, NULL); + queue = tdm_hwc_window_get_buffer_queue(NULL, NULL); ASSERT_EQ(NULL, queue); } @@ -152,12 +138,12 @@ TEST_P(TDMHwcWindow, GetBufferQueueSuccessful) 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[w], &error); + queue = tdm_hwc_window_get_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[w], NULL); + queue = tdm_hwc_window_get_buffer_queue(hwc_wins[w], NULL); tbm_surface_queue_destroy(queue); ASSERT_NE(NULL, queue); } @@ -197,12 +183,12 @@ TEST_P(TDMHwcWindow, SetCompositionTypeFailInvalieCompositionType) } } -/* tdm_error tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_hwc_region damage); */ +/* tdm_error tdm_hwc_window_set_buffer_damage(tdm_hwc_window *hwc_window, tdm_region damage); */ TEST_P(TDMHwcWindow, SetBufferDamageFailNullHwcWindow) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_region damage = {.num_rects = 0, .rects = NULL}; error = tdm_hwc_window_set_buffer_damage(NULL, damage); ASSERT_NE(TDM_ERROR_NONE, error); @@ -212,7 +198,7 @@ TEST_P(TDMHwcWindow, SetBufferDamageFailNullDamageRects) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 1, .rects = NULL}; + tdm_region damage = {.num_rects = 1, .rects = NULL}; for (int w = 0; w < hwc_count; w++) { error = tdm_hwc_window_set_buffer_damage(hwc_wins[w], damage); @@ -226,7 +212,7 @@ 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}; + tdm_region damage = {.num_rects = 1, .rects = rects}; for (int w = 0; w < hwc_count; w++) { error = tdm_hwc_window_set_buffer_damage(hwc_wins[w], damage); @@ -292,92 +278,8 @@ TEST_P(TDMHwcWindow, SetBufferSuccessful) } } -/* tdm_error tdm_hwc_window_set_flags(tdm_hwc_window *hwc_window, tdm_hwc_window_flag flags); */ -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_P(TDMHwcWindow, SetFlagsSuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - - for (int w = 0; w < hwc_count; w++) { - - 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_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_P(TDMHwcWindow, UnsetFlagsSuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_flag flag = (tdm_hwc_window_flag)0; - - for (int w = 0; w < hwc_count; w++) { - - 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_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); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (hwc_count > 0) { - error = tdm_hwc_window_video_get_capability(hwc_wins[0], NULL); - ASSERT_NE(TDM_ERROR_NONE, error); - } - -} - -TEST_P(TDMHwcWindow, VideoGetCapabilitySuccessful) -{ - TDM_UT_SKIP_FLAG(has_outputs); - - tdm_hwc_window_video_capability video_capability; - - 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[w], &video_capability); - ASSERT_NE(TDM_ERROR_NONE, error); - - if (video_hwc_win != NULL) { - error = tdm_hwc_window_video_get_capability(video_hwc_win, &video_capability); - ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); - } - } -} - - -/* tdm_hwc_window_video_get_available_properties() */ +/* tdm_hwc_get_available_properties() */ +/* TEST_P(TDMHwcWindow, GetAvailablePropertiesFailNullWin) { TDM_UT_SKIP_FLAG(has_outputs); @@ -386,13 +288,13 @@ TEST_P(TDMHwcWindow, GetAvailablePropertiesFailNullWin) const tdm_prop *props; int count; - error = tdm_hwc_window_video_get_available_properties(NULL, &props, &count); + error = tdm_hwc_get_available_properties(NULL, &props, &count); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_available_properties(video_hwc_win, NULL, &count); + error = tdm_hwc_get_available_properties(video_hwc_win, NULL, &count); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_available_properties(video_hwc_win, &props, NULL); + error = tdm_hwc_get_available_properties(video_hwc_win, &props, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -405,11 +307,12 @@ TEST_P(TDMHwcWindow, GetAvailablePropertiesSuccess) const tdm_prop *props; int count; - error = tdm_hwc_window_video_get_available_properties(video_hwc_win, &props, &count); + error = tdm_hwc_get_available_properties(video_hwc_win, &props, &count); ASSERT_TRUE(TDM_ERROR_NONE == error || TDM_ERROR_NOT_IMPLEMENTED == error); } +*/ -/* tdm_hwc_window_video_get_property() */ +/* tdm_hwc_window_get_property() */ TEST_P(TDMHwcWindow, GetPropertyFailNull) { TDM_UT_SKIP_FLAG(has_outputs); @@ -418,10 +321,10 @@ TEST_P(TDMHwcWindow, GetPropertyFailNull) tdm_value value; int id = 1; - error = tdm_hwc_window_video_get_property(NULL, id, &value); + error = tdm_hwc_window_get_property(NULL, id, &value); ASSERT_NE(TDM_ERROR_NONE, error); - error = tdm_hwc_window_video_get_property(video_hwc_win, id, NULL); + error = tdm_hwc_window_get_property(video_hwc_win, id, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -433,11 +336,11 @@ TEST_P(TDMHwcWindow, GetPropertyFailWrongId) tdm_value value; int id = INT_MAX; - error = tdm_hwc_window_video_get_property(video_hwc_win, id, &value); + error = tdm_hwc_window_get_property(video_hwc_win, id, &value); ASSERT_NE(TDM_ERROR_NONE, error); } -/* tdm_hwc_window_video_set_property() */ +/* tdm_hwc_window_set_property() */ TEST_P(TDMHwcWindow, SetPropertyFailNull) { TDM_UT_SKIP_FLAG(has_outputs); @@ -446,7 +349,7 @@ TEST_P(TDMHwcWindow, SetPropertyFailNull) tdm_value value; int id = 1; - error = tdm_hwc_window_video_set_property(NULL, id, value); + error = tdm_hwc_window_set_property(NULL, id, value); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -458,7 +361,7 @@ TEST_P(TDMHwcWindow, SetPropertyFailWrongId) tdm_value value; int id = INT_MAX; - error = tdm_hwc_window_video_set_property(video_hwc_win, id, value); + error = tdm_hwc_window_set_property(video_hwc_win, id, value); ASSERT_NE(TDM_ERROR_NONE, error); } diff --git a/utests/src/ut_tdm_output_hwc.cpp b/utests/src/ut_tdm_output_hwc.cpp index e84860d..29019c5 100644 --- a/utests/src/ut_tdm_output_hwc.cpp +++ b/utests/src/ut_tdm_output_hwc.cpp @@ -57,15 +57,16 @@ void TDMOutputHwc::TearDown(void) TDMOutput::TearDown(); } -/* tdm_hwc_window * tdm_output_hwc_create_window(tdm_output *output, tdm_error *error); */ +/* tdm_hwc_window * tdm_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_EQ(NULL, tdm_hwc_create_window(NULL, &error)); ASSERT_NE(TDM_ERROR_NONE, error); } +/* TEST_P(TDMOutputHwc, CreateWindowSuccessful) { TDM_UT_SKIP_FLAG(has_outputs); @@ -74,40 +75,40 @@ TEST_P(TDMOutputHwc, CreateWindowSuccessful) 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); + hw = tdm_hwc_create_window(hwc[o], &error); ASSERT_EQ(TDM_ERROR_NONE, error); + tdm_hwc_window_destroy(hw); } else { - ASSERT_EQ(NULL, tdm_output_hwc_create_window(outputs[o], &error)); + ASSERT_EQ(NULL, tdm_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_error tdm_hwc_set_client_target_buffer(tdm_output *output, + tbm_surface_h target_buffer, tdm_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; + tdm_region reg; tbm_surface_h target_buff = CreateBufferForOutput(0); - error = tdm_output_hwc_set_client_target_buffer(NULL, target_buff, reg, NULL, 0 ); + error = tdm_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}; + tdm_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); + error = tdm_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); tbm_surface_internal_destroy(target_buff); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -117,18 +118,18 @@ TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulSetBuff) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_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, + error = tdm_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, + error = tdm_hwc_set_client_target_buffer(outputs[o], target_buff, damage, NULL, 0); tbm_surface_internal_destroy(target_buff); ASSERT_NE(TDM_ERROR_NONE, error); @@ -140,15 +141,15 @@ TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff) { TDM_UT_SKIP_FLAG(has_outputs); - tdm_hwc_region damage = {.num_rects = 0, .rects = NULL}; + tdm_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, + error = tdm_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, + error = tdm_hwc_set_client_target_buffer(outputs[o], NULL, damage, NULL, 0); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -156,18 +157,19 @@ TEST_P(TDMOutputHwc, SetClientTargetBufferSuccessfulResetBuff) } */ -/* tbm_surface_queue_h tdm_output_hwc_get_target_buffer_queue(tdm_output *output, tdm_error *error); */ +/* tbm_surface_queue_h tdm_hwc_get_client_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); + queue = tdm_hwc_get_client_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); + queue = tdm_hwc_get_client_target_buffer_queue(NULL, NULL); ASSERT_EQ(NULL, queue); } @@ -178,11 +180,12 @@ TEST_P(TDMOutputHwc, GetTargetBufferQueueFainNoHwc) 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); + queue = tdm_hwc_get_client_target_buffer_queue(outputs[o], &error); ASSERT_NE(TDM_ERROR_NONE, error); ASSERT_EQ(NULL, queue); } } +*/ TEST_P(TDMOutputHwc, GetTargetBufferQueueSuccessful) { @@ -192,28 +195,28 @@ TEST_P(TDMOutputHwc, GetTargetBufferQueueSuccessful) 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); + queue = tdm_hwc_get_client_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); + queue = tdm_hwc_get_client_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); + queue = tdm_hwc_get_client_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); + queue = tdm_hwc_get_client_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, +/* tdm_error tdm_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) @@ -221,11 +224,11 @@ TEST_P(TDMOutputHwc, ValidateFailNull) TDM_UT_SKIP_FLAG(has_outputs); uint32_t num_types; - error = tdm_output_hwc_validate(NULL, NULL, 0, &num_types); + error = tdm_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); + error = tdm_hwc_validate(outputs[0], NULL, 0, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } } @@ -237,7 +240,7 @@ TEST_P(TDMOutputHwc, ValidateFailNoHwc) uint32_t num_types; for (int o = 0; o < output_count; o++) { - error = tdm_output_hwc_validate(outputs[o], &num_types); + error = tdm_hwc_validate(outputs[o], &num_types); ASSERT_NE(TDM_ERROR_NONE, error); } } @@ -249,31 +252,31 @@ TEST_P(TDMOutputHwc, ValidateSuccessful) 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); + error = tdm_hwc_validate(outputs[o], &num_types); ASSERT_EQ(TDM_ERROR_NONE, error); } else { - error = tdm_output_hwc_validate(outputs[o], &num_types); + error = tdm_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, +/* tdm_error tdm_hwc_get_changed_composition_types(tdm_hwc *hwc, 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); + error = tdm_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); + error = tdm_hwc_get_changed_composition_types(outputs[0], NULL, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } } @@ -285,11 +288,11 @@ TEST_P(TDMOutputHwc, GetChangedCompositionTypesFailNoHwc) 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); + error = tdm_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) { @@ -309,48 +312,48 @@ TEST_P(TDMHwcWindow, GetChangedCompositionTypesSuccessful) 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); + error = tdm_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); + error = tdm_hwc_get_changed_composition_types(outputs[o], &get_num, NULL, NULL); ASSERT_EQ(TDM_ERROR_NONE, error); ASSERT_EQ(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); + error = tdm_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); + error = tdm_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); */ - +/* tdm_error tdm_hwc_accept_changes(tdm_hwc *hwc); */ +/* TEST_P(TDMOutputHwc, AcceptChangesFailNull) { TDM_UT_SKIP_FLAG(has_outputs); - error = tdm_output_hwc_accept_changes(NULL); + error = tdm_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]); + error = tdm_hwc_accept_changes(outputs[o]); ASSERT_NE(TDM_ERROR_NONE, error); } } - +*/ /* TODO: fix the validate test later. TEST_P(TDMHwcWindow, AcceptChangesSuccessful) { @@ -365,11 +368,11 @@ TEST_P(TDMHwcWindow, AcceptChangesSuccessful) 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); + error = tdm_hwc_validate(outputs[o], &validate_num); ASSERT_EQ(TDM_ERROR_NONE, error); if (validate_num > 0) { - error = tdm_output_hwc_accept_changes(outputs[o]); + error = tdm_hwc_accept_changes(outputs[o]); ASSERT_EQ(TDM_ERROR_NONE, error); } } @@ -377,45 +380,15 @@ TEST_P(TDMHwcWindow, AcceptChangesSuccessful) } */ -/* 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() */ +/* tdm_hwc_get_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); + error = tdm_hwc_get_supported_formats(NULL, NULL, NULL); ASSERT_NE(TDM_ERROR_NONE, error); } @@ -429,18 +402,19 @@ TEST_P(TDMOutputHwc, GetVideoSupportedFormatsSuccessful) 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); + error = tdm_hwc_get_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); + error = tdm_hwc_get_supported_formats(outputs[o], &formats, &count); ASSERT_NE(TDM_ERROR_NONE, error); } } } +*/ #ifdef TDM_UT_TEST_WITH_PARAMS INSTANTIATE_TEST_CASE_P(TDMOutputHwcParams, -- 2.7.4 From 21d7d5d114c1e79b2d9ce2c52bb35c7adbc0a4bd Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 13 Apr 2018 10:51:29 +0900 Subject: [PATCH 16/16] package version up to 1.17.0 Change-Id: I40c285e4e703d8da3dcf997894885443f2001905 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index c7855e4..e7e92b0 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -2,7 +2,7 @@ %define UTEST_GCOV 0 Name: libtdm -Version: 1.16.13 +Version: 1.17.0 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4