Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / tools / perf / scripts / python / Perf-Trace-Util / lib / Perf / Trace / SchedGui.py
diff --git a/kernel/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py b/kernel/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py
new file mode 100644 (file)
index 0000000..fdd92f6
--- /dev/null
@@ -0,0 +1,184 @@
+# SchedGui.py - Python extension for perf script, basic GUI code for
+#              traces drawing and overview.
+#
+# Copyright (C) 2010 by Frederic Weisbecker <fweisbec@gmail.com>
+#
+# This software is distributed under the terms of the GNU General
+# Public License ("GPL") version 2 as published by the Free Software
+# Foundation.
+
+
+try:
+       import wx
+except ImportError:
+       raise ImportError, "You need to install the wxpython lib for this script"
+
+
+class RootFrame(wx.Frame):
+       Y_OFFSET = 100
+       RECT_HEIGHT = 100
+       RECT_SPACE = 50
+       EVENT_MARKING_WIDTH = 5
+
+       def __init__(self, sched_tracer, title, parent = None, id = -1):
+               wx.Frame.__init__(self, parent, id, title)
+
+               (self.screen_width, self.screen_height) = wx.GetDisplaySize()
+               self.screen_width -= 10
+               self.screen_height -= 10
+               self.zoom = 0.5
+               self.scroll_scale = 20
+               self.sched_tracer = sched_tracer
+               self.sched_tracer.set_root_win(self)
+               (self.ts_start, self.ts_end) = sched_tracer.interval()
+               self.update_width_virtual()
+               self.nr_rects = sched_tracer.nr_rectangles() + 1
+               self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
+
+               # whole window panel
+               self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
+
+               # scrollable container
+               self.scroll = wx.ScrolledWindow(self.panel)
+               self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
+               self.scroll.EnableScrolling(True, True)
+               self.scroll.SetFocus()
+
+               # scrollable drawing area
+               self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
+               self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
+               self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
+               self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
+               self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
+               self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
+               self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
+
+               self.scroll.Fit()
+               self.Fit()
+
+               self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
+
+               self.txt = None
+
+               self.Show(True)
+
+       def us_to_px(self, val):
+               return val / (10 ** 3) * self.zoom
+
+       def px_to_us(self, val):
+               return (val / self.zoom) * (10 ** 3)
+
+       def scroll_start(self):
+               (x, y) = self.scroll.GetViewStart()
+               return (x * self.scroll_scale, y * self.scroll_scale)
+
+       def scroll_start_us(self):
+               (x, y) = self.scroll_start()
+               return self.px_to_us(x)
+
+       def paint_rectangle_zone(self, nr, color, top_color, start, end):
+               offset_px = self.us_to_px(start - self.ts_start)
+               width_px = self.us_to_px(end - self.ts_start)
+
+               offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
+               width_py = RootFrame.RECT_HEIGHT
+
+               dc = self.dc
+
+               if top_color is not None:
+                       (r, g, b) = top_color
+                       top_color = wx.Colour(r, g, b)
+                       brush = wx.Brush(top_color, wx.SOLID)
+                       dc.SetBrush(brush)
+                       dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
+                       width_py -= RootFrame.EVENT_MARKING_WIDTH
+                       offset_py += RootFrame.EVENT_MARKING_WIDTH
+
+               (r ,g, b) = color
+               color = wx.Colour(r, g, b)
+               brush = wx.Brush(color, wx.SOLID)
+               dc.SetBrush(brush)
+               dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
+
+       def update_rectangles(self, dc, start, end):
+               start += self.ts_start
+               end += self.ts_start
+               self.sched_tracer.fill_zone(start, end)
+
+       def on_paint(self, event):
+               dc = wx.PaintDC(self.scroll_panel)
+               self.dc = dc
+
+               width = min(self.width_virtual, self.screen_width)
+               (x, y) = self.scroll_start()
+               start = self.px_to_us(x)
+               end = self.px_to_us(x + width)
+               self.update_rectangles(dc, start, end)
+
+       def rect_from_ypixel(self, y):
+               y -= RootFrame.Y_OFFSET
+               rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
+               height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
+
+               if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
+                       return -1
+
+               return rect
+
+       def update_summary(self, txt):
+               if self.txt:
+                       self.txt.Destroy()
+               self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
+
+
+       def on_mouse_down(self, event):
+               (x, y) = event.GetPositionTuple()
+               rect = self.rect_from_ypixel(y)
+               if rect == -1:
+                       return
+
+               t = self.px_to_us(x) + self.ts_start
+
+               self.sched_tracer.mouse_down(rect, t)
+
+
+       def update_width_virtual(self):
+               self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
+
+       def __zoom(self, x):
+               self.update_width_virtual()
+               (xpos, ypos) = self.scroll.GetViewStart()
+               xpos = self.us_to_px(x) / self.scroll_scale
+               self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
+               self.Refresh()
+
+       def zoom_in(self):
+               x = self.scroll_start_us()
+               self.zoom *= 2
+               self.__zoom(x)
+
+       def zoom_out(self):
+               x = self.scroll_start_us()
+               self.zoom /= 2
+               self.__zoom(x)
+
+
+       def on_key_press(self, event):
+               key = event.GetRawKeyCode()
+               if key == ord("+"):
+                       self.zoom_in()
+                       return
+               if key == ord("-"):
+                       self.zoom_out()
+                       return
+
+               key = event.GetKeyCode()
+               (x, y) = self.scroll.GetViewStart()
+               if key == wx.WXK_RIGHT:
+                       self.scroll.Scroll(x + 1, y)
+               elif key == wx.WXK_LEFT:
+                       self.scroll.Scroll(x - 1, y)
+               elif key == wx.WXK_DOWN:
+                       self.scroll.Scroll(x, y + 1)
+               elif key == wx.WXK_UP:
+                       self.scroll.Scroll(x, y - 1)