3228e9058d6161e56d200f871b9130be169b6b81
[platform/core/uifw/wayland-tbm.git] / src / wayland-tbm-util.c
1 /*
2 Copyright (C) 2015 Samsung Electronics co., Ltd. All Rights Reserved.
3
4 Contact:
5       SooChan Lim <sc1.lim@samsung.com>,
6       Sangjin Lee <lsj119@samsung.com>,
7       Boram Park <boram1288.park@samsung.com>,
8       Changyeon Lee <cyeon.lee@samsung.com>
9
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the "Software"),
12 to deal in the Software without restriction, including without limitation
13 the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 and/or sell copies of the Software, and to permit persons to whom the
15 Software is furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice (including the next
18 paragraph) shall be included in all copies or substantial portions of the
19 Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
24 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 DEALINGS IN THE SOFTWARE.
28 */
29
30 #include "config.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #include <limits.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <tbm_surface.h>
41 #include <tbm_surface_internal.h>
42 #include "wayland-tbm-int.h"
43
44 #ifdef HAVE_DLOG
45 int bDlog;
46 #endif
47
48 int bTrace = 1;
49 int bDump = 0;
50
51 int
52 _str_to_pid(char * pid_str)
53 {
54         int pid = 0;
55         int d;
56
57         if (pid_str == NULL)
58                 return -1;
59
60         do {
61                 d = *pid_str - '0';
62                 if (d >= 0 && d <= 9)
63                         pid = pid*10 + d;
64                 else
65                         return -1;
66                 pid_str++;
67         } while (*pid_str);
68
69         return pid;
70 }
71
72 int
73 _waylend_tbm_util_target_parse(char * target_str, struct wayland_tbm_monitor_target *target)
74 {
75         char *t = NULL;
76         char *end = target_str;
77         int i = 0;
78         int pid = 0;
79         int server = 0;
80         int all = 0;
81
82         if (!target)
83                 return 0;
84
85         if (target_str == NULL || !strncmp(target_str, "all", 3)) {
86                 all = 1;
87                 server = 1;
88         } else {
89                 while ((t = strtok_r(NULL, ",", &end)) != NULL) {
90                         if (!strncmp(t, "server", 6))
91                                 server = 1;
92                         else if ((pid = _str_to_pid(t)) >= 0)
93                                 target->pid[i++] = pid;
94                         else
95                                 return 0;
96                 }
97         }
98
99         target->server = server;
100         target->all = all;
101
102         return 1;
103 }
104
105
106 int
107 _waylend_tbm_util_scale_parse(char * scale_str, double *scale)
108 {
109         if (!scale_str)
110                 return 1;
111
112         if (sscanf(scale_str, "scale=%lf", scale) == 1)
113                 if (*scale >= 0 && *scale <= 1)
114                         return 1;
115
116         return 0;
117 }
118
119 WL_TBM_MONITOR_PROC_STATE
120 _waylend_tbm_util_proc_state_parse(char *str)
121 {
122         if (str == NULL)
123                 return WL_TBM_MONITOR_PROC_STATE_UNKNOWN;
124         if (!strncmp(str, "on", 2))
125                 return WL_TBM_MONITOR_PROC_STATE_ON;
126         if (!strncmp(str, "off", 3))
127                 return WL_TBM_MONITOR_PROC_STATE_OFF;
128         if (!strncmp(str, "status", 6))
129                 return WL_TBM_MONITOR_PROC_STATE_STATUS;
130         return WL_TBM_MONITOR_PROC_STATE_UNKNOWN;
131 }
132
133 int
134 _wayland_tbm_util_show_path_parse(char * path_str, char * cwd, struct wayland_tbm_monitor_path *path)
135 {
136         char *end = path_str;
137         char *p = NULL;
138
139         if (!path_str)
140                 return 0;
141
142         /* parse options */
143         while ((p = strtok_r(NULL, ",", &end)) != NULL) {
144                 if (!strncmp(p, "dlog", 4))
145                         path->dlog = 1;
146                 else if (!strncmp(p, "console", 7))
147                         path->console = 1;
148                 else {
149                         if (p[0] == '/')
150                                 snprintf(path->file, WL_TBM_MONITOR_PATH_LEN, "%s", p);
151                         else {
152                                 if (cwd)
153                                         snprintf(path->file, WL_TBM_MONITOR_PATH_LEN, "%s/%s", cwd, p);
154                                 else
155                                         snprintf(path->file, WL_TBM_MONITOR_PATH_LEN, "%s", p);
156                         }
157                 }
158         }
159
160         return 1;
161 }
162
163
164 int
165 _waylend_tbm_util_trace(WL_TBM_MONITOR_PROC_STATE cmd, tbm_bufmgr bufmgr)
166 {
167         if (!bTrace && cmd == WL_TBM_MONITOR_PROC_STATE_ON) {
168                 tbm_bufmgr_debug_trace(bufmgr, 1);
169                 bTrace = 1;
170         } else if (bTrace && cmd == WL_TBM_MONITOR_PROC_STATE_OFF) {
171                 tbm_bufmgr_debug_trace(bufmgr, 0);
172                 bTrace = 0;
173         }
174         return bTrace;
175 }
176 void
177 _waylend_tbm_util_dump_snapshot(tbm_bufmgr bufmgr, double scale)
178 {
179         char *path = _wayland_tbm_dump_directory_make();
180         if (path) {
181                 tbm_bufmgr_debug_dump_set_scale(scale);
182                 tbm_bufmgr_debug_dump_all(path);
183                 free(path);
184                 path = NULL;
185         }
186 }
187
188 int
189 _waylend_tbm_util_dump_queue(WL_TBM_MONITOR_PROC_STATE cmd, tbm_bufmgr bufmgr, double scale)
190 {
191         static char *path = NULL;
192
193         if (!bDump && cmd == WL_TBM_MONITOR_PROC_STATE_ON) {
194                 path = _wayland_tbm_dump_directory_make();
195                 if (path != NULL) {
196                         tbm_bufmgr_debug_dump_set_scale(scale);
197                         tbm_bufmgr_debug_queue_dump(path, 20, 1);
198                         bDump = 1;
199                 }
200         } else if (bDump && cmd == WL_TBM_MONITOR_PROC_STATE_OFF) {
201                 tbm_bufmgr_debug_queue_dump(NULL, 0, 0);
202                 if (path) {
203                         free(path);
204                         path = NULL;
205                 }
206                 bDump = 0;
207         }
208         return bDump;
209 }
210
211 void
212 _wayland_tbm_util_get_appname_brief(char *brief)
213 {
214         char delim[] = "/";
215         char *token = NULL;
216         char temp[255] = {0,};
217         char *saveptr = NULL;
218
219         token = strtok_r(brief, delim, &saveptr);
220
221         while (token != NULL) {
222                 memset(temp, 0x00, 255 * sizeof(char));
223                 strncpy(temp, token, 254 * sizeof(char));
224                 token = strtok_r(NULL, delim, &saveptr);
225         }
226
227         snprintf(brief, sizeof(temp), "%s", temp);
228 }
229
230 void
231 _wayland_tbm_util_get_appname_from_pid(long pid, char *str)
232 {
233         FILE *fp;
234         int len;
235         long app_pid = pid;
236         char fn_cmdline[255] = {0,};
237         char cmdline[255] = {0,};
238
239         snprintf(fn_cmdline, sizeof(fn_cmdline), "/proc/%ld/cmdline", app_pid);
240
241         fp = fopen(fn_cmdline, "r");
242         if (fp == 0) {
243                 fprintf(stderr, "cannot file open /proc/%ld/cmdline", app_pid);
244                 return;
245         }
246
247         if (!fgets(cmdline, 255, fp)) {
248                 fprintf(stderr, "fail to get appname for pid(%ld)\n", app_pid);
249                 fclose(fp);
250                 return;
251         }
252         fclose(fp);
253
254         len = strlen(cmdline);
255         if (len < 1)
256                 memset(cmdline, 0x00, 255);
257         else
258                 cmdline[len] = 0;
259
260         snprintf(str, sizeof(cmdline), "%s", cmdline);
261 }
262
263 void
264 _wayland_tbm_check_dlog_enable(void)
265 {
266 #ifdef HAVE_DLOG
267         char *env;
268
269         env = getenv("WL_TBM_DLOG");
270         if (env) {
271                 bDlog = atoi(env);
272                 WL_TBM_LOG("WL_TBM_DLOG=%s", env);
273         } else {
274                 bDlog = 1;
275         }
276 #endif
277         return;
278 }
279
280 char *
281 _wayland_tbm_dump_directory_make(void)
282 {
283         char *fullpath;
284         time_t timer;
285         struct tm *t, *buf;
286         char appname[255] = {'\0'};
287
288         timer = time(NULL);
289
290         buf = calloc(1, sizeof(struct tm));
291         if (buf == 0)
292                 return NULL;
293
294         t = localtime_r(&timer, buf);
295         if (!t) {
296                 free(buf);
297                 return NULL;
298         }
299
300         fullpath = (char *) calloc(1, PATH_MAX * sizeof(char));
301         if (!fullpath) {
302                 free(buf);
303                 return NULL;
304         }
305
306         _wayland_tbm_util_get_appname_from_pid(getpid(), appname);
307
308         _wayland_tbm_util_get_appname_brief(appname);
309
310
311         snprintf(fullpath, PATH_MAX, "/tmp/tbm_dump_%s_%04d%02d%02d.%02d%02d%02d", appname, t->tm_year + 1900,
312                         t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
313
314         free(buf);
315
316         if ((mkdir(fullpath, 0755)) < 0) {
317                 free(fullpath);
318                 return NULL;
319         }
320
321         return fullpath;
322 }