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