From aff08f43b31fb88160915b27b19dfb70233313f7 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 23 Jan 2018 08:20:50 +0900 Subject: [PATCH 01/16] buffer: remove unused functions Change-Id: I6c73f3978a3f89422904390cb9683c8fd7b25b40 --- src/tdm_buffer.c | 36 ------------------------------------ src/tdm_private.h | 5 ----- 2 files changed, 41 deletions(-) diff --git a/src/tdm_buffer.c b/src/tdm_buffer.c index 3c9fb48..5d501b0 100644 --- a/src/tdm_buffer.c +++ b/src/tdm_buffer.c @@ -275,39 +275,3 @@ tdm_buffer_remove_destroy_handler(tbm_surface_h buffer, } } -INTERN tbm_surface_h -tdm_buffer_list_get_first_entry(struct list_head *list) -{ - tdm_buffer_info *buf_info = NULL; - - TDM_RETURN_VAL_IF_FAIL(list != NULL, NULL); - - if (LIST_IS_EMPTY(list)) - return NULL; - - buf_info = container_of((list)->next, buf_info, link); - - return buf_info->buffer; -} - -INTERN void -tdm_buffer_list_dump(struct list_head *list) -{ - tdm_buffer_info *buf_info = NULL; - char str[256], *p; - int len = sizeof(str); - - TDM_RETURN_IF_FAIL(list != NULL); - - p = str; - LIST_FOR_EACH_ENTRY(buf_info, list, link) { - if (len > 0) { - int l = snprintf(p, len, " %p", buf_info->buffer); - p += l; - len -= l; - } else - break; - } - - TDM_INFO("\t %s", str); -} diff --git a/src/tdm_private.h b/src/tdm_private.h index 5a07b89..a055105 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -200,11 +200,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); -tbm_surface_h -tdm_buffer_list_get_first_entry(struct list_head *list); -void -tdm_buffer_list_dump(struct list_head *list); - void tdm_buffer_remove_release_handler_internal(tbm_surface_h buffer); -- 2.7.4 From 7951d09e6a7d1029481935ac3399084dbc673427 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 12 Jan 2018 17:31:29 +0900 Subject: [PATCH 02/16] ini: first implementation Change-Id: I9e2fd2892279fbc84d1265802b5b33ef6d68dc27 --- configure.ac | 11 +- include/tdm_backend.h | 23 ++++ packaging/libtdm.spec | 2 + src/Makefile.am | 1 + src/tdm.c | 12 ++ src/tdm_config.c | 283 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_config.h | 67 ++++++++++++ src/tdm_private.h | 1 + tools/tdm_test_server.c | 4 +- 9 files changed, 402 insertions(+), 2 deletions(-) create mode 100644 src/tdm_config.c create mode 100644 src/tdm_config.h diff --git a/configure.ac b/configure.ac index 9a706cf..02919f8 100644 --- a/configure.ac +++ b/configure.ac @@ -44,7 +44,7 @@ fi PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner >= 1.7.0) -PKG_CHECK_MODULES(TDM, dlog libtbm libpng pixman-1 wayland-server) +PKG_CHECK_MODULES(TDM, dlog libtbm libpng pixman-1 wayland-server iniparser) PKG_CHECK_MODULES(TDM_CLIENT, dlog wayland-client) PKG_CHECK_MODULES(TTRACE, @@ -72,6 +72,14 @@ AC_ARG_WITH(tdm-module-path, AS_HELP_STRING([--with-tdm-module-path=PATH], [tdm AC_DEFINE_UNQUOTED(TDM_MODULE_PATH, "${TDM_MODULE_PATH}", [Directory for the modules of tdm]) AC_SUBST(TDM_MODULE_PATH) +# set the data dir for the tdm config +DEFAULT_TDM_DATA_PATH="${datadir}/tdm" +AC_ARG_WITH(tdm-data-path, AS_HELP_STRING([--with-tdm-data-path=PATH], [tdm data dir]), + [ TDM_DATA_PATH="$withval" ], + [ TDM_DATA_PATH="${DEFAULT_TDM_DATA_PATH}" ]) +AC_DEFINE_UNQUOTED(TDM_DATA_PATH, "${TDM_DATA_PATH}", [Directory for the data of tdm]) +AC_SUBST(TDM_DATA_PATH) + AC_SUBST([TDM_MAJOR_VERSION], [tdm_major_version]) AC_SUBST([TDM_MINOR_VERSION], [tdm_minor_version]) AC_SUBST([TDM_MICRO_VERSION], [tdm_micro_version]) @@ -105,4 +113,5 @@ echo "TDM_LIBS : $TDM_LIBS" echo "TDM_CLIENT_CFLAGS : $TDM_CLIENT_CFLAGS" echo "TDM_CLIENT_LIBS : $TDM_CLIENT_LIBS" echo "TDM_MODULE_PATH : $TDM_MODULE_PATH" +echo "TDM_DATA_PATH : $TDM_DATA_PATH" echo "" diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 09b1377..de6fb24 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -1446,6 +1446,29 @@ 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. * @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. diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 876648f..7140089 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -13,6 +13,7 @@ BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(libpng) BuildRequires: pkgconfig(ttrace) BuildRequires: pkgconfig(wayland-server) +BuildRequires: pkgconfig(iniparser) BuildRequires: pkgconfig(pixman-1) BuildRequires: gtest-devel @@ -82,6 +83,7 @@ LDFLAGS+=" -lgcov" %endif %reconfigure --disable-static --with-utests=${UTEST} \ + --with-tdm-data-path=%{TZ_SYS_RO_SHARE}/tdm \ CFLAGS="${CFLAGS} -Wall -Werror" \ CXXFLAGS="${CXXFLAGS} -Wall -Werror" \ LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed" diff --git a/src/Makefile.am b/src/Makefile.am index feabb5d..7ec1cd4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,7 @@ libtdm_la_CFLAGS = \ libtdm_la_SOURCES = \ $(top_srcdir)/protocol/tdm-protocol.c \ tdm_backend.c \ + tdm_config.c \ tdm_server.c \ tdm_vblank.c \ tdm_event_loop.c \ diff --git a/src/tdm.c b/src/tdm.c index 312bac9..96bed27 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -943,6 +943,14 @@ tdm_display_init(tdm_error *error) start = stamp1 = tdm_helper_get_time(); + ret = tdm_config_init(); + if (ret != TDM_ERROR_NONE) + goto failed_config; + + stamp2 = tdm_helper_get_time(); + TDM_DBG("config init time: %.3f ms", (stamp2 - stamp1) * 1000.0); + stamp1 = stamp2; + private_display = calloc(1, sizeof(tdm_private_display)); if (!private_display) { /* LCOV_EXCL_START */ @@ -1077,6 +1085,8 @@ failed_vblank: failed_mutex_init: free(private_display); failed_alloc: + tdm_config_deinit(); +failed_config: if (error) *error = ret; pthread_mutex_unlock(&gLock); @@ -1131,6 +1141,8 @@ tdm_display_deinit(tdm_display *dpy) tdm_debug_dump_dir = NULL; } + tdm_config_deinit(); + pthread_mutex_unlock(&gLock); TDM_INFO("done"); diff --git a/src/tdm_config.c b/src/tdm_config.c new file mode 100644 index 0000000..6686769 --- /dev/null +++ b/src/tdm_config.c @@ -0,0 +1,283 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * 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 + +#include "tdm_log.h" +#include "tdm_macro.h" +#include "tdm_list.h" +#include "tdm.h" +#include "tdm_private.h" +#include "tdm_config.h" + +#define TDM_CONFIG_FILENAME "tdm.ini" +#define TDM_CONFIG_GENERAL_SECTION "general" + +static dictionary *g_dic = NULL; +static pthread_mutex_t g_dic_lock; + +static int +_tdm_config_check_file_owner(const char *filepath) +{ + struct stat sb; + + if (stat(filepath, &sb) < 0) { + TDM_WRN("%s: %m", filepath); + return -1; + } + + if (sb.st_uid != getuid()) { + TDM_WRN("'%s': not owned by %u", filepath, getuid()); + return -1; + } + + return 0; +} + +static dictionary * +_tdm_config_load_file(const char *dir, const char *filename) +{ + char filepath[TDM_PATH_LEN]; + dictionary *dic; + + snprintf(filepath, sizeof filepath, "%s/%s", dir, filename); + + if (_tdm_config_check_file_owner(filepath) < 0) + return NULL; + + dic = iniparser_load(filepath); + TDM_RETURN_VAL_IF_FAIL(dic != NULL, NULL); + + if (!iniparser_find_entry(dic, TDM_CONFIG_GENERAL_SECTION)) { + TDM_ERR("no '%s' section: '%s'", TDM_CONFIG_GENERAL_SECTION, filepath); + iniparser_freedict(dic); + return NULL; + } + + TDM_INFO("opened successed: '%s'", filepath); + + return dic; +} + +static dictionary * +_tdm_config_load(void) +{ + dictionary *dic = NULL; + +#if 0 + /* not allowed: try to read from RW directory */ + dic = _tdm_config_load_file(TDM_SYSCONF_PATH, TDM_CONFIG_FILENAME); +#endif + + if (!dic) { + /* try to read from RO directory */ + dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME); + } + + return dic; +} + +INTERN tdm_error +tdm_config_init(void) +{ + if (g_dic) { + TDM_ERR("init failed: twice"); + return TDM_ERROR_OPERATION_FAILED; + } + + if (pthread_mutex_init(&g_dic_lock, NULL)) { + TDM_ERR("mutex init failed: %m"); + return TDM_ERROR_OUT_OF_MEMORY; + } + + g_dic = _tdm_config_load(); + if (!g_dic) { + if (!getenv("TDM_NO_CONFIG")) { + TDM_ERR("Loading config file failed!!"); + pthread_mutex_destroy(&g_dic_lock); + return TDM_ERROR_NONE; + } + } + + TDM_INFO("tdm config init done (%p)", g_dic); + + return TDM_ERROR_NONE; +} + +INTERN void +tdm_config_deinit(void) +{ + if (!g_dic) { + return; + } + + iniparser_freedict(g_dic); + g_dic = NULL; + + /* we don't need to lock/unlock here because we come here + * after tdm_thread has been destroyed + */ + pthread_mutex_destroy(&g_dic_lock); + + TDM_INFO("tdm config deinit done"); +} + +static const char* +_tdm_config_get_string_internal(dictionary *dic, const char *key, const char *default_value) +{ + char *temp = NULL; + const char *result; + + if (default_value) { + temp = strdup(default_value); + if (!temp) { + TDM_ERR("strdup failed: %m"); + return default_value; + } + } + + result = (const char *)iniparser_getstring(dic, key, temp); + if (!result || strlen(result) == 0) { + free(temp); + return default_value; + } + + free(temp); + + return result; +} + +INTERN int +tdm_config_get_int(const char *key, int default_value) +{ + const char *result; + int value; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value); + + if (!g_dic) { + TDM_INFO("%s = %d: default", key, default_value); + return default_value; + } + + pthread_mutex_lock(&g_dic_lock); + result = _tdm_config_get_string_internal(g_dic, key, NULL); + pthread_mutex_unlock(&g_dic_lock); + + if (!result) { + TDM_INFO("%s = %d: no key", key, default_value); + return default_value; + } + + value = (int)strtol(result, NULL, 0); + + TDM_INFO("%s = %d", key, value); + + return value; +} + +INTERN const char* +tdm_config_get_string(const char *key, const char *default_value) +{ + const char *result; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value); + + if (!g_dic) { + TDM_INFO("%s = %s: default", key, default_value); + return default_value; + } + + pthread_mutex_lock(&g_dic_lock); + result = _tdm_config_get_string_internal(g_dic, key, default_value); + pthread_mutex_unlock(&g_dic_lock); + + TDM_INFO("%s = %s", key, result); + + return result; +} + +INTERN tdm_error +tdm_config_set_int(const char *key, int value) +{ + char temp[TDM_NAME_LEN]; + int ret; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!g_dic) { + TDM_INFO("%s = %d set failed", key, value); + return TDM_ERROR_BAD_REQUEST; + } + + snprintf(temp, sizeof temp, "%d", value); + + pthread_mutex_lock(&g_dic_lock); + ret = iniparser_set(g_dic, key, (const char*)temp); + pthread_mutex_unlock(&g_dic_lock); + + TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); + + TDM_INFO("%s = %d set done", key, value); + + return TDM_ERROR_NONE; +} + +INTERN tdm_error +tdm_config_set_string(const char *key, const char *value) +{ + int ret; + + TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (!g_dic) { + TDM_INFO("%s = %s set failed", key, value); + return TDM_ERROR_BAD_REQUEST; + } + + pthread_mutex_lock(&g_dic_lock); + ret = iniparser_set(g_dic, key, value); + pthread_mutex_unlock(&g_dic_lock); + + TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); + + TDM_INFO("%s = %s set done", key, value); + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_config.h b/src/tdm_config.h new file mode 100644 index 0000000..b743f93 --- /dev/null +++ b/src/tdm_config.h @@ -0,0 +1,67 @@ +/************************************************************************** + * + * libtdm + * + * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved. + * + * Contact: Eunchul Kim , + * JinYoung Jeon , + * Taeheon Kim , + * YoungJun Cho , + * SooChan Lim , + * Boram Park + * + * 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. + * +**************************************************************************/ + +#ifndef _TDM_CONFIG_H_ +#define _TDM_CONFIG_H_ + +#include "tdm_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include "tdm_common.h" + +/** + * @file tdm_config.h + * @brief The config header file for a frontend library + */ + +tdm_error +tdm_config_init(void); +void +tdm_config_deinit(void); + +tdm_error +tdm_config_set_int(const char *key, int value); +tdm_error +tdm_config_set_string(const char *key, const char *value); + + +#ifdef __cplusplus +} +#endif + +#endif /* _TDM_CONFIG_H_ */ diff --git a/src/tdm_private.h b/src/tdm_private.h index a055105..f7c2a11 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -64,6 +64,7 @@ #include "tdm_macro.h" #include "tdm_helper.h" #include "tdm_thread.h" +#include "tdm_config.h" #ifdef __cplusplus extern "C" { diff --git a/tools/tdm_test_server.c b/tools/tdm_test_server.c index 52e0f61..db70668 100644 --- a/tools/tdm_test_server.c +++ b/tools/tdm_test_server.c @@ -183,7 +183,6 @@ usage(char *app_name) printf("\t%s\n", usages[t].desc); } printf("\n"); - exit(0); } //////////////////////////////////////////////////////////////////////////////// @@ -316,6 +315,7 @@ struct _tdm_test_server { tdm_display *display; }; +static void destroy(tdm_test_server *data); static void run_test(tdm_test_server *data); static void output_setup(tdm_test_server_output *o); static void layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b); @@ -517,6 +517,7 @@ parse_args(tdm_test_server *data, int argc, char *argv[]) if (argc < 2) { usage(argv[0]); + destroy(data); exit(0); } @@ -597,6 +598,7 @@ parse_args(tdm_test_server *data, int argc, char *argv[]) data->do_vblank = 1; } else { usage(argv[0]); + destroy(data); exit(0); } } -- 2.7.4 From 6cb389489783e8ef807cb31da6c1f22a17dad06f Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Jan 2018 16:54:28 +0900 Subject: [PATCH 03/16] ini: not using getenv Change-Id: I82ccecd7a09d5b4e1e5c391b4499ac47e307c96c --- common/tdm_log.c | 61 ++++++++++++++------------ include/tdm_log.h | 2 + src/tdm.c | 108 ++++++++++++----------------------------------- src/tdm_config.c | 50 ++++++++++++---------- src/tdm_config.h | 62 +++++++++++++++++++++++++++ src/tdm_monitor_server.c | 5 +-- src/tdm_private.h | 2 - src/tdm_thread.c | 8 ++-- 8 files changed, 157 insertions(+), 141 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 2f7152b..0bad256 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -49,8 +49,6 @@ #include "tdm_log.h" #include "tdm_macro.h" -//#define TDM_CONFIG_ASSERT - #define LOG_MAX_LEN 4076 #define COLOR_RED "\x1b[31m" /* for error */ @@ -64,32 +62,13 @@ static unsigned int dlog_enable = 1; static unsigned int color_enable = 1; -static unsigned int need_check_env = 1; +static unsigned int assert_level = TDM_LOG_LEVEL_NONE; static unsigned int log_lock_init; static pthread_mutex_t log_lock; unsigned int tdm_log_debug_level = TDM_LOG_LEVEL_INFO; -static void -_tdm_log_check_env(void) -{ - const char *str; - char *end; - - str = getenv("TDM_DEBUG_LEVEL"); - if (str) - tdm_log_debug_level = strtol(str, &end, 10); - - str = getenv("TDM_DEBUG"); - if (str && (strstr(str, "1"))) - tdm_log_debug_level = TDM_LOG_LEVEL_DBG; - - str = getenv("TDM_DLOG"); - if (str && (strstr(str, "0"))) - dlog_enable = 0; -} - EXTERN void tdm_log_enable_color(unsigned int enable) { @@ -118,6 +97,37 @@ tdm_log_set_debug_level(int level) } EXTERN void +tdm_log_set_assert_level(int level) +{ + assert_level = level; +} + +EXTERN void +tdm_log_set_path(const char *path) +{ + char fd_name[TDM_PATH_LEN]; + int log_fd = -1; + FILE *log_fl; + + snprintf(fd_name, TDM_PATH_LEN, "%s", path); + + log_fl = fopen(fd_name, "a"); + if (!log_fl) { + TDM_ERR("failed: open file(%s)\n", fd_name); + return; + } + + fflush(stdout); + close(STDOUT_FILENO); + + setvbuf(log_fl, NULL, _IOLBF, 512); + log_fd = fileno(log_fl); + + dup2(log_fd, STDOUT_FILENO); + fclose(log_fl); +} + +EXTERN void tdm_log_print(int level, const char *fmt, ...) { va_list arg; @@ -128,11 +138,6 @@ tdm_log_print(int level, const char *fmt, ...) } - if (need_check_env) { - need_check_env = 0; - _tdm_log_check_env(); - } - if (level > tdm_log_debug_level) return; @@ -180,7 +185,7 @@ tdm_log_print(int level, const char *fmt, ...) } #ifdef TDM_CONFIG_ASSERT - if (level < 3) + if (level <= assert_level) assert(0); #endif } diff --git a/include/tdm_log.h b/include/tdm_log.h index 1cab32d..7ee4d95 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -68,6 +68,8 @@ void tdm_log_enable_color(unsigned int enable); void tdm_log_enable_dlog(unsigned int enable); void tdm_log_enable_debug(unsigned int enable); void tdm_log_set_debug_level(int level); +void tdm_log_set_assert_level(int level); +void tdm_log_set_path(const char *path); void tdm_log_print(int level, const char *fmt, ...); extern unsigned int tdm_log_debug_level; diff --git a/src/tdm.c b/src/tdm.c index 96bed27..2b0de50 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -865,47 +865,30 @@ failed_load: static tdm_error _tdm_display_load_module(tdm_private_display *private_display) { - const char *module_name; - struct dirent **namelist; - int n, len; + const char *module_names; tdm_error ret = 0; + char temp[TDM_PATH_LEN]; + char *arg; + char *end; - module_name = getenv("TDM_MODULE"); - if (!module_name) - module_name = TDM_DEFAULT_MODULE; + module_names = tdm_config_get_string(TDM_CONFIG_KEY_GENERAL_BACKENDS, TDM_DEFAULT_MODULE); - len = strlen(module_name); - if (len > TDM_NAME_LEN - 1) { - TDM_ERR("TDM_MODULE is too long\n"); - return TDM_ERROR_OPERATION_FAILED; - } + snprintf(temp, TDM_PATH_LEN, "%s", module_names); - /* load bufmgr priv from default lib */ - ret = _tdm_display_load_module_with_file(private_display, module_name); - if (ret == TDM_ERROR_NONE) - return TDM_ERROR_NONE; + arg = strtok_r(temp, TDM_CONFIG_DELIM, &end); + while (arg) { + ret = _tdm_display_load_module_with_file(private_display, arg); + if (ret == TDM_ERROR_NONE) + return TDM_ERROR_NONE; + + arg = strtok_r(NULL, TDM_CONFIG_DELIM, &end); + } /* load bufmgr priv from dummy lib */ ret = _tdm_display_load_module_with_file(private_display, TDM_DUMMY_MODULE); if (ret == TDM_ERROR_NONE) return TDM_ERROR_NONE; - /* load bufmgr priv from configured path */ - n = scandir(TDM_MODULE_PATH, &namelist, 0, alphasort); - if (n < 0) { - TDM_ERR("no module in '%s'\n", TDM_MODULE_PATH); - return TDM_ERROR_BAD_MODULE; - } - - ret = TDM_ERROR_BAD_MODULE; - while (n--) { - if (ret < 0 && strstr(namelist[n]->d_name, SUFFIX_MODULE)) - ret = _tdm_display_load_module_with_file(private_display, namelist[n]->d_name); - - free(namelist[n]); - } - free(namelist); - return ret; } @@ -930,6 +913,7 @@ tdm_display_init(tdm_error *error) const char *str; tdm_error ret; double stamp1, stamp2, start; + int mode; pthread_mutex_lock(&gLock); @@ -943,12 +927,13 @@ tdm_display_init(tdm_error *error) start = stamp1 = tdm_helper_get_time(); + /* tdm_config_init should be called first of all tdm apis for tdm_log */ ret = tdm_config_init(); if (ret != TDM_ERROR_NONE) goto failed_config; stamp2 = tdm_helper_get_time(); - TDM_DBG("config init time: %.3f ms", (stamp2 - stamp1) * 1000.0); + TDM_INFO("config init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; private_display = calloc(1, sizeof(tdm_private_display)); @@ -960,18 +945,14 @@ tdm_display_init(tdm_error *error) /* LCOV_EXCL_STOP */ } - str = getenv("TDM_DEBUG_MODULE"); + str = tdm_config_get_string(TDM_CONFIG_KEY_DEBUG_MODULE, NULL); if (str) tdm_display_enable_debug_module(str); - str = getenv("TDM_DEBUG_DUMP"); + str = tdm_config_get_string(TDM_CONFIG_KEY_DEBUG_DUMP, NULL); if (str) tdm_display_enable_dump(private_display, str, NULL, NULL); - str = getenv("TDM_DEBUG_PATH"); - if (str) - tdm_display_enable_path(str); - if (pthread_mutex_init(&private_display->lock, NULL)) { /* LCOV_EXCL_START */ ret = TDM_ERROR_OPERATION_FAILED; @@ -995,7 +976,7 @@ tdm_display_init(tdm_error *error) goto failed_event; stamp2 = tdm_helper_get_time(); - TDM_DBG("creating event loop time: %.3f ms", (stamp2 - stamp1) * 1000.0); + TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; ret = _tdm_display_load_module(private_display); @@ -1003,7 +984,7 @@ tdm_display_init(tdm_error *error) goto failed_load; stamp2 = tdm_helper_get_time(); - TDM_DBG("loading backend time: %.3f ms", (stamp2 - stamp1) * 1000.0); + TDM_INFO("loading backend time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; #ifdef INIT_BUFMGR @@ -1048,11 +1029,9 @@ tdm_display_init(tdm_error *error) /* 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 */ - str = getenv("TDM_COMMIT_PER_VBLANK"); - if (str) { + mode = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); + if (mode > 0) { tdm_private_output *o = NULL; - char *end; - int mode = strtol(str, &end, 10); /* outputs which support hwc capability can work only * if commit_per_vblank mode is '0' (default mode) */ @@ -1193,7 +1172,7 @@ tdm_display_enable_debug_module(const char*modules) tdm_debug_module = 0; - arg = strtok_r(temp, TDM_DELIM, &end); + arg = strtok_r(temp, TDM_CONFIG_DELIM, &end); while (arg) { if (!strncmp(arg, "none", 4)) { tdm_debug_module = 0; @@ -1214,7 +1193,7 @@ tdm_display_enable_debug_module(const char*modules) else if (!strncmp(arg, "commit", 6)) tdm_debug_module |= TDM_DEBUG_COMMIT; - arg = strtok_r(NULL, TDM_DELIM, &end); + arg = strtok_r(NULL, TDM_CONFIG_DELIM, &end); } TDM_INFO("module debugging... '%s'", modules); @@ -1314,39 +1293,6 @@ done: return TDM_ERROR_NONE; } -INTERN tdm_error -tdm_display_enable_path(const char *path) -{ - static int old_stdout = -1; - char fd_name[TDM_PATH_LEN]; - int log_fd = -1; - FILE *log_fl; - - if (old_stdout == -1) - old_stdout = dup(STDOUT_FILENO); - - tdm_log_enable_dlog(0); - - snprintf(fd_name, TDM_PATH_LEN, "%s", path); - - log_fl = fopen(fd_name, "a"); - if (!log_fl) { - TDM_ERR("failed: open file(%s)\n", fd_name); - return TDM_ERROR_OPERATION_FAILED; - } - - fflush(stderr); - close(STDOUT_FILENO); - - setvbuf(log_fl, NULL, _IOLBF, 512); - log_fd = fileno(log_fl); - - dup2(log_fd, STDOUT_FILENO); - fclose(log_fl); - - return TDM_ERROR_NONE; -} - static void _tdm_display_ttrace_vblank_cb(tdm_vblank *vblank, tdm_error error, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) @@ -1436,7 +1382,7 @@ tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttra return ret; } - arg = strtok_r(temp, TDM_DELIM, &end); + arg = strtok_r(temp, TDM_CONFIG_DELIM, &end); while (arg) { if (!strncmp(arg, "none", 4)) tdm_ttrace_module = 0; @@ -1464,7 +1410,7 @@ tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttra return TDM_ERROR_NONE; } - arg = strtok_r(NULL, TDM_DELIM, &end); + arg = strtok_r(NULL, TDM_CONFIG_DELIM, &end); } TDM_SNPRINTF(reply, len, "ttrace debugging... '%s' %x\n", ttrace, tdm_ttrace_module); diff --git a/src/tdm_config.c b/src/tdm_config.c index 6686769..15cc877 100644 --- a/src/tdm_config.c +++ b/src/tdm_config.c @@ -95,22 +95,27 @@ _tdm_config_load_file(const char *dir, const char *filename) return dic; } -static dictionary * -_tdm_config_load(void) +static void +_tdm_config_check_logs(void) { - dictionary *dic = NULL; - -#if 0 - /* not allowed: try to read from RW directory */ - dic = _tdm_config_load_file(TDM_SYSCONF_PATH, TDM_CONFIG_FILENAME); -#endif - - if (!dic) { - /* try to read from RO directory */ - dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME); + const char *path; + int level; + + level = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_LOG_LEVEL, 3); + tdm_log_set_debug_level(level); + + level = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_ASSERT_LEVEL, 0); + tdm_log_set_assert_level(level); + + /* if TDM_CONFIG_KEY_DEBUG_LOG_PATH is setted, TDM_CONFIG_KEY_DEBUG_DLOG will be ignored. */ + path = tdm_config_get_string(TDM_CONFIG_KEY_DEBUG_LOG_PATH, NULL); + if (path) { + tdm_log_enable_dlog(0); + tdm_log_set_path(path); + } else { + int dlog = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_log_enable_dlog(dlog); } - - return dic; } INTERN tdm_error @@ -126,14 +131,9 @@ tdm_config_init(void) return TDM_ERROR_OUT_OF_MEMORY; } - g_dic = _tdm_config_load(); - if (!g_dic) { - if (!getenv("TDM_NO_CONFIG")) { - TDM_ERR("Loading config file failed!!"); - pthread_mutex_destroy(&g_dic_lock); - return TDM_ERROR_NONE; - } - } + g_dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME); + + _tdm_config_check_logs(); TDM_INFO("tdm config init done (%p)", g_dic); @@ -250,6 +250,9 @@ tdm_config_set_int(const char *key, int value) pthread_mutex_lock(&g_dic_lock); ret = iniparser_set(g_dic, key, (const char*)temp); + + _tdm_config_check_logs(); + pthread_mutex_unlock(&g_dic_lock); TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); @@ -273,6 +276,9 @@ tdm_config_set_string(const char *key, const char *value) pthread_mutex_lock(&g_dic_lock); ret = iniparser_set(g_dic, key, value); + + _tdm_config_check_logs(); + pthread_mutex_unlock(&g_dic_lock); TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); diff --git a/src/tdm_config.h b/src/tdm_config.h index b743f93..2592643 100644 --- a/src/tdm_config.h +++ b/src/tdm_config.h @@ -60,6 +60,68 @@ tdm_error tdm_config_set_string(const char *key, const char *value); +#define TDM_CONFIG_DELIM ", " + +/*** general keys ************************************************************/ + +/* backends order list to load. + * default: libtdm-default.so + * ex) libtdm-default.so,libtdm-dummy.so + */ +#define TDM_CONFIG_KEY_GENERAL_BACKENDS "general:backends" + +/* enable thd tdm thread. [0(disable), 1(enable)] + * default: 0 + * ex) 1 + */ +#define TDM_CONFIG_KEY_GENERAL_THREAD "general:thread" + +/* enable the tdm commit-per-vblank functionality. [0(disable), 1(enable)] + * default: 0 + * ex) 1 + */ +#define TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK "general:commit_per_vblank" + + +/*** debug keys **************************************************************/ + +/* debugging module list. [0(disable), 1(enable)] + * default: 1 + * ex) 0 + */ +#define TDM_CONFIG_KEY_DEBUG_DLOG "debug:dlog" + +/* debugging module list. [none,all,buffer,thread,mutex,vblank,commit] + * default: none + * ex) mutex,vblank + */ +#define TDM_CONFIG_KEY_DEBUG_MODULE "debug:module" + +/* debugging dump list. [none,current,all,layer,pp,capture,window] + * default: none + * ex) layer,capture + */ +#define TDM_CONFIG_KEY_DEBUG_DUMP "debug:dump" + +/* debugging log path. [{filepath}] + * default: + * ex) /var/tdm.log + */ +#define TDM_CONFIG_KEY_DEBUG_LOG_PATH "debug:log_path" + +/* debugging log level. [1(ERR),2(WRN),3(INFO),4(DBG)] + * default: 3 + * ex) 4 + */ +#define TDM_CONFIG_KEY_DEBUG_LOG_LEVEL "debug:log_level" + +/* debugging log level to assert. [0(NONE),1(ERR),2(WRN),3(INFO),4(DBG)] + * default: 0 + * ex) 1 + */ +#define TDM_CONFIG_KEY_DEBUG_ASSERT_LEVEL "debug:assert_level" + + #ifdef __cplusplus } #endif diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index 6fdb190..f1edee7 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -181,10 +181,7 @@ _tdm_monitor_server_log_path(unsigned int pid, char *cwd, int argc, char *argv[] tdm_log_enable_color(0); } - if (tdm_display_enable_path((const char*)fd_name) != TDM_ERROR_NONE) { - TDM_SNPRINTF(reply, len, "failed: '%s'\n", path); - return; - } + tdm_log_set_path((const char*)fd_name); done: TDM_SNPRINTF(reply, len, "log path: '%s'\n", path); diff --git a/src/tdm_private.h b/src/tdm_private.h index f7c2a11..ff8e244 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -247,8 +247,6 @@ tdm_display_enable_debug_module(const char*modules); tdm_error tdm_display_enable_dump(tdm_private_display *private_display, const char *dump_str, char *reply, int *len); tdm_error -tdm_display_enable_path(const char *path); -tdm_error tdm_display_enable_ttrace(tdm_private_display *private_display, const char *ttrace, int output_id, char *reply, int *len); tdm_error tdm_display_enable_fps(tdm_private_display *private_display, int enable); diff --git a/src/tdm_thread.c b/src/tdm_thread.c index f71f3a1..a3e7cf0 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -120,7 +120,7 @@ tdm_thread_init(tdm_private_loop *private_loop) { tdm_private_display *private_display; tdm_private_thread *private_thread; - const char *thread; + int thread; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(private_loop->dpy, TDM_ERROR_OPERATION_FAILED); @@ -132,9 +132,9 @@ tdm_thread_init(tdm_private_loop *private_loop) return TDM_ERROR_NONE; /* enable as default */ - thread = getenv("TDM_THREAD"); - if (!thread || strncmp(thread, "1", 1)) { - TDM_INFO("not using a TDM event thread: %s", (thread) ? thread : "none"); + thread = tdm_config_get_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + if (!thread) { + TDM_INFO("not using a TDM event thread"); return TDM_ERROR_NONE; } -- 2.7.4 From 60f1b2e516e4ea7bfa581a77897ce1a8d21b3603 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Feb 2018 18:17:32 +0900 Subject: [PATCH 04/16] config: export tdm_config functions Change-Id: I95bcd81ba94b21a7383f88e99a5b254effb10597 --- include/Makefile.am | 1 + {src => include}/tdm_config.h | 0 packaging/libtdm.spec | 1 + src/tdm.c | 7 ----- src/tdm_config.c | 71 +++++++++++++++++++++++-------------------- 5 files changed, 40 insertions(+), 40 deletions(-) rename {src => include}/tdm_config.h (100%) diff --git a/include/Makefile.am b/include/Makefile.am index aa1d502..ce83e6e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -4,6 +4,7 @@ libtdminclude_HEADERS = \ tdm_common.h \ tdm_types.h \ tdm_list.h \ + tdm_config.h \ tdm_log.h \ tdm_backend.h \ tdm_helper.h diff --git a/src/tdm_config.h b/include/tdm_config.h similarity index 100% rename from src/tdm_config.h rename to include/tdm_config.h diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 7140089..a8f8003 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -128,6 +128,7 @@ rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %{_includedir}/tdm_list.h %{_includedir}/tdm_log.h %{_includedir}/tdm_types.h +%{_includedir}/tdm_config.h %{_libdir}/pkgconfig/libtdm.pc %{_libdir}/libtdm.so diff --git a/src/tdm.c b/src/tdm.c index 2b0de50..6306966 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -927,11 +927,6 @@ tdm_display_init(tdm_error *error) start = stamp1 = tdm_helper_get_time(); - /* tdm_config_init should be called first of all tdm apis for tdm_log */ - ret = tdm_config_init(); - if (ret != TDM_ERROR_NONE) - goto failed_config; - stamp2 = tdm_helper_get_time(); TDM_INFO("config init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; @@ -1064,8 +1059,6 @@ failed_vblank: failed_mutex_init: free(private_display); failed_alloc: - tdm_config_deinit(); -failed_config: if (error) *error = ret; pthread_mutex_unlock(&gLock); diff --git a/src/tdm_config.c b/src/tdm_config.c index 15cc877..4c66e07 100644 --- a/src/tdm_config.c +++ b/src/tdm_config.c @@ -49,8 +49,8 @@ #define TDM_CONFIG_FILENAME "tdm.ini" #define TDM_CONFIG_GENERAL_SECTION "general" +static pthread_mutex_t g_dic_lock = PTHREAD_MUTEX_INITIALIZER; static dictionary *g_dic = NULL; -static pthread_mutex_t g_dic_lock; static int _tdm_config_check_file_owner(const char *filepath) @@ -101,6 +101,8 @@ _tdm_config_check_logs(void) const char *path; int level; + pthread_mutex_unlock(&g_dic_lock); + level = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_LOG_LEVEL, 3); tdm_log_set_debug_level(level); @@ -116,46 +118,41 @@ _tdm_config_check_logs(void) int dlog = tdm_config_get_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); tdm_log_enable_dlog(dlog); } + + pthread_mutex_lock(&g_dic_lock); } -INTERN tdm_error -tdm_config_init(void) +static unsigned int +_tdm_config_check_init(void) { - if (g_dic) { - TDM_ERR("init failed: twice"); - return TDM_ERROR_OPERATION_FAILED; - } - - if (pthread_mutex_init(&g_dic_lock, NULL)) { - TDM_ERR("mutex init failed: %m"); - return TDM_ERROR_OUT_OF_MEMORY; - } + if (g_dic) + return 1; g_dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME); _tdm_config_check_logs(); - TDM_INFO("tdm config init done (%p)", g_dic); + TDM_INFO("tdm config init %s (%p)", (g_dic) ? "successed" : "failed", g_dic); - return TDM_ERROR_NONE; + return (g_dic) ? 1 : 0; } INTERN void tdm_config_deinit(void) { + pthread_mutex_lock(&g_dic_lock); + if (!g_dic) { + pthread_mutex_unlock(&g_dic_lock); return; } iniparser_freedict(g_dic); g_dic = NULL; - /* we don't need to lock/unlock here because we come here - * after tdm_thread has been destroyed - */ - pthread_mutex_destroy(&g_dic_lock); - TDM_INFO("tdm config deinit done"); + + pthread_mutex_unlock(&g_dic_lock); } static const char* @@ -183,7 +180,7 @@ _tdm_config_get_string_internal(dictionary *dic, const char *key, const char *de return result; } -INTERN int +EXTERN int tdm_config_get_int(const char *key, int default_value) { const char *result; @@ -191,12 +188,14 @@ tdm_config_get_int(const char *key, int default_value) TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value); - if (!g_dic) { + pthread_mutex_lock(&g_dic_lock); + + if (!_tdm_config_check_init()) { TDM_INFO("%s = %d: default", key, default_value); + pthread_mutex_unlock(&g_dic_lock); return default_value; } - pthread_mutex_lock(&g_dic_lock); result = _tdm_config_get_string_internal(g_dic, key, NULL); pthread_mutex_unlock(&g_dic_lock); @@ -212,19 +211,21 @@ tdm_config_get_int(const char *key, int default_value) return value; } -INTERN const char* +EXTERN const char* tdm_config_get_string(const char *key, const char *default_value) { const char *result; TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value); - if (!g_dic) { + pthread_mutex_lock(&g_dic_lock); + + if (!_tdm_config_check_init()) { TDM_INFO("%s = %s: default", key, default_value); + pthread_mutex_unlock(&g_dic_lock); return default_value; } - pthread_mutex_lock(&g_dic_lock); result = _tdm_config_get_string_internal(g_dic, key, default_value); pthread_mutex_unlock(&g_dic_lock); @@ -233,7 +234,7 @@ tdm_config_get_string(const char *key, const char *default_value) return result; } -INTERN tdm_error +EXTERN tdm_error tdm_config_set_int(const char *key, int value) { char temp[TDM_NAME_LEN]; @@ -241,14 +242,16 @@ tdm_config_set_int(const char *key, int value) TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER); - if (!g_dic) { + snprintf(temp, sizeof temp, "%d", value); + + pthread_mutex_lock(&g_dic_lock); + + if (!_tdm_config_check_init()) { TDM_INFO("%s = %d set failed", key, value); + pthread_mutex_unlock(&g_dic_lock); return TDM_ERROR_BAD_REQUEST; } - snprintf(temp, sizeof temp, "%d", value); - - pthread_mutex_lock(&g_dic_lock); ret = iniparser_set(g_dic, key, (const char*)temp); _tdm_config_check_logs(); @@ -262,19 +265,21 @@ tdm_config_set_int(const char *key, int value) return TDM_ERROR_NONE; } -INTERN tdm_error +EXTERN tdm_error tdm_config_set_string(const char *key, const char *value) { int ret; TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER); - if (!g_dic) { + pthread_mutex_lock(&g_dic_lock); + + if (!_tdm_config_check_init()) { TDM_INFO("%s = %s set failed", key, value); + pthread_mutex_unlock(&g_dic_lock); return TDM_ERROR_BAD_REQUEST; } - pthread_mutex_lock(&g_dic_lock); ret = iniparser_set(g_dic, key, value); _tdm_config_check_logs(); -- 2.7.4 From 7f9b27be3fc997cc631dc6f0a98409a29bd326ec Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 20 Feb 2018 18:17:58 +0900 Subject: [PATCH 05/16] utests: not using setenv Change-Id: I734c97d423ddf0dc85068fea9cf3f7393d6ab681 --- utests/src/ut_tdm_buffer.cpp | 10 ++++------ utests/src/ut_tdm_capture.cpp | 12 ++++-------- utests/src/ut_tdm_client.cpp | 4 ++++ utests/src/ut_tdm_display.cpp | 15 +++++++-------- utests/src/ut_tdm_event_loop.cpp | 10 ++++------ utests/src/ut_tdm_helper.cpp | 8 ++++---- utests/src/ut_tdm_hwc_window.cpp | 16 ++++------------ utests/src/ut_tdm_layer.cpp | 35 +++++++++++------------------------ utests/src/ut_tdm_output.cpp | 17 +++++------------ utests/src/ut_tdm_pp.cpp | 12 ++++-------- utests/src/ut_tdm_vblank.cpp | 8 ++++++-- 11 files changed, 57 insertions(+), 90 deletions(-) diff --git a/utests/src/ut_tdm_buffer.cpp b/utests/src/ut_tdm_buffer.cpp index db5c4ca..6896547 100644 --- a/utests/src/ut_tdm_buffer.cpp +++ b/utests/src/ut_tdm_buffer.cpp @@ -4,6 +4,7 @@ extern "C" { #include "tdm.h" +#include "tdm_config.h" #include "tdm_backend.h" #include "tbm_bufmgr.h" #include "tbm_surface.h" @@ -23,18 +24,15 @@ protected: static void SetEnv(void) { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_THREAD", "0", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } static void UnsetEnv(void) { - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); - unsetenv("TDM_THREAD"); unsetenv("XDG_RUNTIME_DIR"); unsetenv("TBM_DISPLAY_SERVER"); } diff --git a/utests/src/ut_tdm_capture.cpp b/utests/src/ut_tdm_capture.cpp index 068220a..4ebcc5a 100644 --- a/utests/src/ut_tdm_capture.cpp +++ b/utests/src/ut_tdm_capture.cpp @@ -31,6 +31,7 @@ #include "gtest/gtest.h" #include "ut_tdm.h" #include "tdm.h" +#include "tdm_config.h" extern "C" { #include "tbm_bufmgr.h" #include "tbm_drm_helper.h" @@ -50,21 +51,16 @@ protected: virtual void SetEnvs() { - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } virtual void UnsetEnvs() { - unsetenv("TDM_DLOG"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); unsetenv("TBM_DISPLAY_SERVER"); } diff --git a/utests/src/ut_tdm_client.cpp b/utests/src/ut_tdm_client.cpp index adb71d5..1b65ed4 100644 --- a/utests/src/ut_tdm_client.cpp +++ b/utests/src/ut_tdm_client.cpp @@ -47,6 +47,7 @@ extern "C" { #include "tdm.h" +#include "tdm_config.h" #include "tdm_client.h" #include "tbm_surface.h" @@ -151,6 +152,9 @@ private: { setenv("XDG_RUNTIME_DIR", "/run", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } void unset_env_vars(void) diff --git a/utests/src/ut_tdm_display.cpp b/utests/src/ut_tdm_display.cpp index 2ba98ca..a80fb47 100644 --- a/utests/src/ut_tdm_display.cpp +++ b/utests/src/ut_tdm_display.cpp @@ -31,6 +31,7 @@ #include "gtest/gtest.h" extern "C" { #include "tdm.h" +#include "tdm_config.h" #include "tbm_bufmgr.h" #include "tbm_drm_helper.h" } @@ -40,10 +41,11 @@ protected: int master_fd = -42, tbm_fd = -42; void SetUp(void) { - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } void TearDown(void) { @@ -61,9 +63,7 @@ protected: exit(1); close(tbm_fd); } - unsetenv("TDM_DLOG"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); unsetenv("TBM_DISPLAY_SERVER"); } }; @@ -75,10 +75,11 @@ protected: int master_fd = -42, tbm_fd = -42; void SetUp(void) { - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); tbm_bufmgr = tbm_bufmgr_init(-1); ASSERT_FALSE(tbm_bufmgr == NULL); tdm_error error = TDM_ERROR_NONE; @@ -108,9 +109,7 @@ protected: exit(1); close(tbm_fd); } - unsetenv("TDM_DLOG"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); unsetenv("TBM_DISPLAY_SERVER"); } }; diff --git a/utests/src/ut_tdm_event_loop.cpp b/utests/src/ut_tdm_event_loop.cpp index b0dc4e7..e8ecaaa 100644 --- a/utests/src/ut_tdm_event_loop.cpp +++ b/utests/src/ut_tdm_event_loop.cpp @@ -5,6 +5,7 @@ extern "C" { #include "tdm.h" +#include "tdm_config.h" #include "tdm_backend.h" #include "tbm_bufmgr.h" #include "tbm_surface.h" @@ -22,18 +23,15 @@ protected: static void SetEnv(void) { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_THREAD", "0", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 0); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } static void UnsetEnv(void) { - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); - unsetenv("TDM_THREAD"); unsetenv("XDG_RUNTIME_DIR"); unsetenv("TBM_DISPLAY_SERVER"); } diff --git a/utests/src/ut_tdm_helper.cpp b/utests/src/ut_tdm_helper.cpp index b9d8ba4..a093ffc 100644 --- a/utests/src/ut_tdm_helper.cpp +++ b/utests/src/ut_tdm_helper.cpp @@ -7,6 +7,7 @@ extern "C" { #include "tdm.h" +#include "tdm_config.h" #include "tdm_helper.h" #include "tdm_backend.h" #include "tbm_bufmgr.h" @@ -31,16 +32,15 @@ protected: tbm_surface_h surface; virtual void SetEnv() { - setenv("TDM_THREAD", "0", 1); - setenv("TDM_COMMIT_PER_VBLANK", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1); } void UnsetEnv() { - unsetenv("TDM_THREAD"); - unsetenv("TDM_COMMIT_PER_VBLANK"); unsetenv("XDG_RUNTIME_DIR"); unsetenv("TBM_DISPLAY_SERVER"); } diff --git a/utests/src/ut_tdm_hwc_window.cpp b/utests/src/ut_tdm_hwc_window.cpp index 52ebc5b..aaa5d50 100644 --- a/utests/src/ut_tdm_hwc_window.cpp +++ b/utests/src/ut_tdm_hwc_window.cpp @@ -34,6 +34,7 @@ #include "stdint.h" #include "tdm.h" +#include "tdm_config.h" #include "tdm_backend.h" extern "C" { #include "tbm_bufmgr.h" @@ -52,27 +53,18 @@ protected: tdm_error error ; virtual void SetEnv() { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_THREAD", "1", 1); - setenv("TDM_COMMIT_PER_VBLANK", "1", 1); - setenv("TDM_DLOG", "1", 1); setenv("TDM_HWC", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1); } void UnsetEnv() { - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); - unsetenv("TDM_THREAD"); - unsetenv("TDM_COMMIT_PER_VBLANK"); - unsetenv("TDM_DLOG"); unsetenv("TDM_HWC"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); unsetenv("TBM_DISPLAY_SERVER"); } diff --git a/utests/src/ut_tdm_layer.cpp b/utests/src/ut_tdm_layer.cpp index 051c41f..dba3023 100644 --- a/utests/src/ut_tdm_layer.cpp +++ b/utests/src/ut_tdm_layer.cpp @@ -36,6 +36,8 @@ #include #include "tdm.h" +#include "tdm_config.h" + extern "C" { #include "tbm_bufmgr.h" #include "tbm_drm_helper.h" @@ -56,14 +58,11 @@ protected: bool has_layers = false; virtual void SetEnv() { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_THREAD", "0", 1); - setenv("TDM_COMMIT_PER_VBLANK", "1", 1); - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1); } void SetUp(void) { @@ -200,13 +199,7 @@ protected: close(tbm_fd); } - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); - unsetenv("TDM_THREAD"); - unsetenv("TDM_COMMIT_PER_VBLANK"); - unsetenv("TDM_DLOG"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); unsetenv("TBM_DISPLAY_SERVER"); } @@ -359,14 +352,11 @@ class TDMLayerCommitThread : public TDMLayerCommit protected: void SetEnv() { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_THREAD", "1", 1); - setenv("TDM_COMMIT_PER_VBLANK", "1", 1); - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1); } }; @@ -375,14 +365,11 @@ class TDMLayerCommitWithDisabledCommitPerVblank : public TDMLayerCommit protected: void SetEnv() { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_THREAD", "0", 1); - setenv("TDM_COMMIT_PER_VBLANK", "0", 1); - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } }; diff --git a/utests/src/ut_tdm_output.cpp b/utests/src/ut_tdm_output.cpp index 0355065..db15445 100644 --- a/utests/src/ut_tdm_output.cpp +++ b/utests/src/ut_tdm_output.cpp @@ -32,6 +32,7 @@ #include "ut_tdm.h" #include #include "tdm.h" +#include "tdm_config.h" extern "C" { #include "tbm_bufmgr.h" #include "tbm_drm_helper.h" @@ -59,24 +60,17 @@ protected: } virtual void SetEnvs() { - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); - setenv("TDM_COMMIT_PER_VBLANK", "0", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } virtual void UnsetEnvs() { - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); - unsetenv("TDM_DLOG"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); unsetenv("TBM_DISPLAY_SERVER"); - unsetenv("TDM_COMMIT_PER_VBLANK"); } void SetUp(void) @@ -397,12 +391,11 @@ class TDMOutputCommitPerVblankEnabled : public TDMOutputCommit { { TDMOutputCommit::SetEnvs(); - setenv("TDM_COMMIT_PER_VBLANK", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 1); } void UnsetEnvs(void) { TDMOutputCommit::UnsetEnvs(); - unsetenv("TDM_COMMIT_PER_VBLANK"); } }; diff --git a/utests/src/ut_tdm_pp.cpp b/utests/src/ut_tdm_pp.cpp index d420204..dd26f0e 100644 --- a/utests/src/ut_tdm_pp.cpp +++ b/utests/src/ut_tdm_pp.cpp @@ -31,6 +31,7 @@ #include "gtest/gtest.h" #include "ut_tdm.h" #include "tdm.h" +#include "tdm_config.h" extern "C" { #include "tbm_bufmgr.h" #include "tbm_drm_helper.h" @@ -53,21 +54,16 @@ protected: virtual void SetEnvs() { - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); - setenv("TDM_DEBUG_MODULE", "all", 1); - setenv("TDM_DEBUG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); } virtual void UnsetEnvs() { - unsetenv("TDM_DLOG"); unsetenv("XDG_RUNTIME_DIR"); - unsetenv("TBM_DLOG"); - unsetenv("TDM_DEBUG_MODULE"); - unsetenv("TDM_DEBUG"); unsetenv("TBM_DISPLAY_SERVER"); } diff --git a/utests/src/ut_tdm_vblank.cpp b/utests/src/ut_tdm_vblank.cpp index 9eed3dc..a1cdc4d 100644 --- a/utests/src/ut_tdm_vblank.cpp +++ b/utests/src/ut_tdm_vblank.cpp @@ -30,6 +30,7 @@ #include "gtest/gtest.h" #include "tdm.h" +#include "tdm_config.h" #include "tbm_bufmgr.h" #include "ut_tdm.h" #include @@ -52,10 +53,13 @@ protected: tdm_output_conn_status status; tdm_error error = TDM_ERROR_NONE; - setenv("TDM_DLOG", "1", 1); setenv("XDG_RUNTIME_DIR", "/run", 1); - setenv("TBM_DLOG", "1", 1); setenv("TBM_DISPLAY_SERVER", "1", 1); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_DLOG, 1); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_THREAD, 0); + tdm_config_set_int(TDM_CONFIG_KEY_GENERAL_COMMIT_PER_VBLANK, 0); + tdm_config_set_int(TDM_CONFIG_KEY_DEBUG_LOG_LEVEL, 4); + tdm_config_set_string(TDM_CONFIG_KEY_DEBUG_MODULE, "vblank,thread"); /* FIXME: fix the error. If we initialize TBM before TDM we get fail * in the tdm_output_set_dpms */ -- 2.7.4 From ee6ae6a14f40cdae1c458e37d82c6b6f49bb444d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 16 Jan 2018 11:12:55 +0900 Subject: [PATCH 06/16] server: remove useless codes Change-Id: I09d265a0a5ab8eda71826f55ce9e4b23e1a25048 --- src/tdm_private.h | 1 - src/tdm_server.c | 132 ------------------------------------------------------ 2 files changed, 133 deletions(-) diff --git a/src/tdm_private.h b/src/tdm_private.h index ff8e244..30dfb81 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -52,7 +52,6 @@ #include #include #include -#include #include #include diff --git a/src/tdm_server.c b/src/tdm_server.c index 8fc2336..1bb5683 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -808,136 +808,6 @@ _tdm_server_bind(struct wl_client *client, void *data, wl_resource_set_implementation(resource, &tdm_implementation, data, destroy_client); } -static int -_tdm_getgrnam_r(const char *name) -{ - struct group *grp = NULL; - struct group *grp_res = NULL; - char* buf = NULL; - size_t buf_len; - int ret; - int id; - - buf_len = sysconf(_SC_GETGR_R_SIZE_MAX); - if (buf_len == -1) - buf_len = 2048; - - buf = calloc(1, buf_len * sizeof(char)); - if (!buf) { - TDM_ERR("creating buffer failed"); - goto failed; - } - - grp = calloc(1, sizeof(struct group)); - if (!grp) { - TDM_ERR("creating group failed"); - goto failed; - } - - ret = getgrnam_r(name, grp, buf, buf_len, &grp_res); - if (ret < 0) { - TDM_ERR("getgrnam_r failed errno:%d(%m)", ret); - goto failed; - } - - if (grp_res == NULL) { - TDM_ERR("finding name:%s group failed", name); - goto failed; - } - - id = grp->gr_gid; - free(buf); - free(grp); - - return id; - -failed: - /* LCOV_EXCL_START */ - - if (buf) - free(buf); - if (grp) - free(grp); - - return -1; - - /* LCOV_EXCL_STOP */ -} - -static void -_tdm_socket_init(tdm_private_loop *private_loop) -{ - const char *dir = NULL; - char socket_path[TDM_NAME_LEN * 2]; - int ret = -1, len; - uid_t uid; - gid_t gid; - - dir = getenv("XDG_RUNTIME_DIR"); - if (!dir) { - /* LCOV_EXCL_START */ - - TDM_WRN("getting XDG_RUNTIME_DIR failed"); - return; - - /* LCOV_EXCL_STOP */ - } - - len = strlen(dir); - if (len > TDM_NAME_LEN - 1) { - TDM_ERR("XDG_RUNTIME_DIR is too long\n"); - return; - } - - strncpy(socket_path, dir, TDM_NAME_LEN - 1); - socket_path[TDM_NAME_LEN - 1] = '\0'; - - strncat(socket_path, "/tdm-socket", 11); - socket_path[TDM_NAME_LEN + 10] = '\0'; - - ret = chmod(socket_path, 509); - if (ret < 0) { - /* LCOV_EXCL_START */ - - TDM_WRN("changing modes of socket file failed:%s (%m)", socket_path); - return; - - /* LCOV_EXCL_STOP */ - } - - ret = _tdm_getgrnam_r("root"); - if (ret < 0) { - /* LCOV_EXCL_START */ - - TDM_WRN("getting uid failed"); - return; - - /* LCOV_EXCL_STOP */ - } - uid = ret; - - ret = _tdm_getgrnam_r("display"); - if (ret < 0) { - /* LCOV_EXCL_START */ - - TDM_WRN("getting gid failed"); - return; - - /* LCOV_EXCL_STOP */ - } - gid = ret; - - ret = chown(socket_path, uid, gid); - if (ret < 0) { - /* LCOV_EXCL_START */ - - TDM_WRN("changing owner of socket file failed:%s (%m)", socket_path); - return; - - /* LCOV_EXCL_STOP */ - } -} - INTERN tdm_error tdm_server_init(tdm_private_loop *private_loop) { @@ -958,8 +828,6 @@ tdm_server_init(tdm_private_loop *private_loop) /* LCOV_EXCL_STOP */ } - _tdm_socket_init(private_loop); - private_server = calloc(1, sizeof * private_server); if (!private_server) { TDM_ERR("alloc failed"); -- 2.7.4 From a0b81702cc5507fe05c913c121ec533699a01ebd Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 23 Jan 2018 11:15:05 +0900 Subject: [PATCH 07/16] debug: add event type Change-Id: Ib12af60beac82dd6bfc8e3f57f2930c1158dfe3b --- include/tdm_config.h | 2 +- src/tdm.c | 2 ++ src/tdm_display.c | 4 ++-- src/tdm_event_loop.c | 4 ++-- src/tdm_private_types.h | 9 +++++---- src/tdm_thread.c | 8 ++++---- 6 files changed, 16 insertions(+), 13 deletions(-) diff --git a/include/tdm_config.h b/include/tdm_config.h index 2592643..0428b56 100644 --- a/include/tdm_config.h +++ b/include/tdm_config.h @@ -91,7 +91,7 @@ tdm_config_set_string(const char *key, const char *value); */ #define TDM_CONFIG_KEY_DEBUG_DLOG "debug:dlog" -/* debugging module list. [none,all,buffer,thread,mutex,vblank,commit] +/* debugging module list. [none,all,buffer,thread,event,mutex,vblank,commit] * default: none * ex) mutex,vblank */ diff --git a/src/tdm.c b/src/tdm.c index 6306966..69d9ebd 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1177,6 +1177,8 @@ tdm_display_enable_debug_module(const char*modules) } if (!strncmp(arg, "buffer", 6)) tdm_debug_module |= TDM_DEBUG_BUFFER; + else if (!strncmp(arg, "event", 5)) + tdm_debug_module |= TDM_DEBUG_EVENT; else if (!strncmp(arg, "thread", 6)) tdm_debug_module |= TDM_DEBUG_THREAD; else if (!strncmp(arg, "mutex", 5)) diff --git a/src/tdm_display.c b/src/tdm_display.c index 8febaf0..5bd7ca6 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -342,7 +342,7 @@ tdm_display_handle_events(tdm_display *dpy) fds.fd = fd; fds.revents = 0; - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling in", fd); while (poll(&fds, 1, -1) < 0) { @@ -356,7 +356,7 @@ tdm_display_handle_events(tdm_display *dpy) /* LCOV_EXCL_STOP */ } - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling out", fd); if (tdm_thread_is_running()) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index 4be20ce..1745d8e 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -71,7 +71,7 @@ _tdm_event_loop_main_fd_handler(int fd, tdm_event_loop_mask mask, void *user_dat private_loop = private_display->private_loop; - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("backend fd(%d) event happens", private_loop->backend_fd); func_display = &private_display->func_display; @@ -231,7 +231,7 @@ tdm_event_loop_dispatch(tdm_private_display *private_display) TDM_RETURN_VAL_IF_FAIL(private_loop->wl_loop != NULL, TDM_ERROR_OPERATION_FAILED); - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("dispatch"); if (tdm_thread_is_running() && diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index cc234c0..6c7d2d5 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -60,10 +60,11 @@ enum { TDM_DEBUG_NONE, TDM_DEBUG_BUFFER = (1 << 0), TDM_DEBUG_MUTEX = (1 << 1), - TDM_DEBUG_THREAD = (1 << 2), - TDM_DEBUG_SERVER = (1 << 3), - TDM_DEBUG_VBLANK = (1 << 4), - TDM_DEBUG_COMMIT = (1 << 5), + TDM_DEBUG_EVENT = (1 << 2), + TDM_DEBUG_THREAD = (1 << 3), + TDM_DEBUG_SERVER = (1 << 4), + TDM_DEBUG_VBLANK = (1 << 5), + TDM_DEBUG_COMMIT = (1 << 6), }; enum { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index a3e7cf0..ebac0be 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -82,16 +82,16 @@ _tdm_thread_main(void *data) fds.revents = 0; while (1) { - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("server flush"); tdm_event_loop_flush(private_loop->dpy); - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling in", fd); ret = poll(&fds, 1, -1); - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling out", fd); if (ret < 0) { @@ -103,7 +103,7 @@ _tdm_thread_main(void *data) } } - if (tdm_debug_module & TDM_DEBUG_THREAD) + if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("thread got events"); if (tdm_event_loop_dispatch(private_loop->dpy) < 0) -- 2.7.4 From 3b2ea9bbd4f335ed70ccc472414d6edc01e9f28e Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 18 Jan 2018 15:45:39 +0900 Subject: [PATCH 08/16] thread: support cb for multi-thread communication Change-Id: Ic59dd29fbc574232ec28e3a34e63533a8bd4d6f8 --- common/tdm_log.c | 7 + include/tdm_log.h | 1 + src/tdm.c | 6 + src/tdm_display.c | 7 +- src/tdm_macro.h | 14 ++ src/tdm_private.h | 3 + src/tdm_private_types.h | 4 + src/tdm_thread.c | 386 +++++++++++++++++++++++++++++++++++++++++++++--- src/tdm_thread.h | 13 ++ 9 files changed, 419 insertions(+), 22 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index 0bad256..b77e765 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -189,3 +189,10 @@ tdm_log_print(int level, const char *fmt, ...) assert(0); #endif } + +EXTERN void +tdm_log_reset(void) +{ + pthread_mutex_trylock(&log_lock); + pthread_mutex_unlock(&log_lock); +} diff --git a/include/tdm_log.h b/include/tdm_log.h index 7ee4d95..02e8b0c 100644 --- a/include/tdm_log.h +++ b/include/tdm_log.h @@ -71,6 +71,7 @@ void tdm_log_set_debug_level(int level); void tdm_log_set_assert_level(int level); void tdm_log_set_path(const char *path); void tdm_log_print(int level, const char *fmt, ...); +void tdm_log_reset(void); extern unsigned int tdm_log_debug_level; diff --git a/src/tdm.c b/src/tdm.c index 69d9ebd..2536479 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1120,6 +1120,12 @@ tdm_display_deinit(tdm_display *dpy) TDM_INFO("done"); } +INTERN tdm_private_display * +tdm_display_get(void) +{ + return g_private_display; +} + INTERN int tdm_display_is_valid(tdm_display *dpy) { diff --git a/src/tdm_display.c b/src/tdm_display.c index 5bd7ca6..abf4374 100644 --- a/src/tdm_display.c +++ b/src/tdm_display.c @@ -359,10 +359,13 @@ tdm_display_handle_events(tdm_display *dpy) if (tdm_debug_module & TDM_DEBUG_EVENT) TDM_INFO("fd(%d) polling out", fd); - if (tdm_thread_is_running()) + if (tdm_thread_is_running()) { + _pthread_mutex_lock(&private_display->lock); ret = tdm_thread_handle_cb(private_display->private_loop); - else + _pthread_mutex_unlock(&private_display->lock); + } else { ret = tdm_event_loop_dispatch(private_display); + } return ret; } diff --git a/src/tdm_macro.h b/src/tdm_macro.h index e75220c..77538a3 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -232,6 +232,20 @@ static struct tdm_type_name tdm_value_type_names[] = { }; TDM_TYPE_NAME_FN(value_type) +static struct tdm_type_name tdm_cb_type_names[] = { + { TDM_THREAD_CB_NONE, "none" }, + { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, + { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, + { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, + { TDM_THREAD_CB_OUTPUT_DPMS, "output-dpms" }, + { TDM_THREAD_CB_PP_DONE, "pp-done" }, + { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, + { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, + { TDM_THREAD_CB_VBLANK_CREATE, "vblank-create" }, + { TDM_THREAD_CB_NEED_VALIDATE, "need-validate" }, +}; +TDM_TYPE_NAME_FN(cb_type) + #define TDM_BIT_NAME_FB(res) \ static inline const char * tdm_##res##_str(int type, char **reply, int *len) \ { \ diff --git a/src/tdm_private.h b/src/tdm_private.h index 30dfb81..f04eebb 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -83,6 +84,8 @@ extern int tdm_ttrace_output; int tdm_display_is_valid(tdm_display *display); +tdm_private_display * +tdm_display_get(void); int tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, int abimin); diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 6c7d2d5..a4ac11d 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -440,6 +440,7 @@ typedef enum { TDM_THREAD_CB_VBLANK_SW, TDM_THREAD_CB_VBLANK_CREATE, TDM_THREAD_CB_NEED_VALIDATE, + TDM_THREAD_CB_MAX, } tdm_thread_cb_type; typedef struct _tdm_thread_cb_base tdm_thread_cb_base; @@ -456,6 +457,9 @@ typedef struct _tdm_thread_cb_need_validate tdm_thread_cb_need_validate; struct _tdm_thread_cb_base { tdm_thread_cb_type type; unsigned int length; + double object_stamp; + void *data; + unsigned int sync; }; struct _tdm_thread_cb_output_vblank { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index ebac0be..5b7f00e 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -44,15 +44,56 @@ static tdm_private_thread *keep_private_thread; struct _tdm_private_thread { tdm_private_loop *private_loop; + pthread_cond_t event_cond; pthread_t event_thread; pid_t display_tid; pid_t thread_tid; - /* 0: read, 1: write */ + /* 0: read, 1: write (tdm-thread -> display-thread) */ int pipe[2]; + + /* 0: read, 1: write (tdm-thread <- display-thread) */ + int sub_pipe[2]; + tdm_event_loop_source *sub_event_source; }; +typedef struct _tdm_private_thread_cb { + struct list_head link; + struct list_head call_link; + + void *object; + tdm_thread_cb_type cb_type; + void *cb_data; + tdm_thread_cb func; + void *user_data; + + pid_t owner_tid; + unsigned int called; +} tdm_private_thread_cb; + +static tdm_thread_find_object find_funcs[TDM_THREAD_CB_MAX] = {0, }; +static struct list_head cb_list; + +static void _tdm_thread_free_cb(tdm_private_thread_cb *cb); + +static tdm_error +_tdm_thread_handle_events(int fd, tdm_event_loop_mask mask, void *user_data) +{ + tdm_private_loop *private_loop = user_data; + tdm_error ret; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); + TDM_RETURN_VAL_IF_FAIL(private_loop != NULL, TDM_ERROR_OPERATION_FAILED); + TDM_RETURN_VAL_IF_FAIL(private_loop->dpy != NULL, TDM_ERROR_OPERATION_FAILED); + + ret = tdm_thread_handle_cb(private_loop); + + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, ret); + + return TDM_ERROR_NONE; +} + static void* _tdm_thread_main(void *data) { @@ -61,6 +102,7 @@ _tdm_thread_main(void *data) int fd; struct pollfd fds; int ret; + tdm_error error; /* Not lock/unlock for the private_thread and private_loop structure * because they won't be destroyed as long as tdm thread is running. @@ -71,6 +113,28 @@ _tdm_thread_main(void *data) TDM_INFO("display_tid:%d, thread_tid: %d", private_thread->display_tid, private_thread->thread_tid); + /* fd SHOULD be the same with sub_pipe[0] to make sure that using + * tdm_thread_get_fd, tdm_thread_send_cb, tdm_thread_handle_cb in + * both threads is fine. Otherwise, assert. + */ + tdm_display_lock(private_loop->dpy); + assert(tdm_thread_get_fd(private_loop) == private_thread->sub_pipe[0]); + + private_thread->sub_event_source = + tdm_event_loop_add_fd_handler(private_loop->dpy, + private_thread->sub_pipe[0], + TDM_EVENT_LOOP_READABLE, + _tdm_thread_handle_events, + private_loop, + &error); + TDM_GOTO_IF_FAIL(error == TDM_ERROR_NONE, exit_thread); + TDM_GOTO_IF_FAIL(private_thread->sub_event_source != NULL, exit_thread); + + pthread_cond_signal(&private_thread->event_cond); + + /* mutex shall be locked by the thread calling pthread_cond_signal() */ + tdm_display_unlock(private_loop->dpy); + fd = tdm_event_loop_get_fd(private_loop->dpy); if (fd < 0) { TDM_ERR("couldn't get fd"); @@ -111,6 +175,7 @@ _tdm_thread_main(void *data) } exit_thread: + tdm_display_unlock(private_loop->dpy); pthread_exit(NULL); } @@ -128,6 +193,8 @@ tdm_thread_init(tdm_private_loop *private_loop) private_display = private_loop->dpy; TDM_RETURN_VAL_IF_FAIL(private_display->private_loop, TDM_ERROR_OPERATION_FAILED); + LIST_INITHEAD(&cb_list); + if (private_loop->private_thread) return TDM_ERROR_NONE; @@ -144,24 +211,49 @@ tdm_thread_init(tdm_private_loop *private_loop) return TDM_ERROR_OUT_OF_MEMORY; } + if (pthread_cond_init(&private_thread->event_cond, NULL)) { + TDM_ERR("pthread_cond_init failed: %m"); + free(private_thread); + return TDM_ERROR_OUT_OF_MEMORY; + } + if (pipe(private_thread->pipe) != 0) { - TDM_ERR("socketpair failed: %m"); + TDM_ERR("pipe failed: %m"); + pthread_cond_destroy(&private_thread->event_cond); free(private_thread); return TDM_ERROR_OPERATION_FAILED; } + if (pipe(private_thread->sub_pipe) != 0) { + TDM_ERR("sub_pipe failed: %m"); + close(private_thread->pipe[0]); + close(private_thread->pipe[1]); + pthread_cond_destroy(&private_thread->event_cond); + free(private_thread); + return TDM_ERROR_OPERATION_FAILED; + } + + keep_private_thread = private_thread; + private_thread->private_loop = private_loop; private_loop->private_thread = private_thread; private_thread->display_tid = syscall(SYS_gettid); + /* pthread_cond_wait atomically release mutex, Upon successful return, + * the mutex shall have been locked and shall be owned by the calling thread + */ + tdm_mutex_locked = 0; pthread_create(&private_thread->event_thread, NULL, _tdm_thread_main, private_thread); - keep_private_thread = private_thread; + /* wait until the tdm thread starts */ + pthread_cond_wait(&private_thread->event_cond, &private_display->lock); + tdm_mutex_locked = 1; - TDM_INFO("using a TDM event thread. pipe(%d,%d)", - private_thread->pipe[0], private_thread->pipe[1]); + TDM_INFO("using a TDM event thread. pipe(%d,%d) sub_pipe(%d,%d)", + private_thread->pipe[0], private_thread->pipe[1], + private_thread->sub_pipe[0], private_thread->sub_pipe[1]); return TDM_ERROR_NONE; } @@ -170,12 +262,17 @@ INTERN void tdm_thread_deinit(tdm_private_loop *private_loop) { tdm_private_display *private_display; + tdm_private_thread_cb *cb = NULL, *hh = NULL; + int i; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); if (!private_loop->private_thread) return; + if (private_loop->private_thread->sub_event_source) + tdm_event_loop_source_remove(private_loop->private_thread->sub_event_source); + pthread_cancel(private_loop->private_thread->event_thread); private_display = private_loop->dpy; @@ -186,15 +283,31 @@ tdm_thread_deinit(tdm_private_loop *private_loop) _pthread_mutex_unlock(&private_display->lock); pthread_join(private_loop->private_thread->event_thread, NULL); + tdm_log_reset(); + + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list, link) { + _tdm_thread_free_cb(cb); + } + if (private_loop->private_thread->pipe[0] >= 0) close(private_loop->private_thread->pipe[0]); if (private_loop->private_thread->pipe[1] >= 0) close(private_loop->private_thread->pipe[1]); + if (private_loop->private_thread->sub_pipe[0] >= 0) + close(private_loop->private_thread->sub_pipe[0]); + if (private_loop->private_thread->sub_pipe[1] >= 0) + close(private_loop->private_thread->sub_pipe[1]); + + pthread_cond_destroy(&private_loop->private_thread->event_cond); + free(private_loop->private_thread); private_loop->private_thread = NULL; keep_private_thread = NULL; + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + TDM_INFO("Finish a TDM event thread"); } @@ -202,6 +315,7 @@ INTERN int tdm_thread_get_fd(tdm_private_loop *private_loop) { tdm_private_thread *private_thread; + int in_main; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(private_loop, -1); @@ -209,7 +323,13 @@ tdm_thread_get_fd(tdm_private_loop *private_loop) private_thread = private_loop->private_thread; - return private_thread->pipe[0]; + /* seems like ticky. but easy way to use the same APIs for both threads */ + in_main = tdm_thread_in_display_thread(syscall(SYS_gettid)); + + if (in_main) + return private_thread->pipe[0]; + else + return private_thread->sub_pipe[0]; } INTERN tdm_error @@ -217,6 +337,7 @@ tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base) { tdm_private_thread *private_thread; ssize_t len; + int pipe, in_main; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(base, TDM_ERROR_INVALID_PARAMETER); @@ -225,43 +346,58 @@ tdm_thread_send_cb(tdm_private_loop *private_loop, tdm_thread_cb_base *base) private_thread = private_loop->private_thread; + /* seems like ticky. but easy way to use the same APIs for both threads */ + in_main = tdm_thread_in_display_thread(syscall(SYS_gettid)); + + if (in_main) + pipe = private_thread->sub_pipe[1]; + else + pipe = private_thread->pipe[1]; + if (tdm_debug_module & TDM_DEBUG_THREAD) - TDM_INFO("fd(%d) type(%d), length(%d)", - private_thread->pipe[1], base->type, base->length); + TDM_INFO("fd(%d) type(%d), length(%d)", pipe, base->type, base->length); - len = write(private_thread->pipe[1], base, base->length); + len = write(pipe, base, base->length); if (len != base->length) { TDM_ERR("write failed (%d != %d): %m", (int)len, base->length); return TDM_ERROR_OPERATION_FAILED; } + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("[%s] write fd(%d) length(%d)", (in_main) ? "main" : "sub", pipe, len); + return TDM_ERROR_NONE; } INTERN tdm_error tdm_thread_handle_cb(tdm_private_loop *private_loop) { - tdm_private_display *private_display; tdm_private_thread *private_thread; tdm_thread_cb_base *base; char buffer[1024]; unsigned int i; - int len; - - /* DON'T check TDM_MUTEX_IS_LOCKED here */ + int len, pipe, in_main; + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(private_loop, TDM_ERROR_INVALID_PARAMETER); TDM_RETURN_VAL_IF_FAIL(private_loop->private_thread, TDM_ERROR_INVALID_PARAMETER); private_thread = private_loop->private_thread; - private_display = private_loop->dpy; + + /* seems like ticky. but easy way to use the same APIs for both threads */ + in_main = tdm_thread_in_display_thread(syscall(SYS_gettid)); + + if (in_main) + pipe = private_thread->pipe[0]; + else + pipe = private_thread->sub_pipe[0]; do { - len = read(private_thread->pipe[0], buffer, sizeof buffer); + len = read(pipe, buffer, sizeof buffer); } while (len < 0 && errno == EINTR); if (tdm_debug_module & TDM_DEBUG_THREAD) - TDM_INFO("fd(%d) read length(%d)", private_thread->pipe[0], len); + TDM_INFO("[%s] read fd(%d) length(%d)", (in_main) ? "main" : "sub", pipe, len); if (len < 0) { TDM_ERR("read failed: errno(%d), len(%d) %m", errno, len); @@ -276,8 +412,6 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) return TDM_ERROR_OPERATION_FAILED; } - _pthread_mutex_lock(&private_display->lock); - i = 0; while (i < len) { base = (tdm_thread_cb_base*)&buffer[i]; @@ -380,8 +514,6 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) i += base->length; } - _pthread_mutex_unlock(&private_display->lock); - return TDM_ERROR_NONE; } @@ -403,3 +535,217 @@ tdm_thread_is_running(void) return (keep_private_thread) ? 1 : 0; } + +static void +_tdm_thread_free_cb(tdm_private_thread_cb *cb) +{ + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("cb(%p) removed", cb); + + assert(LIST_IS_EMPTY(&cb->call_link)); + + LIST_DEL(&cb->link); + free(cb); +} + +static tdm_private_thread_cb * +_tdm_thread_find_cb(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_thread_cb func, void *user_data, pid_t owner_tid) +{ + tdm_private_thread_cb *cb = NULL; + + LIST_FOR_EACH_ENTRY(cb, &cb_list, link) { + if (cb->object == object && + cb->cb_type == cb_type && + cb->cb_data == cb_data && + cb->func == func && + cb->user_data == user_data && + cb->owner_tid == owner_tid) + return cb; + } + + return NULL; +} + +static void +_tdm_thread_reset_cb(tdm_thread_cb_type cb_type) +{ + tdm_private_thread_cb *cb = NULL; + + LIST_FOR_EACH_ENTRY(cb, &cb_list, link) { + if (cb->cb_type == cb_type) + cb->called = 0; + } +} + +INTERN void +tdm_thread_cb_set_find_func(tdm_thread_cb_type cb_type, tdm_thread_find_object func) +{ + TDM_RETURN_IF_FAIL(cb_type > 0); + + if (func && find_funcs[cb_type]) + TDM_NEVER_GET_HERE(); + + find_funcs[cb_type] = func; +} + +INTERN tdm_error +tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_thread_cb func, void *user_data) +{ + tdm_private_thread_cb *cb = NULL; + pid_t caller_tid; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); + TDM_RETURN_VAL_IF_FAIL(object != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(cb_type > 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); + + caller_tid = syscall(SYS_gettid); + + cb = _tdm_thread_find_cb(object, cb_type, cb_data, func, user_data, caller_tid); + if (cb) { + TDM_ERR("can't be added twice with same data"); +#if 1 + assert(0); +#endif + return TDM_ERROR_BAD_REQUEST; + } + + cb = calloc(1, sizeof *cb); + if (!cb) { + TDM_ERR("calloc failed"); + return TDM_ERROR_OUT_OF_MEMORY; + } + + LIST_ADDTAIL(&cb->link, &cb_list); + LIST_INITHEAD(&cb->call_link); + + cb->object = object; + cb->cb_type = cb_type; + cb->cb_data = cb_data; + cb->func = func; + cb->user_data = user_data; + cb->owner_tid = caller_tid; + + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("cb_type(%d) cb(%p) added", cb_type, cb); + + return TDM_ERROR_NONE; +} + +INTERN void +tdm_thread_cb_remove(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_thread_cb func, void *user_data) +{ + tdm_private_thread_cb *cb; + pid_t caller_tid; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + TDM_RETURN_IF_FAIL(object != NULL); + TDM_RETURN_IF_FAIL(cb_type > 0); + TDM_RETURN_IF_FAIL(func != NULL); + + caller_tid = syscall(SYS_gettid); + + cb = _tdm_thread_find_cb(object, cb_type, cb_data, func, user_data, caller_tid); + if (!cb) + return; + + _tdm_thread_free_cb(cb); +} + +/* when call a callback, we check both cb_base's type and cb_base's data, + * because a callback is added with cb_type and cb_data. + */ +INTERN tdm_error +tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base) +{ + tdm_private_display *private_display = tdm_display_get(); + tdm_private_thread_cb *cb = NULL, *hh = NULL; + int handler_in_other_thread = 0; + pid_t caller_tid; + struct list_head call_list; + tdm_error ret; + + TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); + TDM_RETURN_VAL_IF_FAIL(cb_base != NULL, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(cb_base->type > 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(cb_base->length > 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(cb_base->sync == 0 || cb_base->sync == 1, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_VAL_IF_FAIL(cb_base->object_stamp > 0, TDM_ERROR_INVALID_PARAMETER); + + caller_tid = syscall(SYS_gettid); + + assert(find_funcs[cb_base->type] != NULL); + + if (!object) { + object = find_funcs[cb_base->type](private_display, cb_base->object_stamp); + if (!object) { + TDM_WRN("%p gone", object); + return TDM_ERROR_NONE; + } + } + + LIST_INITHEAD(&call_list); + + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &cb_list, link) { + if (cb->called || + cb->object != object || + cb->cb_type != cb_base->type || + cb->cb_data != cb_base->data) + continue; + + if (cb->owner_tid == caller_tid) + LIST_ADDTAIL(&cb->call_link, &call_list); + else + handler_in_other_thread = 1; + } + + if (!LIST_IS_EMPTY(&call_list)) { + LIST_FOR_EACH_ENTRY_SAFE(cb, hh, &call_list, call_link) { + LIST_DELINIT(&cb->call_link); + cb->called = 1; + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("cb_type(%d) cb(%p) called", cb->cb_type, cb); + cb->func(private_display, cb->object, cb_base, cb->user_data); + } + } + + assert(LIST_IS_EMPTY(&call_list)); + + if (!handler_in_other_thread) { + _tdm_thread_reset_cb(cb_base->type); + if (keep_private_thread) { + if (cb_base->sync) { + pthread_cond_signal(&keep_private_thread->event_cond); + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("pthread broadcase"); + } + } + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("'%s' thread_cb done(sync:%d)", tdm_cb_type_str(cb_base->type), cb_base->sync); + return TDM_ERROR_NONE; + } + + /* Once we reach here, it means that keep_private_thread is not NULL. + * Just make the crash. Avoiding it is not going to help us. + */ + ret = tdm_thread_send_cb(private_display->private_loop, cb_base); + TDM_RETURN_VAL_IF_FAIL(ret == TDM_ERROR_NONE, TDM_ERROR_OPERATION_FAILED); + + /* waiting until all cb are done in another thread */ + if (cb_base->sync) { + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("pthread wait"); + + /* pthread_cond_wait atomically release mutex, Upon successful return, + * the mutex shall have been locked and shall be owned by the calling thread + */ + tdm_mutex_locked = 0; + pthread_cond_wait(&keep_private_thread->event_cond, &private_display->lock); + tdm_mutex_locked = 1; + } + + if (tdm_debug_module & TDM_DEBUG_THREAD) + TDM_INFO("'%s' thread_cb done(sync:%d)", tdm_cb_type_str(cb_base->type), cb_base->sync); + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_thread.h b/src/tdm_thread.h index c9ef06d..1a91933 100644 --- a/src/tdm_thread.h +++ b/src/tdm_thread.h @@ -57,6 +57,19 @@ tdm_thread_in_display_thread(pid_t tid); int tdm_thread_is_running(void); +typedef void* (*tdm_thread_find_object)(tdm_private_display *private_display, double stamp); +typedef void (*tdm_thread_cb)(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); + +void +tdm_thread_cb_set_find_func(tdm_thread_cb_type cb_type, tdm_thread_find_object func); +tdm_error +tdm_thread_cb_add(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_thread_cb func, void *user_data); +void +tdm_thread_cb_remove(void *object, tdm_thread_cb_type cb_type, void *cb_data, tdm_thread_cb func, void *user_data); +tdm_error +tdm_thread_cb_call(void *object, tdm_thread_cb_base *cb_base); + + #ifdef __cplusplus } #endif -- 2.7.4 From 8b977463ed4b95abc75aa2ab547a877cb6d08d09 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Jan 2018 09:53:05 +0900 Subject: [PATCH 09/16] pp: using thread_cb Change-Id: I02bdd31434f95ff5c249e839442fd397afaffdef --- src/tdm.c | 4 +++ src/tdm_pp.c | 85 +++++++++++++++++++++++++++++++++---------------- src/tdm_private.h | 7 ++-- src/tdm_private_types.h | 2 -- src/tdm_thread.c | 12 ++----- 5 files changed, 65 insertions(+), 45 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 2536479..a35bb4b 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -974,6 +974,10 @@ tdm_display_init(tdm_error *error) TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; + ret = tdm_pp_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_load; + ret = _tdm_display_load_module(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 6e1dafd..8f4fd8d 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -68,7 +68,7 @@ _tdm_pp_print_list(struct list_head *list) break; } - TDM_WRN("\t %s", str); + TDM_INFO("\t %s", str); } static tdm_pp_private_buffer * @@ -97,35 +97,21 @@ _tdm_pp_find_buffer(struct list_head *list, tdm_pp_private_buffer *pp_buffer) return NULL; } -INTERN void -tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, - void *user_data) +static void +_tdm_pp_thread_cb_done(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_pp *private_pp = user_data; - tdm_private_display *private_display = private_pp->private_display; + tdm_thread_cb_pp_done *pp_done = (tdm_thread_cb_pp_done *)cb_base; + tdm_private_pp *private_pp = object; tdm_pp_private_buffer *pp_buffer = NULL, *first_entry = NULL; + tbm_surface_h src; + tbm_surface_h dst; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - if (private_pp->owner_tid != syscall(SYS_gettid)) { - tdm_thread_cb_pp_done pp_done; - tdm_error ret; - - pp_done.base.type = TDM_THREAD_CB_PP_DONE; - pp_done.base.length = sizeof pp_done; - pp_done.pp_stamp = private_pp->stamp; - pp_done.src = src; - pp_done.dst = dst; - pp_done.user_data = user_data; - - ret = tdm_thread_send_cb(private_display->private_loop, &pp_done.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } + assert(private_pp->owner_tid == syscall(SYS_gettid)); - if (private_pp->owner_tid != syscall(SYS_gettid)) - TDM_NEVER_GET_HERE(); + src = pp_done->src; + dst = pp_done->dst; if (tdm_debug_dump & TDM_DUMP_FLAG_PP) { /* LCOV_EXCL_START */ @@ -167,8 +153,30 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, } } -INTERN tdm_private_pp * -tdm_pp_find_stamp(tdm_private_display *private_display, double stamp) +static void +_tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, void *user_data) +{ + tdm_thread_cb_pp_done pp_done; + tdm_private_pp *private_pp = user_data; + tdm_error ret; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + memset(&pp_done, 0, sizeof pp_done); + pp_done.base.type = TDM_THREAD_CB_PP_DONE; + pp_done.base.length = sizeof pp_done; + pp_done.base.object_stamp = private_pp->stamp; + pp_done.base.data = NULL; + pp_done.base.sync = 0; + pp_done.src = src; + pp_done.dst = dst; + + ret = tdm_thread_cb_call(private_pp, &pp_done.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +static void * +_tdm_pp_find_object(tdm_private_display *private_display, double stamp) { tdm_private_pp *private_pp = NULL; @@ -182,6 +190,14 @@ tdm_pp_find_stamp(tdm_private_display *private_display, double stamp) return NULL; } +INTERN tdm_error +tdm_pp_init(tdm_private_display *private_display) +{ + tdm_thread_cb_set_find_func(TDM_THREAD_CB_PP_DONE, _tdm_pp_find_object); + + return TDM_ERROR_NONE; +} + INTERN tdm_private_pp * tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) { @@ -225,11 +241,22 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) /* LCOV_EXCL_STOP */ } - ret = func_pp->pp_set_done_handler(pp_backend, tdm_pp_cb_done, private_pp); + ret = tdm_thread_cb_add(private_pp, TDM_THREAD_CB_PP_DONE, NULL, _tdm_pp_thread_cb_done, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("pp tdm_thread_cb_add failed"); + func_pp->pp_destroy(pp_backend); + free(private_pp); + if (error) + *error = ret; + return NULL; + } + + ret = func_pp->pp_set_done_handler(pp_backend, _tdm_pp_cb_done, private_pp); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ TDM_ERR("spp(%p) et pp_done_handler failed", private_pp); func_pp->pp_destroy(pp_backend); + free(private_pp); if (error) *error = ret; return NULL; @@ -237,7 +264,7 @@ tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error) } private_pp->stamp = tdm_helper_get_time(); - while (tdm_pp_find_stamp(private_display, private_pp->stamp)) + while (_tdm_pp_find_object(private_display, private_pp->stamp)) private_pp->stamp++; LIST_ADD(&private_pp->link, &private_display->pp_list); @@ -267,6 +294,8 @@ tdm_pp_destroy_internal(tdm_private_pp *private_pp) if (!private_pp) return; + tdm_thread_cb_remove(private_pp, TDM_THREAD_CB_PP_DONE, NULL, _tdm_pp_thread_cb_done, NULL); + private_display = private_pp->private_display; func_pp = &private_display->func_pp; diff --git a/src/tdm_private.h b/src/tdm_private.h index f04eebb..fb1886f 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -92,8 +92,6 @@ tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, i tdm_private_output * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp); -tdm_private_pp * -tdm_pp_find_stamp(tdm_private_display *private_display, double stamp); tdm_private_capture * tdm_capture_find_stamp(tdm_private_display *private_display, double stamp); @@ -151,9 +149,6 @@ tdm_error tdm_layer_unset_buffer_internal(tdm_private_layer *private_layer); void -tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, - void *user_data); -void tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data); tdm_error @@ -181,6 +176,8 @@ tdm_output_call_change_handler_internal(tdm_private_output *private_output, tdm_output_change_type type, tdm_value value); +tdm_error +tdm_pp_init(tdm_private_display *private_display); tdm_private_pp * tdm_pp_create_internal(tdm_private_display *private_display, tdm_error *error); void diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index a4ac11d..85413c4 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -487,10 +487,8 @@ struct _tdm_thread_cb_output_dpms { struct _tdm_thread_cb_pp_done { tdm_thread_cb_base base; - double pp_stamp; tbm_surface_h src; tbm_surface_h dst; - void *user_data; }; struct _tdm_thread_cb_capture_done { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 5b7f00e..0bd4e86 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -471,17 +471,9 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) break; /* LCOV_EXCL_STOP */ } - case TDM_THREAD_CB_PP_DONE: { - tdm_thread_cb_pp_done *pp_done = (tdm_thread_cb_pp_done*)base; - tdm_pp *pp_backend = - tdm_pp_find_stamp(private_loop->dpy, pp_done->pp_stamp); - if (!pp_backend) { - TDM_WRN("no pp(%f)", pp_done->pp_stamp); - break; - } - tdm_pp_cb_done(pp_backend, pp_done->src, pp_done->dst, pp_done->user_data); + case TDM_THREAD_CB_PP_DONE: + tdm_thread_cb_call(NULL, base); break; - } case TDM_THREAD_CB_CAPTURE_DONE: { tdm_thread_cb_capture_done *capture_done = (tdm_thread_cb_capture_done*)base; tdm_capture *capture_backend = -- 2.7.4 From e95be5f458e48a9eb5968fb98e6fc71f27804ff7 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Jan 2018 09:53:31 +0900 Subject: [PATCH 10/16] capture: using thread_cb Change-Id: I9c2e914fb12d472aac1faf354e893a18c3b060e3 --- src/tdm.c | 4 +++ src/tdm_capture.c | 82 ++++++++++++++++++++++++++++++++----------------- src/tdm_private.h | 7 ++--- src/tdm_private_types.h | 2 -- src/tdm_thread.c | 12 +------- 5 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index a35bb4b..b81347d 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -978,6 +978,10 @@ tdm_display_init(tdm_error *error) if (ret != TDM_ERROR_NONE) goto failed_load; + ret = tdm_capture_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_load; + ret = _tdm_display_load_module(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 2ba0e5f..869e31f 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -97,34 +97,19 @@ _tdm_capture_find_buffer(struct list_head *list, tdm_capture_private_buffer *cap return NULL; } -INTERN void -tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, - void *user_data) +static void +_tdm_capture_thread_cb_done(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_capture *private_capture = user_data; - tdm_private_display *private_display = private_capture->private_display; + tdm_thread_cb_capture_done *capture_done = (tdm_thread_cb_capture_done *)cb_base; + tdm_private_capture *private_capture = object; tdm_capture_private_buffer *capture_buffer = NULL, *first_entry = NULL; + tbm_surface_h buffer; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - if (private_capture->owner_tid != syscall(SYS_gettid)) { - tdm_thread_cb_capture_done capture_done; - tdm_error ret; - - capture_done.base.type = TDM_THREAD_CB_CAPTURE_DONE; - capture_done.base.length = sizeof capture_done; - capture_done.capture_stamp = private_capture->stamp; - capture_done.buffer = buffer; - capture_done.user_data = user_data; - - ret = tdm_thread_send_cb(private_display->private_loop, &capture_done.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } + assert(private_capture->owner_tid == syscall(SYS_gettid)); - if (private_capture->owner_tid != syscall(SYS_gettid)) - TDM_NEVER_GET_HERE(); + buffer = capture_done->buffer; if (tdm_debug_dump & TDM_DUMP_FLAG_CAPTURE) { /* LCOV_EXCL_START */ @@ -165,8 +150,29 @@ tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, } } -INTERN tdm_private_capture * -tdm_capture_find_stamp(tdm_private_display *private_display, double stamp) +static void +_tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, void *user_data) +{ + tdm_private_capture *private_capture = user_data; + tdm_thread_cb_capture_done capture_done; + tdm_error ret; + + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + memset(&capture_done, 0, sizeof capture_done); + capture_done.base.type = TDM_THREAD_CB_CAPTURE_DONE; + capture_done.base.length = sizeof capture_done; + capture_done.base.object_stamp = private_capture->stamp; + capture_done.base.data = NULL; + capture_done.base.sync = 0; + capture_done.buffer = buffer; + + ret = tdm_thread_cb_call(private_capture, &capture_done.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +static void * +_tdm_capture_find_object(tdm_private_display *private_display, double stamp) { tdm_private_capture *private_capture = NULL; @@ -180,6 +186,14 @@ tdm_capture_find_stamp(tdm_private_display *private_display, double stamp) return NULL; } +INTERN tdm_error +tdm_capture_init(tdm_private_display *private_display) +{ + tdm_thread_cb_set_find_func(TDM_THREAD_CB_CAPTURE_DONE, _tdm_capture_find_object); + + return TDM_ERROR_NONE; +} + INTERN tdm_private_capture * tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error *error) @@ -232,12 +246,22 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, /* LCOV_EXCL_STOP */ } - ret = func_capture->capture_set_done_handler(capture_backend, - tdm_capture_cb_done, private_capture); + ret = tdm_thread_cb_add(private_capture, TDM_THREAD_CB_CAPTURE_DONE, NULL, _tdm_capture_thread_cb_done, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("capture tdm_thread_cb_add failed"); + func_capture->capture_destroy(capture_backend); + free(private_capture); + if (error) + *error = ret; + return NULL; + } + + ret = func_capture->capture_set_done_handler(capture_backend, _tdm_capture_cb_done, private_capture); if (ret != TDM_ERROR_NONE) { /* LCOV_EXCL_START */ TDM_ERR("capture(%p) set capture_done_handler failed", private_capture); func_capture->capture_destroy(capture_backend); + free(private_capture); if (error) *error = ret; return NULL; @@ -245,7 +269,7 @@ tdm_capture_create_output_internal(tdm_private_output *private_output, } private_capture->stamp = tdm_helper_get_time(); - while (tdm_capture_find_stamp(private_display, private_capture->stamp)) + while (_tdm_capture_find_object(private_display, private_capture->stamp)) private_capture->stamp++; LIST_ADD(&private_capture->link, &private_output->capture_list); @@ -313,7 +337,7 @@ tdm_capture_create_layer_internal(tdm_private_layer *private_layer, } private_capture->stamp = tdm_helper_get_time(); - while (tdm_capture_find_stamp(private_display, private_capture->stamp)) + while (_tdm_capture_find_object(private_display, private_capture->stamp)) private_capture->stamp++; LIST_ADD(&private_capture->link, &private_layer->capture_list); @@ -353,6 +377,8 @@ tdm_capture_destroy_internal(tdm_private_capture *private_capture) private_display = private_capture->private_display; + tdm_thread_cb_remove(private_capture, TDM_THREAD_CB_CAPTURE_DONE, NULL, _tdm_capture_thread_cb_done, NULL); + LIST_DEL(&private_capture->link); LIST_DEL(&private_capture->display_link); diff --git a/src/tdm_private.h b/src/tdm_private.h index fb1886f..c19ceb4 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -92,8 +92,6 @@ tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, i tdm_private_output * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp); -tdm_private_capture * -tdm_capture_find_stamp(tdm_private_display *private_display, double stamp); int tdm_output_is_valid(tdm_output *output); @@ -148,9 +146,6 @@ tdm_layer_set_buffer_internal(tdm_private_layer *private_layer, tbm_surface_h bu tdm_error tdm_layer_unset_buffer_internal(tdm_private_layer *private_layer); -void -tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, - void *user_data); tdm_error tdm_vblank_init(tdm_display *dpy); void @@ -188,6 +183,8 @@ tdm_hwc_window_create_internal(tdm_private_output *private_output, int is_video, tdm_error tdm_hwc_window_destroy_internal(tdm_private_hwc_window * private_hwc_window); +tdm_error +tdm_capture_init(tdm_private_display *private_display); tdm_private_capture * tdm_capture_create_output_internal(tdm_private_output *private_output, tdm_error *error); diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 85413c4..188d3fe 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -493,9 +493,7 @@ struct _tdm_thread_cb_pp_done { struct _tdm_thread_cb_capture_done { tdm_thread_cb_base base; - double capture_stamp; tbm_surface_h buffer; - void *user_data; }; struct _tdm_thread_cb_vblank_sw { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index 0bd4e86..ff0d0c8 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -472,19 +472,9 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) /* LCOV_EXCL_STOP */ } case TDM_THREAD_CB_PP_DONE: + case TDM_THREAD_CB_CAPTURE_DONE: tdm_thread_cb_call(NULL, base); break; - case TDM_THREAD_CB_CAPTURE_DONE: { - tdm_thread_cb_capture_done *capture_done = (tdm_thread_cb_capture_done*)base; - tdm_capture *capture_backend = - tdm_capture_find_stamp(private_loop->dpy, capture_done->capture_stamp); - if (!capture_backend) { - TDM_WRN("no capture(%f)", capture_done->capture_stamp); - break; - } - tdm_capture_cb_done(capture_backend, capture_done->buffer, capture_done->user_data); - break; - } case TDM_THREAD_CB_VBLANK_SW: { tdm_thread_cb_vblank_sw *vblank_sw = (tdm_thread_cb_vblank_sw*)base; tdm_vblank_cb_vblank_SW(NULL, vblank_sw->vblank_stamp); -- 2.7.4 From 37fd93539622189a546c8f00296d3e3a0ac8a9ae Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Jan 2018 09:53:49 +0900 Subject: [PATCH 11/16] vblank: using thread_cb Change-Id: I2974baaff66cbe7fd1ea0e18ed89e68229efdd0f --- src/tdm.c | 2 + src/tdm_private.h | 4 - src/tdm_private_types.h | 3 +- src/tdm_thread.c | 12 +-- src/tdm_vblank.c | 228 ++++++++++++++++++++++++++++-------------------- 5 files changed, 138 insertions(+), 111 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index b81347d..0213cb7 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -940,6 +940,8 @@ tdm_display_init(tdm_error *error) /* LCOV_EXCL_STOP */ } + private_display->stamp = tdm_helper_get_time(); + str = tdm_config_get_string(TDM_CONFIG_KEY_DEBUG_MODULE, NULL); if (str) tdm_display_enable_debug_module(str); diff --git a/src/tdm_private.h b/src/tdm_private.h index c19ceb4..44359f9 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -151,10 +151,6 @@ tdm_vblank_init(tdm_display *dpy); void tdm_vblank_deinit(tdm_display *dpy); tdm_error -tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp); -tdm_error -tdm_vblank_cb_vblank_create(tdm_vblank *vblank, double vblank_stamp); -tdm_error tdm_vblank_set_add_front(tdm_vblank *vblank, unsigned int add_front); tdm_error tdm_vblank_set_resource(tdm_vblank *vblank, struct wl_resource *resource); diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 188d3fe..4f3da84 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -118,6 +118,8 @@ struct _tdm_private_display { pthread_mutex_t lock; unsigned int init_count; + double stamp; + /* backend module info */ void *module; tdm_backend_module *module_data; @@ -498,7 +500,6 @@ struct _tdm_thread_cb_capture_done { struct _tdm_thread_cb_vblank_sw { tdm_thread_cb_base base; - double vblank_stamp; }; struct _tdm_thread_cb_vblank_create { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index ff0d0c8..e9fec48 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -473,18 +473,10 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) } case TDM_THREAD_CB_PP_DONE: case TDM_THREAD_CB_CAPTURE_DONE: + case TDM_THREAD_CB_VBLANK_SW: + case TDM_THREAD_CB_VBLANK_CREATE: tdm_thread_cb_call(NULL, base); break; - case TDM_THREAD_CB_VBLANK_SW: { - tdm_thread_cb_vblank_sw *vblank_sw = (tdm_thread_cb_vblank_sw*)base; - tdm_vblank_cb_vblank_SW(NULL, vblank_sw->vblank_stamp); - break; - } - case TDM_THREAD_CB_VBLANK_CREATE: { - tdm_thread_cb_vblank_create *vblank_create = (tdm_thread_cb_vblank_create*)base; - tdm_vblank_cb_vblank_create(NULL, vblank_create->vblank_stamp); - break; - } case TDM_THREAD_CB_NEED_VALIDATE: { tdm_thread_cb_need_validate *ev = (tdm_thread_cb_need_validate*)base; tdm_output_cb_need_validate(ev->o); diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index ad4b9c0..12b760d 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -169,7 +169,8 @@ static unsigned int vblank_list_inited; static unsigned int vblank_global_fps; static double stamp = 0; -static tdm_error _tdm_vblank_cb_vblank_SW(void *user_data); +static void _tdm_vblank_cb_vblank_SW(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); +static tdm_error _tdm_vblank_cb_timeout_SW(void *user_data); static tdm_error _tdm_vblank_wait_SW(tdm_vblank_wait_info *wait_info); static void _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, @@ -180,14 +181,25 @@ static void _tdm_vblank_get_client_information(tdm_private_vblank *private_vblan #if 0 static void -_print_list(struct list_head *list) +_print_list(tdm_private_vblank *private_vblank) { tdm_vblank_wait_info *w = NULL; + int count = 0; - LIST_FOR_EACH_ENTRY(w, list, link) { - printf(" %d", w->interval); + LIST_FOR_EACH_ENTRY(w, &private_vblank->HW_wait_list, link) { + VIN("HW_wait(%p): type(%d) req_time(%.6f) target_time(%.6f) target_seq(%u)", + w, w->type, w->req_time, w->target_time, w->target_seq); + count++; + } + + LIST_FOR_EACH_ENTRY(w, &private_vblank->SW_wait_list, link) { + VIN("SW_wait(%p): type(%d) req_time(%.6f) target_time(%.6f) target_seq(%u)", + w, w->type, w->req_time, w->target_time, w->target_seq); + count++; } - printf("\n"); + + if (!count) + VIN("NO_wait"); } #endif @@ -226,14 +238,11 @@ _tdm_vblank_valid_list_del(struct list_head *valid_link) pthread_mutex_unlock(&valid_list_lock); } -static inline tdm_private_vblank* -_tdm_vblank_find(double vblank_stamp) +static inline void* +_tdm_vblank_find_object(tdm_private_display *private_display, double vblank_stamp) { tdm_private_vblank *v = NULL; - if (!vblank_stamp) - return 0; - pthread_mutex_lock(&valid_list_lock); LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { if (v->stamp == vblank_stamp) { @@ -243,7 +252,7 @@ _tdm_vblank_find(double vblank_stamp) } pthread_mutex_unlock(&valid_list_lock); - return 0; + return NULL; } static inline unsigned int @@ -353,7 +362,7 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un tdm_display_unlock(private_vblank->dpy); VDB("wait(%p) last(%.6f) sequence(%u) done (error:%d, call_cb:%u)", - w, 0, w->target_seq, error, call_cb); + w, (double)0.0, w->target_seq, error, call_cb); if (call_cb && w->func) w->func(private_vblank, error, 0, 0, 0, w->user_data); @@ -550,47 +559,45 @@ tdm_vblank_enable_global_fps(unsigned int enable, unsigned int fps) return TDM_ERROR_NONE; } -INTERN tdm_error -tdm_vblank_cb_vblank_create(tdm_vblank *vblank, double vblank_stamp) +static void +_tdm_vblank_thread_cb_create(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { + tdm_thread_cb_vblank_create *vblank_create = (tdm_thread_cb_vblank_create *)cb_base; + tdm_vblank_create_handler_info *ch_info = user_data; tdm_private_vblank *private_vblank; - tdm_vblank_create_handler_info *ch_info = NULL, *hh = NULL; - TDM_RETURN_VAL_IF_FAIL(vblank || vblank_stamp > 0, TDM_ERROR_INVALID_PARAMETER); + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - if (vblank) - private_vblank = vblank; - else { - private_vblank = _tdm_vblank_find(vblank_stamp); - if (!private_vblank) { - TDM_DBG("can't find vblank(%.0f) from valid_list", vblank_stamp); - return TDM_ERROR_NONE; - } - } + assert(ch_info != NULL); - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - tdm_thread_cb_vblank_create vblank_create; - tdm_private_display *private_display = private_vblank->dpy; - tdm_error ret; + private_vblank = _tdm_vblank_find_object(private_display, vblank_create->vblank_stamp); + if (!private_vblank) { + TDM_DBG("can't find vblank(%.0f) from valid_list", vblank_create->vblank_stamp); + return; + } - vblank_create.base.type = TDM_THREAD_CB_VBLANK_CREATE; - vblank_create.base.length = sizeof vblank_create; - vblank_create.vblank_stamp = private_vblank->stamp; + /* use in_create_handler instead of mutext unlock/lock */ + private_vblank->in_create_handler = 1; + ch_info->func(private_vblank, ch_info->user_data); + private_vblank->in_create_handler = 0; +} - ret = tdm_thread_send_cb(private_display->private_loop, &vblank_create.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +static tdm_error +_tdm_vblank_call_thread_cb(tdm_private_vblank *private_vblank) +{ + tdm_thread_cb_vblank_create vblank_create; + tdm_error ret; - return TDM_ERROR_NONE; - } + memset(&vblank_create, 0, sizeof vblank_create); + vblank_create.base.type = TDM_THREAD_CB_VBLANK_CREATE; + vblank_create.base.length = sizeof vblank_create; + vblank_create.base.object_stamp = 1; + vblank_create.base.data = NULL; + vblank_create.base.sync = 0; + vblank_create.vblank_stamp = private_vblank->stamp; - LIST_FOR_EACH_ENTRY_SAFE(ch_info, hh, &create_handler_list, link) { - /* use in_create_handler instead of mutext unlock/lock */ - private_vblank->in_create_handler = 1; - //_pthread_mutex_unlock(&private_display->lock); - ch_info->func(private_vblank, ch_info->user_data); - //_pthread_mutex_lock(&private_display->lock); - private_vblank->in_create_handler = 0; - } + ret = tdm_thread_cb_call(private_vblank->dpy, &vblank_create.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); return TDM_ERROR_NONE; } @@ -598,27 +605,36 @@ tdm_vblank_cb_vblank_create(tdm_vblank *vblank, double vblank_stamp) EXTERN tdm_error tdm_vblank_add_create_handler(tdm_display *dpy, tdm_vblank_create_handler func, void *user_data) { - tdm_vblank_create_handler_info *ch_info; + tdm_vblank_create_handler_info *ch_info = NULL; + tdm_error ret; + TDM_RETURN_VAL_IF_FAIL(!TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(func != NULL, TDM_ERROR_INVALID_PARAMETER); - /* we don't allow adding a create handler in sub-thread because tdm_vblank_create() - * can be called in both threads and tdm_thread_send_cb supports only one-way - * communication now. - */ - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - TDM_ERR("add_create_handler should be called in main thread"); - return TDM_ERROR_BAD_REQUEST; + LIST_FOR_EACH_ENTRY(ch_info, &create_handler_list, link) { + if (ch_info->func == func && ch_info->user_data == user_data) { + TDM_ERR("can't be added twice"); + return TDM_ERROR_BAD_REQUEST; + } } ch_info = calloc(1, sizeof *ch_info); TDM_RETURN_VAL_IF_FAIL(ch_info != NULL, TDM_ERROR_OUT_OF_MEMORY); + tdm_display_lock(dpy); + ret = tdm_thread_cb_add(dpy, TDM_THREAD_CB_VBLANK_CREATE, NULL, _tdm_vblank_thread_cb_create, ch_info); + tdm_display_unlock(dpy); + + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + free(ch_info); + return ret; + } + ch_info->func = func; ch_info->user_data = user_data; LIST_ADDTAIL(&ch_info->link, &create_handler_list); - return TDM_ERROR_NONE; } @@ -627,6 +643,8 @@ tdm_vblank_remove_create_handler(tdm_display *dpy, tdm_vblank_create_handler fun { tdm_vblank_create_handler_info *ch_info = NULL, *hh = NULL; + TDM_RETURN_IF_FAIL(!TDM_MUTEX_IS_LOCKED()); + /* we don't allow adding a create handler in sub-thread because tdm_vblank_create() * can be called in both threads and tdm_thread_send_cb supports only one-way * communication now. @@ -636,14 +654,27 @@ tdm_vblank_remove_create_handler(tdm_display *dpy, tdm_vblank_create_handler fun return; } + tdm_display_lock(dpy); + LIST_FOR_EACH_ENTRY_SAFE(ch_info, hh, &create_handler_list, link) { if (ch_info->func != func && ch_info->user_data != user_data) continue; + tdm_thread_cb_remove(dpy, TDM_THREAD_CB_VBLANK_CREATE, NULL, _tdm_vblank_thread_cb_create, ch_info); + LIST_DEL(&ch_info->link); free(ch_info); + tdm_display_unlock(dpy); return; } + + tdm_display_unlock(dpy); +} + +static void* +_tdm_vblank_find_display(tdm_private_display *private_display, double stamp) +{ + return private_display; } INTERN tdm_error @@ -661,6 +692,9 @@ tdm_vblank_init(tdm_display *dpy) LIST_INITHEAD(&valid_wait_list); LIST_INITHEAD(&create_handler_list); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_VBLANK_SW, _tdm_vblank_find_object); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_VBLANK_CREATE, _tdm_vblank_find_display); + vblank_list_inited = 1; return TDM_ERROR_NONE; @@ -736,7 +770,7 @@ tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) private_vblank->vrefresh, private_vblank->connection); tdm_display_lock(private_vblank->dpy); - tdm_vblank_cb_vblank_create(NULL, private_vblank->stamp); + _tdm_vblank_call_thread_cb(private_vblank); tdm_display_unlock(private_vblank->dpy); return (tdm_vblank *)private_vblank; @@ -759,6 +793,7 @@ tdm_vblank_destroy(tdm_vblank *vblank) if (private_vblank->SW_timer) { tdm_display_lock(private_vblank->dpy); + tdm_thread_cb_remove(private_vblank, TDM_THREAD_CB_VBLANK_SW, NULL, _tdm_vblank_cb_vblank_SW, NULL); tdm_event_loop_source_remove(private_vblank->SW_timer); tdm_display_unlock(private_vblank->dpy); } @@ -1083,7 +1118,7 @@ _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) if (!private_vblank->SW_timer) { private_vblank->SW_timer = tdm_event_loop_add_timer_handler(private_vblank->dpy, - _tdm_vblank_cb_vblank_SW, + _tdm_vblank_cb_timeout_SW, private_vblank, &ret); if (!private_vblank->SW_timer) { @@ -1091,6 +1126,16 @@ _tdm_vblank_sw_timer_update(tdm_private_vblank *private_vblank) VER("couldn't add timer"); return ret; } + + ret = tdm_thread_cb_add(private_vblank, TDM_THREAD_CB_VBLANK_SW, NULL, _tdm_vblank_cb_vblank_SW, NULL); + if (ret != TDM_ERROR_NONE) { + tdm_event_loop_source_remove(private_vblank->SW_timer); + private_vblank->SW_timer = NULL; + tdm_display_unlock(private_vblank->dpy); + VER("couldn't add thread_cb"); + return ret; + } + VIN("Create SW timer"); } @@ -1126,6 +1171,8 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, private_vblank = wait_info->private_vblank; TDM_RETURN_IF_FAIL(tdm_vblank_is_valid(private_vblank)); + assert(private_vblank->owner_tid == syscall(SYS_gettid)); + if (!_tdm_vblank_find_wait(wait_info, &private_vblank->HW_wait_list)) { VER("can't find wait(%p)", wait_info); return; @@ -1146,7 +1193,7 @@ _tdm_vblank_cb_vblank_HW(tdm_output *output, unsigned int sequence, ret = _tdm_vblank_sw_timer_update(private_vblank); - /* wait_info will be freed in _tdm_vblank_cb_vblank_SW() */ + /* wait_info will be freed in _tdm_vblank_cb_timeout_SW() */ if (ret == TDM_ERROR_NONE) { VIN("wait(%p) SW timer", wait_info); return; @@ -1271,59 +1318,26 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) return TDM_ERROR_NONE; } -static tdm_error -_tdm_vblank_cb_vblank_SW(void *user_data) -{ - tdm_private_vblank *private_vblank = user_data; - - TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(private_vblank), TDM_ERROR_OPERATION_FAILED); - - return tdm_vblank_cb_vblank_SW(private_vblank, 0); -} - -INTERN tdm_error -tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp) +static void +_tdm_vblank_cb_vblank_SW(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_vblank *private_vblank; + tdm_private_vblank *private_vblank = object; tdm_vblank_wait_info *first_wait_info = NULL, *w = NULL, *ww = NULL; - TDM_RETURN_VAL_IF_FAIL(vblank || vblank_stamp > 0, TDM_ERROR_INVALID_PARAMETER); - - if (vblank) - private_vblank = vblank; - else { - private_vblank = _tdm_vblank_find(vblank_stamp); - if (!private_vblank) { - TDM_ERR("can't find vblank(%.0f) from valid_list", vblank_stamp); - return TDM_ERROR_NONE; - } - } - - if (private_vblank->owner_tid != syscall(SYS_gettid)) { - tdm_thread_cb_vblank_sw vblank_sw; - tdm_private_display *private_display = private_vblank->dpy; - tdm_error ret; + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - vblank_sw.base.type = TDM_THREAD_CB_VBLANK_SW; - vblank_sw.base.length = sizeof vblank_sw; - vblank_sw.vblank_stamp = private_vblank->stamp; - - ret = tdm_thread_send_cb(private_display->private_loop, &vblank_sw.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return TDM_ERROR_NONE; - } + assert(private_vblank->owner_tid == syscall(SYS_gettid)); if (LIST_IS_EMPTY(&private_vblank->SW_wait_list)) { VER("no wait_info"); - return TDM_ERROR_OPERATION_FAILED; + return; } if (!LIST_IS_EMPTY(&private_vblank->HW_wait_list)) TDM_NEVER_GET_HERE(); first_wait_info = container_of(private_vblank->SW_wait_list.next, first_wait_info, link); - TDM_RETURN_VAL_IF_FAIL(first_wait_info != NULL, TDM_ERROR_OPERATION_FAILED); + TDM_RETURN_IF_FAIL(first_wait_info != NULL); _tdm_vblank_timeout_timer_update(private_vblank, 0); @@ -1352,6 +1366,28 @@ tdm_vblank_cb_vblank_SW(tdm_vblank *vblank, double vblank_stamp) free(w); } +} + +static tdm_error +_tdm_vblank_cb_timeout_SW(void *user_data) +{ + tdm_private_vblank *private_vblank = user_data; + tdm_thread_cb_vblank_sw vblank_sw; + tdm_error ret; + + TDM_RETURN_VAL_IF_FAIL(tdm_vblank_is_valid(private_vblank), TDM_ERROR_OPERATION_FAILED); + + VIN("timeout_SW -> thread-cb"); + + memset(&vblank_sw, 0, sizeof vblank_sw); + vblank_sw.base.type = TDM_THREAD_CB_VBLANK_SW; + vblank_sw.base.length = sizeof vblank_sw; + vblank_sw.base.object_stamp = private_vblank->stamp; + vblank_sw.base.data = NULL; + vblank_sw.base.sync = 0; + + ret = tdm_thread_cb_call(private_vblank, &vblank_sw.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); return TDM_ERROR_NONE; } -- 2.7.4 From d7a3a75c32b83cc1859589e38ba5b1d0cb1a20ff Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 29 Jan 2018 09:54:16 +0900 Subject: [PATCH 12/16] output: using thread_cb Change-Id: I00fa06b60a2fa808df7a54d6739d1c4d8b3ae54e --- src/tdm.c | 54 +++--- src/tdm_macro.h | 3 +- src/tdm_output.c | 491 +++++++++++++++++++++--------------------------- src/tdm_private.h | 20 +- src/tdm_private_types.h | 34 +--- src/tdm_thread.c | 62 +----- 6 files changed, 263 insertions(+), 401 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 0213cb7..7fabc4a 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -61,9 +61,8 @@ _tdm_display_find_private_layer(tdm_private_output *private_output, return NULL; } -static tdm_private_output * -_tdm_display_find_private_output(tdm_private_display *private_display, - tdm_output *output_backend) +INTERN tdm_private_output * +tdm_display_find_private_output(tdm_private_display *private_display, tdm_output *output_backend) { tdm_private_output *private_output = NULL; @@ -75,7 +74,7 @@ _tdm_display_find_private_output(tdm_private_display *private_display, return NULL; } -INTERN tdm_private_output * +INTERN void * tdm_display_find_output_stamp(tdm_private_display *private_display, double stamp) { tdm_private_output *private_output = NULL; @@ -135,8 +134,6 @@ _tdm_display_destroy_private_layer(tdm_private_layer *private_layer) { tdm_private_capture *c = NULL, *cc = NULL; - LIST_DEL(&private_layer->link); - tdm_layer_unset_buffer_internal(private_layer); LIST_FOR_EACH_ENTRY_SAFE(c, cc, &private_layer->capture_list, link) @@ -144,6 +141,11 @@ _tdm_display_destroy_private_layer(tdm_private_layer *private_layer) _tdm_display_destroy_caps_layer(&private_layer->caps); + /* when destroying layer, someone could check if layer is valid. So delete + * the layer's link at last. + */ + LIST_DEL(&private_layer->link); + free(private_layer); } @@ -154,13 +156,11 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) tdm_private_layer *l = NULL, *ll = NULL; tdm_private_hwc_window *hw = NULL, *hww = NULL; tdm_private_capture *c = NULL, *cc = NULL; - tdm_private_vblank_handler *v = NULL, *vv = NULL; + tdm_private_output_vblank_handler *v = NULL, *vv = NULL; tdm_private_output_commit_handler *om = NULL, *omm = NULL; tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; tdm_private_output_change_handler *h = NULL, *hh = NULL; - LIST_DEL(&private_output->link); - free(private_output->layers_ptr); if (private_output->vblank_timeout_timer) @@ -186,13 +186,9 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) free(lm); } - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) { - LIST_DEL(&h->link); - free(h); - } - - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) { + LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list, link) { LIST_DEL(&h->link); + tdm_thread_cb_remove(h->private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, h); free(h); } @@ -221,12 +217,16 @@ _tdm_display_destroy_private_output(tdm_private_output *private_output) _tdm_display_destroy_caps_output(&private_output->caps); - if (private_output->dpms_changed_timer) - tdm_event_loop_source_remove(private_output->dpms_changed_timer); - + 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. + */ + LIST_DEL(&private_output->link); + private_output->stamp = 0; free(private_output); } @@ -401,7 +401,7 @@ tdm_display_update_output(tdm_private_display *private_display, int layer_count = 0, i; tdm_error ret; - private_output = _tdm_display_find_private_output(private_display, output_backend); + private_output = tdm_display_find_private_output(private_display, output_backend); if (!private_output) { private_output = calloc(1, sizeof(tdm_private_output)); TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OUT_OF_MEMORY); @@ -425,8 +425,7 @@ tdm_display_update_output(tdm_private_display *private_display, 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_main); - LIST_INITHEAD(&private_output->change_handler_list_sub); + LIST_INITHEAD(&private_output->change_handler_list); if (func_output->output_set_status_handler) { func_output->output_set_status_handler(private_output->output_backend, @@ -976,6 +975,10 @@ tdm_display_init(tdm_error *error) TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; + ret = tdm_output_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; @@ -1100,11 +1103,16 @@ tdm_display_deinit(tdm_display *dpy) */ _pthread_mutex_lock(&private_display->lock); tdm_event_loop_stop(private_display); + tdm_event_loop_deinit(private_display); + _pthread_mutex_unlock(&private_display->lock); + + /* when private_output is destroyed, all vblank resources of client and server + * are destroyed. Then we can call tdm_vblank_deinit. After destroying display, + * we can unload backend modulues. + */ _tdm_display_destroy_private_display(private_display); _tdm_display_unload_module(private_display); - _pthread_mutex_unlock(&private_display->lock); - tdm_event_loop_deinit(private_display); tdm_vblank_deinit(private_display); #ifdef INIT_BUFMGR diff --git a/src/tdm_macro.h b/src/tdm_macro.h index 77538a3..98f25b4 100644 --- a/src/tdm_macro.h +++ b/src/tdm_macro.h @@ -236,8 +236,7 @@ static struct tdm_type_name tdm_cb_type_names[] = { { TDM_THREAD_CB_NONE, "none" }, { TDM_THREAD_CB_OUTPUT_COMMIT, "output-commit" }, { TDM_THREAD_CB_OUTPUT_VBLANK, "output-vblank" }, - { TDM_THREAD_CB_OUTPUT_STATUS, "output-status" }, - { TDM_THREAD_CB_OUTPUT_DPMS, "output-dpms" }, + { TDM_THREAD_CB_OUTPUT_CHANGE, "output-change" }, { TDM_THREAD_CB_PP_DONE, "pp-done" }, { TDM_THREAD_CB_CAPTURE_DONE, "capture-done" }, { TDM_THREAD_CB_VBLANK_SW, "vblank-sw" }, diff --git a/src/tdm_output.c b/src/tdm_output.c index 1edf7fc..accdfa3 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -64,7 +64,7 @@ static tdm_error _tdm_output_vblank_timeout_cb(void *user_data) { tdm_private_output *private_output = user_data; - tdm_private_vblank_handler *v = NULL; + tdm_private_output_vblank_handler *v = NULL; TDM_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_OPERATION_FAILED); @@ -81,7 +81,7 @@ _tdm_output_vblank_timeout_cb(void *user_data) INTERN void tdm_output_vblank_print_wait_information(tdm_private_output *private_output, void *user_data) { - tdm_private_vblank_handler *v = NULL; + tdm_private_output_vblank_handler *v = NULL; TDM_RETURN_IF_FAIL(private_output != NULL); TDM_RETURN_IF_FAIL(user_data != NULL); @@ -135,6 +135,16 @@ _tdm_output_find_private_hwc_window(tdm_private_output *private_output, return NULL; } +INTERN tdm_error +tdm_output_init(tdm_private_display *private_display) +{ + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_COMMIT, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_VBLANK, tdm_display_find_output_stamp); + tdm_thread_cb_set_find_func(TDM_THREAD_CB_OUTPUT_CHANGE, tdm_display_find_output_stamp); + + return TDM_ERROR_NONE; +} + EXTERN tdm_error tdm_output_get_model_info(tdm_output *output, const char **maker, const char **model, const char **name) @@ -202,59 +212,80 @@ _tdm_output_update(tdm_output *output_backend, void *user_data) ret = tdm_display_update_output(private_display, output_backend, private_output->pipe); TDM_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); } +/* LCOV_EXCL_STOP */ INTERN void -tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, - void *user_data) +tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_display *private_display; - tdm_private_output *private_output = user_data; - tdm_value value; + tdm_private_output *private_output = object; + tdm_thread_cb_output_change *output_change = (tdm_thread_cb_output_change *)cb_base; + tdm_private_output_change_handler *change_handler = user_data; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(private_output); - - private_display = private_output->private_display; - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - tdm_thread_cb_output_status output_status; - tdm_error ret; + assert(change_handler->owner_tid == syscall(SYS_gettid)); - TDM_INFO("output(%d) sub %s", private_output->pipe, tdm_status_str(status)); + _pthread_mutex_unlock(&private_display->lock); + change_handler->func(private_output, output_change->type, output_change->value, change_handler->user_data); + _pthread_mutex_lock(&private_display->lock); +} - _tdm_output_update(output_backend, user_data); +static tdm_error +_tdm_output_call_thread_cb_change(tdm_private_output *private_output, tdm_output_change_type type, tdm_value value) +{ + tdm_thread_cb_output_change output_change; + tdm_error ret; - output_status.base.type = TDM_THREAD_CB_OUTPUT_STATUS; - output_status.base.length = sizeof output_status; - output_status.output_stamp = private_output->stamp; - output_status.status = status; - output_status.user_data = user_data; + memset(&output_change, 0, sizeof output_change); + output_change.base.type = TDM_THREAD_CB_OUTPUT_CHANGE; + output_change.base.length = sizeof output_change; + output_change.base.object_stamp = private_output->stamp; + output_change.base.data = NULL; + output_change.base.sync = 1; + output_change.type = type; + output_change.value = value; - value.u32 = status; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_sub, - TDM_OUTPUT_CHANGE_CONNECTION, - value); + ret = tdm_thread_cb_call(private_output, &output_change.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - ret = tdm_thread_send_cb(private_display->private_loop, &output_status.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); + return TDM_ERROR_NONE; +} - return; - } +INTERN void +tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void *user_data) +{ + tdm_private_output *private_output = user_data; + tdm_value value; + tdm_error ret; TDM_INFO("output(%d) main %s", private_output->pipe, tdm_status_str(status)); - if (!tdm_thread_is_running()) - _tdm_output_update(output_backend, user_data); - private_output->caps.status = status; + _tdm_output_update(output_backend, user_data); value.u32 = status; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_CONNECTION, - value); + + ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_CONNECTION, value); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +INTERN void +tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) +{ + tdm_private_output *private_output = user_data; + tdm_value value; + tdm_error ret; + + TDM_INFO("output(%d) %s", private_output->pipe, tdm_status_str(dpms)); + + private_output->current_dpms_value = dpms; + private_output->waiting_dpms_change = 0; + TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); + + value.u32 = dpms; + + ret = _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); } -/* LCOV_EXCL_STOP */ EXTERN tdm_error tdm_output_add_change_handler(tdm_output *output, @@ -277,15 +308,22 @@ tdm_output_add_change_handler(tdm_output *output, /* LCOV_EXCL_STOP */ } + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); + if (ret != TDM_ERROR_NONE) { + /* LCOV_EXCL_START */ + TDM_ERR("tdm_thread_cb_add failed"); + free(change_handler); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_OPERATION_FAILED; + /* LCOV_EXCL_STOP */ + } + change_handler->private_output = private_output; change_handler->func = func; change_handler->user_data = user_data; change_handler->owner_tid = syscall(SYS_gettid); - if (!tdm_thread_in_display_thread(change_handler->owner_tid)) - LIST_ADDTAIL(&change_handler->link, &private_output->change_handler_list_sub); - else - LIST_ADDTAIL(&change_handler->link, &private_output->change_handler_list_main); + LIST_ADDTAIL(&change_handler->link, &private_output->change_handler_list); _pthread_mutex_unlock(&private_display->lock); @@ -299,7 +337,7 @@ tdm_output_remove_change_handler(tdm_output *output, { tdm_private_display *private_display; tdm_private_output *private_output; - tdm_private_output_change_handler *h = NULL, *hh = NULL; + tdm_private_output_change_handler *change_handler = NULL, *hh = NULL; TDM_RETURN_IF_FAIL(tdm_output_is_valid(output)); TDM_RETURN_IF_FAIL(func != NULL); @@ -309,24 +347,14 @@ tdm_output_remove_change_handler(tdm_output *output, _pthread_mutex_lock(&private_display->lock); - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_main, link) { - if (h->func != func || h->user_data != user_data) + LIST_FOR_EACH_ENTRY_SAFE(change_handler, hh, &private_output->change_handler_list, link) { + if (change_handler->func != func || change_handler->user_data != user_data) continue; - LIST_DEL(&h->link); - free(h); - - _pthread_mutex_unlock(&private_display->lock); - - return; - } - - LIST_FOR_EACH_ENTRY_SAFE(h, hh, &private_output->change_handler_list_sub, link) { - if (h->func != func || h->user_data != user_data) - continue; + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_CHANGE, NULL, tdm_output_thread_cb_change, change_handler); - LIST_DEL(&h->link); - free(h); + LIST_DEL(&change_handler->link); + free(change_handler); _pthread_mutex_unlock(&private_display->lock); @@ -644,50 +672,26 @@ tdm_output_get_property(tdm_output *output, unsigned int id, tdm_value *value) return ret; } -INTERN void -tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data) +static void +_tdm_output_thread_cb_vblank(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) { - tdm_private_vblank_handler *vblank_handler = user_data; - tdm_private_vblank_handler *v = NULL, *vv = NULL; - tdm_private_output *private_output; - tdm_private_display *private_display; + tdm_thread_cb_output_vblank *output_vblank = (tdm_thread_cb_output_vblank *)cb_base; + tdm_private_output_vblank_handler *vblank_handler = output_vblank->base.data; + tdm_private_output_vblank_handler *v = NULL, *vv = NULL; + tdm_private_output *private_output = object; struct list_head clone_list; int interval, sync; pid_t tid = syscall(SYS_gettid); TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(vblank_handler); - - private_output = vblank_handler->private_output; - private_display = private_output->private_display; - - if (vblank_handler->owner_tid != tid) { - tdm_thread_cb_output_vblank output_vblank; - tdm_error ret; - vblank_handler->sent_to_frontend = 1; - - output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK; - output_vblank.base.length = sizeof output_vblank; - output_vblank.output_stamp = vblank_handler->private_output->stamp; - output_vblank.sequence = sequence; - output_vblank.tv_sec = tv_sec; - output_vblank.tv_usec = tv_usec; - output_vblank.user_data = user_data; - - ret = tdm_thread_send_cb(private_display->private_loop, &output_vblank.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } + assert(vblank_handler->owner_tid == tid); vblank_handler->sent_to_frontend = 0; _tdm_output_vblank_timeout_update(private_output, 0); - if (vblank_handler->owner_tid != tid) - TDM_NEVER_GET_HERE(); + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_VBLANK, vblank_handler, _tdm_output_thread_cb_vblank, NULL); interval = vblank_handler->interval; sync = vblank_handler->sync; @@ -713,7 +717,11 @@ tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, LIST_DEL(&v->link); if (v->func) - v->func(v->private_output, sequence, tv_sec, tv_usec, v->user_data); + v->func(v->private_output, + output_vblank->sequence, + output_vblank->tv_sec, + output_vblank->tv_usec, + v->user_data); free(v); } @@ -723,13 +731,36 @@ tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, TDM_INFO("-----------------------------------------..."); } -INTERN void -tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data) +static void +_tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) { - tdm_private_output_commit_handler *output_commit_handler = user_data; - tdm_private_display *private_display; - tdm_private_output *private_output; + tdm_private_output_vblank_handler *vblank_handler = user_data; + tdm_thread_cb_output_vblank output_vblank; + tdm_error ret; + + memset(&output_vblank, 0, sizeof output_vblank); + output_vblank.base.type = TDM_THREAD_CB_OUTPUT_VBLANK; + output_vblank.base.length = sizeof output_vblank; + output_vblank.base.object_stamp = vblank_handler->private_output->stamp; + output_vblank.base.data = vblank_handler; + output_vblank.base.sync = 0; + output_vblank.sequence = sequence; + output_vblank.tv_sec = tv_sec; + output_vblank.tv_usec = tv_usec; + + vblank_handler->sent_to_frontend = 1; + + ret = tdm_thread_cb_call(vblank_handler->private_output, &output_vblank.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + +static void +_tdm_output_thread_cb_commit(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data) +{ + tdm_thread_cb_output_commit *output_commit = (tdm_thread_cb_output_commit *)cb_base; + tdm_private_output_commit_handler *output_commit_handler = output_commit->base.data; + tdm_private_output *private_output = object; tdm_private_layer *private_layer = NULL; TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); @@ -737,26 +768,9 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, if (!output_commit_handler) return; - private_output = output_commit_handler->private_output; - private_display = private_output->private_display; - - if (output_commit_handler->owner_tid != syscall(SYS_gettid)) { - tdm_thread_cb_output_commit output_commit; - tdm_error ret; - - output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT; - output_commit.base.length = sizeof output_commit; - output_commit.output_stamp = private_output->stamp; - output_commit.sequence = sequence; - output_commit.tv_sec = tv_sec; - output_commit.tv_usec = tv_usec; - output_commit.user_data = user_data; + assert(output_commit_handler->owner_tid == syscall(SYS_gettid)); - ret = tdm_thread_send_cb(private_display->private_loop, &output_commit.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); LIST_DEL(&output_commit_handler->link); @@ -775,8 +789,11 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, if (output_commit_handler->func) { _pthread_mutex_unlock(&private_display->lock); - output_commit_handler->func(private_output, sequence, - tv_sec, tv_usec, output_commit_handler->user_data); + output_commit_handler->func(private_output, + output_commit->sequence, + output_commit->tv_sec, + output_commit->tv_usec, + output_commit_handler->user_data); _pthread_mutex_lock(&private_display->lock); } @@ -786,23 +803,50 @@ tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, TDM_INFO("-----------------------------------------..."); } +static void +_tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, + unsigned int tv_sec, unsigned int tv_usec, void *user_data) +{ + tdm_private_output_commit_handler *output_commit_handler = user_data; + tdm_private_output *private_output; + tdm_thread_cb_output_commit output_commit; + tdm_error ret; + + if (output_commit_handler) + private_output = output_commit_handler->private_output; + else + private_output = tdm_display_find_private_output(tdm_display_get(), output_backend); + + memset(&output_commit, 0, sizeof output_commit); + output_commit.base.type = TDM_THREAD_CB_OUTPUT_COMMIT; + output_commit.base.length = sizeof output_commit; + output_commit.base.object_stamp = private_output->stamp; + output_commit.base.data = output_commit_handler; + output_commit.base.sync = 0; + output_commit.sequence = sequence; + output_commit.tv_sec = tv_sec; + output_commit.tv_usec = tv_usec; + + ret = tdm_thread_cb_call(private_output, &output_commit.base); + TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); +} + /* add_front: To distinguish between the user vblank handlers and the layer * commit vblank handlers. The layer commit handlers will be called * before calling the user vblank handlers. */ static tdm_error -_tdm_output_wait_vblank(tdm_output *output, int interval, int sync, +_tdm_output_wait_vblank(tdm_private_output *private_output, int interval, int sync, tdm_output_vblank_handler func, void *user_data, unsigned int add_front) { tdm_func_output *func_output; - tdm_private_vblank_handler *vblank_handler = NULL, *v = NULL; + tdm_private_output_vblank_handler *vblank_handler = NULL, *v = NULL; unsigned int skip_request = 0; pid_t tid = syscall(SYS_gettid); + tdm_error ret = TDM_ERROR_NONE; - OUTPUT_FUNC_ENTRY(); - - func_output = &private_display->func_output; + func_output = &private_output->private_display->func_output; /* interval SHOULD be at least 1 */ if (interval <= 0) @@ -818,10 +862,10 @@ _tdm_output_wait_vblank(tdm_output *output, int interval, int sync, if (!private_output->regist_vblank_cb) { private_output->regist_vblank_cb = 1; ret = func_output->output_set_vblank_handler(private_output->output_backend, - tdm_output_cb_vblank); + _tdm_output_cb_vblank); } - vblank_handler = calloc(1, sizeof(tdm_private_vblank_handler)); + vblank_handler = calloc(1, sizeof(tdm_private_output_vblank_handler)); if (!vblank_handler) { /* LCOV_EXCL_START */ TDM_ERR("failed: alloc memory"); @@ -853,6 +897,12 @@ _tdm_output_wait_vblank(tdm_output *output, int interval, int sync, /* If there is the previous request, we can skip to call output_wait_vblank() */ if (!skip_request) { + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_VBLANK, vblank_handler, _tdm_output_thread_cb_vblank, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + goto wait_failed; + } + ret = func_output->output_wait_vblank(private_output->output_backend, interval, sync, vblank_handler); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); @@ -868,6 +918,7 @@ _tdm_output_wait_vblank(tdm_output *output, int interval, int sync, wait_failed: /* LCOV_EXCL_START */ if (vblank_handler) { + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_VBLANK, vblank_handler, _tdm_output_thread_cb_vblank, NULL); LIST_DEL(&vblank_handler->link); free(vblank_handler); } @@ -890,7 +941,7 @@ tdm_output_wait_vblank(tdm_output *output, int interval, int sync, return TDM_ERROR_DPMS_OFF; } - ret = _tdm_output_wait_vblank(output, interval, sync, func, user_data, 0); + ret = _tdm_output_wait_vblank(private_output, interval, sync, func, user_data, 0); _pthread_mutex_unlock(&private_display->lock); @@ -913,7 +964,7 @@ tdm_output_wait_vblank_add_front(tdm_output *output, int interval, int sync, return TDM_ERROR_DPMS_OFF; } - ret = _tdm_output_wait_vblank(output, interval, sync, func, user_data, 1); + ret = _tdm_output_wait_vblank(private_output, interval, sync, func, user_data, 1); _pthread_mutex_unlock(&private_display->lock); @@ -925,7 +976,7 @@ INTERN void tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_handler func, void *user_data) { tdm_private_output *private_output = (tdm_private_output*)output; - tdm_private_vblank_handler *v = NULL; + tdm_private_output_vblank_handler *v = NULL; TDM_RETURN_IF_FAIL(private_output != NULL); TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); @@ -1013,8 +1064,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl if (func) { if (!private_output->regist_commit_cb) { private_output->regist_commit_cb = 1; - ret = func_output->output_set_commit_handler(private_output->output_backend, - tdm_output_cb_commit); + ret = func_output->output_set_commit_handler(private_output->output_backend, _tdm_output_cb_commit); TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed); } @@ -1026,6 +1076,13 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl /* LCOV_EXCL_STOP */ } + ret = tdm_thread_cb_add(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_thread_cb_add failed"); + free(output_commit_handler); + return ret; + } + LIST_ADDTAIL(&output_commit_handler->link, &private_output->output_commit_handler_list); output_commit_handler->private_output = private_output; output_commit_handler->func = func; @@ -1068,6 +1125,7 @@ tdm_output_commit_internal(tdm_output *output, int sync, tdm_output_commit_handl commit_failed: /* LCOV_EXCL_START */ if (output_commit_handler) { + tdm_thread_cb_remove(private_output, TDM_THREAD_CB_OUTPUT_COMMIT, output_commit_handler, _tdm_output_thread_cb_commit, NULL); LIST_DEL(&output_commit_handler->link); free(output_commit_handler); } @@ -1169,110 +1227,6 @@ tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode) return ret; } -static tdm_error -_tdm_output_dpms_changed_timeout(void *user_data) -{ - tdm_private_output *private_output = user_data; - tdm_value value; - - value.u32 = private_output->current_dpms_value; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_sub, - TDM_OUTPUT_CHANGE_DPMS, - value); - - return TDM_ERROR_NONE; -} - -static tdm_error -tdm_output_call_dpms_change_handler(tdm_output *output) -{ - tdm_private_output *private_output = (tdm_private_output*)output; - tdm_value value; - - /** Use timer to call the output change callback of the sub-thread. - * The output change callback of tdm_server and tdm_vblank was called - * in the main thread. And it made the multi thread issue. If we use - * the timer, we can call the sub-thread's output change callback in - * sub-thread. - */ - if (!private_output->dpms_changed_timer) { - private_output->dpms_changed_timer = - tdm_event_loop_add_timer_handler(private_output->private_display, - _tdm_output_dpms_changed_timeout, private_output, NULL); - if (!private_output->dpms_changed_timer) { - /* LCOV_EXCL_START */ - TDM_ERR("can't create dpms timer!!"); - return TDM_ERROR_OUT_OF_MEMORY; - /* LCOV_EXCL_STOP */ - } - } - - value.u32 = private_output->current_dpms_value; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_DPMS, - value); - - if (!LIST_IS_EMPTY(&private_output->change_handler_list_sub)) { - tdm_error ret = tdm_event_loop_source_timer_update(private_output->dpms_changed_timer, 1); - if (ret != TDM_ERROR_NONE) - TDM_NEVER_GET_HERE(); - } - - return TDM_ERROR_NONE; -} - -/* LCOV_EXCL_START */ -INTERN void -tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_data) -{ - tdm_private_display *private_display; - tdm_private_output *private_output = user_data; - tdm_value value; - - TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(private_output); - - private_display = private_output->private_display; - - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - tdm_thread_cb_output_dpms output_dpms; - tdm_error ret; - - _tdm_output_update(output_backend, user_data); - - output_dpms.base.type = TDM_THREAD_CB_OUTPUT_DPMS; - output_dpms.base.length = sizeof output_dpms; - output_dpms.output_stamp = private_output->stamp; - output_dpms.dpms = dpms; - output_dpms.user_data = user_data; - - value.u32 = dpms; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_sub, - TDM_OUTPUT_CHANGE_DPMS, - value); - - ret = tdm_thread_send_cb(private_display->private_loop, &output_dpms.base); - TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); - - return; - } - - private_output->current_dpms_value = dpms; - private_output->waiting_dpms_change = 0; - - TDM_INFO("output(%d) dpms async '%s' done", private_output->pipe, tdm_dpms_str(dpms)); - - value.u32 = dpms; - tdm_output_call_change_handler_internal(private_output, - &private_output->change_handler_list_main, - TDM_OUTPUT_CHANGE_DPMS, - value); -} -/* LCOV_EXCL_STOP */ - EXTERN tdm_error tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) { @@ -1317,9 +1271,11 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) done: if (ret == TDM_ERROR_NONE) { if (private_output->current_dpms_value != dpms_value) { + tdm_value value; private_output->current_dpms_value = dpms_value; + value.u32 = dpms_value; + _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); TDM_INFO("output(%d) dpms '%s' done", private_output->pipe, tdm_dpms_str(dpms_value)); - tdm_output_call_dpms_change_handler(output); } } else { tdm_output_dpms temp = TDM_OUTPUT_DPMS_OFF; @@ -1452,11 +1408,13 @@ tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) /* checking with backend's value */ if (*dpms_value != private_output->current_dpms_value) { + tdm_value value; TDM_ERR("output(%d) dpms changed suddenly: %s -> %s", private_output->pipe, private_output->current_dpms_value, tdm_dpms_str(*dpms_value)); private_output->current_dpms_value = *dpms_value; - tdm_output_call_dpms_change_handler(output); + value.u32 = *dpms_value; + _tdm_output_call_thread_cb_change(private_output, TDM_OUTPUT_CHANGE_DPMS, value); } return ret; @@ -2017,42 +1975,6 @@ tdm_output_hwc_get_video_supported_formats(tdm_output *output, const tbm_format return ret; } -INTERN void -tdm_output_call_change_handler_internal(tdm_private_output *private_output, - struct list_head *change_handler_list, - tdm_output_change_type type, - tdm_value value) -{ - tdm_private_display *private_display; - tdm_private_output_change_handler *change_handler = NULL; - - TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); - TDM_RETURN_IF_FAIL(private_output); - - private_display = private_output->private_display; - if (!tdm_thread_in_display_thread(syscall(SYS_gettid))) { - if (type & TDM_OUTPUT_CHANGE_CONNECTION) - TDM_INFO("output(%d) changed: %s (%d)", - private_output->pipe, tdm_status_str(value.u32), value.u32); - if (type & TDM_OUTPUT_CHANGE_DPMS) - TDM_INFO("output(%d) changed: dpms %s (%d)", - private_output->pipe, tdm_dpms_str(value.u32), value.u32); - } - - if (LIST_IS_EMPTY(change_handler_list)) - return; - - LIST_FOR_EACH_ENTRY(change_handler, change_handler_list, link) { - if (change_handler->owner_tid != syscall(SYS_gettid)) - TDM_NEVER_GET_HERE(); - - _pthread_mutex_unlock(&private_display->lock); - change_handler->func(private_output, type, - value, change_handler->user_data); - _pthread_mutex_lock(&private_display->lock); - } -} - static int _is_hwc_output_still_existed(tdm_private_output *private_output) { @@ -2079,22 +2001,28 @@ exist: } /* gets called on behalf of the ecore-main-loop thread */ -INTERN tdm_error -tdm_output_cb_need_validate(tdm_private_output *private_output) +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_RETURN_VAL_IF_FAIL(private_output != NULL, TDM_ERROR_INVALID_PARAMETER); + 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)) - return TDM_ERROR_NONE; + if (!_is_hwc_output_still_existed(private_output)) { + _pthread_mutex_unlock(&private_display->lock); + return; + } + + _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); - - return TDM_ERROR_NONE; } /* gets called on behalf of the tdm-thread */ @@ -2113,11 +2041,14 @@ _need_validate_handler(int fd, tdm_event_loop_mask mask, void *user_data) return TDM_ERROR_OPERATION_FAILED; } + memset(&ev, 0, sizeof ev); ev.base.type = TDM_THREAD_CB_NEED_VALIDATE; ev.base.length = sizeof ev; - ev.o = private_output; + ev.base.object_stamp = private_output->stamp; + ev.base.data = NULL; + ev.base.sync = 0; - ret = tdm_thread_send_cb(private_output->private_display->private_loop, &ev.base); + ret = tdm_thread_cb_call(private_output, &ev.base); TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); TDM_INFO("tdm-thread: get a 'need to revalidate' event for the ouptut:%p.", private_output); diff --git a/src/tdm_private.h b/src/tdm_private.h index 44359f9..a35aea8 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -90,18 +90,18 @@ tdm_display_get(void); int tdm_display_check_module_abi(tdm_private_display *private_display, int abimaj, int abimin); -tdm_private_output * +void * 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); +tdm_error +tdm_output_init(tdm_private_display *private_display); int tdm_output_is_valid(tdm_output *output); void -tdm_output_cb_vblank(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data); -void -tdm_output_cb_commit(tdm_output *output_backend, unsigned int sequence, - unsigned int tv_sec, unsigned int tv_usec, void *user_data); +tdm_output_thread_cb_change(tdm_private_display *private_display, void *object, tdm_thread_cb_base *cb_base, void *user_data); void tdm_output_cb_status(tdm_output *output_backend, tdm_output_conn_status status, void *user_data); @@ -123,6 +123,8 @@ 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); @@ -161,12 +163,6 @@ tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned in void tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len); -void -tdm_output_call_change_handler_internal(tdm_private_output *private_output, - struct list_head *change_handler_list, - tdm_output_change_type type, - tdm_value value); - tdm_error tdm_pp_init(tdm_private_display *private_display); tdm_private_pp * diff --git a/src/tdm_private_types.h b/src/tdm_private_types.h index 4f3da84..77393f1 100644 --- a/src/tdm_private_types.h +++ b/src/tdm_private_types.h @@ -105,9 +105,9 @@ typedef struct _tdm_private_capture tdm_private_capture; typedef struct _tdm_private_loop tdm_private_loop; typedef struct _tdm_private_server tdm_private_server; typedef struct _tdm_private_thread tdm_private_thread; -typedef struct _tdm_private_vblank_handler tdm_private_vblank_handler; typedef struct _tdm_private_output_change_handler tdm_private_output_change_handler; 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; @@ -194,15 +194,10 @@ struct _tdm_private_output { tdm_event_loop_source *vblank_timeout_timer; - /* seperate list for multi-thread*/ - struct list_head change_handler_list_main; - struct list_head change_handler_list_sub; + struct list_head change_handler_list; void **layers_ptr; - /* TODO: temp solution for handling DPMS things in sub-htread */ - tdm_event_loop_source *dpms_changed_timer; - struct { /* look at the tdm_output_set_need_revalidate_handler() declaration for the details */ tdm_output_need_validate_handler hndl; @@ -344,7 +339,7 @@ struct _tdm_private_loop { tdm_private_thread *private_thread; }; -struct _tdm_private_vblank_handler { +struct _tdm_private_output_vblank_handler { struct list_head link; tdm_private_output *private_output; @@ -435,8 +430,7 @@ typedef enum { TDM_THREAD_CB_NONE, TDM_THREAD_CB_OUTPUT_COMMIT, TDM_THREAD_CB_OUTPUT_VBLANK, - TDM_THREAD_CB_OUTPUT_STATUS, - TDM_THREAD_CB_OUTPUT_DPMS, + TDM_THREAD_CB_OUTPUT_CHANGE, TDM_THREAD_CB_PP_DONE, TDM_THREAD_CB_CAPTURE_DONE, TDM_THREAD_CB_VBLANK_SW, @@ -448,8 +442,7 @@ typedef enum { typedef struct _tdm_thread_cb_base tdm_thread_cb_base; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_commit; typedef struct _tdm_thread_cb_output_vblank tdm_thread_cb_output_vblank; -typedef struct _tdm_thread_cb_output_status tdm_thread_cb_output_status; -typedef struct _tdm_thread_cb_output_dpms tdm_thread_cb_output_dpms; +typedef struct _tdm_thread_cb_output_change tdm_thread_cb_output_change; 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; @@ -466,25 +459,15 @@ struct _tdm_thread_cb_base { struct _tdm_thread_cb_output_vblank { tdm_thread_cb_base base; - double output_stamp; unsigned int sequence; unsigned int tv_sec; unsigned int tv_usec; - void *user_data; }; -struct _tdm_thread_cb_output_status { +struct _tdm_thread_cb_output_change { tdm_thread_cb_base base; - double output_stamp; - tdm_output_conn_status status; - void *user_data; -}; - -struct _tdm_thread_cb_output_dpms { - tdm_thread_cb_base base; - double output_stamp; - tdm_output_dpms dpms; - void *user_data; + tdm_output_change_type type; + tdm_value value; }; struct _tdm_thread_cb_pp_done { @@ -509,7 +492,6 @@ struct _tdm_thread_cb_vblank_create { struct _tdm_thread_cb_need_validate { tdm_thread_cb_base base; - tdm_private_output *o; }; struct argument_details { diff --git a/src/tdm_thread.c b/src/tdm_thread.c index e9fec48..cf76c82 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -418,70 +418,16 @@ tdm_thread_handle_cb(tdm_private_loop *private_loop) if (tdm_debug_module & TDM_DEBUG_THREAD) TDM_INFO("type(%d), length(%d)", base->type, base->length); switch (base->type) { - case TDM_THREAD_CB_OUTPUT_COMMIT: { - tdm_thread_cb_output_commit *output_commit = (tdm_thread_cb_output_commit*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_commit->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_commit->output_stamp); - break; - } - tdm_output_cb_commit(output_backend, output_commit->sequence, - output_commit->tv_sec, output_commit->tv_usec, - output_commit->user_data); - break; - } - case TDM_THREAD_CB_OUTPUT_VBLANK: { - tdm_thread_cb_output_vblank *output_vblank = (tdm_thread_cb_output_vblank*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_vblank->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_vblank->output_stamp); - break; - } - tdm_output_cb_vblank(output_backend, output_vblank->sequence, - output_vblank->tv_sec, output_vblank->tv_usec, - output_vblank->user_data); - break; - } - case TDM_THREAD_CB_OUTPUT_STATUS: { - /* LCOV_EXCL_START */ - tdm_thread_cb_output_status *output_status = (tdm_thread_cb_output_status*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_status->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_status->output_stamp); - break; - } - tdm_output_cb_status(output_backend, output_status->status, - output_status->user_data); - break; - /* LCOV_EXCL_STOP */ - } - case TDM_THREAD_CB_OUTPUT_DPMS: { - /* LCOV_EXCL_START */ - tdm_thread_cb_output_dpms *output_dpms = (tdm_thread_cb_output_dpms*)base; - tdm_output *output_backend = - tdm_display_find_output_stamp(private_loop->dpy, output_dpms->output_stamp); - if (!output_backend) { - TDM_WRN("no output(%f)", output_dpms->output_stamp); - break; - } - tdm_output_cb_dpms(output_backend, output_dpms->dpms, output_dpms->user_data); - break; - /* LCOV_EXCL_STOP */ - } + case TDM_THREAD_CB_OUTPUT_COMMIT: + case TDM_THREAD_CB_OUTPUT_VBLANK: + case TDM_THREAD_CB_OUTPUT_CHANGE: case TDM_THREAD_CB_PP_DONE: case TDM_THREAD_CB_CAPTURE_DONE: case TDM_THREAD_CB_VBLANK_SW: case TDM_THREAD_CB_VBLANK_CREATE: + case TDM_THREAD_CB_NEED_VALIDATE: tdm_thread_cb_call(NULL, base); break; - case TDM_THREAD_CB_NEED_VALIDATE: { - tdm_thread_cb_need_validate *ev = (tdm_thread_cb_need_validate*)base; - tdm_output_cb_need_validate(ev->o); - break; - } default: break; } -- 2.7.4 From ddaded5fa255c078568e7f92311c335151dc1b99 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:36:26 +0900 Subject: [PATCH 13/16] log: no need to use ifdef Change-Id: I2f1b03b99b6925511410d87b0649db1c19580ba5 --- common/tdm_log.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/common/tdm_log.c b/common/tdm_log.c index b77e765..3ddcda1 100644 --- a/common/tdm_log.c +++ b/common/tdm_log.c @@ -184,10 +184,7 @@ tdm_log_print(int level, const char *fmt, ...) pthread_mutex_unlock(&log_lock); } -#ifdef TDM_CONFIG_ASSERT - if (level <= assert_level) - assert(0); -#endif + assert(level > assert_level); } EXTERN void -- 2.7.4 From 1b73cea10c215e7640a0a7a94da2fde7d7120760 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:36:52 +0900 Subject: [PATCH 14/16] thread: reset find_funcs table when init, deinit Change-Id: I20f572f7dd6014daf0ee02a656f188c3d89d5900 --- src/tdm_thread.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tdm_thread.c b/src/tdm_thread.c index cf76c82..30966b4 100644 --- a/src/tdm_thread.c +++ b/src/tdm_thread.c @@ -185,7 +185,7 @@ tdm_thread_init(tdm_private_loop *private_loop) { tdm_private_display *private_display; tdm_private_thread *private_thread; - int thread; + int thread, i; TDM_RETURN_VAL_IF_FAIL(TDM_MUTEX_IS_LOCKED(), TDM_ERROR_OPERATION_FAILED); TDM_RETURN_VAL_IF_FAIL(private_loop->dpy, TDM_ERROR_OPERATION_FAILED); @@ -193,6 +193,9 @@ tdm_thread_init(tdm_private_loop *private_loop) private_display = private_loop->dpy; TDM_RETURN_VAL_IF_FAIL(private_display->private_loop, TDM_ERROR_OPERATION_FAILED); + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + LIST_INITHEAD(&cb_list); if (private_loop->private_thread) @@ -267,6 +270,9 @@ tdm_thread_deinit(tdm_private_loop *private_loop) TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + for (i = 0; i < TDM_THREAD_CB_MAX; i++) + find_funcs[i] = NULL; + if (!private_loop->private_thread) return; @@ -305,9 +311,6 @@ tdm_thread_deinit(tdm_private_loop *private_loop) private_loop->private_thread = NULL; keep_private_thread = NULL; - for (i = 0; i < TDM_THREAD_CB_MAX; i++) - find_funcs[i] = NULL; - TDM_INFO("Finish a TDM event thread"); } -- 2.7.4 From 342aaf80ca0d017f1dad08e16d1460d8abfdb674 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:37:35 +0900 Subject: [PATCH 15/16] config: remove unuseful codes Change-Id: If5b99cb203fcb7e58fc3e9c40e45f64bd3d84a3a --- src/tdm_config.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/tdm_config.c b/src/tdm_config.c index 4c66e07..703ae0a 100644 --- a/src/tdm_config.c +++ b/src/tdm_config.c @@ -254,8 +254,6 @@ tdm_config_set_int(const char *key, int value) ret = iniparser_set(g_dic, key, (const char*)temp); - _tdm_config_check_logs(); - pthread_mutex_unlock(&g_dic_lock); TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); @@ -282,8 +280,6 @@ tdm_config_set_string(const char *key, const char *value) ret = iniparser_set(g_dic, key, value); - _tdm_config_check_logs(); - pthread_mutex_unlock(&g_dic_lock); TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED); -- 2.7.4 From d53c7f30fde17401402cdac430c936c4aa4c0110 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 21 Feb 2018 14:39:28 +0900 Subject: [PATCH 16/16] should init event_loop before vblank when initing event_loop, thread's find_funcs table is also inited. This should be done before initing others. Change-Id: Iae6c0e44b3f00c0b6a5aa77bbdbee158ce74baa0 --- src/tdm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 7fabc4a..b0d1f40 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -963,10 +963,6 @@ tdm_display_init(tdm_error *error) TDM_DBG("prepare init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; - ret = tdm_vblank_init(private_display); - if (ret != TDM_ERROR_NONE) - goto failed_vblank; - ret = tdm_event_loop_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_event; @@ -975,6 +971,10 @@ tdm_display_init(tdm_error *error) TDM_INFO("event loop init time: %.3f ms", (stamp2 - stamp1) * 1000.0); stamp1 = stamp2; + ret = tdm_vblank_init(private_display); + if (ret != TDM_ERROR_NONE) + goto failed_vblank; + ret = tdm_output_init(private_display); if (ret != TDM_ERROR_NONE) goto failed_load; -- 2.7.4