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 p_ref = _findXDbgRefPixmap (d, d->pRefPixmap->pPixmap);
455 xorg_list_del (&d->pRefPixmap->link);
456 free (d->pRefPixmap);
459 XDBG_WARNING (MMEM, "Unknown refpixmap : WinPixmap win(0x%x) pixmap(%p) \n",
460 (unsigned int)pWin->drawable.id, d->pRefPixmap->pPixmap);
462 d->pRefPixmap = NULL;
464 if (xorg_list_is_empty (&d->refPixmaps))
466 xorg_list_del (&d->link);
474 XDbgLogDestroyWindow (WindowPtr pWindow)
477 ScreenPtr pScreen = pWindow->drawable.pScreen;
478 XDbgDrawable *d = NULL;
479 XDbgPixmap *p = NULL;
480 XDbgRefPixmap *pos = NULL, *tmp = NULL;
482 pScreen->DestroyWindow = fnDestroyWindow;
483 ret = pScreen->DestroyWindow (pWindow);
484 pScreen->DestroyWindow = XDbgLogDestroyWindow;
486 d = _findXDbgDrawable (&pWindow->drawable);
489 XDBG_TRACE (MMEM, "Remove drawable(0x%x)\n",
490 (unsigned int)pWindow->drawable.id);
492 xorg_list_for_each_entry_safe (pos, tmp, &d->refPixmaps, link)
494 p = _findXDbgPixmap (pos->pPixmap);
498 XDBG_TRACE (MMEM, "Remove ref_pixmap(%p), dbgPixmap(%p)\n",
501 xorg_list_del (&pos->link);
505 xorg_list_del (&d->link);
513 xDbgLogPListInit (ScreenPtr pScreen)
517 xorg_list_init (&xdbgPixmaps);
518 xorg_list_init (&xdbgDrawables);
520 fnSetWindowPixmap = pScreen->SetWindowPixmap;
521 fnDestroyWindow = pScreen->DestroyWindow;
522 fnCreatePixmap = pScreen->CreatePixmap;
523 fnModifyPixmap = pScreen->ModifyPixmapHeader;
524 fnDestroyPixmap = pScreen->DestroyPixmap;
526 pScreen->CreatePixmap = XDbgLogCreatePixmap;
527 pScreen->DestroyPixmap = XDbgLogDestroyPixmap;
528 pScreen->ModifyPixmapHeader = XDbgLogModifyPixmapHeader;
529 pScreen->SetWindowPixmap = XDbgLogSetWindowPixmap;
530 pScreen->DestroyWindow = XDbgLogDestroyWindow;
534 xDbgLogPListDeinit (ScreenPtr pScreen)
539 xDbgLogPListDrawAddRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
541 XDbgDrawable *d = NULL;
542 XDbgPixmap *p = NULL;
543 XDbgRefPixmap *p_ref = NULL;
545 XDBG_RETURN_IF_FAIL (pDraw != NULL);
546 XDBG_RETURN_IF_FAIL (pRefPixmap != NULL);
548 d = _findXDbgDrawable (pDraw);
549 p = _findXDbgPixmap (pRefPixmap);
552 XDBG_WARNING (MMEM, "%s:%d : Unknown pixmap XID:0x%x, pPix:%p\n",
553 __FUNCTION__, __LINE__,
554 (unsigned int)pRefPixmap->drawable.id, pRefPixmap);
560 d = calloc (1, sizeof(XDbgDrawable));
562 xorg_list_init (&d->refPixmaps);
563 xorg_list_add (&d->link, &xdbgDrawables);
565 XDBG_TRACE (MMEM, " Add window(0x%x)\n", (unsigned int)pDraw->id);
568 p_ref =_findXDbgRefPixmap (d, pRefPixmap);
572 p_ref = calloc (1, sizeof(XDbgRefPixmap));
573 p_ref->pPixmap = pRefPixmap;
574 xorg_list_init (&p_ref->link);
575 xorg_list_add (&p_ref->link, &d->refPixmaps);
578 if (p->numHistory < (MAX_HISTORY-1))
579 p->refHistorys[p->numHistory++] = pDraw->id;
581 if (pDraw->type == DRAWABLE_WINDOW)
582 XDBG_TRACE (MMEM, " Add RefPixmap win(0x%x), pixmap(%p) hint:%s\n",
583 (unsigned int)pDraw->id, p->pPixmap, p->hint);
585 XDBG_TRACE (MMEM, " Add RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
586 (unsigned int)pDraw->id, p->pPixmap, p->hint);
590 xDbgLogPListDrawRemoveRefPixmap (DrawablePtr pDraw, PixmapPtr pRefPixmap)
592 XDbgDrawable *d = NULL;
593 XDbgRefPixmap *p_ref = NULL;
594 XDbgPixmap *p = NULL;
596 p = _findXDbgPixmap (pRefPixmap);
599 if (p && p->refs > 0)
601 XDBG_ERROR (MMEM, "Error:%s:%d null draw pixmap(%p)\n",
602 __FUNCTION__, __LINE__, pRefPixmap);
607 d = _findXDbgDrawable (pDraw);
610 XDBG_WARNING (MMEM, "%s:%d : Unknown drawable XID:0x%x, pPix:%p\n",
611 __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
615 p_ref = _findXDbgRefPixmap (d, pRefPixmap);
618 XDBG_WARNING (MMEM, "%s:%d : Unknown refpixmap XID:0x%x, pPix:%p\n",
619 __FUNCTION__, __LINE__, (unsigned int)pDraw->id, pRefPixmap);
623 xorg_list_del (&p_ref->link);
628 if (xorg_list_is_empty (&d->refPixmaps))
630 xorg_list_del(&d->link);
634 if (pDraw->type == DRAWABLE_WINDOW)
635 XDBG_TRACE (MMEM, " Remove RefPixmap win(0x%x), pixmap(%p) hint:%s\n",
636 (unsigned int)pDraw->id, pRefPixmap,
637 _get_pixmap_hint_name(pRefPixmap->usage_hint));
639 XDBG_TRACE (MMEM, " Remove RefPixmap pix(0x%x), pixmap(%p) hint:%s\n",
640 (unsigned int)pDraw->id, pRefPixmap,
641 _get_pixmap_hint_name(pRefPixmap->usage_hint));
646 xDbgLogPList (char *reply, int *len)
650 XDBG_REPLY ("plist is not supported.\n");
654 XDBG_REPLY ("\n\n====================================\n");
655 XDBG_REPLY (" Total:%d, Peek:%d\n", (unsigned int)total_size/1024, (unsigned int)peek_size/1024);
656 XDBG_REPLY ( "====================================\n");
658 XDBG_REPLY ("== WINDOWS ==\n");
659 XDbgDrawable *dd = NULL, *ddtmp = NULL;
660 XDbgRefPixmap *rp = NULL, *rptmp = NULL;
661 XDbgPixmap *dp = NULL;
663 xorg_list_for_each_entry_safe (dd, ddtmp, &xdbgDrawables, link)
665 XDBG_REPLY ("[%d] XID:0x%x type:%s %dx%d+%d+%d\n",
666 CLIENT_ID(dd->pDraw->id),
667 (unsigned int)dd->pDraw->id,
668 (dd->pDraw->type == DRAWABLE_WINDOW ? "window":"pixmap"),
669 dd->pDraw->width, dd->pDraw->height, dd->pDraw->x, dd->pDraw->y);
671 xorg_list_for_each_entry_safe (rp, rptmp, &dd->refPixmaps, link)
673 dp = _findXDbgPixmap (rp->pPixmap);
676 XDBG_REPLY ("\t***[REF_Pixmap] unknown pixmap(%p)\n", rp->pPixmap);
680 XDBG_REPLY ("\t[REF_Pixmap] %p, hint:%s, size:%d\n",
681 dp->pPixmap, dp->hint, (unsigned int)dp->size/1024);
687 XDBG_REPLY ( "== PIXMAPS ==\n");
688 XDbgPixmap *cur = NULL, *tmp = NULL;
694 cur = _findXDbgPixmap (pPixRoot);
695 XDBG_RETURN_IF_FAIL (cur != NULL);
696 XDBG_REPLY ("ROOT_Pixmap XID:0x%x pixmap(%p) hint:%s(0x%x) size:%d\n",
697 (unsigned int)cur->pPixmap->drawable.id, pPixRoot,
698 cur->hint, cur->pPixmap->usage_hint,
699 (unsigned int)cur->size/1024);
702 xorg_list_for_each_entry_safe (cur, tmp, &xdbgPixmaps, link)
704 if (cur->pPixmap == pPixRoot)
707 if (cur->pPixmap->drawable.id || cur->refs == 0)
709 client_id = CLIENT_ID(cur->pPixmap->drawable.id);
710 if (cur->pPixmap->drawable.id)
712 XDBG_REPLY ("[%d] XID:0x%x %dx%d hint:%s(0x%x) size:%d refs:%d\n",
713 client_id, (unsigned int)cur->pPixmap->drawable.id,
714 cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
715 cur->hint, cur->pPixmap->usage_hint,
716 (unsigned int)cur->size/1024, cur->refs);
720 XDBG_REPLY ("[%d] Pixmap:%p %dx%d hint:%s(0x%x) size:%d refs:%d\n",
721 client_id, cur->pPixmap,
722 cur->pPixmap->drawable.width, cur->pPixmap->drawable.height,
723 cur->hint, cur->pPixmap->usage_hint,
724 (unsigned int)cur->size/1024, cur->refs);
729 XDBG_REPLY ("\t[RefHistory] ");
730 for (i = 0; i < cur->numHistory; i++)
732 XDBG_REPLY ("0x%x ", (unsigned int)cur->refHistorys[i]);