1 /**************************************************************************
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: Boram Park <boram1288.park@samsung.com>
8 Sangjin LEE <lsj119@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
41 #include "xdbg_dump.h"
42 #include "xdbg_dump_module.h"
46 #define API __attribute__ ((visibility("default")))
49 #define DUMP_BUFCNT 50
50 #define DUMP_DIR "/tmp/xdump"
51 #define DUMP_SCALE_RATIO 2
57 void *bo; /* buffer object */
72 struct xorg_list link;
84 xDbgDumpBufferFunc func;
87 struct xorg_list *cursor;
88 struct xorg_list buffers;
95 static xDbgDumpInfo xdbg_dump_info;
107 snprintf (temp, sizeof (temp), "%s", s);
114 if (s[0] == 'x' || s[0] == 'X')
116 (void) sscanf (s, fmt, &retval);
118 return (thesign * retval);
122 _xDbgDumpEnsureDir (void)
124 char *dir = DUMP_DIR;
128 if (!(dp = opendir (dir)))
130 ret = mkdir (dir, 0755);
133 XDBG_ERROR (MXDBG, "fail: mkdir '%s'\n", DUMP_DIR);
144 _xDbgDumpSetOptions (void)
147 int tempsize = sizeof (options);
148 char *reply = options;
149 int *len = &tempsize;
154 if (xdbg_dump_info.type_str)
156 char *c = xdbg_dump_info.type_str;
157 if (!strcmp (c, "drawable"))
158 xdbg_dump_info.type = XDBG_DUMP_TYPE_DRAWABLE;
159 else if (!strcmp (c, "fb"))
160 xdbg_dump_info.type = XDBG_DUMP_TYPE_FB;
161 else if (!strcmp (c, "ui"))
162 xdbg_dump_info.type = XDBG_DUMP_TYPE_UI;
163 else if (!strcmp (c, "video"))
164 xdbg_dump_info.type = XDBG_DUMP_TYPE_VIDEO;
166 xdbg_dump_info.type = _parse_int (c);
169 xdbg_dump_info.type = XDBG_DUMP_TYPE_UI;
170 XDBG_REPLY ("type(0x%x) ", xdbg_dump_info.type);
173 if (xdbg_dump_info.count_str)
174 xdbg_dump_info.count = atoi (xdbg_dump_info.count_str);
176 xdbg_dump_info.count = DUMP_BUFCNT;
177 XDBG_REPLY ("count(%d) ", xdbg_dump_info.count);
180 if (xdbg_dump_info.file_str)
181 XDBG_REPLY ("file(%s) ", xdbg_dump_info.file_str);
184 if (xdbg_dump_info.crop_str)
192 if (xdbg_dump_info.crop)
194 free (xdbg_dump_info.crop);
195 xdbg_dump_info.crop = NULL;
198 snprintf (temp, sizeof (temp), "%s", xdbg_dump_info.crop_str);
200 c = strtok_r (temp, ",", &tokp);
205 c = strtok_r (NULL, ",", &tokp);
212 xdbg_dump_info.crop = calloc (1, sizeof (xRectangle));
213 XDBG_RETURN_IF_FAIL (xdbg_dump_info.crop != NULL);
215 xdbg_dump_info.crop->x = nums[0];
216 xdbg_dump_info.crop->y = nums[1];
217 xdbg_dump_info.crop->width = nums[2];
218 xdbg_dump_info.crop->height = nums[3];
220 XDBG_REPLY ("crop(%d,%d %dx%d) ",
221 nums[0], nums[1], nums[2], nums[3]);
225 XDBG_DEBUG (MXDBG, "%s\n", options);
231 if (xdbg_dump_info.init)
234 xdbg_dump_info.init = TRUE;
235 xdbg_dump_info.cursor = NULL;
236 xorg_list_init (&xdbg_dump_info.buffers);
240 _xDbgDumpBmp (const char * file, const void * data, int width, int height)
246 unsigned char magic[2];
247 } bmpfile_magic = { {'B', 'M'} };
252 unsigned short creator1;
253 unsigned short creator2;
254 unsigned int bmp_offset;
255 } bmpfile_header = { 0, 0, 0, 0x36 };
259 unsigned int header_sz;
262 unsigned short nplanes;
263 unsigned short bitspp;
264 unsigned int compress_type;
265 unsigned int bmp_bytesz;
268 unsigned int ncolors;
269 unsigned int nimpcolors;
270 } bmp_dib_v3_header_t = { 0x28, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0 };
271 unsigned int * blocks;
273 XDBG_RETURN_VAL_IF_FAIL (file != NULL, FALSE);
274 XDBG_RETURN_VAL_IF_FAIL (data != NULL, FALSE);
275 XDBG_RETURN_VAL_IF_FAIL (width > 0, FALSE);
276 XDBG_RETURN_VAL_IF_FAIL (height > 0, FALSE);
278 FILE * fp = fopen (file, "w+");
279 XDBG_RETURN_VAL_IF_FAIL (fp != NULL, FALSE);
281 bmpfile_header.filesz = sizeof (bmpfile_magic) + sizeof (bmpfile_header) +
282 sizeof (bmp_dib_v3_header_t) + width * height * 3;
283 bmp_dib_v3_header_t.header_sz = sizeof (bmp_dib_v3_header_t);
284 bmp_dib_v3_header_t.width = width;
285 bmp_dib_v3_header_t.height = -height;
286 bmp_dib_v3_header_t.nplanes = 1;
287 bmp_dib_v3_header_t.bmp_bytesz = width * height * 3;
289 fwrite (&bmpfile_magic, sizeof (bmpfile_magic), 1, fp);
290 fwrite (&bmpfile_header, sizeof (bmpfile_header), 1, fp);
291 fwrite (&bmp_dib_v3_header_t, sizeof (bmp_dib_v3_header_t), 1, fp);
293 blocks = (unsigned int*)data;
294 for (i=0; i<height * width; i++)
295 fwrite (&blocks[i], 3, 1, fp);
299 XDBG_TRACE (MXDBG, "%s saved\n", file);
305 _xDbgDumpRaw (const char * file, const void * data, int size)
307 XDBG_RETURN_VAL_IF_FAIL (file != NULL, FALSE);
308 XDBG_RETURN_VAL_IF_FAIL (data != NULL, FALSE);
309 XDBG_RETURN_VAL_IF_FAIL (size > 0, FALSE);
311 FILE * fp = fopen (file, "w+");
312 XDBG_RETURN_VAL_IF_FAIL (fp != NULL, FALSE);
314 unsigned int *blocks = (unsigned int*)data;
315 fwrite (blocks, 1, size, fp);
318 XDBG_TRACE (MXDBG, "%s saved\n", file);
324 xDbgDumpSetType (char *type_str)
326 XDBG_RETURN_VAL_IF_FAIL (type_str != NULL, FALSE);
330 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
332 XDBG_ERROR (MXDBG, "can't set.\n");
336 if (xdbg_dump_info.type_str)
337 free (xdbg_dump_info.type_str);
339 xdbg_dump_info.type_str = strdup (type_str);
340 XDBG_DEBUG (MXDBG, "type_str: %s\n", xdbg_dump_info.type_str);
346 xDbgDumpSetFile (char *file_str)
348 XDBG_RETURN_VAL_IF_FAIL (file_str != NULL, FALSE);
352 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
354 XDBG_ERROR (MXDBG, "can't set.\n");
358 if (xdbg_dump_info.file_str)
359 free (xdbg_dump_info.file_str);
361 xdbg_dump_info.file_str = strdup (file_str);
362 XDBG_DEBUG (MXDBG, "file_str: %s\n", xdbg_dump_info.file_str);
368 xDbgDumpSetCount (char *count_str)
370 XDBG_RETURN_VAL_IF_FAIL (count_str != NULL, FALSE);
374 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
376 XDBG_ERROR (MXDBG, "can't set.\n");
380 if (xdbg_dump_info.count_str)
381 free (xdbg_dump_info.count_str);
383 xdbg_dump_info.count_str = strdup (count_str);
384 XDBG_DEBUG (MXDBG, "count_str: %s\n", xdbg_dump_info.count_str);
390 xDbgDumpSetCrop (char *crop_str)
392 XDBG_RETURN_VAL_IF_FAIL (crop_str != NULL, FALSE);
396 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
398 XDBG_ERROR (MXDBG, "can't set.\n");
402 if (xdbg_dump_info.crop_str)
403 free (xdbg_dump_info.crop_str);
405 xdbg_dump_info.crop_str = strdup (crop_str);
406 XDBG_DEBUG (MXDBG, "crop_str: %s\n", xdbg_dump_info.crop_str);
412 xDbgDumpGetType (void)
414 return xdbg_dump_info.type_str;
418 xDbgDumpGetFile (void)
420 return xdbg_dump_info.file_str;
424 xDbgDumpGetCount (void)
426 return xdbg_dump_info.count_str;
430 xDbgDumpGetCrop (void)
432 return xdbg_dump_info.crop_str;
436 xDbgDumpPrepare (void)
442 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
445 _xDbgDumpSetOptions ();
447 for (i = 0; i < xdbg_dump_info.count; i++)
449 xDbgDumpBuffer *dumpbuf = calloc (1, sizeof (xDbgDumpBuffer));
450 XDBG_GOTO_IF_FAIL (dumpbuf != NULL, fail);
452 xorg_list_add (&dumpbuf->link, &xdbg_dump_info.buffers);
454 dumpbuf->bo_size = xdbg_dump_info.bo_size;
455 if (xdbg_dump_info.func.alloc)
457 dumpbuf->bo = xdbg_dump_info.func.alloc (dumpbuf->bo_size);
458 XDBG_GOTO_IF_FAIL (dumpbuf->bo != NULL, fail);
462 xdbg_dump_info.cursor = &xdbg_dump_info.buffers;
473 xDbgDumpBuffer *cur = NULL, *next = NULL;
477 if (!_xDbgDumpEnsureDir ())
480 xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
488 if (xdbg_dump_info.func.map)
489 ptr = xdbg_dump_info.func.map (cur->bo);
492 XDBG_GOTO_IF_FAIL (ptr != NULL, reset_dump);
494 snprintf (file, sizeof(file), "%s/%s", DUMP_DIR, cur->file);
498 unsigned int *p = (unsigned int*)ptr;
501 /* fill magenta color(#FF00FF) for background */
502 for (j = 0; j < cur->u.a.dump_h; j++)
503 for (i = 0; i < cur->u.a.dump_w ; i++)
505 if (i >= cur->u.a.dump_rect.x && i < (cur->u.a.dump_rect.x + cur->u.a.dump_rect.width))
506 if (j >= cur->u.a.dump_rect.y && j < (cur->u.a.dump_rect.y + cur->u.a.dump_rect.height))
508 p[i + j * cur->u.a.dump_w] = 0xFFFF00FF;
511 _xDbgDumpBmp (file, ptr, cur->u.a.dump_w, cur->u.a.dump_h);
513 if (xdbg_dump_info.file_str && !strcmp (xdbg_dump_info.file_str, "raw"))
515 snprintf (file, sizeof(file), "%s/%s.raw", DUMP_DIR, cur->file);
516 _xDbgDumpRaw (file, ptr, cur->u.a.dump_w*cur->u.a.dump_h*4);
521 _xDbgDumpRaw (file, ptr, cur->u.dump_size);
524 if (xdbg_dump_info.func.unmap)
525 xdbg_dump_info.func.unmap (cur->bo);
529 memset (&cur->u, 0, sizeof (cur->u));
530 cur->is_dirty = FALSE;
538 xDbgDumpBuffer *cur = NULL, *next = NULL;
542 xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
544 if (xdbg_dump_info.func.free)
545 xdbg_dump_info.func.free (cur->bo);
546 xorg_list_del (&cur->link);
550 xdbg_dump_info.cursor = NULL;
552 xdbg_dump_info.type = XDBG_DUMP_TYPE_NONE;
553 xdbg_dump_info.count = 0;
554 if (xdbg_dump_info.crop)
556 free (xdbg_dump_info.crop);
557 xdbg_dump_info.crop = NULL;
560 XDBG_DEBUG (MXDBG, "\n");
564 xDbgDumpSetBufferFunc (xDbgDumpBufferFunc *func, int bo_size)
566 XDBG_RETURN_VAL_IF_FAIL (bo_size > 0, FALSE);
567 XDBG_RETURN_VAL_IF_FAIL (func != NULL, FALSE);
568 XDBG_RETURN_VAL_IF_FAIL (func->alloc != NULL, FALSE);
569 XDBG_RETURN_VAL_IF_FAIL (func->free != NULL, FALSE);
571 XDBG_RETURN_VAL_IF_FAIL (func->unmap != NULL, FALSE);
575 xdbg_dump_info.func = *func;
576 xdbg_dump_info.bo_size = bo_size;
578 XDBG_INFO (MXDBG, "\n");
584 xDbgDumpIsEnable (xDbgDumpType type)
586 return (xdbg_dump_info.type & type) ? TRUE : FALSE;
590 xDbgDumpRaw (void *data, xDbgDumpType type, void *var_buf, const char *file)
592 xDbgDumpBuffer *dumpbuf;
593 struct xorg_list *next_cursor;
595 XDBG_RETURN_IF_FAIL (type > 0);
596 XDBG_RETURN_IF_FAIL (var_buf != NULL);
597 XDBG_RETURN_IF_FAIL (file != NULL);
600 if (xorg_list_is_empty (&xdbg_dump_info.buffers))
602 XDBG_WARNING (MXDBG, "not ready to dump\n");
606 next_cursor = xdbg_dump_info.cursor->next;
607 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
609 if (next_cursor == &xdbg_dump_info.buffers)
611 next_cursor = next_cursor->next;
612 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
615 dumpbuf = xorg_list_entry (next_cursor, xDbgDumpBuffer, link);
616 XDBG_RETURN_IF_FAIL (dumpbuf != NULL);
618 if (xdbg_dump_info.func.dumpRaw)
623 ret = xdbg_dump_info.func.dumpRaw (data, type,
624 var_buf, dumpbuf->bo, dumpbuf->bo_size,
626 XDBG_RETURN_IF_FAIL (ret == TRUE);
627 XDBG_RETURN_IF_FAIL (dump_size > 0);
628 XDBG_RETURN_IF_FAIL (dump_size <= dumpbuf->bo_size);
630 snprintf (dumpbuf->file, sizeof (dumpbuf->file), "%.3f_%s", GetTimeInMillis()/1000.0, file);
631 dumpbuf->u.dump_size = dump_size;
632 dumpbuf->is_dirty = TRUE;
633 dumpbuf->is_bmp = FALSE;
635 xdbg_dump_info.cursor = next_cursor;
638 XDBG_DEBUG (MXDBG, "type:0x%x file: %s\n", type, file);
642 xDbgDumpBmp (void *data, xDbgDumpType type, void *var_buf, const char *file)
644 xDbgDumpBuffer *dumpbuf;
645 struct xorg_list *next_cursor;
647 XDBG_RETURN_IF_FAIL (type > 0);
648 XDBG_RETURN_IF_FAIL (var_buf != NULL);
649 XDBG_RETURN_IF_FAIL (file != NULL);
652 if (xorg_list_is_empty (&xdbg_dump_info.buffers))
654 XDBG_WARNING (MXDBG, "not ready to dump\n");
658 next_cursor = xdbg_dump_info.cursor->next;
659 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
661 if (next_cursor == &xdbg_dump_info.buffers)
663 next_cursor = next_cursor->next;
664 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
667 dumpbuf = xorg_list_entry (next_cursor, xDbgDumpBuffer, link);
668 XDBG_RETURN_IF_FAIL (dumpbuf != NULL);
670 if (xdbg_dump_info.func.dumpBmp)
673 int dump_w = 0, dump_h = 0;
674 xRectangle dump_rect = {0,};
676 ret = xdbg_dump_info.func.dumpBmp (data, type,
677 var_buf, dumpbuf->bo, dumpbuf->bo_size,
678 &dump_w, &dump_h, &dump_rect);
679 XDBG_RETURN_IF_FAIL (ret == TRUE);
680 XDBG_RETURN_IF_FAIL (dump_w > 0);
681 XDBG_RETURN_IF_FAIL (dump_h > 0);
682 XDBG_RETURN_IF_FAIL (dump_rect.width > 0);
683 XDBG_RETURN_IF_FAIL (dump_rect.height > 0);
685 snprintf (dumpbuf->file, sizeof (dumpbuf->file), "%.3f_%s", GetTimeInMillis()/1000.0, file);
686 dumpbuf->u.a.dump_w = dump_w;
687 dumpbuf->u.a.dump_h = dump_h;
688 dumpbuf->u.a.dump_rect = dump_rect;
689 dumpbuf->is_dirty = TRUE;
690 dumpbuf->is_bmp = TRUE;
692 xdbg_dump_info.cursor = next_cursor;
695 XDBG_DEBUG (MXDBG, "type:0x%x file: %s\n", type, file);
699 xDbgDumpReplaceBuffer (void *old_dump_buf, void *new_dump_buf, int new_dump_buf_size)
701 xDbgDumpBuffer *cur = NULL, *next = NULL;
703 XDBG_RETURN_VAL_IF_FAIL (new_dump_buf != NULL, FALSE);
704 XDBG_RETURN_VAL_IF_FAIL (new_dump_buf_size > 0, FALSE);
708 xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
710 if (cur->bo == old_dump_buf)
712 if (xdbg_dump_info.func.free)
713 xdbg_dump_info.func.free (cur->bo);
715 cur->bo = new_dump_buf;
716 cur->bo_size = new_dump_buf_size;