summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2017-03-15 11:34:05 +0100
committerRobin Gareus <robin@gareus.org>2017-03-15 11:34:05 +0100
commit4ae5737beb158b14003b87e29dac10431cbab14b (patch)
tree615ab493aab397a230161bfb88e97ab394e8a7df
parentcd4462323f6820fee53e26168cb3e8b46d9edd0b (diff)
Add GUI-Idle debugging/profiling util
-rw-r--r--gtk2_ardour/ardour.menus.in3
-rw-r--r--gtk2_ardour/ardour_ui.cc4
-rw-r--r--gtk2_ardour/ardour_ui.h3
-rw-r--r--gtk2_ardour/idleometer.cc156
-rw-r--r--gtk2_ardour/idleometer.h58
-rw-r--r--gtk2_ardour/wscript1
6 files changed, 225 insertions, 0 deletions
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index 622aa95fa4..898d9fb8a9 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -573,6 +573,9 @@
#if 0
<menuitem action='toggle-speaker-config'/>
#endif
+#if 0
+ <menuitem action='toggle-idle-o-meter'/>
+#endif
<separator/>
#ifdef MIXBUS
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 10d637d2e9..1cf2d3f79f 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -142,6 +142,7 @@ typedef uint64_t microseconds_t;
#include "global_port_matrix.h"
#include "gui_object.h"
#include "gui_thread.h"
+#include "idleometer.h"
#include "keyboard.h"
#include "keyeditor.h"
#include "location_ui.h"
@@ -308,6 +309,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
, audio_midi_setup (X_("audio-midi-setup"), _("Audio/MIDI Setup"))
, export_video_dialog (X_("video-export"), _("Video Export Dialog"))
, lua_script_window (X_("script-manager"), _("Script Manager"))
+ , idleometer (X_("idle-o-meter"), _("Idle'o'Meter"))
, session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
, add_video_dialog (X_("add-video"), _("Add Video"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
, bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
@@ -479,6 +481,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
midi_port_matrix.set_state (*ui_xml, 0);
export_video_dialog.set_state (*ui_xml, 0);
lua_script_window.set_state (*ui_xml, 0);
+ idleometer.set_state (*ui_xml, 0);
}
/* Separate windows */
@@ -498,6 +501,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
WM::Manager::instance().register_window (&big_clock_window);
WM::Manager::instance().register_window (&audio_port_matrix);
WM::Manager::instance().register_window (&midi_port_matrix);
+ WM::Manager::instance().register_window (&idleometer);
/* do not retain position for add route dialog */
add_route_dialog.set_state_mask (WindowProxy::Size);
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 0073a36edc..93a9a0ef73 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -90,6 +90,7 @@
#include "engine_dialog.h"
#include "export_video_dialog.h"
#include "global_port_matrix.h"
+#include "idleometer.h"
#include "keyeditor.h"
#include "location_ui.h"
#include "lua_script_manager.h"
@@ -114,6 +115,7 @@ class RouteParams_UI;
class SessionOptionEditor;
class SpeakerDialog;
class GlobalPortMatrixWindow;
+class IdleOMeter;
#endif
class VideoTimeLine;
@@ -729,6 +731,7 @@ private:
WM::Proxy<EngineControl> audio_midi_setup;
WM::Proxy<ExportVideoDialog> export_video_dialog;
WM::Proxy<LuaScriptManager> lua_script_window;
+ WM::Proxy<IdleOMeter> idleometer;
/* Windows/Dialogs that require a creator method */
diff --git a/gtk2_ardour/idleometer.cc b/gtk2_ardour/idleometer.cc
new file mode 100644
index 0000000000..56b50c5f3e
--- /dev/null
+++ b/gtk2_ardour/idleometer.cc
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2076 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2011 Paul Davis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <gtkmm/table.h>
+
+#include "idleometer.h"
+#include "pbd/i18n.h"
+
+static int64_t _x_get_monotonic_usec() {
+#ifdef PLATFORM_WINDOWS
+ return PBD::get_microseconds();
+#endif
+ return g_get_monotonic_time();
+}
+
+using namespace Gtk;
+
+IdleOMeter::IdleOMeter ()
+ : ArdourDialog (_("Idle O Meter"))
+{
+ get_vbox()->set_spacing (8);
+ Label* l = manage (new Label (_("<b>GUI Idle Timing Statistics</b>"), ALIGN_CENTER));
+ l->set_use_markup ();
+
+ get_vbox()->pack_start (*l, false, false);
+
+ HBox* b = manage (new HBox ());
+ Table* t = manage (new Table ());
+ b->pack_start (*t, true, false);
+ get_vbox()->pack_start (*b, false, false);
+
+ _label_cur.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
+ _label_min.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
+ _label_max.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
+ _label_avg.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
+ _label_dev.set_alignment (ALIGN_RIGHT, ALIGN_CENTER);
+
+ int row = 0;
+ t->attach (*manage (new Label (_("Current:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
+ t->attach (_label_cur, 1, 2, row, row + 1, FILL, SHRINK);
+ ++row;
+ t->attach (*manage (new Label (_("Min:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
+ t->attach (_label_min, 1, 2, row, row + 1, FILL, SHRINK);
+ ++row;
+ t->attach (*manage (new Label (_("Max:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
+ t->attach (_label_max, 1, 2, row, row + 1, FILL, SHRINK);
+ ++row;
+ t->attach (*manage (new Label (_("Mean:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
+ t->attach (_label_avg, 1, 2, row, row + 1, FILL, SHRINK);
+ ++row;
+ t->attach (*manage (new Label (_("\u03c3:"), ALIGN_RIGHT)), 0, 1, row, row + 1, FILL, SHRINK);
+ t->attach (_label_dev, 1, 2, row, row + 1, FILL, SHRINK);
+}
+
+IdleOMeter::~IdleOMeter ()
+{
+ _idle_connection.disconnect ();
+}
+
+bool
+IdleOMeter::idle ()
+{
+ const int64_t now = _x_get_monotonic_usec ();
+ const int64_t elapsed = now - _last;
+
+ _max = std::max (_max, elapsed);
+ _min = std::min (_min, elapsed);
+ _last = now;
+ _total += elapsed;
+ ++_cnt;
+
+ const double cnt = _cnt;
+
+ /* running variance */
+ if (_cnt <= 1) {
+ _var_m = elapsed;
+ _var_s = 0;
+ } else {
+ const double var_m1 = _var_m;
+ const double t = elapsed;
+ _var_m += (t - _var_m) / cnt;
+ _var_s += (t - _var_m) * (t - var_m1);
+ }
+
+ if (now - _last_display < 80000 || _cnt < 2) {
+ return true;
+ }
+
+ const double avg = _total / cnt;
+ const double stddev = sqrt (_var_s / (_cnt - 1.0));
+ _last_display = now;
+
+ char buf[128];
+
+ snprintf (buf, sizeof(buf), "%8.2f ms", elapsed / 1000.0);
+ _label_cur.set_text (buf);
+ snprintf (buf, sizeof(buf), "%8.2f ms", _min / 1000.0);
+ _label_min.set_text (buf);
+ snprintf (buf, sizeof(buf), "%8.2f ms", _max / 1000.0);
+ _label_max.set_text (buf);
+ snprintf (buf, sizeof(buf), "%8.3f ms", avg / 1000.0);
+ _label_avg.set_text (buf);
+ snprintf (buf, sizeof(buf), "%8.3f ms", stddev / 1000.0);
+ _label_dev.set_text (buf);
+
+ return true;
+}
+
+void
+IdleOMeter::reset ()
+{
+ _last = _x_get_monotonic_usec ();
+ _last_display = _last;
+ _max = 0;
+ _min = INT64_MAX;
+ _cnt = 0;
+ _total = _var_m = _var_s = 0;
+
+ _label_cur.set_text ("-");
+ _label_min.set_text ("-");
+ _label_max.set_text ("-");
+ _label_avg.set_text ("-");
+ _label_dev.set_text ("-");
+}
+
+void
+IdleOMeter::on_show ()
+{
+ ArdourDialog::on_show ();
+ reset ();
+ _idle_connection = Glib::signal_idle().connect (sigc::mem_fun (*this, &IdleOMeter::idle));
+}
+
+void
+IdleOMeter::on_hide ()
+{
+ _idle_connection.disconnect ();
+ ArdourDialog::on_hide ();
+}
diff --git a/gtk2_ardour/idleometer.h b/gtk2_ardour/idleometer.h
new file mode 100644
index 0000000000..9fcf2a7353
--- /dev/null
+++ b/gtk2_ardour/idleometer.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2076 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2011 Paul Davis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ardour_idle_o_meter_h__
+#define __ardour_idle_o_meter_h__
+
+#include <gtkmm/label.h>
+#include "ardour_dialog.h"
+
+class IdleOMeter : public ArdourDialog
+{
+public:
+ IdleOMeter ();
+ ~IdleOMeter ();
+
+protected:
+ virtual void on_show ();
+ virtual void on_hide ();
+
+private:
+ void reset ();
+ bool idle ();
+
+ Gtk::Label _label_cur;
+ Gtk::Label _label_min;
+ Gtk::Label _label_max;
+ Gtk::Label _label_avg;
+ Gtk::Label _label_dev;
+
+ int64_t _last_display;
+
+ int64_t _last;
+ int64_t _min;
+ int64_t _max;
+
+ int64_t _cnt;
+ double _total;
+ double _var_m, _var_s;
+ sigc::connection _idle_connection;
+};
+#endif
+
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index 7accf20fe5..2d64249246 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -122,6 +122,7 @@ gtk2_ardour_sources = [
'group_tabs.cc',
'gtk_pianokeyboard.c',
'gui_object.cc',
+ 'idleometer.cc',
'insert_remove_time_dialog.cc',
'instrument_selector.cc',
'interthread_progress_window.cc',