set a theme color for VCA axes in the editor
[ardour.git] / gtk2_ardour / timers.cc
1 /*
2     Copyright (C) 2014 Tim Mayberry
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "timers.h"
21
22 #include "pbd/timer.h"
23 #include "pbd/debug.h"
24 #include "pbd/compose.h"
25
26 #include "debug.h"
27
28 namespace {
29
30 class StandardTimer : public PBD::StandardTimer
31 {
32 public:
33         StandardTimer (unsigned int interval)
34                 : PBD::StandardTimer(interval)
35         { }
36
37         virtual bool on_elapsed () {
38                 DEBUG_TIMING_ADD_ELAPSED(PBD::DEBUG::GUITiming, timing_interval_data);
39                 DEBUG_TIMING_START(PBD::DEBUG::GUITiming, timing_exec_data);
40
41                 bool ret_val = PBD::StandardTimer::on_elapsed ();
42
43                 DEBUG_TIMING_ADD_ELAPSED(PBD::DEBUG::GUITiming, timing_exec_data);
44                 DEBUG_TIMING_START(PBD::DEBUG::GUITiming, timing_interval_data);
45                 return ret_val;
46         }
47
48 #ifndef NDEBUG
49         PBD::TimingData timing_interval_data;
50         PBD::TimingData timing_exec_data;
51 #endif
52 };
53
54 class BlinkTimer : public PBD::BlinkTimer
55 {
56 public:
57         BlinkTimer (unsigned int interval)
58                 : PBD::BlinkTimer(interval)
59         { }
60
61         virtual bool on_elapsed () {
62                 DEBUG_TIMING_ADD_ELAPSED(PBD::DEBUG::GUITiming, timing_interval_data);
63                 DEBUG_TIMING_START(PBD::DEBUG::GUITiming, timing_exec_data);
64
65                 bool ret_val = PBD::BlinkTimer::on_elapsed ();
66
67                 DEBUG_TIMING_ADD_ELAPSED(PBD::DEBUG::GUITiming, timing_exec_data);
68                 DEBUG_TIMING_START(PBD::DEBUG::GUITiming, timing_interval_data);
69                 return ret_val;
70         }
71
72 #ifndef NDEBUG
73         PBD::TimingData timing_interval_data;
74         PBD::TimingData timing_exec_data;
75 #endif
76 };
77
78
79 class UITimers
80 {
81
82 public:
83
84         UITimers ()
85                 : blink(240)
86                 , second(1000)
87                 , rapid(100)
88                 , super_rapid(40)
89                 , fps(40)
90                 , _suspend_counter(0)
91         {
92 #ifndef NDEBUG
93                 second.connect (sigc::mem_fun (*this, &UITimers::on_second_timer));
94 #endif
95         }
96
97         BlinkTimer      blink;
98         StandardTimer   second;
99         StandardTimer   rapid;
100         StandardTimer   super_rapid;
101         StandardTimer   fps;
102
103         gint            _suspend_counter;
104
105 #ifndef NDEBUG
106         std::vector<uint64_t> rapid_eps_count;
107         std::vector<uint64_t> super_rapid_eps_count;
108         std::vector<uint64_t> fps_eps_count;
109
110 private:
111
112         void debug_rapid_timer () {
113                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Rapid Connections: %1\n", rapid.connection_count ()));
114
115                 rapid_eps_count.push_back (rapid.timing_exec_data.size());
116
117                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Rapid Exec Totals: %1", PBD::timing_summary (rapid_eps_count)));
118
119                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Rapid Interval: %1", rapid.timing_interval_data.summary()));
120                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Rapid Exec: %1", rapid.timing_exec_data.summary()));
121                 DEBUG_TIMING_RESET(PBD::DEBUG::GUITiming, rapid.timing_interval_data);
122                 DEBUG_TIMING_RESET(PBD::DEBUG::GUITiming, rapid.timing_exec_data);
123         }
124
125         void debug_super_rapid_timer () {
126                 // we don't use this timer on windows so don't display empty data for it
127 #ifndef PLATFORM_WINDOWS
128
129                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Super Rapid Connections: %1\n", super_rapid.connection_count ()));
130
131                 super_rapid_eps_count.push_back (super_rapid.timing_exec_data.size());
132
133                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Super Rapid Exec Totals: %1", PBD::timing_summary (super_rapid_eps_count)));
134                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Super Rapid Interval: %1", super_rapid.timing_interval_data.summary()));
135                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("Super Rapid Exec: %1", super_rapid.timing_exec_data.summary()));
136                 DEBUG_TIMING_RESET(PBD::DEBUG::GUITiming, super_rapid.timing_interval_data);
137                 DEBUG_TIMING_RESET(PBD::DEBUG::GUITiming, super_rapid.timing_exec_data);
138 #endif
139         }
140
141         void debug_fps_timer () {
142                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("FPS Connections: %1\n", fps.connection_count ()));
143
144                 fps_eps_count.push_back (fps.timing_exec_data.size());
145
146                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("FPS Exec Totals: %1", PBD::timing_summary (fps_eps_count)));
147
148                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("FPS Interval: %1", fps.timing_interval_data.summary()));
149                 DEBUG_TRACE(PBD::DEBUG::GUITiming, string_compose ("FPS Exec: %1", fps.timing_exec_data.summary()));
150                 DEBUG_TIMING_RESET(PBD::DEBUG::GUITiming, fps.timing_interval_data);
151                 DEBUG_TIMING_RESET(PBD::DEBUG::GUITiming, fps.timing_exec_data);
152         }
153
154         void on_second_timer () {
155                 debug_rapid_timer ();
156                 debug_super_rapid_timer ();
157                 debug_fps_timer ();
158         }
159 #endif
160 };
161
162 UITimers&
163 get_timers ()
164 {
165         static UITimers timers;
166         return timers;
167 }
168
169 } // anon namespace
170
171 namespace Timers {
172
173 sigc::connection
174 blink_connect(const sigc::slot<void,bool>& slot)
175 {
176         return get_timers().blink.connect (slot);
177 }
178
179 sigc::connection
180 second_connect(const sigc::slot<void>& slot)
181 {
182         return get_timers().second.connect (slot);
183 }
184
185 sigc::connection
186 rapid_connect(const sigc::slot<void>& slot)
187 {
188         return get_timers().rapid.connect (slot);
189 }
190
191 sigc::connection
192 super_rapid_connect(const sigc::slot<void>& slot)
193 {
194 #ifdef PLATFORM_WINDOWS
195         return get_timers().fps.connect (slot);
196 #else
197         return get_timers().super_rapid.connect (slot);
198 #endif
199 }
200
201 void
202 set_fps_interval (unsigned int interval)
203 {
204         get_timers().fps.set_interval (interval);
205 }
206
207 sigc::connection
208 fps_connect(const sigc::slot<void>& slot)
209 {
210         return get_timers().fps.connect (slot);
211 }
212
213 TimerSuspender::TimerSuspender ()
214 {
215         if (g_atomic_int_add(&get_timers()._suspend_counter, 1) == 0) {
216                 get_timers().rapid.suspend();
217                 get_timers().super_rapid.suspend();
218                 get_timers().fps.suspend();
219         }
220 }
221
222 TimerSuspender::~TimerSuspender ()
223 {
224         if (g_atomic_int_dec_and_test (&get_timers()._suspend_counter)) {
225                 get_timers().rapid.resume();
226                 get_timers().super_rapid.resume();
227                 get_timers().fps.resume();
228         }
229 }
230
231 } // namespace Timers