2 * Copyright (C) 2076 Robin Gareus <robin@gareus.org>
3 * Copyright (C) 2011 Paul Davis
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #include <gtkmm/table.h>
23 #include "idleometer.h"
26 static int64_t _x_get_monotonic_usec() {
27 #ifdef PLATFORM_WINDOWS
28 return PBD::get_microseconds();
30 return g_get_monotonic_time();
35 IdleOMeter::IdleOMeter ()
36 : ArdourDialog (_("Idle O Meter"))
38 get_vbox()->set_spacing (8);
39 Label* l = manage (new Label (_("<b>GUI Idle Timing Statistics</b>"), ALIGN_CENTER));
42 get_vbox()->pack_start (*l, false, false);
44 HBox* b = manage (new HBox ());
45 Table* t = manage (new Table ());
46 b->pack_start (*t, true, false);
47 get_vbox()->pack_start (*b, false, false);
49 _label_cur.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
50 _label_min.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
51 _label_max.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
52 _label_avg.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
53 _label_dev.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
56 t->attach (*manage (new Label (_("Current:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
57 t->attach (_label_cur, 1, 2, row, row + 1, FILL, SHRINK);
59 t->attach (*manage (new Label (_("Min:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
60 t->attach (_label_min, 1, 2, row, row + 1, FILL, SHRINK);
62 t->attach (*manage (new Label (_("Max:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
63 t->attach (_label_max, 1, 2, row, row + 1, FILL, SHRINK);
65 t->attach (*manage (new Label (_("Mean:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
66 t->attach (_label_avg, 1, 2, row, row + 1, FILL, SHRINK);
68 t->attach (*manage (new Label (_("\u03c3:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
69 t->attach (_label_dev, 1, 2, row, row + 1, FILL, SHRINK);
72 IdleOMeter::~IdleOMeter ()
74 _idle_connection.disconnect ();
80 const int64_t now = _x_get_monotonic_usec ();
81 const int64_t elapsed = now - _last;
83 _max = std::max (_max, elapsed);
84 _min = std::min (_min, elapsed);
89 const double cnt = _cnt;
91 /* running variance */
96 const double var_m1 = _var_m;
97 const double t = elapsed;
98 _var_m += (t - _var_m) / cnt;
99 _var_s += (t - _var_m) * (t - var_m1);
102 if (now - _last_display < 80000 || _cnt < 2) {
106 const double avg = _total / cnt;
107 const double stddev = sqrt (_var_s / (_cnt - 1.0));
112 snprintf (buf, sizeof(buf), "%8.2f ms", elapsed / 1000.0);
113 _label_cur.set_text (buf);
114 snprintf (buf, sizeof(buf), "%8.2f ms", _min / 1000.0);
115 _label_min.set_text (buf);
116 snprintf (buf, sizeof(buf), "%8.2f ms", _max / 1000.0);
117 _label_max.set_text (buf);
118 snprintf (buf, sizeof(buf), "%8.3f ms", avg / 1000.0);
119 _label_avg.set_text (buf);
120 snprintf (buf, sizeof(buf), "%8.3f ms", stddev / 1000.0);
121 _label_dev.set_text (buf);
129 _last = _x_get_monotonic_usec ();
130 _last_display = _last;
134 _total = _var_m = _var_s = 0;
136 _label_cur.set_text ("-");
137 _label_min.set_text ("-");
138 _label_max.set_text ("-");
139 _label_avg.set_text ("-");
140 _label_dev.set_text ("-");
144 IdleOMeter::on_show ()
146 ArdourDialog::on_show ();
148 _idle_connection = Glib::signal_idle().connect (sigc::mem_fun (*this, &IdleOMeter::idle));
152 IdleOMeter::on_hide ()
154 _idle_connection.disconnect ();
155 ArdourDialog::on_hide ();