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));
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);
197 /* caculate the total_size of pixmaps */
198 total_size += cur->size;
199 if (total_size > peek_size)
200 peek_size = total_size;
202 if (pPixmap->usage_hint == CREATE_PIXMAP_USAGE_FB)
205 XDBG_TRACE (MMEM, "Add pixmap(%p) size:%d, hint:%s\n",
206 cur->pPixmap, cur->size, cur->hint);
210 _removeXDbgPixmap (PixmapPtr pPixmap)
212 XDbgPixmap *cur = NULL;
214 cur = _findXDbgPixmap (pPixmap);
217 XDBG_WARNING (MMEM, "Unknown pixmap XID:0x%x, pPix:%p\n",
218 (unsigned int)pPixmap->drawable.id, pPixmap);
223 XDBG_TRACE (MMEM,"Pixmap(%p) refs:%d\n", cur->pPixmap, cur->refs);
225 /* caculate the total_size of pixmaps */
226 total_size -= cur->size;
228 XDBG_TRACE (MMEM, " Remove pixmap(%p) size:%d, hint:%s\n",
229 cur->pPixmap, cur->size, cur->hint);
231 xorg_list_del(&cur->link);
237 _dumpDraws (char *reply, int *len)
239 XDbgDrawable *cur = NULL, *tmp = NULL;
240 XDbgRefPixmap *p = NULL, *ptmp = NULL;
241 XDbgPixmap *dp = NULL;
243 xorg_list_for_each_entry_safe (cur, tmp, &xdbgDrawables, link)
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);
251 xorg_list_for_each_entry_safe (p, ptmp, &cur->refPixmaps, link)
253 dp = _findXDbgPixmap (p->pPixmap);
256 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", p->pPixmap);
260 XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
261 dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
267 _dumpPixmaps (char *reply, int *len)
269 XDbgPixmap *cur = NULL, *tmp = NULL;
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);
283 xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
285 if (cur->pPixmap == pPixRoot)
288 if (cur->pPixmap->drawable.id || cur->refs == 0)
290 client_id = CLIENT_ID(cur->pPixmap->drawable.id);
291 if (cur->pPixmap->drawable.id)
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);
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);
310 XDBG_REPLY ("\t[RefHistory] ");
311 for (i = 0; i < cur->numHistory; i++)
313 XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);
322 CreatePixmapProcPtr fnCreatePixmap;
323 DestroyPixmapProcPtr fnDestroyPixmap;
324 ModifyPixmapHeaderProcPtr fnModifyPixmap;
325 SetWindowPixmapProcPtr fnSetWindowPixmap;
326 DestroyWindowProcPtr fnDestroyWindow;
329 XDbgLogCreatePixmap (ScreenPtr pScreen, int width, int height,
330 int depth, unsigned usage_hint)
332 PixmapPtr pPixmap = NULL;
334 pScreen->CreatePixmap = fnCreatePixmap;
335 pPixmap = pScreen->CreatePixmap(pScreen, width, height, depth, usage_hint);
336 pScreen->CreatePixmap = XDbgLogCreatePixmap;
339 _addXDbgPixmap (pPixmap);
345 XDbgLogModifyPixmapHeader (PixmapPtr pPixmap, int width, int height,
346 int depth, int bitsPerPixel, int devKind, pointer pPixData)
349 ScreenPtr pScreen = pPixmap->drawable.pScreen;
351 pScreen->ModifyPixmapHeader = fnModifyPixmap;
352 ret = pScreen->ModifyPixmapHeader (pPixmap, width, height,
353 depth, bitsPerPixel, devKind, pPixData);
354 pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
356 _addXDbgPixmap (pPixmap);
362 XDbgLogDestroyPixmap (PixmapPtr pPixmap)
366 ScreenPtr pScreen = pPixmap->drawable.pScreen;
368 if (pPixmap->refcnt == 1)
369 _removeXDbgPixmap (pPixmap);
371 pScreen->DestroyPixmap = fnDestroyPixmap;
372 ret = pScreen->DestroyPixmap(pPixmap);
373 pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
379 XDbgLogSetWindowPixmap (WindowPtr pWin, PixmapPtr pPixmap)
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;
387 pScreen->SetWindowPixmap = fnSetWindowPixmap;
388 pScreen->SetWindowPixmap (pWin, pPixmap);
389 pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
391 if (pPixmap != pScreen->GetWindowPixmap(pParent))
394 p = _findXDbgPixmap (pPixmap);
397 XDBG_WARNING (MMEM, "Unknown pixmap(%p) hint:%s\n",
398 pPixmap, _get_pixmap_hint_name(pPixmap->usage_hint));
402 d = _findXDbgDrawable (&pWin->drawable);
405 d = calloc (1, sizeof(XDbgDrawable));
408 XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory\n",
409 __FUNCTION__, __LINE__);
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);
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;
427 p_ref = calloc (1, sizeof(XDbgRefPixmap));
430 XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory to pixmap\n",
431 __FUNCTION__, __LINE__);
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;
441 p->refHistorys[p->numHistory++] = pWin->drawable.id;
443 XDBG_TRACE (MMEM, " Set WinPixmap win(0x%x), pixmap(%p) hint:%s\n",
444 (unsigned int)pWin->drawable.id, p->pPixmap, p->hint);
449 d = _findXDbgDrawable (&pWin->drawable);
452 if (d && d->pRefPixmap)
454 p = _findXDbgPixmap (d->pRefPixmap->pPixmap);
460 XDBG_WARNING (MMEM, "pixmap(%p), refs(%d)\n",
461 __FUNCTION__, __LINE__, p->pPixmap, p->refs);
464 XDBG_TRACE (MMEM,"Unset WinPixmap win(0x%x): pixmap(%p) to NULL\n",
465 (unsigned int)pWin->drawable.id, d->pRefPixmap->pPixmap);
467 p_ref = _findXDbgRefPixmap (d, d->pRefPixmap->pPixmap);
470 xorg_list_del (&d->pRefPixmap->link);
471 free (d->pRefPixmap);
474 XDBG_WARNING (MMEM, "Unknown refpixmap : WinPixmap win(0x%x) pixmap(%p) \n",
475 (unsigned int)pWin->drawable.id, d->pRefPixmap->pPixmap);
477 d->pRefPixmap = NULL;
479 if (xorg_list_is_empty (&d->refPixmaps))
481 xorg_list_del (&d->link);
489 XDbgLogDestroyWindow (WindowPtr pWindow)
492 ScreenPtr pScreen = pWindow->drawable.pScreen;
493 XDbgDrawable *d = NULL;
494 XDbgPixmap *p = NULL;
495 XDbgRefPixmap *pos = NULL, *tmp = NULL;
497 pScreen->DestroyWindow = fnDestroyWindow;
498 ret = pScreen->DestroyWindow (pWindow);
499 pScreen->DestroyWindow = XDbgLogDestroyWindow;
501 d = _findXDbgDrawable (&pWindow->drawable);
504 XDBG_TRACE (MMEM, "Remove drawable(0x%x)\n",
505 (unsigned int)pWindow->drawable.id);
507 xorg_list_for_each_entry_safe (pos, tmp, &d->refPixmaps, link)
509 p = _findXDbgPixmap (pos->pPixmap);
513 XDBG_TRACE (MMEM, "Remove ref_pixmap(%p), dbgPixmap(%p)\n",
516 xorg_list_del (&pos->link);
520 xorg_list_del (&d->link);
528 xDbgLogPListInit (ScreenPtr pScreen)
532 xorg_list_init (&xdbgPixmaps);
533 xorg_list_init (&xdbgDrawables);
535 fnSetWindowPixmap = pScreen->SetWindowPixmap;
536 fnDestroyWindow = pScreen->DestroyWindow;
537 fnCreatePixmap = pScreen->CreatePixmap;
538 fnModifyPixmap = pScreen->ModifyPixmapHeader;
539 fnDestroyPixmap = pScreen->DestroyPixmap;
541 pScreen->CreatePixmap = XDbgLogCreatePixmap;
542 pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
543 pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
544 pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
545 pScreen->DestroyWindow = XDbgLogDestroyWindow;
549 xDbgLogPListDeinit (ScreenPtr pScreen)
554 xDbgLogPListDrawAddRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
556 XDbgDrawable *d = NULL;
557 XDbgPixmap *p = NULL;
558 XDbgRefPixmap *p_ref = NULL;
560 XDBG_RETURN_IF_FAIL (pDraw != NULL);
561 XDBG_RETURN_IF_FAIL (pRefPixmap != NULL);
563 d = _findXDbgDrawable (pDraw);
564 p = _findXDbgPixmap (pRefPixmap);
567 XDBG_WARNING (MMEM, "%s:%d : Unknown pixmap XID:0x%x, pPix:%p\n",
568 __FUNCTION__, __LINE__,
569 (unsigned int)pRefPixmap->drawable.id, pRefPixmap);
575 d = calloc (1, sizeof(XDbgDrawable));
578 XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory\n",
579 __FUNCTION__, __LINE__);
583 xorg_list_init (&d->refPixmaps);
584 xorg_list_add (&d->link, &xdbgDrawables);
586 XDBG_TRACE (MMEM, " Add window(0x%x)\n", (unsigned int)pDraw->id);
589 p_ref =_findXDbgRefPixmap (d, pRefPixmap);
593 p_ref = calloc (1, sizeof(XDbgRefPixmap));
596 XDBG_WARNING (MMEM, "%s:%d: Failed to allocate memory\n",
597 __FUNCTION__, __LINE__);
600 p_ref->pPixmap = pRefPixmap;
601 xorg_list_init (&p_ref->link);
602 xorg_list_add (&p_ref->link, &d->refPixmaps);
605 if (p->numHistory < (MAX_HISTORY-1))
606 p->refHistorys[p->numHistory++] = pDraw->id;
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);
612 XDBG_TRACE (MMEM, " Add RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
613 (unsigned int)pDraw->id, p->pPixmap, p->hint);
617 xDbgLogPListDrawRemoveRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
619 XDbgDrawable *d = NULL;
620 XDbgRefPixmap *p_ref = NULL;
621 XDbgPixmap *p = NULL;
623 p = _findXDbgPixmap (pRefPixmap);
626 if (p && p->refs > 0)
628 XDBG_ERROR (MMEM, "Error:%s:%d null draw pixmap(%p)\n",
629 __FUNCTION__, __LINE__, pRefPixmap);
634 d = _findXDbgDrawable (pDraw);
637 XDBG_WARNING (MMEM, "%s:%d : Unknown drawable XID:0x%x, pPix:%p\n",
638 __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
642 p_ref = _findXDbgRefPixmap (d, pRefPixmap);
645 XDBG_WARNING (MMEM, "%s:%d : Unknown refpixmap XID:0x%x, pPix:%p\n",
646 __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
650 xorg_list_del (&p_ref->link);
655 if (xorg_list_is_empty (&d->refPixmaps))
657 xorg_list_del(&d->link);
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));
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));
673 xDbgLogPList (char *reply, int *len)
677 XDBG_REPLY ("plist is not supported.\n");
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");
685 XDBG_REPLY ("== WINDOWS ==\n");
686 XDbgDrawable *dd = NULL, *ddtmp = NULL;
687 XDbgRefPixmap *rp = NULL, *rptmp = NULL;
688 XDbgPixmap *dp = NULL;
690 xorg_list_for_each_entry_safe (dd, ddtmp, &xdbgDrawables, link)
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);
698 xorg_list_for_each_entry_safe (rp, rptmp, &dd->refPixmaps, link)
700 dp = _findXDbgPixmap (rp->pPixmap);
703 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", rp->pPixmap);
707 XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
708 dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
714 XDBG_REPLY ( "== PIXMAPS ==\n");
715 XDbgPixmap *cur = NULL, *tmp = NULL;
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);
729 xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
731 if (cur->pPixmap == pPixRoot)
734 if (cur->pPixmap->drawable.id || cur->refs == 0)
736 client_id = CLIENT_ID(cur->pPixmap->drawable.id);
737 if (cur->pPixmap->drawable.id)
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);
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);
756 XDBG_REPLY ("\t[RefHistory] ");
757 for (i = 0; i < cur->numHistory; i++)
759 XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);