Merge lp:~gordallott/unity/perf-logger into lp:unity
- perf-logger
- Merge into trunk
Proposed by
Gord Allott
Status: | Merged |
---|---|
Merged at revision: | 687 |
Proposed branch: | lp:~gordallott/unity/perf-logger |
Merge into: | lp:unity |
Diff against target: |
626 lines (+151/-92) 7 files modified
CMakeLists.txt (+1/-0) libunity/CMakeLists.txt (+1/-0) libunity/perf-logger-utility.h (+34/-0) libunity/perf-logger.vala (+30/-27) src/unity.cpp (+49/-29) tools/CMakeLists.txt (+1/-1) tools/makebootchart.py (+35/-35) |
To merge this branch: | bzr merge lp:~gordallott/unity/perf-logger |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jason Smith (community) | Approve | ||
Review via email: mp+42594@code.launchpad.net |
Commit message
Description of the change
Adds updates the performance logging code for unity
To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote : | # |
It does have a merge conflict with latest trunk however
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2010-11-30 15:44:05 +0000 |
3 | +++ CMakeLists.txt 2010-12-03 08:41:48 +0000 |
4 | @@ -82,6 +82,7 @@ |
5 | PKGDEPS ${UNITY_PLUGIN_DEPS} |
6 | PLUGINDEPS composite opengl |
7 | CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR}" |
8 | + LIBRARIES "unity" |
9 | ) |
10 | |
11 | # |
12 | |
13 | === modified file 'libunity/CMakeLists.txt' |
14 | --- libunity/CMakeLists.txt 2010-11-25 12:08:52 +0000 |
15 | +++ libunity/CMakeLists.txt 2010-12-03 08:41:48 +0000 |
16 | @@ -50,6 +50,7 @@ |
17 | vala_precompile (VALA_C unity-place-activation.vala |
18 | unity-place-browser.vala |
19 | unity-place.vala |
20 | + perf-logger.vala |
21 | PACKAGES gtk+-2.0 gio-2.0 glib-2.0 gobject-2.0 gee-1.0 dbus-glib-1 gio-unix-2.0 |
22 | OPTIONS --thread |
23 | CUSTOM_VAPIS ../vapi/dee-1.0.vapi ../vapi/config.vapi |
24 | |
25 | === added file 'libunity/perf-logger-utility.h' |
26 | --- libunity/perf-logger-utility.h 1970-01-01 00:00:00 +0000 |
27 | +++ libunity/perf-logger-utility.h 2010-12-03 08:41:48 +0000 |
28 | @@ -0,0 +1,34 @@ |
29 | +/* |
30 | + * Copyright (C) 2009-2010 Canonical Ltd |
31 | + * |
32 | + * This program is free software: you can redistribute it and/or modify |
33 | + * it under the terms of the GNU General Public License version 3 as |
34 | + * published by the Free Software Foundation. |
35 | + * |
36 | + * This program is distributed in the hope that it will be useful, |
37 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
38 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
39 | + * GNU General Public License for more details. |
40 | + * |
41 | + * You should have received a copy of the GNU General Public License |
42 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
43 | + * |
44 | + * Authored by Gordon Allott <gord.allott@canonical.com> |
45 | + * |
46 | + */ |
47 | +#ifndef _PERF_LOGGER_H_ |
48 | +#define _PERF_LOGGER_H_ |
49 | + |
50 | +#include <libunity/unity.h> |
51 | + |
52 | +#define START_FUNCTION() G_STMT_START { \ |
53 | + perf_timeline_logger_start_process (perf_timeline_logger_get_default(), G_STRFUNC);\ |
54 | + } G_STMT_END |
55 | +#define LOGGER_START_PROCESS(process) { perf_timeline_logger_start_process (perf_timeline_logger_get_default(), process);} |
56 | + |
57 | +#define END_FUNCTION() G_STMT_START { \ |
58 | + perf_timeline_logger_end_process (perf_timeline_logger_get_default(), G_STRFUNC);\ |
59 | + } G_STMT_END |
60 | +#define LOGGER_END_PROCESS(process) { perf_timeline_logger_end_process (perf_timeline_logger_get_default(), process);} |
61 | + |
62 | +#endif /* PERF_LOGGER_H */ |
63 | |
64 | === renamed file 'unity-private/testing/perf-logger.vala' => 'libunity/perf-logger.vala' |
65 | --- unity-private/testing/perf-logger.vala 2010-04-07 14:46:55 +0000 |
66 | +++ libunity/perf-logger.vala 2010-12-03 08:41:48 +0000 |
67 | @@ -1,5 +1,5 @@ |
68 | /* |
69 | - * Copyright (C) 2009 Canonical Ltd |
70 | + * Copyright (C) 2009-2010 Canonical Ltd |
71 | * |
72 | * This program is free software: you can redistribute it and/or modify |
73 | * it under the terms of the GNU General Public License version 3 as |
74 | @@ -17,9 +17,8 @@ |
75 | * |
76 | */ |
77 | |
78 | -namespace Unity |
79 | +namespace Perf |
80 | { |
81 | - |
82 | public class ProcessInfo |
83 | { |
84 | public ProcessInfo (string name) |
85 | @@ -32,82 +31,86 @@ |
86 | public double start; |
87 | public double end; |
88 | } |
89 | - |
90 | + |
91 | public static TimelineLogger? timeline_singleton; |
92 | - public static bool is_logging; |
93 | - |
94 | + public static bool is_logging; |
95 | + |
96 | public class TimelineLogger : Object |
97 | { |
98 | private Timer global_timer; |
99 | private Gee.HashMap<string, ProcessInfo> process_map; |
100 | - |
101 | - public static unowned Unity.TimelineLogger get_default () |
102 | + |
103 | + public static unowned Perf.TimelineLogger get_default () |
104 | { |
105 | - if (Unity.timeline_singleton == null) |
106 | + if (Perf.timeline_singleton == null) |
107 | { |
108 | - Unity.timeline_singleton = new Unity.TimelineLogger (); |
109 | + Perf.timeline_singleton = new Perf.TimelineLogger (); |
110 | } |
111 | - |
112 | - return Unity.timeline_singleton; |
113 | + |
114 | + return Perf.timeline_singleton; |
115 | } |
116 | - |
117 | + |
118 | construct |
119 | { |
120 | this.process_map = new Gee.HashMap<string, ProcessInfo> (); |
121 | - this.global_timer = new Timer (); |
122 | + this.global_timer = new Timer (); |
123 | this.global_timer.start (); |
124 | } |
125 | - |
126 | + |
127 | public void start_process (string name) |
128 | { |
129 | + debug ("shoop de whoop"); |
130 | if (name in this.process_map.keys) |
131 | { |
132 | warning ("already started process: %s", name); |
133 | return; |
134 | } |
135 | - |
136 | + |
137 | var info = new ProcessInfo (name); |
138 | this.process_map[name] = info; |
139 | info.start = this.global_timer.elapsed (); |
140 | } |
141 | - |
142 | + |
143 | public void end_process (string name) |
144 | { |
145 | + debug ("shonk le donk"); |
146 | double end_time = this.global_timer.elapsed (); |
147 | - |
148 | + print ("the end time is %f", end_time); |
149 | + |
150 | if (name in this.process_map.keys) |
151 | { |
152 | this.process_map[name].end = end_time; |
153 | } |
154 | - else |
155 | + else |
156 | { |
157 | warning ("process %s not started", name); |
158 | } |
159 | } |
160 | - |
161 | + |
162 | public void write_log (string filename) |
163 | { |
164 | debug ("Writing performance log file: %s...", filename); |
165 | var log_file = File.new_for_path (filename); |
166 | FileOutputStream file_stream; |
167 | - try |
168 | + try |
169 | { |
170 | if (!log_file.query_exists (null)) { |
171 | file_stream = log_file.create (FileCreateFlags.NONE, null); |
172 | } |
173 | - else |
174 | + else |
175 | { |
176 | file_stream = log_file.replace (null, false, FileCreateFlags.NONE, null); |
177 | } |
178 | - |
179 | + |
180 | var output_stream = new DataOutputStream (file_stream); |
181 | - |
182 | + |
183 | foreach (ProcessInfo info in this.process_map.values) |
184 | { |
185 | - string outline = "%s, %f, %f\n".printf(info.name, info.start, info.end); |
186 | - output_stream.put_string (outline, null); |
187 | + string name = info.name.replace (",", ";"); |
188 | + string outline = "%s, %f, %f\n".printf(name, info.start, info.end); |
189 | + output_stream.put_string (outline, null); |
190 | } |
191 | - |
192 | + |
193 | file_stream.close (null); |
194 | } catch (Error e) |
195 | { |
196 | |
197 | === modified file 'src/unity.cpp' |
198 | --- src/unity.cpp 2010-11-26 09:11:52 +0000 |
199 | +++ src/unity.cpp 2010-12-03 08:41:48 +0000 |
200 | @@ -39,6 +39,8 @@ |
201 | |
202 | #include <core/atoms.h> |
203 | |
204 | +#include "../libunity/perf-logger-utility.h" |
205 | + |
206 | /* Set up vtable symbols */ |
207 | COMPIZ_PLUGIN_20090315 (unityshell, UnityPluginVTable); |
208 | |
209 | @@ -49,10 +51,10 @@ |
210 | { |
211 | /* reset matrices */ |
212 | glPushAttrib (GL_VIEWPORT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); |
213 | - |
214 | + |
215 | glMatrixMode (GL_PROJECTION); |
216 | glPushMatrix (); |
217 | - |
218 | + |
219 | glMatrixMode (GL_MODELVIEW); |
220 | glPushMatrix (); |
221 | |
222 | @@ -139,19 +141,19 @@ |
223 | std::vector<nux::Geometry>::iterator it; |
224 | std::vector<nux::Geometry> dirty = wt->GetDrawList (); |
225 | nux::Geometry geo; |
226 | - |
227 | + |
228 | for (it = dirty.begin (); it != dirty.end (); it++) |
229 | { |
230 | geo = *it; |
231 | cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height)); |
232 | } |
233 | - |
234 | + |
235 | geo = wt->GetWindowCompositor ().GetTooltipMainWindowGeometry(); |
236 | cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height)); |
237 | cScreen->damageRegion (CompRegion (lastTooltipArea.x, lastTooltipArea.y, lastTooltipArea.width, lastTooltipArea.height)); |
238 | - |
239 | + |
240 | lastTooltipArea = geo; |
241 | - |
242 | + |
243 | wt->ClearDrawList (); |
244 | } |
245 | |
246 | @@ -165,7 +167,7 @@ |
247 | { |
248 | wt->ProcessForeignEvent (event, NULL); |
249 | } |
250 | -} |
251 | +} |
252 | |
253 | |
254 | gboolean |
255 | @@ -258,7 +260,7 @@ |
256 | * stacked on top of one of the nux input windows |
257 | * and if so paint nux and stop us from painting |
258 | * other windows or on top of the whole screen */ |
259 | -bool |
260 | +bool |
261 | UnityWindow::glDraw (const GLMatrix &matrix, |
262 | GLFragment::Attrib &attrib, |
263 | const CompRegion ®ion, |
264 | @@ -278,7 +280,7 @@ |
265 | } |
266 | |
267 | bool ret = gWindow->glDraw (matrix, attrib, region, mask); |
268 | - |
269 | + |
270 | return ret; |
271 | } |
272 | |
273 | @@ -293,7 +295,7 @@ |
274 | } |
275 | |
276 | /* Configure callback for the launcher window */ |
277 | -void |
278 | +void |
279 | UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data) |
280 | { |
281 | int OurWindowHeight = WindowHeight - 24; |
282 | @@ -301,23 +303,25 @@ |
283 | } |
284 | |
285 | /* Configure callback for the panel window */ |
286 | -void |
287 | +void |
288 | UnityScreen::panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data) |
289 | { |
290 | geo = nux::Geometry(0, 0, WindowWidth, 24); |
291 | } |
292 | |
293 | /* Start up nux after OpenGL is initialized */ |
294 | -void |
295 | +void |
296 | UnityScreen::initUnity(nux::NThread* thread, void* InitData) |
297 | { |
298 | + START_FUNCTION (); |
299 | initLauncher(thread, InitData); |
300 | - |
301 | + |
302 | nux::ColorLayer background(nux::Color(0x00000000)); |
303 | static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background); |
304 | + END_FUNCTION (); |
305 | } |
306 | |
307 | -void |
308 | +void |
309 | UnityScreen::onRedrawRequested () |
310 | { |
311 | damageNuxRegions (); |
312 | @@ -342,6 +346,13 @@ |
313 | } |
314 | } |
315 | |
316 | +static gboolean |
317 | +write_logger_data_to_disk (gpointer data) |
318 | +{ |
319 | + perf_timeline_logger_write_log (perf_timeline_logger_get_default (), "/tmp/unity-perf.log"); |
320 | + return FALSE; |
321 | +} |
322 | + |
323 | UnityScreen::UnityScreen (CompScreen *screen) : |
324 | PluginClassHandler <UnityScreen, CompScreen> (screen), |
325 | screen (screen), |
326 | @@ -349,35 +360,37 @@ |
327 | gScreen (GLScreen::get (screen)), |
328 | doShellRepaint (false) |
329 | { |
330 | + START_FUNCTION (); |
331 | int (*old_handler) (Display *, XErrorEvent *); |
332 | old_handler = XSetErrorHandler (NULL); |
333 | - |
334 | + |
335 | g_thread_init (NULL); |
336 | dbus_g_thread_init (); |
337 | gtk_init (NULL, NULL); |
338 | - |
339 | + |
340 | XSetErrorHandler (old_handler); |
341 | |
342 | /* Wrap compiz interfaces */ |
343 | ScreenInterface::setHandler (screen); |
344 | CompositeScreenInterface::setHandler (cScreen); |
345 | GLScreenInterface::setHandler (gScreen); |
346 | - |
347 | + |
348 | StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ()); |
349 | |
350 | nux::NuxInitialize (0); |
351 | - wt = nux::CreateFromForeignWindow (cScreen->output (), |
352 | - glXGetCurrentContext (), |
353 | + wt = nux::CreateFromForeignWindow (cScreen->output (), |
354 | + glXGetCurrentContext (), |
355 | &UnityScreen::initUnity, |
356 | this); |
357 | - |
358 | + |
359 | wt->RedrawRequested.connect (sigc::mem_fun (this, &UnityScreen::onRedrawRequested)); |
360 | - |
361 | + END_FUNCTION (); |
362 | + g_timeout_add (10, write_logger_data_to_disk, NULL); |
363 | wt->Run (NULL); |
364 | uScreen = this; |
365 | |
366 | debugger = new IntrospectionDBusInterface (this); |
367 | - |
368 | + |
369 | PluginAdapter::Initialize (screen); |
370 | |
371 | optionSetLauncherAutohideNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); |
372 | @@ -393,25 +406,28 @@ |
373 | /* Can't create windows until after we have initialized everything */ |
374 | gboolean UnityScreen::strutHackTimeout (gpointer data) |
375 | { |
376 | - UnityScreen *self = (UnityScreen*) data; |
377 | - |
378 | + UnityScreen *self = (UnityScreen*) data; |
379 | + |
380 | if (!self->launcher->AutohideEnabled ()) |
381 | { |
382 | self->launcherWindow->InputWindowEnableStruts(false); |
383 | self->launcherWindow->InputWindowEnableStruts(true); |
384 | } |
385 | - |
386 | + |
387 | self->panelWindow->InputWindowEnableStruts(false); |
388 | self->panelWindow->InputWindowEnableStruts(true); |
389 | - |
390 | + |
391 | return FALSE; |
392 | } |
393 | |
394 | /* Start up the launcher */ |
395 | void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) |
396 | { |
397 | + START_FUNCTION (); |
398 | + |
399 | UnityScreen *self = (UnityScreen*) InitData; |
400 | - |
401 | + |
402 | + LOGGER_START_PROCESS ("initLauncher-Launcher"); |
403 | self->launcherWindow = new nux::BaseWindow(TEXT("")); |
404 | self->launcher = new Launcher(self->launcherWindow); |
405 | self->AddChild (self->launcher); |
406 | @@ -434,8 +450,10 @@ |
407 | self->launcherWindow->InputWindowEnableStruts(true); |
408 | |
409 | self->launcher->SetIconSize (54, 48); |
410 | + LOGGER_END_PROCESS ("initLauncher-Launcher"); |
411 | |
412 | /* Setup panel */ |
413 | + LOGGER_START_PROCESS ("initLauncher-Panel"); |
414 | self->panelView = new PanelView (); |
415 | self->AddChild (self->panelView); |
416 | |
417 | @@ -454,10 +472,12 @@ |
418 | self->panelWindow->SetBackgroundColor(nux::Color(0x00000000)); |
419 | self->panelWindow->SetBlurredBackground(false); |
420 | self->panelWindow->ShowWindow(true); |
421 | - self->panelWindow->EnableInputWindow(true); |
422 | + self->panelWindow->EnableInputWindow(true); |
423 | self->panelWindow->InputWindowEnableStruts(true); |
424 | - |
425 | + LOGGER_END_PROCESS ("initLauncher-Panel"); |
426 | g_timeout_add (2000, &UnityScreen::strutHackTimeout, self); |
427 | + |
428 | + END_FUNCTION (); |
429 | } |
430 | |
431 | /* Window init */ |
432 | |
433 | === modified file 'tools/CMakeLists.txt' |
434 | --- tools/CMakeLists.txt 2010-11-25 15:56:14 +0000 |
435 | +++ tools/CMakeLists.txt 2010-12-03 08:41:48 +0000 |
436 | @@ -1,5 +1,5 @@ |
437 | # |
438 | # Some unity tools |
439 | # |
440 | -install(FILES migrate_favorites.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/) |
441 | +install(FILES makebootchart.py migrate_favorites.py PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib/unity/) |
442 | |
443 | |
444 | === modified file 'tools/makebootchart.py' |
445 | --- tools/makebootchart.py 2010-01-15 12:28:51 +0000 |
446 | +++ tools/makebootchart.py 2010-12-03 08:41:48 +0000 |
447 | @@ -24,8 +24,8 @@ |
448 | import math |
449 | import random |
450 | from string import Template |
451 | -from socket import gethostname |
452 | -from datetime import datetime |
453 | +from socket import gethostname |
454 | +from datetime import datetime |
455 | import re |
456 | import subprocess |
457 | |
458 | @@ -39,22 +39,22 @@ |
459 | if x["start"] - y["start"] < 0: |
460 | return -1 |
461 | else: |
462 | - return +1 |
463 | - |
464 | + return +1 |
465 | + |
466 | def gatherinfo (filename): |
467 | date = datetime.fromtimestamp(os.path.getmtime(filename)) |
468 | - |
469 | + |
470 | cpufile = open ("/proc/cpuinfo") |
471 | cpuinfo = cpufile.read (10024) |
472 | cpure = re.search (r"^model name\s*: (.*$)", cpuinfo, re.MULTILINE) |
473 | cpu = cpure.group(1) |
474 | - |
475 | + |
476 | gpu_prog = subprocess.Popen("glxinfo", stdout=subprocess.PIPE) |
477 | - gpu_prog.wait () |
478 | + gpu_prog.wait () |
479 | gpuinfo = gpu_prog.stdout.read (10024) |
480 | gpure = re.search (r"^OpenGL renderer string: (.*$)", gpuinfo, re.MULTILINE) |
481 | gpu = gpure.group (1) |
482 | - |
483 | + |
484 | return {"hostname":gethostname(), |
485 | "date": date.strftime("%A, %d. %B %Y %I:%M%p"), |
486 | "uname": " ".join (os.uname ()), |
487 | @@ -67,14 +67,14 @@ |
488 | bar_height = 16 |
489 | |
490 | def draw_bg_graph (ctx, seconds, height): |
491 | - |
492 | + |
493 | total_width = seconds * width_multiplier |
494 | ctx.set_source_rgba (0.0, 0.0, 0.0, 0.25) |
495 | - |
496 | + |
497 | ctx.move_to (0, 0) |
498 | ctx.line_to (total_width, 0) |
499 | ctx.stroke () |
500 | - |
501 | + |
502 | per_ten = 0 |
503 | for pos in xrange (0, int(total_width), int (0.01 * width_multiplier)): |
504 | ctx.set_line_width (1) |
505 | @@ -90,67 +90,67 @@ |
506 | ctx.move_to (pos, 0) |
507 | ctx.line_to (pos, height) |
508 | ctx.stroke () |
509 | - |
510 | + |
511 | per_ten += 1 |
512 | per_ten %= 10 |
513 | |
514 | def build_graph (data, filename, info): |
515 | - |
516 | + |
517 | padding_left = 6 |
518 | padding_right = 100 |
519 | padding_top = 6 |
520 | padding_bottom = 6 |
521 | - |
522 | + |
523 | total_size = 0.0 |
524 | for item in data: |
525 | if item['end'] > total_size: |
526 | total_size = item['end'] |
527 | - |
528 | + |
529 | width = total_size * width_multiplier + padding_left + padding_right |
530 | height = (len(data) * (bar_height)) + 80 + padding_bottom + padding_top |
531 | - surface = cairo.SVGSurface(filename, width, height) |
532 | - |
533 | + surface = cairo.SVGSurface(filename, max (width, 800), max (height, 600)) |
534 | + |
535 | ctx = cairo.Context (surface) |
536 | |
537 | #fill background |
538 | ctx.set_source_rgb (1, 1, 1) |
539 | - ctx.rectangle (0, 0, width, height) |
540 | + ctx.rectangle (0, 0, max (width, 800), max (height, 600)) |
541 | ctx.fill () |
542 | - |
543 | + |
544 | #print header |
545 | info['total_time'] = "%s secs" % total_size |
546 | sheader = header.substitute(info) |
547 | - |
548 | + |
549 | ctx.translate (padding_left, padding_top) |
550 | ctx.set_source_rgb (0, 0, 0) |
551 | for line in sheader.split("\n"): |
552 | ctx.translate (0, 12) |
553 | ctx.show_text (line) |
554 | ctx.fill () |
555 | - |
556 | - ctx.translate (0, 12) |
557 | - |
558 | - draw_bg_graph (ctx, total_size, len (data) * bar_height + 16) |
559 | - |
560 | + |
561 | + ctx.translate (6, 12) |
562 | + |
563 | + draw_bg_graph (ctx, total_size + 0.5, max (len (data) * bar_height + 64, 500)) |
564 | + |
565 | ctx.set_line_width (1) |
566 | for item in data: |
567 | x = item['start'] * width_multiplier |
568 | x1 = (item['end'] - item['start']) * width_multiplier |
569 | ctx.translate (x, 0) |
570 | - |
571 | + |
572 | ctx.set_source_rgba (0.35, 0.65, 0.8, 0.5) |
573 | ctx.rectangle (0, 0, x1, 16) |
574 | ctx.fill () |
575 | - |
576 | + |
577 | ctx.set_source_rgba (0.35, 0.65, 0.8, 1.0) |
578 | ctx.rectangle (0, 0, x1, 16) |
579 | ctx.stroke () |
580 | - |
581 | + |
582 | ctx.translate (8, 10) |
583 | ctx.set_source_rgb (0.0, 0.0, 0.0) |
584 | - ctx.show_text ("%s %.2f seconds" % (item['name'], round (item["end"] - item["start"], 2))) |
585 | + ctx.show_text ("%s %.4f seconds" % (item['name'], item["end"] - item["start"])) |
586 | ctx.fill() |
587 | - |
588 | + |
589 | ctx.translate (-x-8, 6) |
590 | |
591 | def build_data_structure (input): |
592 | @@ -162,13 +162,13 @@ |
593 | start = float(row[1]) |
594 | end = float(row[2]) |
595 | structure.append ({"name": name, "start": start, "end": end}) |
596 | - |
597 | + |
598 | structure.sort (sort_by_domain) |
599 | return structure |
600 | - |
601 | + |
602 | |
603 | def usage(): |
604 | - print "use --input=filename.log and --output=filename.svg :)" |
605 | + print "use --input=filename.log and --output=filename.svg :)" |
606 | |
607 | def main(): |
608 | |
609 | @@ -179,7 +179,7 @@ |
610 | print str(err) # will print something like "option -a not recognized" |
611 | usage() |
612 | sys.exit(2) |
613 | - |
614 | + |
615 | output = None |
616 | input = None |
617 | for o, a in opts: |
618 | @@ -196,7 +196,7 @@ |
619 | if (not output or not input): |
620 | usage() |
621 | sys.exit() |
622 | - |
623 | + |
624 | data = build_data_structure (input) |
625 | info = gatherinfo (input) |
626 | build_graph (data, output, info) |
+1 code looks good, everything seems to be in order