tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / lib / xdbg_dump.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8          Sangjin LEE <lsj119@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
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:
17
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
20 of the Software.
21
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.
29
30 **************************************************************************/
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <fcntl.h>
37 #include <dirent.h>
38 #include <sys/stat.h>
39
40 #include "xdbg_log.h"
41 #include "xdbg_dump.h"
42 #include "xdbg_dump_module.h"
43 #include <list.h>
44
45 #ifndef API
46 #define API __attribute__ ((visibility("default")))
47 #endif
48
49 #define DUMP_BUFCNT  50
50 #define DUMP_DIR "/tmp/xdump"
51 #define DUMP_SCALE_RATIO  2
52
53 typedef struct
54 {
55     int    index;
56
57     void  *bo;      /* buffer object */
58     int    bo_size;
59
60     char   file[128];
61     union {
62         struct {
63             int dump_w;
64             int dump_h;
65             xRectangle dump_rect;
66         } a;
67         int dump_size;
68     } u;
69     Bool   is_dirty;
70     Bool   is_bmp;
71
72     struct xorg_list link;
73 } xDbgDumpBuffer;
74
75 typedef struct
76 {
77     Bool init;
78
79     char *type_str;
80     char *file_str;
81     char *count_str;
82     char *crop_str;
83
84     xDbgDumpBufferFunc func;
85     int bo_size;
86
87     struct xorg_list *cursor;
88     struct xorg_list  buffers;
89
90     int   type;
91     int   count;
92     xRectangle *crop;
93 } xDbgDumpInfo;
94
95 static xDbgDumpInfo xdbg_dump_info;
96
97 static int
98 _parse_int (char *s)
99 {
100     char *fmt = "%lu";
101     int retval = 0;
102     int thesign = 1;
103
104     if (s && s[0])
105     {
106         char temp[12];
107         snprintf (temp, sizeof (temp), "%s", s);
108         s = temp;
109
110         if (s[0] == '-')
111             s++, thesign = -1;
112         if (s[0] == '0')
113             s++, fmt = "%o";
114         if (s[0] == 'x' || s[0] == 'X')
115             s++, fmt = "%x";
116         (void) sscanf (s, fmt, &retval);
117     }
118     return (thesign * retval);
119 }
120
121 static Bool
122 _xDbgDumpEnsureDir (void)
123 {
124     char *dir = DUMP_DIR;
125     DIR *dp;
126     int ret;
127
128     if (!(dp = opendir (dir)))
129     {
130         ret = mkdir (dir, 0755);
131         if (ret < 0)
132         {
133             XDBG_ERROR (MXDBG, "fail: mkdir '%s'\n", DUMP_DIR);
134             return FALSE;
135         }
136     }
137     else
138         closedir (dp);
139
140     return TRUE;
141 }
142
143 static void
144 _xDbgDumpSetOptions (void)
145 {
146     char options[256];
147     int tempsize = sizeof (options);
148     char *reply = options;
149     int *len = &tempsize;
150
151     options[0] = '\0';
152
153     /* type */
154     if (xdbg_dump_info.type_str)
155     {
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;
165         else
166             xdbg_dump_info.type = _parse_int (c);
167     }
168     else
169         xdbg_dump_info.type = XDBG_DUMP_TYPE_UI;
170     XDBG_REPLY ("type(0x%x) ", xdbg_dump_info.type);
171
172     /* count */
173     if (xdbg_dump_info.count_str)
174         xdbg_dump_info.count = atoi (xdbg_dump_info.count_str);
175     else
176         xdbg_dump_info.count = DUMP_BUFCNT;
177     XDBG_REPLY ("count(%d) ", xdbg_dump_info.count);
178
179     /* file */
180     if (xdbg_dump_info.file_str)
181         XDBG_REPLY ("file(%s) ", xdbg_dump_info.file_str);
182
183     /* crop */
184     if (xdbg_dump_info.crop_str)
185     {
186         int i;
187         char temp[64];
188         char *c;
189         int nums[4];
190         char *tokp;
191
192         if (xdbg_dump_info.crop)
193         {
194             free (xdbg_dump_info.crop);
195             xdbg_dump_info.crop = NULL;
196         }
197
198         snprintf (temp, sizeof (temp), "%s", xdbg_dump_info.crop_str);
199
200         c = strtok_r (temp, ",", &tokp);
201         i = 0;
202         while (c != NULL)
203         {
204             nums[i++] = atoi(c);
205             c = strtok_r (NULL, ",", &tokp);
206             if (i == 4)
207                 break;
208         }
209
210         if (i == 4)
211         {
212             xdbg_dump_info.crop = calloc (1, sizeof (xRectangle));
213             XDBG_RETURN_IF_FAIL (xdbg_dump_info.crop != NULL);
214
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];
219
220             XDBG_REPLY ("crop(%d,%d %dx%d) ",
221                         nums[0], nums[1], nums[2], nums[3]);
222         }
223     }
224
225     XDBG_DEBUG (MXDBG, "%s\n", options);
226 }
227
228 static void
229 _xDbgDumpInit (void)
230 {
231     if (xdbg_dump_info.init)
232         return;
233
234     xdbg_dump_info.init = TRUE;
235     xdbg_dump_info.cursor = NULL;
236     xorg_list_init (&xdbg_dump_info.buffers);
237 }
238
239 static int
240 _xDbgDumpBmp (const char * file, const void * data, int width, int height)
241 {
242     int i;
243
244     struct
245     {
246         unsigned char magic[2];
247     } bmpfile_magic = { {'B', 'M'} };
248
249     struct
250     {
251         unsigned int filesz;
252         unsigned short creator1;
253         unsigned short creator2;
254         unsigned int bmp_offset;
255     } bmpfile_header = { 0, 0, 0, 0x36 };
256
257     struct
258     {
259         unsigned int header_sz;
260         unsigned int width;
261         unsigned int height;
262         unsigned short nplanes;
263         unsigned short bitspp;
264         unsigned int compress_type;
265         unsigned int bmp_bytesz;
266         unsigned int hres;
267         unsigned int vres;
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;
272
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);
277
278     FILE * fp = fopen (file, "w+");
279     XDBG_RETURN_VAL_IF_FAIL (fp != NULL, FALSE);
280
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;
288
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);
292
293     blocks = (unsigned int*)data;
294     for (i=0; i<height * width; i++)
295         fwrite (&blocks[i], 3, 1, fp);
296
297     fclose (fp);
298
299     XDBG_TRACE (MXDBG, "%s saved\n", file);
300
301     return TRUE;
302 }
303
304 static Bool
305 _xDbgDumpRaw (const char * file, const void * data, int size)
306 {
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);
310
311     FILE * fp = fopen (file, "w+");
312     XDBG_RETURN_VAL_IF_FAIL (fp != NULL, FALSE);
313
314     unsigned int *blocks = (unsigned int*)data;
315     fwrite (blocks, 1, size, fp);
316     fclose (fp);
317
318     XDBG_TRACE (MXDBG, "%s saved\n", file);
319
320     return TRUE;
321 }
322
323 API Bool
324 xDbgDumpSetType (char *type_str)
325 {
326     XDBG_RETURN_VAL_IF_FAIL (type_str != NULL, FALSE);
327
328     _xDbgDumpInit ();
329
330     if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
331     {
332         XDBG_ERROR (MXDBG, "can't set.\n");
333         return FALSE;
334     }
335
336     if (xdbg_dump_info.type_str)
337         free (xdbg_dump_info.type_str);
338
339     xdbg_dump_info.type_str = strdup (type_str);
340     XDBG_DEBUG (MXDBG, "type_str: %s\n", xdbg_dump_info.type_str);
341
342     return TRUE;
343 }
344
345 API Bool
346 xDbgDumpSetFile (char *file_str)
347 {
348     XDBG_RETURN_VAL_IF_FAIL (file_str != NULL, FALSE);
349
350     _xDbgDumpInit ();
351
352     if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
353     {
354         XDBG_ERROR (MXDBG, "can't set.\n");
355         return FALSE;
356     }
357
358     if (xdbg_dump_info.file_str)
359         free (xdbg_dump_info.file_str);
360
361     xdbg_dump_info.file_str = strdup (file_str);
362     XDBG_DEBUG (MXDBG, "file_str: %s\n", xdbg_dump_info.file_str);
363
364     return TRUE;
365 }
366
367 API Bool
368 xDbgDumpSetCount (char *count_str)
369 {
370     XDBG_RETURN_VAL_IF_FAIL (count_str != NULL, FALSE);
371
372     _xDbgDumpInit ();
373
374     if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
375     {
376         XDBG_ERROR (MXDBG, "can't set.\n");
377         return FALSE;
378     }
379
380     if (xdbg_dump_info.count_str)
381         free (xdbg_dump_info.count_str);
382
383     xdbg_dump_info.count_str = strdup (count_str);
384     XDBG_DEBUG (MXDBG, "count_str: %s\n", xdbg_dump_info.count_str);
385
386     return TRUE;
387 }
388
389 API Bool
390 xDbgDumpSetCrop (char *crop_str)
391 {
392     XDBG_RETURN_VAL_IF_FAIL (crop_str != NULL, FALSE);
393
394     _xDbgDumpInit ();
395
396     if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
397     {
398         XDBG_ERROR (MXDBG, "can't set.\n");
399         return FALSE;
400     }
401
402     if (xdbg_dump_info.crop_str)
403         free (xdbg_dump_info.crop_str);
404
405     xdbg_dump_info.crop_str = strdup (crop_str);
406     XDBG_DEBUG (MXDBG, "crop_str: %s\n", xdbg_dump_info.crop_str);
407
408     return TRUE;
409 }
410
411 API char*
412 xDbgDumpGetType (void)
413 {
414     return xdbg_dump_info.type_str;
415 }
416
417 API char*
418 xDbgDumpGetFile (void)
419 {
420     return xdbg_dump_info.file_str;
421 }
422
423 API char*
424 xDbgDumpGetCount (void)
425 {
426     return xdbg_dump_info.count_str;
427 }
428
429 API char*
430 xDbgDumpGetCrop (void)
431 {
432     return xdbg_dump_info.crop_str;
433 }
434
435 API Bool
436 xDbgDumpPrepare (void)
437 {
438     int i;
439
440     _xDbgDumpInit ();
441
442     if (!xorg_list_is_empty (&xdbg_dump_info.buffers))
443         return TRUE;
444
445     _xDbgDumpSetOptions ();
446
447     for (i = 0; i < xdbg_dump_info.count; i++)
448     {
449         xDbgDumpBuffer *dumpbuf = calloc (1, sizeof (xDbgDumpBuffer));
450         XDBG_GOTO_IF_FAIL (dumpbuf != NULL, fail);
451
452         xorg_list_add (&dumpbuf->link, &xdbg_dump_info.buffers);
453         dumpbuf->index = i;
454         dumpbuf->bo_size = xdbg_dump_info.bo_size;
455         if (xdbg_dump_info.func.alloc)
456         {
457             dumpbuf->bo = xdbg_dump_info.func.alloc (dumpbuf->bo_size);
458             XDBG_GOTO_IF_FAIL (dumpbuf->bo != NULL, fail);
459         }
460     }
461
462     xdbg_dump_info.cursor = &xdbg_dump_info.buffers;
463
464     return TRUE;
465 fail:
466     xDbgDumpClear ();
467     return FALSE;
468 }
469
470 API void
471 xDbgDumpSave (void)
472 {
473     xDbgDumpBuffer *cur = NULL, *next = NULL;
474
475     _xDbgDumpInit ();
476
477     if (!_xDbgDumpEnsureDir ())
478         return;
479
480     xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
481     {
482         char file[128];
483         void *ptr;
484
485         if (!cur->is_dirty)
486             continue;
487
488         if (xdbg_dump_info.func.map)
489             ptr = xdbg_dump_info.func.map (cur->bo);
490         else
491             ptr = cur->bo;
492         XDBG_GOTO_IF_FAIL (ptr != NULL, reset_dump);
493
494         snprintf (file, sizeof(file), "%s/%s", DUMP_DIR, cur->file);
495
496         if (cur->is_bmp)
497         {
498             unsigned int *p = (unsigned int*)ptr;
499             int i, j;
500
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++)
504                 {
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))
507                             continue;
508                     p[i + j * cur->u.a.dump_w] = 0xFFFF00FF;
509                 }
510
511             _xDbgDumpBmp (file, ptr, cur->u.a.dump_w, cur->u.a.dump_h);
512
513             if (xdbg_dump_info.file_str && !strcmp (xdbg_dump_info.file_str, "raw"))
514             {
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);
517             }
518         }
519         else
520         {
521             _xDbgDumpRaw (file, ptr, cur->u.dump_size);
522         }
523
524         if (xdbg_dump_info.func.unmap)
525             xdbg_dump_info.func.unmap (cur->bo);
526
527 reset_dump:
528         cur->file[0] = '\0';
529         memset (&cur->u, 0, sizeof (cur->u));
530         cur->is_dirty = FALSE;
531         cur->is_bmp = FALSE;
532     }
533 }
534
535 API void
536 xDbgDumpClear (void)
537 {
538     xDbgDumpBuffer *cur = NULL, *next = NULL;
539
540     _xDbgDumpInit ();
541
542     xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
543     {
544         if (xdbg_dump_info.func.free)
545             xdbg_dump_info.func.free (cur->bo);
546         xorg_list_del (&cur->link);
547         free (cur);        
548     }
549
550     xdbg_dump_info.cursor = NULL;
551
552     xdbg_dump_info.type = XDBG_DUMP_TYPE_NONE;
553     xdbg_dump_info.count = 0;
554     if (xdbg_dump_info.crop)
555     {
556         free (xdbg_dump_info.crop);
557         xdbg_dump_info.crop = NULL;
558     }
559
560     XDBG_DEBUG (MXDBG, "\n");
561 }
562
563 API Bool
564 xDbgDumpSetBufferFunc (xDbgDumpBufferFunc *func, int bo_size)
565 {
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);
570     if (func->map)
571         XDBG_RETURN_VAL_IF_FAIL (func->unmap != NULL, FALSE);
572
573     _xDbgDumpInit ();
574
575     xdbg_dump_info.func = *func;
576     xdbg_dump_info.bo_size = bo_size;
577
578     XDBG_INFO (MXDBG, "\n");
579
580     return TRUE;
581 }
582
583 API Bool
584 xDbgDumpIsEnable (xDbgDumpType type)
585 {
586     return (xdbg_dump_info.type & type) ? TRUE : FALSE;
587 }
588
589 API void
590 xDbgDumpRaw (void *data, xDbgDumpType type, void *var_buf, const char *file)
591 {
592     xDbgDumpBuffer *dumpbuf;
593     struct xorg_list *next_cursor;
594
595     XDBG_RETURN_IF_FAIL (type > 0);
596     XDBG_RETURN_IF_FAIL (var_buf != NULL);
597     XDBG_RETURN_IF_FAIL (file != NULL);
598
599     _xDbgDumpInit ();
600     if (xorg_list_is_empty (&xdbg_dump_info.buffers))
601     {
602         XDBG_WARNING (MXDBG, "not ready to dump\n");
603         return;
604     }
605
606     next_cursor = xdbg_dump_info.cursor->next;
607     XDBG_RETURN_IF_FAIL (next_cursor != NULL);
608
609     if (next_cursor == &xdbg_dump_info.buffers)
610     {
611         next_cursor = next_cursor->next;
612         XDBG_RETURN_IF_FAIL (next_cursor != NULL);
613     }
614
615     dumpbuf = xorg_list_entry (next_cursor, xDbgDumpBuffer, link);
616     XDBG_RETURN_IF_FAIL (dumpbuf != NULL);
617
618     if (xdbg_dump_info.func.dumpRaw)
619     {
620         Bool ret;
621         int dump_size = 0;
622
623         ret = xdbg_dump_info.func.dumpRaw (data, type,
624                                            var_buf, dumpbuf->bo, dumpbuf->bo_size,
625                                            &dump_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);
629
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;
634
635         xdbg_dump_info.cursor = next_cursor;
636     }
637
638     XDBG_DEBUG (MXDBG, "type:0x%x file: %s\n", type, file);
639 }
640
641 API void
642 xDbgDumpBmp (void *data, xDbgDumpType type, void *var_buf, const char *file)
643 {
644     xDbgDumpBuffer *dumpbuf;
645     struct xorg_list *next_cursor;
646
647     XDBG_RETURN_IF_FAIL (type > 0);
648     XDBG_RETURN_IF_FAIL (var_buf != NULL);
649     XDBG_RETURN_IF_FAIL (file != NULL);
650
651     _xDbgDumpInit ();
652     if (xorg_list_is_empty (&xdbg_dump_info.buffers))
653     {
654         XDBG_WARNING (MXDBG, "not ready to dump\n");
655         return;
656     }
657
658     next_cursor = xdbg_dump_info.cursor->next;
659     XDBG_RETURN_IF_FAIL (next_cursor != NULL);
660
661     if (next_cursor == &xdbg_dump_info.buffers)
662     {
663         next_cursor = next_cursor->next;
664         XDBG_RETURN_IF_FAIL (next_cursor != NULL);
665     }
666
667     dumpbuf = xorg_list_entry (next_cursor, xDbgDumpBuffer, link);
668     XDBG_RETURN_IF_FAIL (dumpbuf != NULL);
669
670     if (xdbg_dump_info.func.dumpBmp)
671     {
672         Bool ret;
673         int dump_w = 0, dump_h = 0;
674         xRectangle dump_rect = {0,};
675
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);
684
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;
691
692         xdbg_dump_info.cursor = next_cursor;
693     }
694
695     XDBG_DEBUG (MXDBG, "type:0x%x file: %s\n", type, file);
696 }
697
698 API Bool
699 xDbgDumpReplaceBuffer (void *old_dump_buf, void *new_dump_buf, int new_dump_buf_size)
700 {
701     xDbgDumpBuffer *cur = NULL, *next = NULL;
702
703     XDBG_RETURN_VAL_IF_FAIL (new_dump_buf != NULL, FALSE);
704     XDBG_RETURN_VAL_IF_FAIL (new_dump_buf_size > 0, FALSE);
705
706     _xDbgDumpInit ();
707
708     xorg_list_for_each_entry_safe (cur, next, &xdbg_dump_info.buffers, link)
709     {
710         if (cur->bo == old_dump_buf)
711         {
712             if (xdbg_dump_info.func.free)
713                 xdbg_dump_info.func.free (cur->bo);
714
715             cur->bo = new_dump_buf;
716             cur->bo_size = new_dump_buf_size;
717             return TRUE;
718         }
719     }
720
721     return FALSE;
722 }