From bdf5ec0ef8368ad36dab2a280a4833fb88747d04 Mon Sep 17 00:00:00 2001 From: Junkyeong Kim Date: Mon, 17 Apr 2017 17:43:42 +0900 Subject: [PATCH 01/16] change sscanf to strtol for getting fd Change-Id: I7fed3efbd3fc9a9273a670b3b967707453471be2 Signed-off-by: Junkyeong Kim --- src/tdm_helper.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 6b4178e..4adbcb8 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -521,15 +521,35 @@ tdm_helper_get_fd(const char *env) { const char *value; int fd, newfd, flags, ret; + char *end; + errno = 0; value = (const char*)getenv(env); if (!value) return -1; - ret = sscanf(value, "%d", &fd); - if (ret < 0) { - TDM_ERR("sscanf failed: %m"); + const long sl = strtol(value, &end, 10); + if (end == value) { + TDM_ERR("%s: not a decimal number\n", value); return -1; + } else if (*end != '\0') { + TDM_ERR("%s: extra characters at end of input: %s\n", value, end); + return -1; + } else if ((sl == LONG_MIN || sl == LONG_MAX) && errno == ERANGE) { + TDM_ERR("%s out of range of type long\n", value); + return -1; + } else if (sl > INT_MAX) { + TDM_ERR("%ld greater than INT_MAX\n", sl); + return -1; + } else if (sl < INT_MIN) { + TDM_ERR("%ld less than INT_MIN\n", sl); + return -1; + } else { + fd = (int)sl; + if (fd < 0) { + TDM_ERR("%d out of fd range\n", fd); + return -1; + } } flags = fcntl(fd, F_GETFD); -- 2.7.4 From ffdd7c6a82afdb2dfa91ee75de944fed294ae067 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 28 Apr 2017 09:26:57 +0900 Subject: [PATCH 02/16] package version up to 1.6.16 Change-Id: I8f48e66666d0e2e664facf5a179b327c21683d7b --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index c01dd65..fb7df61 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.15 +Version: 1.6.16 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From cfcdcadec411787e56844a8449376fd7d02c342d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 11:33:43 +0900 Subject: [PATCH 03/16] server: trace client information Change-Id: I3e9ae2599119240628ff276aeebdd7cb34ff1341 --- src/tdm_private.h | 2 ++ src/tdm_server.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/tdm_private.h b/src/tdm_private.h index 2a92f24..4552a5e 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -587,6 +587,8 @@ tdm_error tdm_server_init(tdm_private_loop *private_loop); void tdm_server_deinit(tdm_private_loop *private_loop); +const char* +tdm_server_get_client_name(pid_t pid); char * tdm_helper_dump_make_directory(const char *path, char *reply, int *len); diff --git a/src/tdm_server.c b/src/tdm_server.c index f025365..5299c93 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -81,10 +81,44 @@ typedef struct _tdm_server_wait_info { unsigned int req_id; } tdm_server_wait_info; +typedef struct _tdm_server_client_info { + struct list_head link; + pid_t pid; + char name[TDM_NAME_LEN]; +} tdm_server_client_info; + static tdm_private_server *keep_private_server; +static struct list_head client_list; static void destroy_wait(tdm_server_wait_info *wait_info); +static void +_tdm_server_get_process_name(pid_t pid, char *name, unsigned int size) +{ + char proc[TDM_NAME_LEN], pname[TDM_NAME_LEN]; + FILE *h; + size_t len; + + snprintf(name, size, "Unknown"); + + snprintf(proc, TDM_NAME_LEN, "/proc/%d/cmdline", pid); + h = fopen(proc, "r"); + if (!h) + return; + + len = fread(pname, sizeof(char), TDM_NAME_LEN, h); + if (len == 0) { + char *p = strncpy(pname, "NO NAME", sizeof(pname) - 1); + len = p - pname; + } + pname[len - 1] = '\0'; + + strncpy(name, pname, size - 1); + name[size - 1] = '\0'; + + fclose(h); +} + static tdm_output* _tdm_server_find_output(tdm_private_server *private_server, const char *name) { @@ -544,10 +578,32 @@ static const struct wl_tdm_interface tdm_implementation = { }; static void +destroy_client(struct wl_resource *resource) +{ + tdm_server_client_info *c = NULL, *cc = NULL; + struct wl_client *client; + pid_t pid = -1; + + client = wl_resource_get_client(resource); + TDM_RETURN_IF_FAIL(client != NULL); + + wl_client_get_credentials(client, &pid, NULL, NULL); + + LIST_FOR_EACH_ENTRY_SAFE(c, cc, &client_list, link) { + if (c->pid == pid) { + LIST_DEL(&c->link); + free(c); + return; + } + } +} + +static void _tdm_server_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct wl_resource *resource; + tdm_server_client_info *cinfo; resource = wl_resource_create(client, &wl_tdm_interface, version, id); if (!resource) { @@ -555,7 +611,18 @@ _tdm_server_bind(struct wl_client *client, void *data, return; } - wl_resource_set_implementation(resource, &tdm_implementation, data, NULL); + cinfo = calloc(1, sizeof(tdm_server_client_info)); + if (!cinfo) { + wl_client_post_no_memory(client); + wl_resource_destroy(resource); + return; + } + + LIST_ADDTAIL(&cinfo->link, &client_list); + wl_client_get_credentials(client, &cinfo->pid, NULL, NULL); + _tdm_server_get_process_name(cinfo->pid, cinfo->name, TDM_NAME_LEN); + + wl_resource_set_implementation(resource, &tdm_implementation, data, destroy_client); } INTERN tdm_error @@ -594,6 +661,8 @@ tdm_server_init(tdm_private_loop *private_loop) private_loop->private_server = private_server; keep_private_server = private_server; + LIST_INITHEAD(&client_list); + return TDM_ERROR_NONE; } @@ -602,6 +671,7 @@ tdm_server_deinit(tdm_private_loop *private_loop) { tdm_server_output_info *o = NULL, *oo = NULL; tdm_server_wait_info *w = NULL, *ww = NULL; + tdm_server_client_info *c = NULL, *cc = NULL; tdm_private_server *private_server; if (!private_loop->private_server) @@ -620,5 +690,22 @@ tdm_server_deinit(tdm_private_loop *private_loop) free(private_server); private_loop->private_server = NULL; keep_private_server = NULL; + + LIST_FOR_EACH_ENTRY_SAFE(c, cc, &client_list, link) { + LIST_DEL(&c->link); + free(c); + } } +INTERN const char* +tdm_server_get_client_name(pid_t pid) +{ + tdm_server_client_info *c = NULL; + + LIST_FOR_EACH_ENTRY(c, &client_list, link) { + if (c->pid == pid) + return (const char*)c->name; + } + + return NULL; +} -- 2.7.4 From fd2eadc76fbca53159c630a08e9ae777bb405894 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 11:35:53 +0900 Subject: [PATCH 04/16] vblank: use tdm_server_get_client_name Change-Id: I4f47cca1d1f4fa268ab330fd947cd91e5c9458b8 --- src/tdm_vblank.c | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 662204f..99ce8a0 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -1109,31 +1109,6 @@ tdm_vblank_set_resource(tdm_vblank *vblank, struct wl_resource *resource) return TDM_ERROR_NONE; } -static void -_tdm_vblank_get_process_name(pid_t pid, char *name, unsigned int size) -{ - char proc[TDM_NAME_LEN], pname[TDM_NAME_LEN]; - FILE *h; - size_t len; - - snprintf(proc, TDM_NAME_LEN, "/proc/%d/cmdline", pid); - h = fopen(proc, "r"); - if (!h) - return; - - len = fread(pname, sizeof(char), TDM_NAME_LEN, h); - if (len == 0) { - char *p = strncpy(pname, "NO NAME", sizeof(pname) - 1); - len = p - pname; - } - pname[len - 1] = '\0'; - - strncpy(name, pname, size - 1); - name[size - 1] = '\0'; - - fclose(h); -} - INTERN void tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) { @@ -1147,17 +1122,17 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) pthread_mutex_lock(&valid_list_lock); LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { struct wl_client *client = wl_resource_get_client(v->resource); - char proc_name[TDM_NAME_LEN]; + const char *proc_name = NULL; pid_t pid = 0; - snprintf(proc_name, TDM_NAME_LEN, "Unknown"); if (client) { wl_client_get_credentials(client, &pid, NULL, NULL); - _tdm_vblank_get_process_name(pid, proc_name, TDM_NAME_LEN); + proc_name = tdm_server_get_client_name(pid); } TDM_SNPRINTF(reply, len, "%-12s %u %d %u %s (pid: %u)\n", - v->name, v->fps, v->offset, v->enable_fake, proc_name, pid); + v->name, v->fps, v->offset, v->enable_fake, + (proc_name) ? proc_name : "Unknown", pid); } pthread_mutex_unlock(&valid_list_lock); -- 2.7.4 From 11599cb15fc96bc8389869e0bcd08b3146ebd9c4 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 13:47:32 +0900 Subject: [PATCH 05/16] monitor: add trace option to debug server-client protocol Change-Id: Id27af997282b51db1541e2d7e59e521d95097d66 --- src/tdm_event_loop.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++ src/tdm_monitor_server.c | 23 ++++ src/tdm_private.h | 29 +++++ 3 files changed, 333 insertions(+) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index a2cac7e..7445ad5 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -461,3 +461,284 @@ tdm_event_loop_source_remove(tdm_event_loop_source *source) free(source); } + +static void +_trace_cb_client_destroy(struct wl_listener *listener, void *data) +{ + struct wl_client *client = (struct wl_client *) data; + struct timespec tp; + unsigned int time; + pid_t pid = -1; + const char *proc_name; + char temp[512] = { 0, }, *p = temp; + int len = sizeof(temp), *l = &len; + + wl_client_get_credentials(client, &pid, NULL, NULL); + proc_name = tdm_server_get_client_name(pid); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + TDM_SNPRINTF(p, l, "[%10.3f] Server [PID:%d] client destroying", time / 1000.0, pid); + TDM_SNPRINTF(p, l, ", cmd: %s", proc_name ? proc_name : "Unknown"); + + TDM_INFO("%s", temp); + + wl_list_remove(&listener->link); + free(listener); +} + +static void +_trace_reg_client_destroy_listener(struct wl_client *client) +{ + struct wl_listener *listener; + + listener = wl_client_get_destroy_listener(client, _trace_cb_client_destroy); + if (listener) + return; + + listener = calloc(1, sizeof(struct wl_listener)); + TDM_RETURN_IF_FAIL(listener != NULL); + + listener->notify = _trace_cb_client_destroy; + wl_client_add_destroy_listener(client, listener); +} + +static const char * +_trace_get_next_argument(const char *signature, + struct argument_details *details) +{ + details->nullable = 0; + for (; *signature; ++signature) { + switch (*signature) { + case 'i': + case 'u': + case 'f': + case 's': + case 'o': + case 'n': + case 'a': + case 'h': + details->type = *signature; + return signature + 1; + case '?': + details->nullable = 1; + break; + default: + return NULL; + } + } + details->type = '\0'; + return signature; +} + +#if !TDM_WAYLAND_LOGGER + +static void +_trace_protocol_cb(struct wl_closure *closure, struct wl_resource *resource, int send) +{ + int i; + struct argument_details arg; + struct wl_object *object = &resource->object; + struct wl_client *client = resource->client; + const char *signature = closure->message->signature; + struct timespec tp; + unsigned int time; + pid_t pid = -1; + const char *proc_name; + char temp[512] = { 0, }, *p = temp; + int len = sizeof(temp), *l = &len; + + if (client) { + _trace_reg_client_destroy_listener(client); + wl_client_get_credentials(client, &pid, NULL, NULL); + } + + proc_name = tdm_server_get_client_name(pid); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + TDM_SNPRINTF(p, l, "[%10.3f] %s%d%s%s@%u.%s(", + time / 1000.0, + send ? "Server -> Client [PID:" : "Server <- Client [PID:", + pid, "] ", + object->interface->name, object->id, closure->message->name); + + for (i = 0; i < closure->count; i++) { + signature = _trace_get_next_argument(signature, &arg); + TDM_RETURN_IF_FAIL(signature != NULL); + + if (i > 0) + TDM_SNPRINTF(p, l, ", "); + + switch (arg.type) { + case 'u': + TDM_SNPRINTF(p, l, "%u", closure->args[i].u); + break; + case 'i': + TDM_SNPRINTF(p, l, "%d", closure->args[i].i); + break; + case 'f': + TDM_SNPRINTF(p, l, "%f", wl_fixed_to_double(closure->args[i].f)); + break; + case 's': + TDM_SNPRINTF(p, l, "\"%s\"", closure->args[i].s); + break; + case 'o': + if (closure->args[i].o) + TDM_SNPRINTF(p, l, "%s@%u", closure->args[i].o->interface->name, closure->args[i].o->id); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'n': + TDM_SNPRINTF(p, l, "new id %s@", + (closure->message->types[i]) ? closure->message->types[i]->name : "[unknown]"); + if (closure->args[i].n != 0) + TDM_SNPRINTF(p, l, "%u", closure->args[i].n); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'a': + TDM_SNPRINTF(p, l, "array"); + break; + case 'h': + TDM_SNPRINTF(p, l, "fd %d", closure->args[i].h); + break; + default: + return; + } + } + + TDM_SNPRINTF(p, l, "), cmd: %s", proc_name ? proc_name : "Unknown"); + + TDM_INFO("%s", temp); +} + +#else + +static struct wl_protocol_logger *_trace_protocol_logger; + +static void +_trace_protocol_logger_cb(void *user_data, + enum wl_protocol_logger_type direction, + const struct wl_protocol_logger_message *message) +{ + int i; + struct argument_details arg; + struct wl_client *client = wl_resource_get_client(message->resource); + const char *signature = message->message->signature; + struct timespec tp; + unsigned int time; + pid_t pid = -1; + const char *proc_name; + char temp[512] = { 0, }, *p = temp; + int len = sizeof(temp), *l = &len; + int send; + + if (client) { + _trace_reg_client_destroy_listener(client); + wl_client_get_credentials(client, &pid, NULL, NULL); + } + + proc_name = tdm_server_get_client_name(pid); + + clock_gettime(CLOCK_MONOTONIC, &tp); + time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000); + + send = (direction == WL_PROTOCOL_LOGGER_EVENT) ? 1 : 0; + + TDM_SNPRINTF(p, l, "[%10.3f] %s%d%s%s@%u.%s(", + time / 1000.0, + send ? "Server -> Client [PID:" : "Server <- Client [PID:", + pid, "] ", + wl_resource_get_name(message->resource), + wl_resource_get_id(message->resource), + message->message->name); + + for (i = 0; i < message->arguments_count; i++) { + signature = _trace_get_next_argument(signature, &arg); + TDM_RETURN_IF_FAIL(signature != NULL); + + if (i > 0) + TDM_SNPRINTF(p, l, ", "); + + switch (arg.type) { + case 'u': + TDM_SNPRINTF(p, l, "%u", message->arguments[i].u); + break; + case 'i': + TDM_SNPRINTF(p, l, "%d", message->arguments[i].i); + break; + case 'f': + TDM_SNPRINTF(p, l, "%f", + wl_fixed_to_double(message->arguments[i].f)); + break; + case 's': + TDM_SNPRINTF(p, l, "\"%s\"", message->arguments[i].s); + break; + case 'o': + if (message->arguments[i].o) + TDM_SNPRINTF(p, l, "%s@%u", + wl_resource_get_name((struct wl_resource *) message->arguments[i].o), + wl_resource_get_id((struct wl_resource *) message->arguments[i].o)); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'n': + TDM_SNPRINTF(p, l, "new id %s@", + (message->message->types[i]) ? message->message->types[i]->name : "[unknown]"); + if (message->arguments[i].n != 0) + TDM_SNPRINTF(p, l, "%u", message->arguments[i].n); + else + TDM_SNPRINTF(p, l, "nil"); + break; + case 'a': + TDM_SNPRINTF(p, l, "array"); + break; + case 'h': + TDM_SNPRINTF(p, l, "fd %d", message->arguments[i].h); + break; + default: + return; + } + } + + TDM_SNPRINTF(p, l, "), cmd: %s", proc_name ? proc_name : "Unknown"); + + TDM_INFO("%s", temp); +} +#endif + +INTERN tdm_error +tdm_event_loop_trace_enable(tdm_private_display * private_display, + unsigned int enable) +{ + tdm_private_loop *private_loop = private_display->private_loop; + + TDM_RETURN_VAL_IF_FAIL(private_loop->wl_display != NULL, TDM_ERROR_NONE); + + if (!enable) { +#if !TDM_WAYLAND_LOGGER + wl_debug_server_debug_func_set(NULL); +#else + if (_trace_protocol_logger) { + wl_protocol_logger_destroy(_trace_protocol_logger); + _trace_protocol_logger = NULL; + } +#endif + return TDM_ERROR_NONE; + } + +#if !TDM_WAYLAND_LOGGER + wl_debug_server_debug_func_set((wl_server_debug_func_ptr) _trace_protocol_cb); +#else + if (_trace_protocol_logger) + wl_protocol_logger_destroy(_trace_protocol_logger); + + _trace_protocol_logger = + wl_display_add_protocol_logger(private_loop->wl_display, _trace_protocol_logger_cb, NULL); +#endif + + return TDM_ERROR_NONE; +} diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index d12a9eb..2df4dd3 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -54,6 +54,23 @@ _tdm_monitor_server_query(unsigned int pid, char *cwd, int argc, char *argv[], c } static void +_tdm_monitor_server_protocol_trace(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) +{ + int enable; + + if (argc < 3) { + _tdm_monitor_server_usage(argv[0], reply, len); + return; + } + + enable = atoi(argv[2]); + + tdm_event_loop_trace_enable(dpy, enable); + + TDM_SNPRINTF(reply, len, "protocol trace: '%s'\n", (enable) ? "enabled" : "disabled"); +} + +static void _tdm_monitor_server_dpms(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { tdm_output *output; @@ -463,6 +480,12 @@ static struct { "show tdm output, layer information", NULL, NULL }, { + "trace", _tdm_monitor_server_protocol_trace, + "enable/disable the wl protocol", + "", + "0 or 1" + }, + { "dpms", _tdm_monitor_server_dpms, "set output dpms", ":", "0:3 or 0:0" }, diff --git a/src/tdm_private.h b/src/tdm_private.h index 4552a5e..59cb1ad 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -499,6 +499,8 @@ tdm_error tdm_event_loop_dispatch(tdm_private_display *private_display); void tdm_event_loop_flush(tdm_private_display *private_display); +tdm_error +tdm_event_loop_trace_enable(tdm_private_display *private_display, unsigned int enable); typedef enum { TDM_THREAD_CB_NONE, @@ -692,6 +694,33 @@ tdm_display_enable_fps(tdm_private_display *private_display, int enable); void tdm_monitor_server_command(tdm_display *dpy, const char *options, char *reply, int *len); + + +#define TDM_WAYLAND_LOGGER ((WAYLAND_VERSION_MAJOR == 1) && (WAYLAND_VERSION_MINOR > 11)) + +#if !TDM_WAYLAND_LOGGER +#ifndef WL_CLOSURE_MAX_ARGS +#define WL_CLOSURE_MAX_ARGS 20 +#endif + +struct wl_closure { + int count; + const struct wl_message *message; + uint32_t opcode; + uint32_t sender_id; + union wl_argument args[WL_CLOSURE_MAX_ARGS]; + struct wl_list link; + struct wl_proxy *proxy; + struct wl_array extra[0]; +}; +#endif /* TDM_WAYLAND_LOGGER */ + +struct argument_details { + char type; + int nullable; +}; + + #ifdef __cplusplus } #endif -- 2.7.4 From 24a0b46061fa6640bcc26f4ddf4c7c92d049bee6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 2 May 2017 14:25:12 +0900 Subject: [PATCH 06/16] vblank: correct target time We should consider the vblank interval to calculate the target time. Change-Id: I7f78631d644ce5dce0e2dfb2c8d8bcefbab45205 --- src/tdm_vblank.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index 99ce8a0..ee8d352 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -768,9 +768,9 @@ _tdm_vblank_wait_HW(tdm_vblank_wait_info *wait_info) prev = last + private_vblank->vblank_gap * skip; curr = tdm_helper_get_time(); - target = prev; + target = last; while (target < curr) - target += private_vblank->vblank_gap; + target += (private_vblank->vblank_gap * wait_info->interval); hw_interval = (unsigned int)((target - curr) / private_vblank->HW_vblank_gap + TDM_TIME_MARGIN) + 1; -- 2.7.4 From e6040bf0b3cd187339d64ff16b9eabb30e7c9965 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 27 Apr 2017 13:39:10 +0900 Subject: [PATCH 07/16] vblank: support global fps Change-Id: Iec9c621fc270336a0d95c4a2f90b583704f9cc46 --- include/tdm.h | 28 ++++++++++++++++++++ src/tdm_monitor_server.c | 36 +++++++++++++++++++++++++ src/tdm_vblank.c | 68 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 126 insertions(+), 6 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index 63700a7..29c8193 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -924,6 +924,20 @@ tdm_error tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned int fps); /** + * @brief Set the vblank global fps for the entire system. + * @param[in] enable 1:enable, 0:disable + * @param[in] fps The vblank global fps + * @details + * This global fps will be applied to all client's vblanks for all outputs. + * If the client's vblank fps is less than this, the global fps will be ignored + * for that client. And if a client calls #tdm_vblank_ignore_global_fps to ignore + * the global fps, it will be ignored also. + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_enable_global_fps(unsigned int enable, unsigned int fps); + +/** * @brief Create a vblank object * @param[in] dpy A display object * @param[in] output A output object @@ -982,6 +996,20 @@ tdm_error tdm_vblank_get_fps(tdm_vblank *vblank, unsigned int *fps); /** + * @brief Ignore the vblank global fps + * @details + * The global fps will be applied to all client's vblanks for all outputs. + * If the client's vblank fps is less than this, the global fps will be ignored + * for that client. And if a client calls #tdm_vblank_ignore_global_fps to ignore + * the global fps, it will be ignored also. + * @param[in] vblank A vblank object + * @param[in] ignore 1: ignore 0:not ignore(default) + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + */ +tdm_error +tdm_vblank_ignore_global_fps(tdm_vblank *vblank, unsigned int ignore); + +/** * @brief Set the offset(milli-second) to a vblank object * @details Default is @b 0. * @param[in] vblank A vblank object diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index 2df4dd3..c46d457 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -308,6 +308,36 @@ _tdm_monitor_server_vblank_fps(unsigned int pid, char *cwd, int argc, char *argv } static void +_tdm_monitor_server_global_fps(unsigned int pid, char *cwd, int argc, char *argv[], + char *reply, int *len, tdm_display *dpy) +{ + unsigned int fps; + char *arg; + char *end; + tdm_error ret; + + if (argc < 3) { + _tdm_monitor_server_usage(argv[0], reply, len); + return; + } + + arg = argv[2]; + fps = strtol(arg, &end, 10); + + if (fps > 0) + ret = tdm_vblank_enable_global_fps(1, fps); + else + ret = tdm_vblank_enable_global_fps(0, 0); + + if (ret != TDM_ERROR_NONE) { + TDM_SNPRINTF(reply, len, "can't set '%u' fps to global fps\n", fps); + return; + } + + TDM_SNPRINTF(reply, len, "success: '%u' global fps\n", fps); +} + +static void _tdm_monitor_server_prop(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { tdm_output *output; @@ -531,6 +561,12 @@ static struct { NULL }, { + "global_fps", _tdm_monitor_server_global_fps, + "set the global vblank fps for the entire system", + "", + NULL + }, + { "prop", _tdm_monitor_server_prop, "set the property of a output or a layer", "[,]:,", diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index ee8d352..cb21a0c 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -97,6 +97,7 @@ typedef struct _tdm_private_vblank { unsigned int fps; int offset; unsigned int enable_fake; + unsigned int ignore_global_fps; double vblank_gap; unsigned int quotient; @@ -142,6 +143,7 @@ static pthread_mutex_t valid_list_lock; static struct list_head valid_vblank_list; static struct list_head valid_wait_list; 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); @@ -371,6 +373,32 @@ tdm_vblank_set_client_vblank_fps(unsigned int pid, const char *name, unsigned in return TDM_ERROR_NONE; } +EXTERN tdm_error +tdm_vblank_enable_global_fps(unsigned int enable, unsigned int fps) +{ + tdm_private_vblank *v = NULL; + + if (enable) + TDM_RETURN_VAL_IF_FAIL(fps > 0, TDM_ERROR_INVALID_PARAMETER); + + TDM_INFO("global fps: %s fps(%d)", (enable) ? "enabled" : "disabled", fps); + + pthread_mutex_lock(&valid_list_lock); + + vblank_global_fps = (enable) ? fps : 0; + + LIST_FOR_EACH_ENTRY(v, &valid_vblank_list, valid_link) { + /* skip if vblank is created in server side */ + if (!v->resource) + continue; + + v->check_HW_or_SW = 1; + } + pthread_mutex_unlock(&valid_list_lock); + + return TDM_ERROR_NONE; +} + EXTERN tdm_vblank * tdm_vblank_create(tdm_display *dpy, tdm_output *output, tdm_error *error) { @@ -543,6 +571,25 @@ tdm_vblank_get_fps(tdm_vblank *vblank, unsigned int *fps) } EXTERN tdm_error +tdm_vblank_ignore_global_fps(tdm_vblank *vblank, unsigned int ignore) +{ + tdm_private_vblank *private_vblank = vblank; + + TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); + + if (private_vblank->ignore_global_fps == ignore) + return TDM_ERROR_NONE; + + private_vblank->ignore_global_fps = ignore; + private_vblank->check_HW_or_SW = 1; + + if (tdm_debug_module & TDM_DEBUG_VBLANK) + VIN("ignore_global_fps(%d)", private_vblank->ignore_global_fps); + + return TDM_ERROR_NONE; +} + +EXTERN tdm_error tdm_vblank_set_offset(tdm_vblank *vblank, int offset) { tdm_private_vblank *private_vblank = vblank; @@ -949,6 +996,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, { tdm_private_vblank *private_vblank = vblank; tdm_vblank_wait_info *wait_info; + unsigned int fps; tdm_error ret; TDM_RETURN_VAL_IF_FAIL(private_vblank != NULL, TDM_ERROR_INVALID_PARAMETER); @@ -988,10 +1036,17 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, wait_info->user_data = user_data; wait_info->private_vblank = private_vblank; + if (private_vblank->ignore_global_fps || + vblank_global_fps == 0 || + private_vblank->fps < vblank_global_fps) + fps = private_vblank->fps; + else + fps = vblank_global_fps; + if (private_vblank->check_HW_or_SW) { private_vblank->check_HW_or_SW = 0; - private_vblank->vblank_gap = 1.0 / private_vblank->fps; - private_vblank->quotient = private_vblank->vrefresh / private_vblank->fps; + private_vblank->vblank_gap = 1.0 / fps; + private_vblank->quotient = private_vblank->vrefresh / fps; } /* 1) if fps != factor of vrefresh, SW timer @@ -1000,7 +1055,7 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, * 3) if fps == factor of vrefresh && dpms == on && offset != 0, HW vblank + SW timer * In case of 1), we really don't need to align with HW vblank. */ - if (private_vblank->vrefresh % private_vblank->fps) + if (private_vblank->vrefresh % fps) wait_info->type = VBLANK_TYPE_SW; else if (private_vblank->dpms == TDM_OUTPUT_DPMS_OFF) wait_info->type = VBLANK_TYPE_SW_FAKE; @@ -1115,8 +1170,9 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) tdm_private_vblank *v = NULL; TDM_SNPRINTF(reply, len, "[Client Vblank List]\n"); + TDM_SNPRINTF(reply, len, "* global fps: %u\n", vblank_global_fps); TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n"); - TDM_SNPRINTF(reply, len, "name fps offset fake process\n"); + TDM_SNPRINTF(reply, len, "name fps ignore offset fake process\n"); TDM_SNPRINTF(reply, len, "---------------------------------------------------------------\n"); pthread_mutex_lock(&valid_list_lock); @@ -1130,8 +1186,8 @@ tdm_vblank_get_vblank_list_information(tdm_display *dpy, char *reply, int *len) proc_name = tdm_server_get_client_name(pid); } - TDM_SNPRINTF(reply, len, "%-12s %u %d %u %s (pid: %u)\n", - v->name, v->fps, v->offset, v->enable_fake, + TDM_SNPRINTF(reply, len, "%-12s %u %u %d %u %s (pid: %u)\n", + v->name, v->fps, v->ignore_global_fps, v->offset, v->enable_fake, (proc_name) ? proc_name : "Unknown", pid); } pthread_mutex_unlock(&valid_list_lock); -- 2.7.4 From eaf5e709cf4334c8961398846441987757e48eb3 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 11 May 2017 09:12:51 +0900 Subject: [PATCH 08/16] package version up to 1.6.17 Change-Id: I302bba1a0087af5ba28a90b8cca52e99d70c174b --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index fb7df61..5632f7c 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.16 +Version: 1.6.17 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 884b19df12e2eb24018217824e6e331d3f9c3191 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Mon, 22 May 2017 22:23:05 +0900 Subject: [PATCH 09/16] server: set permission and group to tdm-socket when it is added Change-Id: I9052f391202781a9ac34c2fce7efacdd75e83761 --- packaging/libtdm.spec | 10 ----- service/tdm-socket.path | 5 --- service/tdm-socket.service | 15 ------- src/tdm_private.h | 1 + src/tdm_server.c | 107 ++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 106 insertions(+), 32 deletions(-) delete mode 100644 service/tdm-socket.path delete mode 100644 service/tdm-socket.service diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 5632f7c..8577063 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -81,9 +81,6 @@ make -C ut check rm -rf %{buildroot} %make_install -%__mkdir_p %{buildroot}%{_unitdir} -install -m 644 service/tdm-socket.service %{buildroot}%{_unitdir} -install -m 644 service/tdm-socket.path %{buildroot}%{_unitdir} %__mkdir_p %{buildroot}%{_unitdir_user} install -m 644 service/tdm-socket-user.service %{buildroot}%{_unitdir_user} install -m 644 service/tdm-socket-user.path %{buildroot}%{_unitdir_user} @@ -92,16 +89,11 @@ install -m 644 service/tdm-socket-user.path %{buildroot}%{_unitdir_user} %pre -%__mkdir_p %{_unitdir}/graphical.target.wants -ln -sf ../tdm-socket.path %{_unitdir}/graphical.target.wants/ - %__mkdir_p %{_unitdir_user}/basic.target.wants ln -sf ../tdm-socket-user.path %{_unitdir_user}/basic.target.wants/ %post -p /sbin/ldconfig %postun -p /sbin/ldconfig -rm -f %{_unitdir}/graphical.target.wants/tdm-socket.path - rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %files @@ -110,8 +102,6 @@ rm -f %{_unitdir_user}/basic.target.wants/tdm-socket-user.path %license COPYING %{_libdir}/libtdm.so.* %attr(750,root,root) %{_bindir}/tdm-monitor -%{_unitdir}/tdm-socket.path -%{_unitdir}/tdm-socket.service %{_unitdir_user}/tdm-socket-user.path %{_unitdir_user}/tdm-socket-user.service %if %{with utest} diff --git a/service/tdm-socket.path b/service/tdm-socket.path deleted file mode 100644 index 5ee772b..0000000 --- a/service/tdm-socket.path +++ /dev/null @@ -1,5 +0,0 @@ -[Unit] -Description=Wait for tdm-socket - -[Path] -PathExists=/run/tdm-socket diff --git a/service/tdm-socket.service b/service/tdm-socket.service deleted file mode 100644 index de50ebe..0000000 --- a/service/tdm-socket.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -Description= tdm-socket setup service - -[Service] -User=ui_fw -Group=ui_fw -Capabilities=cap_fowner,cap_chown=i -SecureBits=keep-caps -Type=oneshot -SmackProcessLabel=System -ExecStart=/usr/bin/chmod g+w /run/tdm-socket -ExecStart=/usr/bin/chgrp display /run/tdm-socket - -[Install] -WantedBy=graphical.target diff --git a/src/tdm_private.h b/src/tdm_private.h index 59cb1ad..25b24b7 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -53,6 +53,7 @@ #include #include #include +#include #include #include diff --git a/src/tdm_server.c b/src/tdm_server.c index 5299c93..9363768 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -625,6 +625,109 @@ _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: + if (buf) + free(buf); + if (grp) + free(grp); + + return -1; +} + +static int +_tdm_socket_init(tdm_private_loop *private_loop) +{ + const char *dir = NULL; + char socket_path[128]; + int ret = -1; + uid_t uid; + gid_t gid; + + if (wl_display_add_socket(private_loop->wl_display, "tdm-socket")) { + TDM_ERR("createing a tdm-socket failed"); + return 0; + } + + dir = getenv("XDG_RUNTIME_DIR"); + if (!dir) { + TDM_ERR("getting XDG_RUNTIME_DIR failed"); + return 0; + } + + snprintf(socket_path, sizeof(socket_path), "%s/%s", dir, "tdm-socket"); + + ret = chmod(socket_path, 509); + if (ret < 0) { + TDM_ERR("changing modes of socket file failed:%s (%m)", socket_path); + return 0; + } + + ret = _tdm_getgrnam_r("root"); + if (ret < 0) { + TDM_ERR("getting uid failed"); + return 0; + } + uid = ret; + + ret = _tdm_getgrnam_r("display"); + if (ret < 0) { + TDM_ERR("getting gid failed"); + return 0; + } + gid = ret; + + ret = chown(socket_path, uid, gid); + if (ret < 0) { + TDM_ERR("changing owner of socket file failed:%s (%m)", socket_path); + return 0; + } + + return 1; +} + INTERN tdm_error tdm_server_init(tdm_private_loop *private_loop) { @@ -636,8 +739,8 @@ tdm_server_init(tdm_private_loop *private_loop) if (private_loop->private_server) return TDM_ERROR_NONE; - if (wl_display_add_socket(private_loop->wl_display, "tdm-socket")) { - TDM_ERR("createing a tdm-socket failed"); + if (!_tdm_socket_init(private_loop)) { + TDM_ERR("initializing tdm-socket failed"); return TDM_ERROR_OPERATION_FAILED; } -- 2.7.4 From 27b219f2029a624bdc97caef70b1d536106f1a22 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 23 May 2017 00:23:07 +0900 Subject: [PATCH 10/16] package version up to 1.6.18 Change-Id: I6fc719c0eee8e70d6bf482251490697d6d355492 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 8577063..1b9ff2a 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.17 +Version: 1.6.18 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 8a3937ce76415837b871c775806a2c3ab1e7ed10 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 26 May 2017 13:08:34 +0900 Subject: [PATCH 11/16] server: skip chown if not a super user If tdm_display_init is called by non super user, we don't need to change the owner and group of a tdm socket file. And also changing the owner of the tdm socket file which is created by non super user is not allowed. So we just skip chown in this case. Change-Id: Ib119becc4b9048f0fcc79c52089cfe04907cac60 --- src/tdm_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tdm_server.c b/src/tdm_server.c index 9363768..209429b 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -705,6 +705,10 @@ _tdm_socket_init(tdm_private_loop *private_loop) return 0; } + /* if not super user, we don't need to change owner and group */ + if (getuid() != 0) + return 1; + ret = _tdm_getgrnam_r("root"); if (ret < 0) { TDM_ERR("getting uid failed"); -- 2.7.4 From f75fee79b0695962f6edcb7435b9e42ec4c4d82c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 26 May 2017 13:32:45 +0900 Subject: [PATCH 12/16] package version up to 1.6.19 Change-Id: Ide4d9c9d0deeb0cf0e034497d40824ac8ebd4f8e --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 1b9ff2a..6fbc3c0 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.18 +Version: 1.6.19 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 5e09ccc8b30c7fba349d2acf191a967d7a2ad60d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 30 May 2017 13:57:18 +0900 Subject: [PATCH 13/16] server: ignore chown & chmod errors Change-Id: I0a923486ca44f8b2b0232bfe4d728a39a66d6df0 --- src/tdm_server.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/tdm_server.c b/src/tdm_server.c index 209429b..bd9cd9f 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -677,7 +677,7 @@ failed: return -1; } -static int +static void _tdm_socket_init(tdm_private_loop *private_loop) { const char *dir = NULL; @@ -686,50 +686,39 @@ _tdm_socket_init(tdm_private_loop *private_loop) uid_t uid; gid_t gid; - if (wl_display_add_socket(private_loop->wl_display, "tdm-socket")) { - TDM_ERR("createing a tdm-socket failed"); - return 0; - } - dir = getenv("XDG_RUNTIME_DIR"); if (!dir) { - TDM_ERR("getting XDG_RUNTIME_DIR failed"); - return 0; + TDM_WRN("getting XDG_RUNTIME_DIR failed"); + return; } snprintf(socket_path, sizeof(socket_path), "%s/%s", dir, "tdm-socket"); ret = chmod(socket_path, 509); if (ret < 0) { - TDM_ERR("changing modes of socket file failed:%s (%m)", socket_path); - return 0; + TDM_WRN("changing modes of socket file failed:%s (%m)", socket_path); + return; } - /* if not super user, we don't need to change owner and group */ - if (getuid() != 0) - return 1; - ret = _tdm_getgrnam_r("root"); if (ret < 0) { - TDM_ERR("getting uid failed"); - return 0; + TDM_WRN("getting uid failed"); + return; } uid = ret; ret = _tdm_getgrnam_r("display"); if (ret < 0) { - TDM_ERR("getting gid failed"); - return 0; + TDM_WRN("getting gid failed"); + return; } gid = ret; ret = chown(socket_path, uid, gid); if (ret < 0) { - TDM_ERR("changing owner of socket file failed:%s (%m)", socket_path); - return 0; + TDM_WRN("changing owner of socket file failed:%s (%m)", socket_path); + return; } - - return 1; } INTERN tdm_error @@ -743,11 +732,13 @@ tdm_server_init(tdm_private_loop *private_loop) if (private_loop->private_server) return TDM_ERROR_NONE; - if (!_tdm_socket_init(private_loop)) { - TDM_ERR("initializing tdm-socket failed"); + if (wl_display_add_socket(private_loop->wl_display, "tdm-socket")) { + TDM_ERR("createing a tdm-socket failed"); return TDM_ERROR_OPERATION_FAILED; } + _tdm_socket_init(private_loop); + private_server = calloc(1, sizeof * private_server); if (!private_server) { TDM_ERR("alloc failed"); -- 2.7.4 From 2c307332239ee96a93d80b9737b132977db790f6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 30 May 2017 14:37:17 +0900 Subject: [PATCH 14/16] package version up to 1.6.20 Change-Id: I6aa36f184b3d4e23c9388af1fc89e1d0ea24c11b --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 6fbc3c0..8724a9d 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.6.19 +Version: 1.6.20 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 1578d492620801adc40404340d546adcb9c76645 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sun, 11 Jun 2017 08:24:07 +0900 Subject: [PATCH 15/16] helper: add tdm_helper_get_buffer_full_size() to get the real buffer size Change-Id: Ie27d3b52ab57171b25628e8a85fc509d1e643e21 --- include/tdm_helper.h | 11 +++++++++++ src/tdm_helper.c | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/tdm_helper.h b/include/tdm_helper.h index c80057d..ef0a657 100644 --- a/include/tdm_helper.h +++ b/include/tdm_helper.h @@ -110,6 +110,17 @@ void tdm_helper_clear_buffer(tbm_surface_h buffer); /** + * @brief Get the buffer full size. + * @details + * In some hardware, the buffer width or height is aligned with the fixed size. + * eg. 8, 16, etc. In this case, the real size of buffer could be bigger than + * the buffer size of tbm_surface_info_s. + * @param[in] buffer A TDM buffer + */ +void +tdm_helper_get_buffer_full_size(tbm_surface_h buffer, int *buffer_w, int *buffer_h); + +/** * @brief convert the source buffer to the destination buffer with given rectangles * trannsform * @details diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 4adbcb8..21758f6 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -390,6 +390,28 @@ tdm_helper_clear_buffer(tbm_surface_h buffer) tdm_helper_clear_buffer_pos(buffer, NULL); } +EXTERN void +tdm_helper_get_buffer_full_size(tbm_surface_h buffer, int *buffer_w, int *buffer_h) +{ + tbm_surface_info_s info; + int ret; + + TDM_RETURN_IF_FAIL(buffer != NULL); + + ret = tbm_surface_get_info(buffer, &info); + TDM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE); + + if (buffer_w) { + if (IS_RGB(info.format)) + *buffer_w = info.planes[0].stride >> 2; + else + *buffer_w = info.planes[0].stride; + } + + if (buffer_h) + *buffer_h = info.planes[0].size / info.planes[0].stride; +} + static pixman_format_code_t _tdm_helper_pixman_format_get(tbm_format format) { -- 2.7.4 From c91a6898749a2445d74ddb4162372e75e0442eec Mon Sep 17 00:00:00 2001 From: Boram Park Date: Sun, 11 Jun 2017 08:25:27 +0900 Subject: [PATCH 16/16] helper: consider the real buffer size Change-Id: I6950f430aa2581c93709c80200f7b60600b56af4 --- src/tdm_helper.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 21758f6..90dd618 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -216,7 +216,7 @@ tdm_helper_dump_buffer_str(tbm_surface_h buffer, char *dir, char *str) tbm_surface_info_s info; const char *ext; char file[TDM_PATH_LEN]; - int ret, bw; + int ret, bw, bh; TDM_RETURN_IF_FAIL(buffer != NULL); TDM_RETURN_IF_FAIL(dir != NULL); @@ -225,16 +225,15 @@ tdm_helper_dump_buffer_str(tbm_surface_h buffer, char *dir, char *str) ret = tbm_surface_get_info(buffer, &info); TDM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE); - if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) { + if (IS_RGB(info.format)) ext = file_exts[0]; - bw = info.planes[0].stride >> 2; - } else { + else ext = file_exts[1]; - bw = info.planes[0].stride; - } - snprintf(file, TDM_PATH_LEN, "%s/%c%c%c%c_%dx%d_%s.%s", - dir, FOURCC_STR(info.format), bw, info.height, str, ext); + tdm_helper_get_buffer_full_size(buffer, &bw, &bh); + + snprintf(file, TDM_PATH_LEN, "%s/%c%c%c%c_%dx%d_%dx%d_%s.%s", + dir, FOURCC_STR(info.format), bw, bh, info.width, info.height, str, ext); tdm_helper_dump_buffer(buffer, file); } @@ -246,6 +245,7 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) int len, ret; const char *ext; int bo_cnt; + int bw, bh; TDM_RETURN_IF_FAIL(buffer != NULL); TDM_RETURN_IF_FAIL(file != NULL); @@ -254,7 +254,7 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) TDM_RETURN_IF_FAIL(ret == TBM_SURFACE_ERROR_NONE); len = strnlen(file, 1024); - if (info.format == TBM_FORMAT_ARGB8888 || info.format == TBM_FORMAT_XRGB8888) + if (IS_RGB(info.format)) ext = file_exts[0]; else ext = file_exts[1]; @@ -265,9 +265,11 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) return; } + tdm_helper_get_buffer_full_size(buffer, &bw, &bh); + bo_cnt = tbm_surface_internal_get_num_bos(buffer); - TDM_DBG("buffer: bo_cnt(%d) %dx%d %c%c%c%c, plane: (%p+%d, %d,%d) (%p+%d, %d,%d) (%p+%d, %d,%d)", - bo_cnt, info.width, info.height, FOURCC_STR(info.format), + TDM_DBG("buffer: bo_cnt(%d) %dx%d(%dx%d) %c%c%c%c, plane: (%p+%d, %d,%d) (%p+%d, %d,%d) (%p+%d, %d,%d)", + bo_cnt, bw, bh, info.width, info.height, FOURCC_STR(info.format), info.planes[0].ptr, info.planes[0].offset, info.planes[0].stride, info.planes[0].size, info.planes[1].ptr, info.planes[1].offset, info.planes[1].stride, info.planes[1].size, info.planes[2].ptr, info.planes[2].offset, info.planes[2].stride, info.planes[2].size); @@ -275,37 +277,32 @@ tdm_helper_dump_buffer(tbm_surface_h buffer, const char *file) switch (info.format) { case TBM_FORMAT_ARGB8888: case TBM_FORMAT_XRGB8888: - _tdm_helper_dump_png(file, info.planes[0].ptr, - info.planes[0].stride >> 2, info.height); + _tdm_helper_dump_png(file, info.planes[0].ptr, bw, bh); break; case TBM_FORMAT_YVU420: case TBM_FORMAT_YUV420: _tdm_helper_dump_raw(file, info.planes[0].ptr, - info.planes[0].stride * info.height, + info.planes[0].size, info.planes[1].ptr, - info.planes[1].stride * (info.height >> 1), + info.planes[1].size, info.planes[2].ptr, - info.planes[2].stride * (info.height >> 1)); + info.planes[2].size); break; case TBM_FORMAT_NV12: case TBM_FORMAT_NV21: - if (bo_cnt == 1 && - (info.planes[0].ptr + info.planes[0].stride * info.height) != info.planes[1].ptr) - TDM_WRN("%p != %p", info.planes[0].ptr + info.planes[0].stride * info.height, info.planes[1].ptr); - _tdm_helper_dump_raw(file, info.planes[0].ptr, - info.planes[0].stride * info.height, + info.planes[0].size, info.planes[1].ptr, - info.planes[1].stride * (info.height >> 1), NULL, + info.planes[1].size, NULL, 0); break; case TBM_FORMAT_YUYV: case TBM_FORMAT_UYVY: _tdm_helper_dump_raw(file, info.planes[0].ptr, - info.planes[0].stride * info.height, NULL, 0, + info.planes[0].size, NULL, 0, NULL, 0); break; default: -- 2.7.4