Mercurial > hg > svgui
comparison layer/RenderTimer.h @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | 6f98aa5291d4 |
children | eaab8bab3522 |
comparison
equal
deleted
inserted
replaced
1048:e8102ff5573b | 1216:dc2af6616c83 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 | |
8 This program is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU General Public License as | |
10 published by the Free Software Foundation; either version 2 of the | |
11 License, or (at your option) any later version. See the file | |
12 COPYING included with this distribution for more information. | |
13 */ | |
14 | |
15 #ifndef RENDER_TIMER_H | |
16 #define RENDER_TIMER_H | |
17 | |
18 #include <chrono> | |
19 | |
20 class RenderTimer | |
21 { | |
22 public: | |
23 enum Type { | |
24 /// A normal rendering operation with normal responsiveness demands | |
25 FastRender, | |
26 | |
27 /// An operation that the user might accept being slower | |
28 SlowRender, | |
29 | |
30 /// An operation that should always complete, i.e. as if there | |
31 /// were no RenderTimer in use, but without having to change | |
32 /// client code structurally | |
33 NoTimeout | |
34 }; | |
35 | |
36 /** | |
37 * Create a new RenderTimer and start timing. Make one of these | |
38 * before rendering, and then call outOfTime() regularly during | |
39 * rendering. If outOfTime() returns true, abandon rendering! and | |
40 * schedule the rest for after some user responsiveness has | |
41 * happened. | |
42 */ | |
43 RenderTimer(Type t) : | |
44 m_start(std::chrono::steady_clock::now()), | |
45 m_haveLimits(true), | |
46 m_minFraction(0.1), | |
47 m_softLimit(0.1), | |
48 m_hardLimit(0.2), | |
49 m_softLimitOverridden(false) { | |
50 | |
51 if (t == NoTimeout) { | |
52 m_haveLimits = false; | |
53 } else if (t == SlowRender) { | |
54 m_softLimit = 0.2; | |
55 m_hardLimit = 0.4; | |
56 } | |
57 } | |
58 | |
59 | |
60 /** | |
61 * Return true if we have run out of time and should suspend | |
62 * rendering and handle user events instead. Call this regularly | |
63 * during rendering work: fractionComplete should be an estimate | |
64 * of how much of the work has been done as of this call, as a | |
65 * number between 0.0 (none of it) and 1.0 (all of it). | |
66 */ | |
67 bool outOfTime(double fractionComplete) { | |
68 | |
69 if (!m_haveLimits || fractionComplete < m_minFraction) { | |
70 return false; | |
71 } | |
72 | |
73 auto t = std::chrono::steady_clock::now(); | |
74 double elapsed = std::chrono::duration<double>(t - m_start).count(); | |
75 | |
76 if (elapsed > m_hardLimit) { | |
77 return true; | |
78 } else if (!m_softLimitOverridden && elapsed > m_softLimit) { | |
79 if (fractionComplete > 0.6) { | |
80 // If we're significantly more than half way by the | |
81 // time we reach the soft limit, ignore it (though | |
82 // always respect the hard limit, above). Otherwise | |
83 // respect the soft limit and report out of time now. | |
84 m_softLimitOverridden = true; | |
85 } else { | |
86 return true; | |
87 } | |
88 } | |
89 | |
90 return false; | |
91 } | |
92 | |
93 private: | |
94 std::chrono::time_point<std::chrono::steady_clock> m_start; | |
95 bool m_haveLimits; | |
96 double m_minFraction; | |
97 double m_softLimit; | |
98 double m_hardLimit; | |
99 bool m_softLimitOverridden; | |
100 }; | |
101 | |
102 #endif |