Back to home page

OSCL-LXR

 
 

    


0001 # SchedGui.py - Python extension for perf script, basic GUI code for
0002 #       traces drawing and overview.
0003 #
0004 # Copyright (C) 2010 by Frederic Weisbecker <fweisbec@gmail.com>
0005 #
0006 # This software is distributed under the terms of the GNU General
0007 # Public License ("GPL") version 2 as published by the Free Software
0008 # Foundation.
0009 
0010 
0011 try:
0012     import wx
0013 except ImportError:
0014     raise ImportError("You need to install the wxpython lib for this script")
0015 
0016 
0017 class RootFrame(wx.Frame):
0018     Y_OFFSET = 100
0019     RECT_HEIGHT = 100
0020     RECT_SPACE = 50
0021     EVENT_MARKING_WIDTH = 5
0022 
0023     def __init__(self, sched_tracer, title, parent = None, id = -1):
0024         wx.Frame.__init__(self, parent, id, title)
0025 
0026         (self.screen_width, self.screen_height) = wx.GetDisplaySize()
0027         self.screen_width -= 10
0028         self.screen_height -= 10
0029         self.zoom = 0.5
0030         self.scroll_scale = 20
0031         self.sched_tracer = sched_tracer
0032         self.sched_tracer.set_root_win(self)
0033         (self.ts_start, self.ts_end) = sched_tracer.interval()
0034         self.update_width_virtual()
0035         self.nr_rects = sched_tracer.nr_rectangles() + 1
0036         self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
0037 
0038         # whole window panel
0039         self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
0040 
0041         # scrollable container
0042         self.scroll = wx.ScrolledWindow(self.panel)
0043         self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
0044         self.scroll.EnableScrolling(True, True)
0045         self.scroll.SetFocus()
0046 
0047         # scrollable drawing area
0048         self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
0049         self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
0050         self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
0051         self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
0052         self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
0053         self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
0054         self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
0055 
0056         self.scroll.Fit()
0057         self.Fit()
0058 
0059         self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
0060 
0061         self.txt = None
0062 
0063         self.Show(True)
0064 
0065     def us_to_px(self, val):
0066         return val / (10 ** 3) * self.zoom
0067 
0068     def px_to_us(self, val):
0069         return (val / self.zoom) * (10 ** 3)
0070 
0071     def scroll_start(self):
0072         (x, y) = self.scroll.GetViewStart()
0073         return (x * self.scroll_scale, y * self.scroll_scale)
0074 
0075     def scroll_start_us(self):
0076         (x, y) = self.scroll_start()
0077         return self.px_to_us(x)
0078 
0079     def paint_rectangle_zone(self, nr, color, top_color, start, end):
0080         offset_px = self.us_to_px(start - self.ts_start)
0081         width_px = self.us_to_px(end - self.ts_start)
0082 
0083         offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
0084         width_py = RootFrame.RECT_HEIGHT
0085 
0086         dc = self.dc
0087 
0088         if top_color is not None:
0089             (r, g, b) = top_color
0090             top_color = wx.Colour(r, g, b)
0091             brush = wx.Brush(top_color, wx.SOLID)
0092             dc.SetBrush(brush)
0093             dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
0094             width_py -= RootFrame.EVENT_MARKING_WIDTH
0095             offset_py += RootFrame.EVENT_MARKING_WIDTH
0096 
0097         (r ,g, b) = color
0098         color = wx.Colour(r, g, b)
0099         brush = wx.Brush(color, wx.SOLID)
0100         dc.SetBrush(brush)
0101         dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
0102 
0103     def update_rectangles(self, dc, start, end):
0104         start += self.ts_start
0105         end += self.ts_start
0106         self.sched_tracer.fill_zone(start, end)
0107 
0108     def on_paint(self, event):
0109         dc = wx.PaintDC(self.scroll_panel)
0110         self.dc = dc
0111 
0112         width = min(self.width_virtual, self.screen_width)
0113         (x, y) = self.scroll_start()
0114         start = self.px_to_us(x)
0115         end = self.px_to_us(x + width)
0116         self.update_rectangles(dc, start, end)
0117 
0118     def rect_from_ypixel(self, y):
0119         y -= RootFrame.Y_OFFSET
0120         rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
0121         height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
0122 
0123         if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
0124             return -1
0125 
0126         return rect
0127 
0128     def update_summary(self, txt):
0129         if self.txt:
0130             self.txt.Destroy()
0131         self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
0132 
0133 
0134     def on_mouse_down(self, event):
0135         (x, y) = event.GetPositionTuple()
0136         rect = self.rect_from_ypixel(y)
0137         if rect == -1:
0138             return
0139 
0140         t = self.px_to_us(x) + self.ts_start
0141 
0142         self.sched_tracer.mouse_down(rect, t)
0143 
0144 
0145     def update_width_virtual(self):
0146         self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
0147 
0148     def __zoom(self, x):
0149         self.update_width_virtual()
0150         (xpos, ypos) = self.scroll.GetViewStart()
0151         xpos = self.us_to_px(x) / self.scroll_scale
0152         self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
0153         self.Refresh()
0154 
0155     def zoom_in(self):
0156         x = self.scroll_start_us()
0157         self.zoom *= 2
0158         self.__zoom(x)
0159 
0160     def zoom_out(self):
0161         x = self.scroll_start_us()
0162         self.zoom /= 2
0163         self.__zoom(x)
0164 
0165 
0166     def on_key_press(self, event):
0167         key = event.GetRawKeyCode()
0168         if key == ord("+"):
0169             self.zoom_in()
0170             return
0171         if key == ord("-"):
0172             self.zoom_out()
0173             return
0174 
0175         key = event.GetKeyCode()
0176         (x, y) = self.scroll.GetViewStart()
0177         if key == wx.WXK_RIGHT:
0178             self.scroll.Scroll(x + 1, y)
0179         elif key == wx.WXK_LEFT:
0180             self.scroll.Scroll(x - 1, y)
0181         elif key == wx.WXK_DOWN:
0182             self.scroll.Scroll(x, y + 1)
0183         elif key == wx.WXK_UP:
0184             self.scroll.Scroll(x, y - 1)