annotate layer/RenderTimer.h @ 1245:f0e291fa7b9c

Use Range01 normalisation in Colour 3D Plot. This gives us the same column normalisation behaviour as in 2.5 (better than the Max1 option).
author Chris Cannam
date Tue, 28 Feb 2017 14:06:24 +0000
parents eaab8bab3522
children a34a2a25907c
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@1074 24 /// A normal rendering operation with normal responsiveness demands
Chris@1074 25 FastRender,
Chris@1074 26
Chris@1074 27 /// An operation that the user might accept being slower
Chris@1074 28 SlowRender,
Chris@1074 29
Chris@1074 30 /// An operation that should always complete, i.e. as if there
Chris@1074 31 /// were no RenderTimer in use, but without having to change
Chris@1074 32 /// client code structurally
Chris@1074 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@1074 44 m_start(std::chrono::steady_clock::now()),
Chris@1074 45 m_haveLimits(true),
Chris@1074 46 m_minFraction(0.1),
Chris@1074 47 m_softLimit(0.1),
Chris@1074 48 m_hardLimit(0.2),
Chris@1074 49 m_softLimitOverridden(false) {
Chris@1074 50
Chris@1074 51 if (t == NoTimeout) {
Chris@1074 52 m_haveLimits = false;
Chris@1074 53 } else if (t == SlowRender) {
Chris@1074 54 m_softLimit = 0.2;
Chris@1074 55 m_hardLimit = 0.4;
Chris@1074 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@1074 69 if (!m_haveLimits || fractionComplete < m_minFraction) {
Chris@1074 70 return false;
Chris@1074 71 }
Chris@1074 72
Chris@1074 73 auto t = std::chrono::steady_clock::now();
Chris@1074 74 double elapsed = std::chrono::duration<double>(t - m_start).count();
Chris@1074 75
Chris@1074 76 if (elapsed > m_hardLimit) {
Chris@1074 77 return true;
Chris@1074 78 } else if (!m_softLimitOverridden && elapsed > m_softLimit) {
Chris@1074 79 if (fractionComplete > 0.6) {
Chris@1074 80 // If we're significantly more than half way by the
Chris@1074 81 // time we reach the soft limit, ignore it (though
Chris@1074 82 // always respect the hard limit, above). Otherwise
Chris@1074 83 // respect the soft limit and report out of time now.
Chris@1074 84 m_softLimitOverridden = true;
Chris@1074 85 } else {
Chris@1074 86 return true;
Chris@1074 87 }
Chris@1074 88 }
Chris@1074 89
Chris@1074 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@1221 97 auto t = std::chrono::steady_clock::now();
Chris@1221 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