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)
191 if (xdbg_dump_info.crop)
193 free (xdbg_dump_info.crop);
194 xdbg_dump_info.crop = NULL;
197 snprintf (temp, sizeof (temp), "%s", xdbg_dump_info.crop_str);
199 c = strtok (temp, ",");
204 c = strtok (NULL, ",");
211 xdbg_dump_info.crop = calloc (1, sizeof (xRectangle));
212 XDBG_RETURN_IF_FAIL (xdbg_dump_info.crop != NULL);
214 xdbg_dump_info.crop->x = nums[0];
215 xdbg_dump_info.crop->y = nums[1];
216 xdbg_dump_info.crop->width = nums[2];
217 xdbg_dump_info.crop->height = nums[3];
219 XDBG_REPLY ("crop(%d,%d %dx%d) ",
220 nums[0], nums[1], nums[2], nums[3]);
224 XDBG_DEBUG (MXDBG, "%s\n", options);
230 if (xdbg_dump_info.init)
233 xdbg_dump_info.init = TRUE;
234 xdbg_dump_info.cursor = NULL;
235 xorg_list_init (&xdbg_dump_info.buffers);
239 _xDbgDumpBmp (const char * file, const void * data, int width, int height)
245 unsigned char magic[2];
246 } bmpfile_magic = { {'B', 'M'} };
251 unsigned short creator1;
252 unsigned short creator2;
253 unsigned int bmp_offset;
254 } bmpfile_header = { 0, 0, 0, 0x36 };
258 unsigned int header_sz;
261 unsigned short nplanes;
262 unsigned short bitspp;
263 unsigned int compress_type;
264 unsigned int bmp_bytesz;
267 unsigned int ncolors;
268 unsigned int nimpcolors;
269 } bmp_dib_v3_header_t = { 0x28, 0, 0, 1, 24, 0, 0, 0, 0, 0, 0 };
270 unsigned int * blocks;
272 XDBG_RETURN_VAL_IF_FAIL (file != NULL, FALSE);
273 XDBG_RETURN_VAL_IF_FAIL (data != NULL, FALSE);
274 XDBG_RETURN_VAL_IF_FAIL (width > 0, FALSE);
275 XDBG_RETURN_VAL_IF_FAIL (height > 0, FALSE);
277 FILE * fp = fopen (file, "w+");
278 XDBG_RETURN_VAL_IF_FAIL (fp != NULL, FALSE);
280 bmpfile_header.filesz = sizeof (bmpfile_magic) + sizeof (bmpfile_header) +
281 sizeof (bmp_dib_v3_header_t) + width * height * 3;
282 bmp_dib_v3_header_t.header_sz = sizeof (bmp_dib_v3_header_t);
283 bmp_dib_v3_header_t.width = width;
284 bmp_dib_v3_header_t.height = -height;
285 bmp_dib_v3_header_t.nplanes = 1;
286 bmp_dib_v3_header_t.bmp_bytesz = width * height * 3;
288 fwrite (&bmpfile_magic, sizeof (bmpfile_magic), 1, fp);
289 fwrite (&bmpfile_header, sizeof (bmpfile_header), 1, fp);
290 fwrite (&bmp_dib_v3_header_t, sizeof (bmp_dib_v3_header_t), 1, fp);
292 blocks = (unsigned int*)data;
293 for (i=0; i<height * width; i++)
294 fwrite (&blocks[i], 3, 1, fp);
298 XDBG_TRACE (MXDBG, "%s saved\n", file);
304 _xDbgDumpRaw (const char * file, const void * data, int size)
306 XDBG_RETURN_VAL_IF_FAIL (file != NULL, FALSE);
307 XDBG_RETURN_VAL_IF_FAIL (data != NULL, FALSE);
308 XDBG_RETURN_VAL_IF_FAIL (size > 0, FALSE);
310 FILE * fp = fopen (file, "w+");
311 XDBG_RETURN_VAL_IF_FAIL (fp != NULL, FALSE);
313 unsigned int *blocks = (unsigned int*)data;
314 fwrite (blocks, 1, size, fp);
317 XDBG_TRACE (MXDBG, "%s saved\n", file);
323 xDbgDumpSetType (char *type_str)
325 XDBG_RETURN_VAL_IF_FAIL (type_str != NULL, FALSE);
329 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
331 XDBG_ERROR (MXDBG, "can't set.\n");
335 if (xdbg_dump_info.type_str)
336 free (xdbg_dump_info.type_str);
338 xdbg_dump_info.type_str = strdup (type_str);
339 XDBG_DEBUG (MXDBG, "type_str: %s\n", xdbg_dump_info.type_str);
345 xDbgDumpSetFile (char *file_str)
347 XDBG_RETURN_VAL_IF_FAIL (file_str != NULL, FALSE);
351 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
353 XDBG_ERROR (MXDBG, "can't set.\n");
357 if (xdbg_dump_info.file_str)
358 free (xdbg_dump_info.file_str);
360 xdbg_dump_info.file_str = strdup (file_str);
361 XDBG_DEBUG (MXDBG, "file_str: %s\n", xdbg_dump_info.file_str);
367 xDbgDumpSetCount (char *count_str)
369 XDBG_RETURN_VAL_IF_FAIL (count_str != NULL, FALSE);
373 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
375 XDBG_ERROR (MXDBG, "can't set.\n");
379 if (xdbg_dump_info.count_str)
380 free (xdbg_dump_info.count_str);
382 xdbg_dump_info.count_str = strdup (count_str);
383 XDBG_DEBUG (MXDBG, "count_str: %s\n", xdbg_dump_info.count_str);
389 xDbgDumpSetCrop (char *crop_str)
391 XDBG_RETURN_VAL_IF_FAIL (crop_str != NULL, FALSE);
395 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
397 XDBG_ERROR (MXDBG, "can't set.\n");
401 if (xdbg_dump_info.crop_str)
402 free (xdbg_dump_info.crop_str);
404 xdbg_dump_info.crop_str = strdup (crop_str);
405 XDBG_DEBUG (MXDBG, "crop_str: %s\n", xdbg_dump_info.crop_str);
411 xDbgDumpGetType (void)
413 return xdbg_dump_info.type_str;
417 xDbgDumpGetFile (void)
419 return xdbg_dump_info.file_str;
423 xDbgDumpGetCount (void)
425 return xdbg_dump_info.count_str;
429 xDbgDumpGetCrop (void)
431 return xdbg_dump_info.crop_str;
435 xDbgDumpPrepare (void)
441 if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
444 _xDbgDumpSetOptions ();
446 for (i = 0; i < xdbg_dump_info.count; i++)
448 xDbgDumpBuffer *dumpbuf = calloc (1, sizeof (xDbgDumpBuffer));
449 XDBG_GOTO_IF_FAIL (dumpbuf != NULL, fail);
451 xorg_list_add (&dumpbuf->link, &xdbg_dump_info.buffers);
453 dumpbuf->bo_size = xdbg_dump_info.bo_size;
454 if (xdbg_dump_info.func.alloc)
456 dumpbuf->bo = xdbg_dump_info.func.alloc (dumpbuf->bo_size);
457 XDBG_GOTO_IF_FAIL (dumpbuf->bo != NULL, fail);
461 xdbg_dump_info.cursor = &xdbg_dump_info.buffers;
472 xDbgDumpBuffer *cur = NULL, *next = NULL;
476 if (!_xDbgDumpEnsureDir ())
479 xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
487 if (xdbg_dump_info.func.map)
488 ptr = xdbg_dump_info.func.map (cur->bo);
491 XDBG_GOTO_IF_FAIL (ptr != NULL, reset_dump);
493 snprintf (file, sizeof(file), "%s/%s", DUMP_DIR, cur->file);
497 unsigned int *p = (unsigned int*)ptr;
500 /* fill magenta color(#FF00FF) for background */
501 for (j = 0; j < cur->u.a.dump_h; j++)
502 for (i = 0; i < cur->u.a.dump_w ; i++)
504 if (i >= cur->u.a.dump_rect.x && i < (cur->u.a.dump_rect.x + cur->u.a.dump_rect.width))
505 if (j >= cur->u.a.dump_rect.y && j < (cur->u.a.dump_rect.y + cur->u.a.dump_rect.height))
507 p[i + j * cur->u.a.dump_w] = 0xFFFF00FF;
510 _xDbgDumpBmp (file, ptr, cur->u.a.dump_w, cur->u.a.dump_h);
512 if (xdbg_dump_info.file_str && !strcmp (xdbg_dump_info.file_str, "raw"))
514 snprintf (file, sizeof(file), "%s/%s.raw", DUMP_DIR, cur->file);
515 _xDbgDumpRaw (file, ptr, cur->u.a.dump_w*cur->u.a.dump_h*4);
520 _xDbgDumpRaw (file, ptr, cur->u.dump_size);
523 if (xdbg_dump_info.func.unmap)
524 xdbg_dump_info.func.unmap (cur->bo);
528 memset (&cur->u, 0, sizeof (cur->u));
529 cur->is_dirty = FALSE;
537 xDbgDumpBuffer *cur = NULL, *next = NULL;
541 xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
543 if (xdbg_dump_info.func.free)
544 xdbg_dump_info.func.free (cur->bo);
545 xorg_list_del (&cur->link);
549 xdbg_dump_info.cursor = NULL;
551 xdbg_dump_info.type = XDBG_DUMP_TYPE_NONE;
552 xdbg_dump_info.count = 0;
553 if (xdbg_dump_info.crop)
555 free (xdbg_dump_info.crop);
556 xdbg_dump_info.crop = NULL;
559 XDBG_DEBUG (MXDBG, "\n");
563 xDbgDumpSetBufferFunc (xDbgDumpBufferFunc *func, int bo_size)
565 XDBG_RETURN_VAL_IF_FAIL (bo_size > 0, FALSE);
566 XDBG_RETURN_VAL_IF_FAIL (func != NULL, FALSE);
567 XDBG_RETURN_VAL_IF_FAIL (func->alloc != NULL, FALSE);
568 XDBG_RETURN_VAL_IF_FAIL (func->free != NULL, FALSE);
570 XDBG_RETURN_VAL_IF_FAIL (func->unmap != NULL, FALSE);
574 xdbg_dump_info.func = *func;
575 xdbg_dump_info.bo_size = bo_size;
577 XDBG_INFO (MXDBG, "\n");
583 xDbgDumpIsEnable (xDbgDumpType type)
585 return (xdbg_dump_info.type & type) ? TRUE : FALSE;
589 xDbgDumpRaw (void *data, xDbgDumpType type, void *var_buf, const char *file)
591 xDbgDumpBuffer *dumpbuf;
592 struct xorg_list *next_cursor;
594 XDBG_RETURN_IF_FAIL (type > 0);
595 XDBG_RETURN_IF_FAIL (var_buf != NULL);
596 XDBG_RETURN_IF_FAIL (file != NULL);
599 if (xorg_list_is_empty (&xdbg_dump_info.buffers))
601 XDBG_WARNING (MXDBG, "not ready to dump\n");
605 next_cursor = xdbg_dump_info.cursor->next;
606 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
608 if (next_cursor == &xdbg_dump_info.buffers)
610 next_cursor = next_cursor->next;
611 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
614 dumpbuf = xorg_list_entry (next_cursor, xDbgDumpBuffer, link);
615 XDBG_RETURN_IF_FAIL (dumpbuf != NULL);
617 if (xdbg_dump_info.func.dumpRaw)
622 ret = xdbg_dump_info.func.dumpRaw (data, type,
623 var_buf, dumpbuf->bo, dumpbuf->bo_size,
625 XDBG_RETURN_IF_FAIL (ret == TRUE);
626 XDBG_RETURN_IF_FAIL (dump_size > 0);
627 XDBG_RETURN_IF_FAIL (dump_size <= dumpbuf->bo_size);
629 snprintf (dumpbuf->file, sizeof (dumpbuf->file), "%.3f_%s", GetTimeInMillis()/1000.0, file);
630 dumpbuf->u.dump_size = dump_size;
631 dumpbuf->is_dirty = TRUE;
632 dumpbuf->is_bmp = FALSE;
634 xdbg_dump_info.cursor = next_cursor;
637 XDBG_DEBUG (MXDBG, "type:0x%x file: %s\n", type, file);
641 xDbgDumpBmp (void *data, xDbgDumpType type, void *var_buf, const char *file)
643 xDbgDumpBuffer *dumpbuf;
644 struct xorg_list *next_cursor;
646 XDBG_RETURN_IF_FAIL (type > 0);
647 XDBG_RETURN_IF_FAIL (var_buf != NULL);
648 XDBG_RETURN_IF_FAIL (file != NULL);
651 if (xorg_list_is_empty (&xdbg_dump_info.buffers))
653 XDBG_WARNING (MXDBG, "not ready to dump\n");
657 next_cursor = xdbg_dump_info.cursor->next;
658 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
660 if (next_cursor == &xdbg_dump_info.buffers)
662 next_cursor = next_cursor->next;
663 XDBG_RETURN_IF_FAIL (next_cursor != NULL);
666 dumpbuf = xorg_list_entry (next_cursor, xDbgDumpBuffer, link);
667 XDBG_RETURN_IF_FAIL (dumpbuf != NULL);
669 if (xdbg_dump_info.func.dumpBmp)
672 int dump_w = 0, dump_h = 0;
673 xRectangle dump_rect = {0,};
675 ret = xdbg_dump_info.func.dumpBmp (data, type,
676 var_buf, dumpbuf->bo, dumpbuf->bo_size,
677 &dump_w, &dump_h, &dump_rect);
678 XDBG_RETURN_IF_FAIL (ret == TRUE);
679 XDBG_RETURN_IF_FAIL (dump_w > 0);
680 XDBG_RETURN_IF_FAIL (dump_h > 0);
681 XDBG_RETURN_IF_FAIL (dump_rect.width > 0);
682 XDBG_RETURN_IF_FAIL (dump_rect.height > 0);
684 snprintf (dumpbuf->file, sizeof (dumpbuf->file), "%.3f_%s", GetTimeInMillis()/1000.0, file);
685 dumpbuf->u.a.dump_w = dump_w;
686 dumpbuf->u.a.dump_h = dump_h;
687 dumpbuf->u.a.dump_rect = dump_rect;
688 dumpbuf->is_dirty = TRUE;
689 dumpbuf->is_bmp = TRUE;
691 xdbg_dump_info.cursor = next_cursor;
694 XDBG_DEBUG (MXDBG, "type:0x%x file: %s\n", type, file);
698 xDbgDumpReplaceBuffer (void *old_dump_buf, void *new_dump_buf, int new_dump_buf_size)
700 xDbgDumpBuffer *cur = NULL, *next = NULL;
702 XDBG_RETURN_VAL_IF_FAIL (new_dump_buf != NULL, FALSE);
703 XDBG_RETURN_VAL_IF_FAIL (new_dump_buf_size > 0, FALSE);
707 xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
709 if (cur->bo == old_dump_buf)
711 if (xdbg_dump_info.func.free)
712 xdbg_dump_info.func.free (cur->bo);
714 cur->bo = new_dump_buf;
715 cur->bo_size = new_dump_buf_size;