1 /**************************************************************************
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: SooChan Lim <sc1.lim@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 **************************************************************************/
37 #include "xorg-server.h"
39 #include <scrnintstr.h>
41 #include <windowstr.h>
45 #include "xdbg_log_int.h"
46 #include "xdbg_types.h"
47 #include "xdbg_log_plist.h"
49 /* for debug message */
50 #define MMEM XDBG_M('M','E','M',0)
53 #define API __attribute__ ((visibility("default")))
56 /*=========================================================================*/
57 /* trace the usage of the pixmaps in xserver */
58 /*=========================================================================*/
60 #define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK)
61 #define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET))
62 #define MAX_HISTORY 10
69 XID refHistorys[MAX_HISTORY];
71 struct xorg_list link;
76 struct xorg_list link;
81 XDbgRefPixmap *pRefPixmap;
82 struct xorg_list link;
83 struct xorg_list refPixmaps;
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;
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"},
111 _get_pixmap_hint_name (signed int usage_hint)
115 while (pixmap_hint[i].hint)
117 if (pixmap_hint[i].hint == usage_hint)
118 return pixmap_hint[i].str;
125 _findXDbgPixmap (PixmapPtr pPixmap)
127 XDbgPixmap *cur = NULL, *tmp = NULL;
129 xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
131 if (cur->pPixmap == pPixmap)
138 static XDbgDrawable *
139 _findXDbgDrawable (DrawablePtr pDraw)
141 XDbgDrawable *cur = NULL, *tmp = NULL;
143 xorg_list_for_each_entry_safe (cur, tmp, &xdbgDrawables, link)
145 if (cur->pDraw == pDraw)
152 static XDbgRefPixmap*
153 _findXDbgRefPixmap (XDbgDrawable* pXDbgDrawable, PixmapPtr pPixmap)
155 XDbgRefPixmap *cur = NULL, *tmp = NULL;
157 xorg_list_for_each_entry_safe (cur, tmp, &pXDbgDrawable->refPixmaps, link)
159 if (cur->pPixmap == pPixmap)
167 _addXDbgPixmap (PixmapPtr pPixmap)
169 XDbgPixmap *cur = NULL;
172 cur = _findXDbgPixmap (pPixmap);
175 size = pPixmap->devKind * pPixmap->drawable.height;
176 if (size == cur->size)
179 XDBG_TRACE (MMEM, " Change pixmap(%p) size(%d -> %d)\n",
180 cur->pPixmap, cur->size, size);
182 total_size -= cur->size;
184 cur->hint = _get_pixmap_hint_name (pPixmap->usage_hint);
188 cur = calloc (1, sizeof (XDbgPixmap));
189 cur->pPixmap = pPixmap;
190 cur->size = pPixmap->devKind*pPixmap->drawable.height;
191 cur->hint = _get_pixmap_hint_name (pPixmap->usage_hint);
192 xorg_list_add (&cur->link, &xdbgPixmaps);
195 /* caculate the total_size of pixmaps */
196 total_size += cur->size;
197 if (total_size > peek_size)
198 peek_size = total_size;
200 if (pPixmap->usage_hint == CREATE_PIXMAP_USAGE_FB)
203 XDBG_TRACE (MMEM, "Add pixmap(%p) size:%d, hint:%s\n",
204 cur->pPixmap, cur->size, cur->hint);
208 _removeXDbgPixmap (PixmapPtr pPixmap)
210 XDbgPixmap *cur = NULL;
212 cur = _findXDbgPixmap (pPixmap);
215 XDBG_WARNING (MMEM, "Unknown pixmap XID:0x%x, pPix:%p\n",
216 (unsigned int)pPixmap->drawable.id, pPixmap);
221 XDBG_TRACE (MMEM,"Pixmap(%p) refs:%d\n", cur->pPixmap, cur->refs);
223 /* caculate the total_size of pixmaps */
224 total_size -= cur->size;
226 XDBG_TRACE (MMEM, " Remove pixmap(%p) size:%d, hint:%s\n",
227 cur->pPixmap, cur->size, cur->hint);
229 xorg_list_del(&cur->link);
235 _dumpDraws (char *reply, int *len)
237 XDbgDrawable *cur = NULL, *tmp = NULL;
238 XDbgRefPixmap *p = NULL, *ptmp = NULL;
239 XDbgPixmap *dp = NULL;
241 xorg_list_for_each_entry_safe (cur, tmp, &xdbgDrawables, link)
243 XDBG_REPLY ("[%d] XID:0x%x type:%s %dx%d+%d+%d\n",
244 CLIENT_ID(cur->pDraw->id),
245 (unsigned int)cur->pDraw->id,
246 (cur->pDraw->type == DRAWABLE_WINDOW ? "window":"pixmap"),
247 cur->pDraw->width, cur->pDraw->height, cur->pDraw->x, cur->pDraw->y);
249 xorg_list_for_each_entry_safe (p, ptmp, &cur->refPixmaps, link)
251 dp = _findXDbgPixmap (p->pPixmap);
254 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", p->pPixmap);
258 XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
259 dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
265 _dumpPixmaps (char *reply, int *len)
267 XDbgPixmap *cur = NULL, *tmp = NULL;
273 cur = _findXDbgPixmap (pPixRoot);
274 XDBG_RETURN_IF_FAIL (cur != NULL);
275 XDBG_REPLY ("ROOT_Pixmap XID:0x%x pixmap(%p) hint:%s(0x%x) size:%d\n",
276 (unsigned int)cur->pPixmap->drawable.id, pPixRoot,
277 cur->hint, cur->pPixmap->usage_hint,
278 (unsigned int)cur->size/1024);
281 xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
283 if (cur->pPixmap == pPixRoot)
286 if (cur->pPixmap->drawable.id || cur->refs == 0)
288 client_id = CLIENT_ID(cur->pPixmap->drawable.id);
289 if (cur->pPixmap->drawable.id)
291 XDBG_REPLY ("[%d] XID:0x%x %dx%d hint:%s(0x%x) size:%d refs:%d\n",
292 client_id, (unsigned int)cur->pPixmap->drawable.id,
293 cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
294 cur->hint, cur->pPixmap->usage_hint,
295 (unsigned int)cur->size/1024, cur->refs);
299 XDBG_REPLY ("[%d] Pixmap:%p %dx%d hint:%s(0x%x) size:%d refs:%d\n",
300 client_id, cur->pPixmap,
301 cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
302 cur->hint, cur->pPixmap->usage_hint,
303 (unsigned int)cur->size/1024, cur->refs);
308 XDBG_REPLY ("\t[RefHistory] ");
309 for (i = 0; i < cur->numHistory; i++)
311 XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);
320 CreatePixmapProcPtr fnCreatePixmap;
321 DestroyPixmapProcPtr fnDestroyPixmap;
322 ModifyPixmapHeaderProcPtr fnModifyPixmap;
323 SetWindowPixmapProcPtr fnSetWindowPixmap;
324 DestroyWindowProcPtr fnDestroyWindow;
327 XDbgLogCreatePixmap (ScreenPtr pScreen, int width, int height,
328 int depth, unsigned usage_hint)
330 PixmapPtr pPixmap = NULL;
332 pScreen->CreatePixmap = fnCreatePixmap;
333 pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
334 pScreen->CreatePixmap = XDbgLogCreatePixmap;
337 _addXDbgPixmap (pPixmap);
343 XDbgLogModifyPixmapHeader (PixmapPtr pPixmap, int width, int height,
344 int depth, int bitsPerPixel, int devKind, pointer pPixData)
347 ScreenPtr pScreen = pPixmap->drawable.pScreen;
349 pScreen->ModifyPixmapHeader = fnModifyPixmap;
350 ret = pScreen->ModifyPixmapHeader (pPixmap, width, height,
351 depth, bitsPerPixel, devKind, pPixData);
352 pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
354 _addXDbgPixmap (pPixmap);
360 XDbgLogDestroyPixmap (PixmapPtr pPixmap)
364 ScreenPtr pScreen = pPixmap->drawable.pScreen;
366 if (pPixmap->refcnt == 1)
367 _removeXDbgPixmap (pPixmap);
369 pScreen->DestroyPixmap = fnDestroyPixmap;
370 ret = pScreen->DestroyPixmap(pPixmap);
371 pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
377 XDbgLogSetWindowPixmap (WindowPtr pWin, PixmapPtr pPixmap)
379 ScreenPtr pScreen = (ScreenPtr) pWin->drawable.pScreen;
380 WindowPtr pParent = pWin->parent;
381 XDbgDrawable *d = NULL;
382 XDbgPixmap *p = NULL;
383 XDbgRefPixmap *p_ref = NULL;
385 pScreen->SetWindowPixmap = fnSetWindowPixmap;
386 pScreen->SetWindowPixmap (pWin, pPixmap);
387 pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
389 if (pPixmap != pScreen->GetWindowPixmap(pParent))
392 p = _findXDbgPixmap (pPixmap);
395 XDBG_WARNING (MMEM, "Unknown pixmap(%p) hint:%s\n",
396 pPixmap, _get_pixmap_hint_name(pPixmap->usage_hint));
400 d = _findXDbgDrawable (&pWin->drawable);
403 d = calloc (1, sizeof(XDbgDrawable));
404 d->pDraw = &pWin->drawable;
405 xorg_list_init (&d->refPixmaps);
406 xorg_list_add (&d->link, &xdbgDrawables);
407 XDBG_TRACE (MMEM, " Add window(0x%x)\n", (unsigned int)pWin->drawable.id);
412 XDBG_TRACE (MMEM, " Unset WinPixmap win(0x%x), pixmap(%p) hint:%s\n",
413 (unsigned int)pWin->drawable.id, p->pPixmap, p->hint);
414 xorg_list_del (&d->pRefPixmap->link);
415 free (d->pRefPixmap);
416 d->pRefPixmap = NULL;
419 p_ref = calloc (1, sizeof(XDbgRefPixmap));
420 p_ref->pPixmap = pPixmap;
421 xorg_list_init (&p_ref->link);
422 xorg_list_add (&p_ref->link, &d->refPixmaps);
423 d->pRefPixmap = p_ref;
426 p->refHistorys[p->numHistory++] = pWin->drawable.id;
428 XDBG_TRACE (MMEM, " Set WinPixmap win(0x%x), pixmap(%p) hint:%s\n",
429 (unsigned int)pWin->drawable.id, p->pPixmap, p->hint);
434 d = _findXDbgDrawable (&pWin->drawable);
437 if (d && d->pRefPixmap)
439 p = _findXDbgPixmap (d->pRefPixmap->pPixmap);
445 XDBG_WARNING (MMEM, "pixmap(%p), refs(%d)\n",
446 __FUNCTION__, __LINE__, p->pPixmap, p->refs);
449 XDBG_TRACE (MMEM,"Unset WinPixmap win(0x%x): pixmap(%p) to NULL\n",
450 (unsigned int)pWin->drawable.id, d->pRefPixmap->pPixmap);
452 xorg_list_del (&d->pRefPixmap->link);
453 free (d->pRefPixmap);
454 d->pRefPixmap = NULL;
456 if (xorg_list_is_empty (&d->refPixmaps))
458 xorg_list_del (&d->link);
466 XDbgLogDestroyWindow (WindowPtr pWindow)
469 ScreenPtr pScreen = pWindow->drawable.pScreen;
470 XDbgDrawable *d = NULL;
471 XDbgPixmap *p = NULL;
472 XDbgRefPixmap *pos = NULL, *tmp = NULL;
474 pScreen->DestroyWindow = fnDestroyWindow;
475 ret = pScreen->DestroyWindow (pWindow);
476 pScreen->DestroyWindow = XDbgLogDestroyWindow;
478 d = _findXDbgDrawable (&pWindow->drawable);
481 XDBG_TRACE (MMEM, "Remove drawable(0x%x)\n",
482 (unsigned int)pWindow->drawable.id);
484 xorg_list_for_each_entry_safe (pos, tmp, &d->refPixmaps, link)
486 p = _findXDbgPixmap (pos->pPixmap);
490 XDBG_TRACE (MMEM, "Remove ref_pixmap(%p), dbgPixmap(%p)\n",
493 xorg_list_del (&pos->link);
497 xorg_list_del (&d->link);
505 xDbgLogPListInit (ScreenPtr pScreen)
509 xorg_list_init (&xdbgPixmaps);
510 xorg_list_init (&xdbgDrawables);
512 fnSetWindowPixmap = pScreen->SetWindowPixmap;
513 fnDestroyWindow = pScreen->DestroyWindow;
514 fnCreatePixmap = pScreen->CreatePixmap;
515 fnModifyPixmap = pScreen->ModifyPixmapHeader;
516 fnDestroyPixmap = pScreen->DestroyPixmap;
518 pScreen->CreatePixmap = XDbgLogCreatePixmap;
519 pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
520 pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
521 pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
522 pScreen->DestroyWindow = XDbgLogDestroyWindow;
526 xDbgLogPListDeinit (ScreenPtr pScreen)
531 xDbgLogPListDrawAddRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
533 XDbgDrawable *d = NULL;
534 XDbgPixmap *p = NULL;
535 XDbgRefPixmap *p_ref = NULL;
537 XDBG_RETURN_IF_FAIL (pDraw != NULL);
538 XDBG_RETURN_IF_FAIL (pRefPixmap != NULL);
540 d = _findXDbgDrawable (pDraw);
541 p = _findXDbgPixmap (pRefPixmap);
544 XDBG_WARNING (MMEM, "%s:%d : Unknown pixmap XID:0x%x, pPix:%p\n",
545 __FUNCTION__, __LINE__,
546 (unsigned int)pRefPixmap->drawable.id, pRefPixmap);
552 d = calloc (1, sizeof(XDbgDrawable));
554 xorg_list_init (&d->refPixmaps);
555 xorg_list_add (&d->link, &xdbgDrawables);
557 XDBG_TRACE (MMEM, " Add window(0x%x)\n", (unsigned int)pDraw->id);
560 p_ref =_findXDbgRefPixmap (d, pRefPixmap);
564 p_ref = calloc (1, sizeof(XDbgRefPixmap));
565 p_ref->pPixmap = pRefPixmap;
566 xorg_list_init (&p_ref->link);
567 xorg_list_add (&p_ref->link, &d->refPixmaps);
570 if (p->numHistory < (MAX_HISTORY-1))
571 p->refHistorys[p->numHistory++] = pDraw->id;
573 if (pDraw->type == DRAWABLE_WINDOW)
574 XDBG_TRACE (MMEM, " Add RefPixmap win(0x%x), pixmap(%p) hint:%s\n",
575 (unsigned int)pDraw->id, p->pPixmap, p->hint);
577 XDBG_TRACE (MMEM, " Add RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
578 (unsigned int)pDraw->id, p->pPixmap, p->hint);
582 xDbgLogPListDrawRemoveRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
584 XDbgDrawable *d = NULL;
585 XDbgRefPixmap *p_ref = NULL;
586 XDbgPixmap *p = NULL;
588 p = _findXDbgPixmap (pRefPixmap);
591 if (p && p->refs > 0)
593 XDBG_ERROR (MMEM, "Error:%s:%d null draw pixmap(%p)\n",
594 __FUNCTION__, __LINE__, pRefPixmap);
599 d = _findXDbgDrawable (pDraw);
602 XDBG_WARNING (MMEM, "%s:%d : Unknown drawable XID:0x%x, pPix:%p\n",
603 __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
607 p_ref = _findXDbgRefPixmap (d, pRefPixmap);
610 XDBG_WARNING (MMEM, "%s:%d : Unknown refpixmap XID:0x%x, pPix:%p\n",
611 __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
615 xorg_list_del (&p_ref->link);
620 if (xorg_list_is_empty (&d->refPixmaps))
622 xorg_list_del(&d->link);
626 if (pDraw->type == DRAWABLE_WINDOW)
627 XDBG_TRACE (MMEM, " Remove RefPixmap win(0x%x), pixmap(%p) hint:%s\n",
628 (unsigned int)pDraw->id, pRefPixmap,
629 _get_pixmap_hint_name(pRefPixmap->usage_hint));
631 XDBG_TRACE (MMEM, " Remove RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
632 (unsigned int)pDraw->id, pRefPixmap,
633 _get_pixmap_hint_name(pRefPixmap->usage_hint));
638 xDbgLogPList (char *reply, int *len)
642 XDBG_REPLY ("plist is not supported.\n");
646 XDBG_REPLY ("\n\n====================================\n");
647 XDBG_REPLY (" Total:%d, Peek:%d\n", (unsigned int)total_size/1024, (unsigned int)peek_size/1024);
648 XDBG_REPLY ( "====================================\n");
650 XDBG_REPLY ("== WINDOWS ==\n");
651 XDbgDrawable *dd = NULL, *ddtmp = NULL;
652 XDbgRefPixmap *rp = NULL, *rptmp = NULL;
653 XDbgPixmap *dp = NULL;
655 xorg_list_for_each_entry_safe (dd, ddtmp, &xdbgDrawables, link)
657 XDBG_REPLY ("[%d] XID:0x%x type:%s %dx%d+%d+%d\n",
658 CLIENT_ID(dd->pDraw->id),
659 (unsigned int)dd->pDraw->id,
660 (dd->pDraw->type == DRAWABLE_WINDOW ? "window":"pixmap"),
661 dd->pDraw->width, dd->pDraw->height, dd->pDraw->x, dd->pDraw->y);
663 xorg_list_for_each_entry_safe (rp, rptmp, &dd->refPixmaps, link)
665 dp = _findXDbgPixmap (rp->pPixmap);
668 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", rp->pPixmap);
672 XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
673 dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
679 XDBG_REPLY ( "== PIXMAPS ==\n");
680 XDbgPixmap *cur = NULL, *tmp = NULL;
686 cur = _findXDbgPixmap (pPixRoot);
687 XDBG_RETURN_IF_FAIL (cur != NULL);
688 XDBG_REPLY ("ROOT_Pixmap XID:0x%x pixmap(%p) hint:%s(0x%x) size:%d\n",
689 (unsigned int)cur->pPixmap->drawable.id, pPixRoot,
690 cur->hint, cur->pPixmap->usage_hint,
691 (unsigned int)cur->size/1024);
694 xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
696 if (cur->pPixmap == pPixRoot)
699 if (cur->pPixmap->drawable.id || cur->refs == 0)
701 client_id = CLIENT_ID(cur->pPixmap->drawable.id);
702 if (cur->pPixmap->drawable.id)
704 XDBG_REPLY ("[%d] XID:0x%x %dx%d hint:%s(0x%x) size:%d refs:%d\n",
705 client_id, (unsigned int)cur->pPixmap->drawable.id,
706 cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
707 cur->hint, cur->pPixmap->usage_hint,
708 (unsigned int)cur->size/1024, cur->refs);
712 XDBG_REPLY ("[%d] Pixmap:%p %dx%d hint:%s(0x%x) size:%d refs:%d\n",
713 client_id, cur->pPixmap,
714 cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
715 cur->hint, cur->pPixmap->usage_hint,
716 (unsigned int)cur->size/1024, cur->refs);
721 XDBG_REPLY ("\t[RefHistory] ");
722 for (i = 0; i < cur->numHistory; i++)
724 XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);