tizen 2.4 release
[adaptation/xorg/driver/xserver-xorg-module-xdbg.git] / lib / xdbg_log_plist.c
1 /**************************************************************************
2
3 xdbg
4
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
6
7 Contact: SooChan Lim <sc1.lim@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 <stdio.h>
37 #include "xorg-server.h"
38 #include "xf86.h"
39 #include <scrnintstr.h>
40 #include <resource.h>
41 #include <windowstr.h>
42 #include <pixmap.h>
43 #include <list.h>
44 #include "xdbg.h"
45 #include "xdbg_log_int.h"
46 #include "xdbg_types.h"
47 #include "xdbg_log_plist.h"
48
49 /* for debug message */
50 #define MMEM    XDBG_M('M','E','M',0)
51
52 #ifndef API
53 #define API __attribute__ ((visibility("default")))
54 #endif
55
56 /*=========================================================================*/
57 /* trace the usage of the pixmaps in xserver                               */
58 /*=========================================================================*/
59
60 #define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
61 #define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
62 #define MAX_HISTORY  10
63
64 typedef struct {
65     PixmapPtr pPixmap;
66     unsigned int size;
67     unsigned int refs;
68     char *hint;
69     XID refHistorys[MAX_HISTORY];
70     int numHistory;
71     struct xorg_list link;
72 } XDbgPixmap;
73
74 typedef struct {
75     PixmapPtr pPixmap;
76     struct xorg_list link;
77 } XDbgRefPixmap;
78
79 typedef struct {
80     DrawablePtr pDraw;
81     XDbgRefPixmap *pRefPixmap;
82     struct xorg_list link;
83     struct xorg_list refPixmaps;
84 } XDbgDrawable;
85
86 static int init_plist = 0;
87 static struct xorg_list xdbgPixmaps;
88 static struct xorg_list xdbgDrawables;
89 static PixmapPtr pPixRoot = NULL;
90 unsigned int total_size = 0;
91 unsigned int peek_size = 0;
92
93 const struct {
94     unsigned int hint;
95     char* str;
96 } pixmap_hint[] = {
97     {CREATE_PIXMAP_USAGE_SCRATCH,        "scratch"},
98     {CREATE_PIXMAP_USAGE_BACKING_PIXMAP, "backing_pixmap"},
99     {CREATE_PIXMAP_USAGE_GLYPH_PICTURE,  "glyph_picture"},
100     {CREATE_PIXMAP_USAGE_SHARED,         "shared"},
101     {CREATE_PIXMAP_USAGE_OVERLAY,        "overlay"},
102     {CREATE_PIXMAP_USAGE_DRI2_FLIP_BACK, "dri2_flip_back"},
103     {CREATE_PIXMAP_USAGE_FB,             "fb"},
104     {CREATE_PIXMAP_USAGE_SUB_FB,         "sub_fb"},
105     {CREATE_PIXMAP_USAGE_DRI2_BACK,      "dri2_back"},
106     {CREATE_PIXMAP_USAGE_DRI3_BACK,      "dri3"},
107     /******END********/
108     {0, "normal"}
109 };
110
111 static char *
112 _get_pixmap_hint_name (signed int usage_hint)
113 {
114     int i = 0;
115
116     while (pixmap_hint[i].hint)
117     {
118         if (pixmap_hint[i].hint == usage_hint)
119             return pixmap_hint[i].str;
120         i++;
121     }
122     return NULL;
123 }
124
125 static XDbgPixmap *
126 _findXDbgPixmap (PixmapPtr pPixmap)
127 {
128     XDbgPixmap *cur = NULL, *tmp = NULL;
129
130     xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
131     {
132         if (cur->pPixmap == pPixmap)
133             return cur;
134     }
135
136     return NULL;
137 }
138
139 static XDbgDrawable *
140 _findXDbgDrawable (DrawablePtr pDraw)
141 {
142     XDbgDrawable *cur = NULL, *tmp = NULL;
143
144     xorg_list_for_each_entry_safe (cur, tmp, &xdbgDrawables, link)
145     {
146         if (cur->pDraw == pDraw)
147             return cur;
148     }
149
150     return NULL;
151 }
152
153 static XDbgRefPixmap*
154 _findXDbgRefPixmap (XDbgDrawable* pXDbgDrawable, PixmapPtr pPixmap)
155 {
156     XDbgRefPixmap *cur = NULL, *tmp = NULL;
157
158     xorg_list_for_each_entry_safe (cur, tmp, &pXDbgDrawable->refPixmaps, link)
159     {
160         if (cur->pPixmap == pPixmap)
161             return cur;
162     }
163
164     return NULL;
165 }
166
167 static void
168 _addXDbgPixmap (PixmapPtr pPixmap)
169 {
170     XDbgPixmap *cur = NULL;
171     unsigned int size;
172
173     cur = _findXDbgPixmap (pPixmap);
174     if (cur)
175     {
176         size = pPixmap->devKind * pPixmap->drawable.height;
177         if (size == cur->size)
178             return;
179
180         XDBG_TRACE (MMEM, " Change pixmap(%p) size(%d -> %d)\n",
181                     cur->pPixmap, cur->size, size);
182
183         total_size -= cur->size;
184         cur->size = size;
185         cur->hint = _get_pixmap_hint_name (pPixmap->usage_hint);
186     }
187     else
188     {
189         cur = calloc (1, sizeof (XDbgPixmap));
190         if (!cur) return;
191
192         cur->pPixmap = pPixmap;
193         cur->size = pPixmap->devKind*pPixmap->drawable.height;
194         cur->hint = _get_pixmap_hint_name (pPixmap->usage_hint);
195         xorg_list_add (&cur->link, &xdbgPixmaps);
196     }
197
198     /* caculate the total_size of pixmaps */
199     total_size += cur->size;
200     if (total_size > peek_size)
201         peek_size = total_size;
202
203     if (pPixmap->usage_hint == CREATE_PIXMAP_USAGE_FB)
204         pPixRoot = pPixmap;
205
206     XDBG_TRACE (MMEM, "Add pixmap(%p) size:%d, hint:%s\n",
207                 cur->pPixmap, cur->size, cur->hint);
208 }
209
210 static void
211 _removeXDbgPixmap (PixmapPtr pPixmap)
212 {
213     XDbgPixmap *cur = NULL;
214
215     cur = _findXDbgPixmap (pPixmap);
216     if (!cur)
217     {
218         XDBG_WARNING (MMEM, "Unknown pixmap XID:0x%x, pPix:%p\n",
219                       (unsigned int)pPixmap->drawable.id, pPixmap);
220         return;
221     }
222
223     if (cur->refs > 0)
224         XDBG_TRACE (MMEM,"Pixmap(%p) refs:%d\n", cur->pPixmap, cur->refs);
225
226     /* caculate the total_size of pixmaps */
227     total_size -= cur->size;
228
229     XDBG_TRACE (MMEM, " Remove pixmap(%p) size:%d, hint:%s\n",
230                 cur->pPixmap, cur->size, cur->hint);
231
232     xorg_list_del(&cur->link);
233     free(cur);
234 }
235
236 #if 0
237 static void
238 _dumpDraws (char *reply, int *len)
239 {
240     XDbgDrawable *cur = NULL, *tmp = NULL;
241     XDbgRefPixmap *p = NULL, *ptmp = NULL;
242     XDbgPixmap *dp = NULL;
243
244     xorg_list_for_each_entry_safe (cur, tmp, &xdbgDrawables, link)
245     {
246         XDBG_REPLY ("[%d] XID:0x%x type:%s %dx%d+%d+%d\n",
247                                 CLIENT_ID(cur->pDraw->id),
248                                 (unsigned int)cur->pDraw->id,
249                                 (cur->pDraw->type == DRAWABLE_WINDOW ? "window":"pixmap"),
250                                 cur->pDraw->width, cur->pDraw->height, cur->pDraw->x, cur->pDraw->y);
251
252         xorg_list_for_each_entry_safe (p, ptmp, &cur->refPixmaps, link)
253         {
254             dp = _findXDbgPixmap (p->pPixmap);
255             if(!dp)
256             {
257                 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", p->pPixmap);
258                 continue;
259             }
260
261             XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
262                                      dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
263         }
264     }
265 }
266
267 static void
268 _dumpPixmaps (char *reply, int *len)
269 {
270     XDbgPixmap *cur = NULL, *tmp = NULL;
271     int client_id;
272     int i;
273
274     if (pPixRoot)
275     {
276         cur = _findXDbgPixmap (pPixRoot);
277         XDBG_RETURN_IF_FAIL (cur != NULL);
278         XDBG_REPLY ("ROOT_Pixmap XID:0x%x pixmap(%p) hint:%s(0x%x) size:%d\n",
279                                 (unsigned int)cur->pPixmap->drawable.id, pPixRoot,
280                                 cur->hint, cur->pPixmap->usage_hint,
281                                 (unsigned int)cur->size/1024);
282     }
283
284     xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
285     {
286         if (cur->pPixmap == pPixRoot)
287             continue;
288
289         if (cur->pPixmap->drawable.id || cur->refs == 0)
290         {
291             client_id = CLIENT_ID(cur->pPixmap->drawable.id);
292             if (cur->pPixmap->drawable.id)
293             {
294                 XDBG_REPLY ("[%d] XID:0x%x %dx%d hint:%s(0x%x) size:%d refs:%d\n",
295                                         client_id, (unsigned int)cur->pPixmap->drawable.id,
296                                         cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
297                                         cur->hint, cur->pPixmap->usage_hint,
298                                         (unsigned int)cur->size/1024, cur->refs);
299             }
300             else
301             {
302                 XDBG_REPLY ("[%d] Pixmap:%p %dx%d hint:%s(0x%x) size:%d refs:%d\n",
303                                         client_id, cur->pPixmap,
304                                         cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
305                                         cur->hint, cur->pPixmap->usage_hint,
306                                         (unsigned int)cur->size/1024, cur->refs);
307             }
308
309             if (cur->numHistory)
310             {
311                 XDBG_REPLY ("\t[RefHistory] ");
312                 for (i = 0; i < cur->numHistory; i++)
313                 {
314                     XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);
315                 }
316                 XDBG_REPLY ("\n");
317             }
318         }
319     }
320 }
321 #endif
322
323 CreatePixmapProcPtr fnCreatePixmap;
324 DestroyPixmapProcPtr fnDestroyPixmap;
325 ModifyPixmapHeaderProcPtr fnModifyPixmap;
326 SetWindowPixmapProcPtr fnSetWindowPixmap;
327 DestroyWindowProcPtr fnDestroyWindow;
328
329 static PixmapPtr
330 XDbgLogCreatePixmap (ScreenPtr pScreen, int width, int height,
331                         int depth, unsigned usage_hint)
332 {
333     PixmapPtr pPixmap = NULL;
334
335     pScreen->CreatePixmap = fnCreatePixmap;
336     pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
337     pScreen->CreatePixmap = XDbgLogCreatePixmap;
338
339     if(pPixmap)
340         _addXDbgPixmap (pPixmap);
341
342     return pPixmap;
343 }
344
345 static Bool
346 XDbgLogModifyPixmapHeader (PixmapPtr pPixmap, int width, int height,
347                               int depth, int bitsPerPixel, int devKind, pointer pPixData)
348 {
349     Bool ret;
350     ScreenPtr pScreen = pPixmap->drawable.pScreen;
351
352     pScreen->ModifyPixmapHeader = fnModifyPixmap;
353     ret = pScreen->ModifyPixmapHeader (pPixmap, width, height,
354                                        depth, bitsPerPixel, devKind, pPixData);
355     pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
356
357     _addXDbgPixmap (pPixmap);
358
359     return ret;
360 }
361
362 static Bool
363 XDbgLogDestroyPixmap (PixmapPtr pPixmap)
364 {
365     Bool ret;
366
367     ScreenPtr pScreen = pPixmap->drawable.pScreen;
368
369     if (pPixmap->refcnt == 1)
370         _removeXDbgPixmap (pPixmap);
371
372     pScreen->DestroyPixmap = fnDestroyPixmap;
373     ret = pScreen->DestroyPixmap(pPixmap);
374     pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
375
376     return ret;
377 }
378
379 static void
380 XDbgLogSetWindowPixmap (WindowPtr pWin, PixmapPtr pPixmap)
381 {
382     ScreenPtr pScreen = (ScreenPtr) pWin->drawable.pScreen;
383     WindowPtr pParent = pWin->parent;
384     XDbgDrawable *d = NULL;
385     XDbgPixmap *p = NULL;
386     XDbgRefPixmap *p_ref = NULL;
387
388     pScreen->SetWindowPixmap = fnSetWindowPixmap;
389     pScreen->SetWindowPixmap (pWin, pPixmap);
390     pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
391
392     if (pParent && pPixmap != pScreen->GetWindowPixmap(pParent))
393     {
394         //Add to window list
395         p = _findXDbgPixmap (pPixmap);
396         if (!p)
397         {
398             XDBG_WARNING (MMEM, "Unknown pixmap(%p) hint:%s\n",
399                           pPixmap, _get_pixmap_hint_name(pPixmap->usage_hint));
400             return;
401         }
402
403         d = _findXDbgDrawable (&pWin->drawable);
404         if (!d)
405         {
406             d = calloc (1, sizeof(XDbgDrawable));
407             if (!d)
408             {
409                 XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory\n",
410                           __FUNCTION__, __LINE__);
411                 return;
412             }
413             d->pDraw = &pWin->drawable;
414             xorg_list_init (&d->refPixmaps);
415             xorg_list_add (&d->link, &xdbgDrawables);
416             XDBG_TRACE (MMEM, " Add window(0x%x)\n", (unsigned int)pWin->drawable.id);
417         }
418
419         if (d->pRefPixmap)
420         {
421             XDBG_TRACE (MMEM, " Unset WinPixmap win(0x%x), pixmap(%p) hint:%s\n",
422                                    (unsigned int)pWin->drawable.id, p->pPixmap, p->hint);
423             xorg_list_del (&d->pRefPixmap->link);
424             XDbgPixmap * pix = _findXDbgPixmap (d->pRefPixmap->pPixmap);
425             if (pix) pix->refs--;
426             free (d->pRefPixmap);
427             d->pRefPixmap = NULL;
428         }
429
430         p_ref = calloc (1, sizeof(XDbgRefPixmap));
431         if (!p_ref)
432         {
433             XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory to pixmap\n",
434                                   __FUNCTION__, __LINE__);
435             return;
436         }
437
438         p_ref->pPixmap = pPixmap;
439         xorg_list_init (&p_ref->link);
440         xorg_list_add (&p_ref->link, &d->refPixmaps);
441         d->pRefPixmap = p_ref;
442
443         p->refs++;
444         if (p->numHistory >= MAX_HISTORY)
445             memmove(p->refHistorys, &(p->refHistorys[1]), --(p->numHistory));
446         p->refHistorys[p->numHistory++] = pWin->drawable.id;
447
448         XDBG_TRACE (MMEM, " Set WinPixmap win(0x%x), pixmap(%p) hint:%s\n",
449                             (unsigned int)pWin->drawable.id, p->pPixmap, p->hint);
450     }
451     else
452     {
453         //find window
454         d = _findXDbgDrawable (&pWin->drawable);
455
456         //remove window
457         if (d && d->pRefPixmap)
458         {
459             p = _findXDbgPixmap (d->pRefPixmap->pPixmap);
460             if (p)
461             {
462                 if (p->refs > 0)
463                     p->refs--;
464                 else
465                     XDBG_WARNING (MMEM, "pixmap(%p), refs(%d)\n",
466                                   __FUNCTION__, __LINE__, p->pPixmap, p->refs);
467             }
468
469             XDBG_TRACE (MMEM,"Unset WinPixmap win(0x%x): pixmap(%p) to NULL\n",
470                         (unsigned int)pWin->drawable.id, d->pRefPixmap->pPixmap);
471
472             p_ref = _findXDbgRefPixmap (d, d->pRefPixmap->pPixmap);
473             if(p_ref)
474             {
475                 xorg_list_del (&d->pRefPixmap->link);
476                 free (d->pRefPixmap);
477             }
478             else
479                 XDBG_WARNING (MMEM, "Unknown refpixmap : WinPixmap win(0x%x) pixmap(%p) \n",
480                                        (unsigned int)pWin->drawable.id, d->pRefPixmap->pPixmap);
481
482             d->pRefPixmap = NULL;
483
484             if (xorg_list_is_empty (&d->refPixmaps))
485             {
486                 xorg_list_del (&d->link);
487                 free(d);
488             }
489         }
490     }
491 }
492
493 static Bool
494 XDbgLogDestroyWindow (WindowPtr pWindow)
495 {
496     Bool ret;
497     ScreenPtr pScreen = pWindow->drawable.pScreen;
498     XDbgDrawable *d = NULL;
499     XDbgPixmap *p = NULL;
500     XDbgRefPixmap *pos = NULL, *tmp = NULL;
501
502     pScreen->DestroyWindow = fnDestroyWindow;
503     ret = pScreen->DestroyWindow (pWindow);
504     pScreen->DestroyWindow = XDbgLogDestroyWindow;
505
506     d = _findXDbgDrawable (&pWindow->drawable);
507     if (d)
508     {
509         XDBG_TRACE (MMEM, "Remove drawable(0x%x)\n",
510                     (unsigned int)pWindow->drawable.id);
511
512         xorg_list_for_each_entry_safe (pos, tmp, &d->refPixmaps, link)
513         {
514             p = _findXDbgPixmap (pos->pPixmap);
515             if(p)
516                 p->refs--;
517
518             XDBG_TRACE (MMEM, "Remove ref_pixmap(%p), dbgPixmap(%p)\n",
519                         pos->pPixmap, p);
520
521             xorg_list_del (&pos->link);
522             free (pos);
523         }
524
525         xorg_list_del (&d->link);
526         free (d);
527     }
528
529     return ret;
530 }
531
532 API void
533 xDbgLogPListInit (ScreenPtr pScreen)
534 {
535     init_plist = 1;
536
537     xorg_list_init (&xdbgPixmaps);
538     xorg_list_init (&xdbgDrawables);
539
540     fnSetWindowPixmap = pScreen->SetWindowPixmap;
541     fnDestroyWindow = pScreen->DestroyWindow;
542     fnCreatePixmap = pScreen->CreatePixmap;
543     fnModifyPixmap = pScreen->ModifyPixmapHeader;
544     fnDestroyPixmap = pScreen->DestroyPixmap;
545
546     pScreen->CreatePixmap = XDbgLogCreatePixmap;
547     pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
548     pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
549     pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
550     pScreen->DestroyWindow = XDbgLogDestroyWindow;
551 }
552
553 API void
554 xDbgLogPListDeinit (ScreenPtr pScreen)
555 {}
556
557
558 API void
559 xDbgLogPListDrawAddRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
560 {
561     XDbgDrawable *d = NULL;
562     XDbgPixmap *p = NULL;
563     XDbgRefPixmap *p_ref = NULL;
564
565     XDBG_RETURN_IF_FAIL (pDraw != NULL);
566     XDBG_RETURN_IF_FAIL (pRefPixmap != NULL);
567
568     d = _findXDbgDrawable (pDraw);
569     p = _findXDbgPixmap (pRefPixmap);
570     if(!p)
571     {
572         XDBG_WARNING (MMEM, "%s:%d : Unknown pixmap XID:0x%x, pPix:%p\n",
573                       __FUNCTION__, __LINE__,
574                       (unsigned int)pRefPixmap->drawable.id, pRefPixmap);
575         return;
576     }
577
578     if (!d)
579     {
580         d = calloc (1, sizeof(XDbgDrawable));
581         if (!d)
582         {
583             XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory\n",
584                       __FUNCTION__, __LINE__);
585             return;
586         }
587         d->pDraw = pDraw;
588         xorg_list_init (&d->refPixmaps);
589         xorg_list_add (&d->link, &xdbgDrawables);
590
591         XDBG_TRACE (MMEM, " Add window(0x%x)\n", (unsigned int)pDraw->id);
592     }
593
594     p_ref =_findXDbgRefPixmap (d, pRefPixmap);
595     if(p_ref)
596         return;
597
598     p_ref = calloc (1, sizeof(XDbgRefPixmap));
599     if (!p_ref)
600     {
601         XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory\n",
602                       __FUNCTION__, __LINE__);
603         return;
604     }
605     p_ref->pPixmap = pRefPixmap;
606     xorg_list_init (&p_ref->link);
607     xorg_list_add (&p_ref->link, &d->refPixmaps);
608
609     p->refs++;
610     if (p->numHistory < (MAX_HISTORY-1))
611         p->refHistorys[p->numHistory++] = pDraw->id;
612
613     if (pDraw->type == DRAWABLE_WINDOW)
614         XDBG_TRACE (MMEM, " Add RefPixmap win(0x%x), pixmap(%p) hint:%s\n",
615                     (unsigned int)pDraw->id, p->pPixmap, p->hint);
616     else
617         XDBG_TRACE (MMEM, " Add RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
618                     (unsigned int)pDraw->id, p->pPixmap, p->hint);
619 }
620
621 API void
622 xDbgLogPListDrawRemoveRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
623 {
624     XDbgDrawable *d = NULL;
625     XDbgRefPixmap *p_ref = NULL;
626     XDbgPixmap *p = NULL;
627
628     p = _findXDbgPixmap (pRefPixmap);
629     if (pDraw == NULL)
630     {
631         if (p && p->refs > 0)
632         {
633             XDBG_ERROR (MMEM, "Error:%s:%d null draw pixmap(%p)\n",
634                         __FUNCTION__, __LINE__, pRefPixmap);
635         }
636         return;
637     }
638
639     d = _findXDbgDrawable (pDraw);
640     if (!d)
641     {
642         XDBG_WARNING (MMEM, "%s:%d : Unknown drawable XID:0x%x, pPix:%p\n",
643                       __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
644         return;
645     }
646
647     p_ref = _findXDbgRefPixmap (d, pRefPixmap);
648     if(!p_ref)
649     {
650         XDBG_WARNING (MMEM, "%s:%d : Unknown refpixmap XID:0x%x, pPix:%p\n",
651                                   __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
652         return;
653     }
654
655     xorg_list_del (&p_ref->link);
656     free (p_ref);
657     if (p)
658         p->refs--;
659
660     if (xorg_list_is_empty (&d->refPixmaps))
661     {
662         xorg_list_del(&d->link);
663         free(d);
664     }
665
666     if (pDraw->type == DRAWABLE_WINDOW)
667         XDBG_TRACE (MMEM, " Remove RefPixmap win(0x%x), pixmap(%p) hint:%s\n",
668                                 (unsigned int)pDraw->id, pRefPixmap,
669                                 _get_pixmap_hint_name(pRefPixmap->usage_hint));
670     else
671         XDBG_TRACE (MMEM, " Remove RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
672                                 (unsigned int)pDraw->id, pRefPixmap,
673                                 _get_pixmap_hint_name(pRefPixmap->usage_hint));
674 }
675
676
677 API void
678 xDbgLogPList (char *reply, int *len)
679 {
680     if (!init_plist)
681     {
682         XDBG_REPLY ("plist is not supported.\n");
683         return;
684     }
685
686     XDBG_REPLY ("\n\n====================================\n");
687     XDBG_REPLY ("    Total:%d, Peek:%d\n", (unsigned int)total_size/1024, (unsigned int)peek_size/1024);
688     XDBG_REPLY ( "====================================\n");
689
690     XDBG_REPLY ("== WINDOWS ==\n");
691     XDbgDrawable *dd = NULL, *ddtmp = NULL;
692     XDbgRefPixmap *rp = NULL, *rptmp = NULL;
693     XDbgPixmap *dp = NULL;
694
695     xorg_list_for_each_entry_safe (dd, ddtmp, &xdbgDrawables, link)
696     {
697         XDBG_REPLY ("[%d] XID:0x%x type:%s %dx%d+%d+%d\n",
698                                 CLIENT_ID(dd->pDraw->id),
699                                 (unsigned int)dd->pDraw->id,
700                                 (dd->pDraw->type == DRAWABLE_WINDOW ? "window":"pixmap"),
701                                 dd->pDraw->width, dd->pDraw->height, dd->pDraw->x, dd->pDraw->y);
702
703         xorg_list_for_each_entry_safe (rp, rptmp, &dd->refPixmaps, link)
704         {
705             dp = _findXDbgPixmap (rp->pPixmap);
706             if(!dp)
707             {
708                 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", rp->pPixmap);
709                 continue;
710             }
711
712             XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
713                                      dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
714         }
715     }
716     XDBG_REPLY ("\n");
717
718
719     XDBG_REPLY ( "== PIXMAPS ==\n");
720     XDbgPixmap *cur = NULL, *tmp = NULL;
721     int client_id;
722     int i;
723
724     if (pPixRoot)
725     {
726         cur = _findXDbgPixmap (pPixRoot);
727         XDBG_RETURN_IF_FAIL (cur != NULL);
728         XDBG_REPLY ("ROOT_Pixmap XID:0x%x pixmap(%p) hint:%s(0x%x) size:%d\n",
729                                 (unsigned int)cur->pPixmap->drawable.id, pPixRoot,
730                                 cur->hint, cur->pPixmap->usage_hint,
731                                 (unsigned int)cur->size/1024);
732     }
733
734     xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
735     {
736         if (cur->pPixmap == pPixRoot)
737             continue;
738
739         if (cur->pPixmap->drawable.id || cur->refs == 0)
740         {
741             client_id = CLIENT_ID(cur->pPixmap->drawable.id);
742             if (cur->pPixmap->drawable.id)
743             {
744                 XDBG_REPLY ("[%d] XID:0x%x %dx%d hint:%s(0x%x) size:%d refs:%d\n",
745                                         client_id, (unsigned int)cur->pPixmap->drawable.id,
746                                         cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
747                                         cur->hint, cur->pPixmap->usage_hint,
748                                         (unsigned int)cur->size/1024, cur->refs);
749             }
750             else
751             {
752                 XDBG_REPLY ("[%d] Pixmap:%p %dx%d hint:%s(0x%x) size:%d refs:%d\n",
753                                         client_id, cur->pPixmap,
754                                         cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
755                                         cur->hint, cur->pPixmap->usage_hint,
756                                         (unsigned int)cur->size/1024, cur->refs);
757             }
758
759             if (cur->numHistory)
760             {
761                 XDBG_REPLY ("\t[RefHistory] ");
762                 for (i = 0; i < cur->numHistory; i++)
763                 {
764                     XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);
765                 }
766                 XDBG_REPLY ("\n");
767             }
768         }
769     }
770     XDBG_REPLY ("\n");
771 }
772