annotate layer/RenderTimer.h @ 1466:0ecfaa463c1b

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