Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace/SchedGui.py
10832 views
1
# SchedGui.py - Python extension for perf script, basic GUI code for
2
# traces drawing and overview.
3
#
4
# Copyright (C) 2010 by Frederic Weisbecker <[email protected]>
5
#
6
# This software is distributed under the terms of the GNU General
7
# Public License ("GPL") version 2 as published by the Free Software
8
# Foundation.
9
10
11
try:
12
import wx
13
except ImportError:
14
raise ImportError, "You need to install the wxpython lib for this script"
15
16
17
class RootFrame(wx.Frame):
18
Y_OFFSET = 100
19
RECT_HEIGHT = 100
20
RECT_SPACE = 50
21
EVENT_MARKING_WIDTH = 5
22
23
def __init__(self, sched_tracer, title, parent = None, id = -1):
24
wx.Frame.__init__(self, parent, id, title)
25
26
(self.screen_width, self.screen_height) = wx.GetDisplaySize()
27
self.screen_width -= 10
28
self.screen_height -= 10
29
self.zoom = 0.5
30
self.scroll_scale = 20
31
self.sched_tracer = sched_tracer
32
self.sched_tracer.set_root_win(self)
33
(self.ts_start, self.ts_end) = sched_tracer.interval()
34
self.update_width_virtual()
35
self.nr_rects = sched_tracer.nr_rectangles() + 1
36
self.height_virtual = RootFrame.Y_OFFSET + (self.nr_rects * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
37
38
# whole window panel
39
self.panel = wx.Panel(self, size=(self.screen_width, self.screen_height))
40
41
# scrollable container
42
self.scroll = wx.ScrolledWindow(self.panel)
43
self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale)
44
self.scroll.EnableScrolling(True, True)
45
self.scroll.SetFocus()
46
47
# scrollable drawing area
48
self.scroll_panel = wx.Panel(self.scroll, size=(self.screen_width - 15, self.screen_height / 2))
49
self.scroll_panel.Bind(wx.EVT_PAINT, self.on_paint)
50
self.scroll_panel.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
51
self.scroll_panel.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
52
self.scroll.Bind(wx.EVT_PAINT, self.on_paint)
53
self.scroll.Bind(wx.EVT_KEY_DOWN, self.on_key_press)
54
self.scroll.Bind(wx.EVT_LEFT_DOWN, self.on_mouse_down)
55
56
self.scroll.Fit()
57
self.Fit()
58
59
self.scroll_panel.SetDimensions(-1, -1, self.width_virtual, self.height_virtual, wx.SIZE_USE_EXISTING)
60
61
self.txt = None
62
63
self.Show(True)
64
65
def us_to_px(self, val):
66
return val / (10 ** 3) * self.zoom
67
68
def px_to_us(self, val):
69
return (val / self.zoom) * (10 ** 3)
70
71
def scroll_start(self):
72
(x, y) = self.scroll.GetViewStart()
73
return (x * self.scroll_scale, y * self.scroll_scale)
74
75
def scroll_start_us(self):
76
(x, y) = self.scroll_start()
77
return self.px_to_us(x)
78
79
def paint_rectangle_zone(self, nr, color, top_color, start, end):
80
offset_px = self.us_to_px(start - self.ts_start)
81
width_px = self.us_to_px(end - self.ts_start)
82
83
offset_py = RootFrame.Y_OFFSET + (nr * (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE))
84
width_py = RootFrame.RECT_HEIGHT
85
86
dc = self.dc
87
88
if top_color is not None:
89
(r, g, b) = top_color
90
top_color = wx.Colour(r, g, b)
91
brush = wx.Brush(top_color, wx.SOLID)
92
dc.SetBrush(brush)
93
dc.DrawRectangle(offset_px, offset_py, width_px, RootFrame.EVENT_MARKING_WIDTH)
94
width_py -= RootFrame.EVENT_MARKING_WIDTH
95
offset_py += RootFrame.EVENT_MARKING_WIDTH
96
97
(r ,g, b) = color
98
color = wx.Colour(r, g, b)
99
brush = wx.Brush(color, wx.SOLID)
100
dc.SetBrush(brush)
101
dc.DrawRectangle(offset_px, offset_py, width_px, width_py)
102
103
def update_rectangles(self, dc, start, end):
104
start += self.ts_start
105
end += self.ts_start
106
self.sched_tracer.fill_zone(start, end)
107
108
def on_paint(self, event):
109
dc = wx.PaintDC(self.scroll_panel)
110
self.dc = dc
111
112
width = min(self.width_virtual, self.screen_width)
113
(x, y) = self.scroll_start()
114
start = self.px_to_us(x)
115
end = self.px_to_us(x + width)
116
self.update_rectangles(dc, start, end)
117
118
def rect_from_ypixel(self, y):
119
y -= RootFrame.Y_OFFSET
120
rect = y / (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
121
height = y % (RootFrame.RECT_HEIGHT + RootFrame.RECT_SPACE)
122
123
if rect < 0 or rect > self.nr_rects - 1 or height > RootFrame.RECT_HEIGHT:
124
return -1
125
126
return rect
127
128
def update_summary(self, txt):
129
if self.txt:
130
self.txt.Destroy()
131
self.txt = wx.StaticText(self.panel, -1, txt, (0, (self.screen_height / 2) + 50))
132
133
134
def on_mouse_down(self, event):
135
(x, y) = event.GetPositionTuple()
136
rect = self.rect_from_ypixel(y)
137
if rect == -1:
138
return
139
140
t = self.px_to_us(x) + self.ts_start
141
142
self.sched_tracer.mouse_down(rect, t)
143
144
145
def update_width_virtual(self):
146
self.width_virtual = self.us_to_px(self.ts_end - self.ts_start)
147
148
def __zoom(self, x):
149
self.update_width_virtual()
150
(xpos, ypos) = self.scroll.GetViewStart()
151
xpos = self.us_to_px(x) / self.scroll_scale
152
self.scroll.SetScrollbars(self.scroll_scale, self.scroll_scale, self.width_virtual / self.scroll_scale, self.height_virtual / self.scroll_scale, xpos, ypos)
153
self.Refresh()
154
155
def zoom_in(self):
156
x = self.scroll_start_us()
157
self.zoom *= 2
158
self.__zoom(x)
159
160
def zoom_out(self):
161
x = self.scroll_start_us()
162
self.zoom /= 2
163
self.__zoom(x)
164
165
166
def on_key_press(self, event):
167
key = event.GetRawKeyCode()
168
if key == ord("+"):
169
self.zoom_in()
170
return
171
if key == ord("-"):
172
self.zoom_out()
173
return
174
175
key = event.GetKeyCode()
176
(x, y) = self.scroll.GetViewStart()
177
if key == wx.WXK_RIGHT:
178
self.scroll.Scroll(x + 1, y)
179
elif key == wx.WXK_LEFT:
180
self.scroll.Scroll(x - 1, y)
181
elif key == wx.WXK_DOWN:
182
self.scroll.Scroll(x, y + 1)
183
elif key == wx.WXK_UP:
184
self.scroll.Scroll(x, y - 1)
185
186