diff options
author | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-08-22 10:43:53 +0900 |
---|---|---|
committer | Jean-Philippe Andre <jp.andre@samsung.com> | 2013-10-28 15:47:14 +0900 |
commit | 71fdd0d3426868dff7f8a9df785f5ef1a20a4c87 (patch) | |
tree | 754ea9185201e4eb0e3fea0d26b301d1e0453aff | |
parent | bc7b337fc065dc922a039897e22f570a26fbf4be (diff) |
evas/cserve2: Add SHM debug tool (CLI)
Prints out the content or the shared index.
Does not need any socket connection to the server, read-only.
-rw-r--r-- | src/Makefile_Evas.am | 12 | ||||
-rw-r--r-- | src/bin/evas/evas_cserve2_shm_debug.c | 759 |
2 files changed, 770 insertions, 1 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am index de3636bf7d..7a52016126 100644 --- a/src/Makefile_Evas.am +++ b/src/Makefile_Evas.am | |||
@@ -999,7 +999,8 @@ bin/evas/dummy_slave | |||
999 | bin_PROGRAMS += \ | 999 | bin_PROGRAMS += \ |
1000 | bin/evas/evas_cserve2_client \ | 1000 | bin/evas/evas_cserve2_client \ |
1001 | bin/evas/evas_cserve2_usage \ | 1001 | bin/evas/evas_cserve2_usage \ |
1002 | bin/evas/evas_cserve2_debug | 1002 | bin/evas/evas_cserve2_debug \ |
1003 | bin/evas/evas_cserve2_shm_debug | ||
1003 | 1004 | ||
1004 | bin_evas_evas_cserve2_SOURCES = \ | 1005 | bin_evas_evas_cserve2_SOURCES = \ |
1005 | bin/evas/evas_cserve2.h \ | 1006 | bin/evas/evas_cserve2.h \ |
@@ -1056,6 +1057,15 @@ bin_evas_evas_cserve2_debug_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | |||
1056 | bin_evas_evas_cserve2_debug_LDADD = @USE_EINA_LIBS@ | 1057 | bin_evas_evas_cserve2_debug_LDADD = @USE_EINA_LIBS@ |
1057 | bin_evas_evas_cserve2_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ | 1058 | bin_evas_evas_cserve2_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ |
1058 | 1059 | ||
1060 | bin_evas_evas_cserve2_shm_debug_SOURCES = \ | ||
1061 | bin/evas/evas_cserve2_shm_debug.c | ||
1062 | bin_evas_evas_cserve2_shm_debug_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ | ||
1063 | -I$(top_srcdir)/src/lib/evas \ | ||
1064 | -I$(top_srcdir)/src/lib/evas/cserve2 \ | ||
1065 | @EINA_CFLAGS@ | ||
1066 | bin_evas_evas_cserve2_shm_debug_LDADD = @USE_EINA_LIBS@ | ||
1067 | bin_evas_evas_cserve2_shm_debug_DEPENDENCIES = @USE_EINA_INTERNAL_LIBS@ | ||
1068 | |||
1059 | bin_evas_evas_cserve2_slave_SOURCES = \ | 1069 | bin_evas_evas_cserve2_slave_SOURCES = \ |
1060 | bin/evas/evas_cserve2_slave.c \ | 1070 | bin/evas/evas_cserve2_slave.c \ |
1061 | bin/evas/evas_cserve2_utils.c \ | 1071 | bin/evas/evas_cserve2_utils.c \ |
diff --git a/src/bin/evas/evas_cserve2_shm_debug.c b/src/bin/evas/evas_cserve2_shm_debug.c new file mode 100644 index 0000000000..e17e5d2b40 --- /dev/null +++ b/src/bin/evas/evas_cserve2_shm_debug.c | |||
@@ -0,0 +1,759 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | #include "config.h" | ||
3 | #endif | ||
4 | |||
5 | #include <unistd.h> | ||
6 | #include <sys/ioctl.h> | ||
7 | |||
8 | #include <Eina.h> | ||
9 | #include "evas_cs2.h" | ||
10 | |||
11 | #define SHM_FOLDER "/dev/shm" | ||
12 | static int _evas_cserve2_shm_debug_log_dom = -1; | ||
13 | |||
14 | #define ERR(...) EINA_LOG_DOM_ERR(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__) | ||
15 | #define DBG(...) EINA_LOG_DOM_DBG(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__) | ||
16 | #define WRN(...) EINA_LOG_DOM_WARN(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__) | ||
17 | #define INF(...) EINA_LOG_DOM_INFO(_evas_cserve2_shm_debug_log_dom, __VA_ARGS__) | ||
18 | |||
19 | typedef struct _Shm_File Shm_File; | ||
20 | struct _Shm_File | ||
21 | { | ||
22 | Eina_File *f; | ||
23 | char *data; | ||
24 | size_t size; | ||
25 | int tag; | ||
26 | |||
27 | Eina_Bool strings; | ||
28 | Shared_Array_Header *header; | ||
29 | }; | ||
30 | |||
31 | Shm_File *sf_strindex = NULL; | ||
32 | Shm_File *sf_strpool = NULL; | ||
33 | Shm_File *sf_fonts = NULL; | ||
34 | Shm_File *sf_files = NULL; | ||
35 | Shm_File *sf_images = NULL; | ||
36 | |||
37 | static int _termsize = 0; | ||
38 | |||
39 | static void | ||
40 | nprintf(int n, const char *fmt, ...) | ||
41 | { | ||
42 | char buf[n+1]; | ||
43 | va_list arg; | ||
44 | int len; | ||
45 | |||
46 | va_start(arg, fmt); | ||
47 | if (!n) | ||
48 | vprintf(fmt, arg); | ||
49 | else | ||
50 | { | ||
51 | len = vsnprintf(buf, n+1, fmt, arg); | ||
52 | buf[n] = 0; | ||
53 | fputs(buf, stdout); | ||
54 | if ((len > 0) && (buf[len-1] != '\n')) | ||
55 | fputc('\n', stdout); | ||
56 | } | ||
57 | va_end(arg); | ||
58 | } | ||
59 | |||
60 | #define printf(...) nprintf(_termsize, __VA_ARGS__) | ||
61 | |||
62 | static Shm_File * | ||
63 | _shm_file_open(const char *path) | ||
64 | { | ||
65 | Shm_File *sf; | ||
66 | Eina_File *f; | ||
67 | char *data; | ||
68 | |||
69 | f = eina_file_open(path, EINA_TRUE); | ||
70 | if (!f) | ||
71 | { | ||
72 | ERR("Could not open file %s: [%d] %m", path, errno); | ||
73 | return NULL; | ||
74 | } | ||
75 | |||
76 | data = eina_file_map_all(f, EINA_FILE_RANDOM); | ||
77 | if (!data) | ||
78 | { | ||
79 | ERR("Could not map the file %s", path); | ||
80 | eina_file_close(f); | ||
81 | return NULL; | ||
82 | } | ||
83 | |||
84 | sf = calloc(1, sizeof(*sf)); | ||
85 | sf->data = data; | ||
86 | sf->f = f; | ||
87 | sf->size = eina_file_size_get(f); | ||
88 | |||
89 | DBG("Successfully opened %s", path); | ||
90 | return sf; | ||
91 | } | ||
92 | |||
93 | static void | ||
94 | _shm_file_close(Shm_File *sf) | ||
95 | { | ||
96 | if (!sf) return; | ||
97 | eina_file_map_free(sf->f, sf->data); | ||
98 | eina_file_close(sf->f); | ||
99 | free(sf); | ||
100 | } | ||
101 | |||
102 | static Eina_Bool | ||
103 | _shm_file_probe(Shm_File *sf) | ||
104 | { | ||
105 | if (!sf || !sf->data) | ||
106 | return EINA_FALSE; | ||
107 | |||
108 | if (sf->size < sizeof(Shared_Array_Header)) | ||
109 | { | ||
110 | sf->header = NULL; | ||
111 | return EINA_TRUE; | ||
112 | } | ||
113 | |||
114 | sf->header = (Shared_Array_Header *) sf->data; | ||
115 | switch (sf->header->tag) | ||
116 | { | ||
117 | case STRING_INDEX_ARRAY_TAG: | ||
118 | DBG("Found string index: %s", eina_file_filename_get(sf->f)); | ||
119 | if (sf->header->elemsize != sizeof(Index_Entry)) | ||
120 | { | ||
121 | ERR("String index looks invalid: elemsize %d", | ||
122 | sf->header->elemsize); | ||
123 | return EINA_FALSE; | ||
124 | } | ||
125 | sf->tag = STRING_INDEX_ARRAY_TAG; | ||
126 | sf_strindex = sf; | ||
127 | break; | ||
128 | |||
129 | case STRING_MEMPOOL_FAKETAG: | ||
130 | DBG("Found string mempool: %s", eina_file_filename_get(sf->f)); | ||
131 | sf->strings = EINA_TRUE; | ||
132 | sf->tag = STRING_MEMPOOL_FAKETAG; | ||
133 | sf->header = NULL; | ||
134 | sf_strpool = sf; | ||
135 | break; | ||
136 | |||
137 | case FILE_DATA_ARRAY_TAG: | ||
138 | DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); | ||
139 | sf->tag = sf->header->tag; | ||
140 | sf_files = sf; | ||
141 | break; | ||
142 | |||
143 | case IMAGE_DATA_ARRAY_TAG: | ||
144 | DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); | ||
145 | sf->tag = sf->header->tag; | ||
146 | sf_images = sf; | ||
147 | break; | ||
148 | |||
149 | case FONT_DATA_ARRAY_TAG: | ||
150 | DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); | ||
151 | sf->tag = sf->header->tag; | ||
152 | sf_fonts = sf; | ||
153 | break; | ||
154 | |||
155 | case GLYPH_INDEX_ARRAY_TAG: | ||
156 | DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); | ||
157 | sf->tag = sf->header->tag; | ||
158 | break; | ||
159 | |||
160 | case GLYPH_DATA_ARRAY_TAG: | ||
161 | DBG("Found index table with tag '%4.4s'", (char *) &sf->header->tag); | ||
162 | sf->tag = sf->header->tag; | ||
163 | break; | ||
164 | |||
165 | default: | ||
166 | //DBG("Unknown tag found: %d", sf->header->tag); | ||
167 | sf->header = NULL; | ||
168 | break; | ||
169 | } | ||
170 | |||
171 | return EINA_TRUE; | ||
172 | } | ||
173 | |||
174 | static Eina_List * | ||
175 | _shm_files_list(const char *folder) | ||
176 | { | ||
177 | Eina_List *lst = NULL; | ||
178 | Eina_Iterator *iter; | ||
179 | const Eina_File_Direct_Info *f_info; | ||
180 | char pattern[64]; | ||
181 | |||
182 | sprintf(pattern, "/evas-shm-%x-", (int) getuid()); | ||
183 | iter = eina_file_direct_ls(folder); | ||
184 | EINA_ITERATOR_FOREACH(iter, f_info) | ||
185 | { | ||
186 | if (strstr(f_info->path, pattern)) | ||
187 | { | ||
188 | const char *shmname = strrchr(f_info->path, '/'); | ||
189 | if (!shmname) continue; | ||
190 | |||
191 | lst = eina_list_append(lst, strdup(shmname)); | ||
192 | } | ||
193 | else | ||
194 | DBG("cserve2 cleanup: ignoring %s", f_info->path); | ||
195 | } | ||
196 | eina_iterator_free(iter); | ||
197 | |||
198 | return lst; | ||
199 | } | ||
200 | |||
201 | static void | ||
202 | printf_newline(Eina_Bool flush) | ||
203 | { | ||
204 | printf("----------------------------------------------------------------" | ||
205 | "----------------\n"); | ||
206 | |||
207 | if (flush) | ||
208 | { | ||
209 | printf("\n\n"); | ||
210 | fflush(stdout); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static void | ||
215 | _index_tables_summary_print(void) | ||
216 | { | ||
217 | printf("Shared index tables\n\n"); | ||
218 | printf("Table Tag MapSize Gen ElSz Count Last Sort Path\n"); | ||
219 | printf_newline(0); | ||
220 | |||
221 | printf("StrIdx %4.4s %7d %4d %4d %5d %5d %5d %s\n", | ||
222 | (char *) &sf_strindex->tag, | ||
223 | (int) eina_file_size_get(sf_strindex->f), | ||
224 | sf_strindex->header->generation_id, sf_strindex->header->elemsize, | ||
225 | sf_strindex->header->count, sf_strindex->header->emptyidx, | ||
226 | sf_strindex->header->sortedidx, | ||
227 | eina_file_filename_get(sf_strindex->f)); | ||
228 | |||
229 | printf("StrData %4.4s %7d %s\n", | ||
230 | (char *) &sf_strpool->tag, | ||
231 | (int) eina_file_size_get(sf_strpool->f), | ||
232 | eina_file_filename_get(sf_strpool->f)); | ||
233 | |||
234 | if (sf_files) | ||
235 | printf("FileIdx %4.4s %7d %4d %4d %5d %5d %5d %s\n", | ||
236 | (char *) &sf_files->tag, | ||
237 | (int) eina_file_size_get(sf_files->f), | ||
238 | sf_files->header->generation_id, sf_files->header->elemsize, | ||
239 | sf_files->header->count, sf_files->header->emptyidx, | ||
240 | sf_files->header->sortedidx, | ||
241 | eina_file_filename_get(sf_files->f)); | ||
242 | else | ||
243 | printf("FileIdx <not found>\n"); | ||
244 | |||
245 | if (sf_images) | ||
246 | printf("Images %4.4s %7d %4d %4d %5d %5d %5d %s\n", | ||
247 | (char *) &sf_images->tag, | ||
248 | (int) eina_file_size_get(sf_images->f), | ||
249 | sf_images->header->generation_id, sf_images->header->elemsize, | ||
250 | sf_images->header->count, sf_images->header->emptyidx, | ||
251 | sf_images->header->sortedidx, | ||
252 | eina_file_filename_get(sf_images->f)); | ||
253 | else | ||
254 | printf("Images <not found>\n"); | ||
255 | |||
256 | if (sf_fonts) | ||
257 | printf("FontIdx %4.4s %7d %4d %4d %5d %5d %5d %s\n", | ||
258 | (char *) &sf_fonts->tag, | ||
259 | (int) eina_file_size_get(sf_fonts->f), | ||
260 | sf_fonts->header->generation_id, sf_fonts->header->elemsize, | ||
261 | sf_fonts->header->count, sf_fonts->header->emptyidx, | ||
262 | sf_fonts->header->sortedidx, | ||
263 | eina_file_filename_get(sf_fonts->f)); | ||
264 | else | ||
265 | printf("FontIdx <not found>\n"); | ||
266 | |||
267 | printf_newline(1); | ||
268 | } | ||
269 | |||
270 | static const Shm_Object * | ||
271 | _shared_index_item_get_by_id(Shm_File *si, int elemsize, unsigned int id) | ||
272 | { | ||
273 | const Shm_Object *obj; | ||
274 | const char *base; | ||
275 | int low = 0, high, start_high; | ||
276 | int cur; | ||
277 | |||
278 | if (!si || elemsize <= 0 || !id) | ||
279 | return NULL; | ||
280 | |||
281 | // FIXME: HACK (consider all arrays always sorted by id) | ||
282 | high = si->header->emptyidx; // Should be si->header->sortedidx | ||
283 | |||
284 | if (high > si->header->count) | ||
285 | high = si->header->count; | ||
286 | |||
287 | base = si->data + sizeof(Shared_Array_Header); | ||
288 | |||
289 | // Binary search | ||
290 | start_high = high; | ||
291 | while(high != low) | ||
292 | { | ||
293 | cur = low + ((high - low) / 2); | ||
294 | obj = (Shm_Object *) (base + (elemsize * cur)); | ||
295 | if (obj->id == id) | ||
296 | return obj; | ||
297 | if (obj->id < id) | ||
298 | low = cur + 1; | ||
299 | else | ||
300 | high = cur; | ||
301 | } | ||
302 | |||
303 | // Linear search | ||
304 | for (cur = start_high; cur < si->header->count; cur++) | ||
305 | { | ||
306 | obj = (Shm_Object *) (base + (elemsize * cur)); | ||
307 | if (!obj->id) | ||
308 | return NULL; | ||
309 | if (obj->id == id) | ||
310 | return obj; | ||
311 | } | ||
312 | |||
313 | return NULL; | ||
314 | } | ||
315 | |||
316 | static void * | ||
317 | _shared_array_item_get(Shm_File *sf, int idx) | ||
318 | { | ||
319 | if (!sf || !sf->header || idx < 0) | ||
320 | return NULL; | ||
321 | |||
322 | if ((idx + 1) * sf->header->elemsize > (int) sf->size) | ||
323 | return NULL; | ||
324 | |||
325 | return (sf->data + sizeof(Shared_Array_Header) + idx * sf->header->elemsize); | ||
326 | } | ||
327 | |||
328 | static const char * | ||
329 | _shared_string_get(int id) | ||
330 | { | ||
331 | Index_Entry *ie; | ||
332 | |||
333 | ie = (Index_Entry *) | ||
334 | _shared_index_item_get_by_id(sf_strindex, sizeof(*ie), id); | ||
335 | if (!ie) return NULL; | ||
336 | if (ie->offset < 0) return NULL; | ||
337 | if (!ie->refcount) return NULL; | ||
338 | if (ie->offset + ie->length > (int) sf_strpool->size) return NULL; | ||
339 | |||
340 | return sf_strpool->data + ie->offset; | ||
341 | } | ||
342 | |||
343 | static void | ||
344 | _strings_all_print(Eina_Bool full) | ||
345 | { | ||
346 | int k; | ||
347 | const char *mindata = sf_strpool->data; | ||
348 | const char *maxdata = sf_strpool->data + sf_strpool->size; | ||
349 | |||
350 | printf("List of strings\n"); | ||
351 | printf("Indexes: %s\n", eina_file_filename_get(sf_strindex->f)); | ||
352 | printf("Data: %s\n", eina_file_filename_get(sf_strpool->f)); | ||
353 | printf(" String BufID Refcnt Offset Buflen Content\n"); | ||
354 | printf_newline(0); | ||
355 | |||
356 | for (k = 0; k < sf_strindex->header->count; k++) | ||
357 | { | ||
358 | Index_Entry *ie; | ||
359 | const char *data; | ||
360 | |||
361 | ie = _shared_array_item_get(sf_strindex, k); | ||
362 | if (!ie) break; | ||
363 | |||
364 | if (!ie->id || (!full && !ie->refcount)) | ||
365 | continue; | ||
366 | |||
367 | data = sf_strpool->data + ie->offset; | ||
368 | if ((data < mindata) || (data + ie->length > maxdata)) | ||
369 | data = "<invalid offset>"; | ||
370 | |||
371 | printf("%7d %7d %7d %7d %7d '%s'\n", | ||
372 | k, ie->id, ie->refcount, ie->offset, ie->length, data); | ||
373 | } | ||
374 | |||
375 | printf_newline(1); | ||
376 | } | ||
377 | |||
378 | static void | ||
379 | _files_all_print(Eina_Bool full) | ||
380 | { | ||
381 | int k; | ||
382 | |||
383 | if (!sf_files) return; | ||
384 | |||
385 | printf("List of image files: %s\n", eina_file_filename_get(sf_files->f)); | ||
386 | printf("A: Alpha, I: Invalid.\n\n"); | ||
387 | printf(" Index FileID WIDTHxHEIGHT A I Loader PathID KeyID Path:Key\n"); | ||
388 | printf_newline(0); | ||
389 | |||
390 | for (k = 0; k < sf_files->header->count; k++) | ||
391 | { | ||
392 | File_Data *fd; | ||
393 | |||
394 | fd = _shared_array_item_get(sf_files, k); | ||
395 | if (!fd) break; | ||
396 | if (!fd->id || (!full && !fd->refcount)) continue; | ||
397 | |||
398 | printf("%7d %7d %5dx%-6d %d %d %6.6s %6d %6d '%s':'%s'\n", | ||
399 | k, fd->id, fd->w, fd->h, !!fd->alpha, !!fd->invalid, | ||
400 | fd->loader_data ? _shared_string_get(fd->loader_data) : "", | ||
401 | fd->path, fd->key, _shared_string_get(fd->path), | ||
402 | _shared_string_get(fd->key)); | ||
403 | } | ||
404 | |||
405 | printf_newline(1); | ||
406 | } | ||
407 | |||
408 | static void | ||
409 | _images_all_print_short(void) | ||
410 | { | ||
411 | int k; | ||
412 | |||
413 | if (!sf_images) return; | ||
414 | |||
415 | printf("List of loaded images: %s\n", eina_file_filename_get(sf_images->f)); | ||
416 | printf("A: Sparse alpha, U: Unused, L: Load requested.\n\n"); | ||
417 | printf(" Index ImageID FileID Refcnt A U L ShmID ShmPath\n"); | ||
418 | printf_newline(0); | ||
419 | |||
420 | for (k = 0; k < sf_images->header->count; k++) | ||
421 | { | ||
422 | Image_Data *id; | ||
423 | |||
424 | id = _shared_array_item_get(sf_images, k); | ||
425 | if (!id) break; | ||
426 | if (!id->id || !id->refcount) continue; | ||
427 | |||
428 | printf("%7d %7d %7d %7d %d %d %d %7d '%s'\n", | ||
429 | k, id->id, id->file_id, id->refcount, | ||
430 | !!id->alpha_sparse, !!id->unused, !!id->doload, id->shm_id, | ||
431 | id->shm_id ? _shared_string_get(id->shm_id) : ""); | ||
432 | } | ||
433 | |||
434 | printf_newline(1); | ||
435 | } | ||
436 | |||
437 | static void | ||
438 | _images_all_print_full(void) | ||
439 | { | ||
440 | int k; | ||
441 | |||
442 | if (!sf_images) return; | ||
443 | |||
444 | printf("List of loaded images: %s\n\n", | ||
445 | eina_file_filename_get(sf_images->f)); | ||
446 | printf_newline(0); | ||
447 | |||
448 | for (k = 0; k < sf_images->header->count; k++) | ||
449 | { | ||
450 | Image_Data *id; | ||
451 | File_Data *fd; | ||
452 | const char *scale_hint; | ||
453 | |||
454 | id = _shared_array_item_get(sf_images, k); | ||
455 | if (!id) break; | ||
456 | if (!id->id) continue; | ||
457 | |||
458 | printf("Image #%-8d %d\n", k, id->id); | ||
459 | printf("Refcount %d\n", id->refcount); | ||
460 | printf("Sparse alpha %s\n" | ||
461 | "Unused: %s\n" | ||
462 | "Load requested: %s\n", | ||
463 | id->alpha_sparse ? "YES" : "NO", | ||
464 | id->unused ? "YES" : "NO", | ||
465 | id->doload ? "YES" : "NO"); | ||
466 | printf("Shm Path: '%s'\n", | ||
467 | id->shm_id ? _shared_string_get(id->shm_id) : ""); | ||
468 | |||
469 | printf("LoadOpts: width %d\n", id->opts.w); | ||
470 | printf(" height %d\n", id->opts.h); | ||
471 | printf(" degree %d\n", id->opts.degree); | ||
472 | printf(" scale_down_by %d\n", id->opts.scale_down_by); | ||
473 | if (id->opts.dpi) | ||
474 | printf(" dpi %.2f\n", id->opts.dpi); | ||
475 | else | ||
476 | printf(" dpi 0\n"); | ||
477 | printf(" orientation %s\n", id->opts.orientation ? "YES" : "NO"); | ||
478 | printf(" region (%d,%d) %dx%d\n", | ||
479 | id->opts.region.x, id->opts.region.y, | ||
480 | id->opts.region.w, id->opts.region.h); | ||
481 | |||
482 | switch (id->opts.scale_load.scale_hint) | ||
483 | { | ||
484 | case EVAS_IMAGE_SCALE_HINT_NONE: | ||
485 | scale_hint = "EVAS_IMAGE_SCALE_HINT_NONE"; break; | ||
486 | case EVAS_IMAGE_SCALE_HINT_DYNAMIC: | ||
487 | scale_hint = "EVAS_IMAGE_SCALE_HINT_DYNAMIC"; break; | ||
488 | case EVAS_IMAGE_SCALE_HINT_STATIC: | ||
489 | scale_hint = "EVAS_IMAGE_SCALE_HINT_STATIC"; break; | ||
490 | default: | ||
491 | scale_hint = "<invalid>"; break; | ||
492 | } | ||
493 | |||
494 | printf(" scale src (%d,%d) %dx%d\n", | ||
495 | id->opts.scale_load.src_x, id->opts.scale_load.src_y, | ||
496 | id->opts.scale_load.src_w, id->opts.scale_load.src_h); | ||
497 | printf(" scale dst %dx%d\n", | ||
498 | id->opts.scale_load.dst_w, id->opts.scale_load.dst_h); | ||
499 | printf(" scale smooth %s\n", | ||
500 | id->opts.scale_load.smooth ? "YES" : "NO"); | ||
501 | printf(" scale hint %s (%d)\n", | ||
502 | scale_hint, id->opts.scale_load.scale_hint); | ||
503 | |||
504 | fd = (File_Data *) | ||
505 | _shared_index_item_get_by_id(sf_files, sizeof(*fd), id->file_id); | ||
506 | if (fd) | ||
507 | { | ||
508 | printf("File: ID %d\n", id->file_id); | ||
509 | printf(" Path:Key: '%s':'%s'\n", | ||
510 | _shared_string_get(fd->path), _shared_string_get(fd->key)); | ||
511 | printf(" Loader: %s\n", | ||
512 | _shared_string_get(fd->loader_data)); | ||
513 | printf(" Geometry: %dx%d\n", fd->w, fd->h); | ||
514 | printf(" Animation: frames: %d, loop: %d, hint: %d\n", | ||
515 | fd->frame_count, fd->loop_count, fd->loop_hint); | ||
516 | printf(" Alpha: %s\n", fd->alpha ? "YES" : "NO"); | ||
517 | printf(" Invalid: %s\n", fd->invalid ? "YES" : "NO"); | ||
518 | } | ||
519 | else | ||
520 | printf("File: ID %d not found\n", id->file_id); | ||
521 | |||
522 | printf_newline(0); | ||
523 | } | ||
524 | |||
525 | printf("\n\n"); | ||
526 | fflush(stdout); | ||
527 | } | ||
528 | |||
529 | static void | ||
530 | _fonts_all_print_short(void) | ||
531 | { | ||
532 | int k; | ||
533 | |||
534 | static const char *rend_flags[] = { "R", "S", "W", "SW", "X" }; | ||
535 | |||
536 | if (!sf_fonts) return; | ||
537 | |||
538 | printf("List of loaded fonts: %s\n", eina_file_filename_get(sf_fonts->f)); | ||
539 | printf("Rendering flags (RF): " | ||
540 | "R: Regular, S: Slanted, W: Weight, X: Invalid\n\n"); | ||
541 | printf(" Index FontID Refcnt Size DPI RF GlIdx GlData File[:Name]\n"); | ||
542 | printf_newline(0); | ||
543 | |||
544 | for (k = 0; k < sf_fonts->header->count; k++) | ||
545 | { | ||
546 | Font_Data *fd; | ||
547 | int rflag; | ||
548 | const char *rf; | ||
549 | |||
550 | fd = _shared_array_item_get(sf_fonts, k); | ||
551 | if (!fd) break; | ||
552 | if (!fd->id || !fd->refcount) continue; | ||
553 | |||
554 | rflag = fd->rend_flags; | ||
555 | if (rflag < 0 || rflag > 3) rflag = 4; | ||
556 | rf = rend_flags[rflag]; | ||
557 | |||
558 | if (fd->name) | ||
559 | printf("%6d %6d %6d %5d %5d %-2s %6d %6d '%s':'%s'\n", | ||
560 | k, fd->id, fd->refcount, fd->size, fd->dpi, rf, | ||
561 | fd->glyph_index_shm, fd->mempool_shm, | ||
562 | fd->file ? _shared_string_get(fd->file) : "", | ||
563 | _shared_string_get(fd->name)); | ||
564 | else | ||
565 | printf("%6d %6d %6d %5d %5d %-2s %6d %6d '%s'\n", | ||
566 | k, fd->id, fd->refcount, fd->size, fd->dpi, rf, | ||
567 | fd->glyph_index_shm, fd->mempool_shm, | ||
568 | fd->file ? _shared_string_get(fd->file) : ""); | ||
569 | } | ||
570 | |||
571 | printf_newline(1); | ||
572 | } | ||
573 | |||
574 | static void | ||
575 | _glyphs_all_print(Shm_File *sf) | ||
576 | { | ||
577 | int k; | ||
578 | int nglyphs = 0; | ||
579 | int mem_used = 0; | ||
580 | |||
581 | printf(" GlyphID Refcnt Index Size Rows Width Pitch Grays Mode " | ||
582 | "BufID Offset ShmPath\n"); | ||
583 | |||
584 | for (k = 0; k < sf->header->count; k++) | ||
585 | { | ||
586 | Glyph_Data *gd; | ||
587 | |||
588 | gd = _shared_array_item_get(sf, k); | ||
589 | if (!gd) break; | ||
590 | if (!gd->id) continue; | ||
591 | |||
592 | printf(" %8u %6u %6u %5u %5u %5u %5u %5u %5u %6u %6u '%s'\n", | ||
593 | gd->id, gd->refcount, gd->index, gd->size, gd->rows, gd->width, | ||
594 | gd->pitch, gd->num_grays, gd->pixel_mode, gd->buffer_id, | ||
595 | gd->offset, _shared_string_get(gd->shm_id)); | ||
596 | |||
597 | nglyphs++; | ||
598 | mem_used += gd->size; | ||
599 | } | ||
600 | |||
601 | printf("Total %d glyph(s) loaded, using %d bytes (w/o padding)\n", | ||
602 | nglyphs, mem_used); | ||
603 | } | ||
604 | |||
605 | static void | ||
606 | _fonts_all_print_full(void) | ||
607 | { | ||
608 | int k; | ||
609 | |||
610 | static const char *rend_flags[] = { "R", "S", "W", "SW", "X" }; | ||
611 | |||
612 | if (!sf_fonts) return; | ||
613 | |||
614 | printf("List of loaded fonts: %s\n", eina_file_filename_get(sf_fonts->f)); | ||
615 | printf("Rendering flags: " | ||
616 | "R: Regular, S: Slanted, W: Weight, X: Invalid\n\n"); | ||
617 | printf_newline(0); | ||
618 | |||
619 | for (k = 0; k < sf_fonts->header->count; k++) | ||
620 | { | ||
621 | Shm_File *sf; | ||
622 | Font_Data *fd; | ||
623 | int rflag; | ||
624 | const char *rf; | ||
625 | |||
626 | fd = _shared_array_item_get(sf_fonts, k); | ||
627 | if (!fd) break; | ||
628 | if (!fd->id) continue; | ||
629 | if (!fd->glyph_index_shm) continue; | ||
630 | |||
631 | sf = _shm_file_open(_shared_string_get(fd->glyph_index_shm)); | ||
632 | if (!_shm_file_probe(sf)) | ||
633 | { | ||
634 | _shm_file_close(sf); | ||
635 | continue; | ||
636 | } | ||
637 | |||
638 | rflag = fd->rend_flags; | ||
639 | if (rflag < 0 || rflag > 3) rflag = 4; | ||
640 | rf = rend_flags[rflag]; | ||
641 | |||
642 | printf("Font #%-8d %d\n", k, fd->id); | ||
643 | printf("Refcount %d\n", fd->refcount); | ||
644 | printf("File '%s'\n", _shared_string_get(fd->file)); | ||
645 | printf("Name '%s'\n", | ||
646 | fd->name ? _shared_string_get(fd->name) : ""); | ||
647 | printf("Size %d\n", fd->size); | ||
648 | printf("DPI %d\n", fd->dpi); | ||
649 | printf("Rendering flag %s (%d)\n", rf, fd->rend_flags); | ||
650 | printf("Glyph index '%s'\n", _shared_string_get(fd->glyph_index_shm)); | ||
651 | printf("Glyph data '%s'\n", _shared_string_get(fd->mempool_shm)); | ||
652 | |||
653 | _glyphs_all_print(sf); | ||
654 | |||
655 | _shm_file_close(sf); | ||
656 | printf_newline(0); | ||
657 | } | ||
658 | |||
659 | printf("\n\n"); | ||
660 | fflush(stdout); | ||
661 | } | ||
662 | |||
663 | |||
664 | int | ||
665 | main(int argc EINA_UNUSED, char **argv EINA_UNUSED) | ||
666 | { | ||
667 | Eina_List *opened_sf = NULL; | ||
668 | Eina_List *shmfiles = NULL, *l1, *l2; | ||
669 | const char *shmfolder = SHM_FOLDER; | ||
670 | Eina_Bool full = EINA_FALSE; | ||
671 | Shm_File *sf; | ||
672 | char *name; | ||
673 | struct winsize w; | ||
674 | |||
675 | if (isatty(STDOUT_FILENO)) | ||
676 | { | ||
677 | ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); | ||
678 | _termsize = w.ws_col; | ||
679 | } | ||
680 | |||
681 | if (argc > 1) | ||
682 | { | ||
683 | if (!strcmp(argv[1], "-h")) | ||
684 | { | ||
685 | printf("Usage: %s [-f] [folder]\n", argv[0]); | ||
686 | return 0; | ||
687 | } | ||
688 | else if (!strcmp(argv[1], "-f")) | ||
689 | { | ||
690 | full = EINA_TRUE; | ||
691 | if (argc > 2) | ||
692 | shmfolder = argv[2]; | ||
693 | } | ||
694 | else | ||
695 | shmfolder = argv[1]; | ||
696 | } | ||
697 | |||
698 | eina_init(); | ||
699 | _evas_cserve2_shm_debug_log_dom = eina_log_domain_register | ||
700 | ("evas_cserve2_shm_debug", EINA_COLOR_BLUE); | ||
701 | |||
702 | shmfiles = _shm_files_list(shmfolder); | ||
703 | if (!shmfiles) | ||
704 | { | ||
705 | WRN("No shm file was found in %s", shmfolder); | ||
706 | goto finish; | ||
707 | } | ||
708 | |||
709 | DBG("Found %d files in %s", eina_list_count(shmfiles), shmfolder); | ||
710 | |||
711 | // Look for strings index & mempool | ||
712 | EINA_LIST_FOREACH_SAFE(shmfiles, l1, l2, name) | ||
713 | { | ||
714 | sf = _shm_file_open(name); | ||
715 | if (!_shm_file_probe(sf)) | ||
716 | { | ||
717 | shmfiles = eina_list_remove_list(shmfiles, l1); | ||
718 | _shm_file_close(sf); | ||
719 | free(name); | ||
720 | continue; | ||
721 | } | ||
722 | |||
723 | if (!sf->tag) | ||
724 | _shm_file_close(sf); | ||
725 | else | ||
726 | opened_sf = eina_list_append(opened_sf, sf); | ||
727 | |||
728 | if (!!sf_strindex | ||
729 | && !!sf_strpool | ||
730 | && !!sf_fonts | ||
731 | && !!sf_images | ||
732 | && !!sf_files) | ||
733 | break; | ||
734 | } | ||
735 | |||
736 | if (!sf_strindex || !sf_strpool) | ||
737 | { | ||
738 | ERR("Could not identify strings memory pool"); | ||
739 | goto finish; | ||
740 | } | ||
741 | |||
742 | _index_tables_summary_print(); | ||
743 | _strings_all_print(full); | ||
744 | _files_all_print(full); | ||
745 | _images_all_print_short(); | ||
746 | if (full) _images_all_print_full(); | ||
747 | _fonts_all_print_short(); | ||
748 | if (full) _fonts_all_print_full(); | ||
749 | |||
750 | finish: | ||
751 | EINA_LIST_FREE(opened_sf, sf) | ||
752 | _shm_file_close(sf); | ||
753 | |||
754 | EINA_LIST_FREE(shmfiles, name) | ||
755 | free(name); | ||
756 | |||
757 | eina_shutdown(); | ||
758 | return 0; | ||
759 | } | ||