/src/skia/tools/timer/TimeUtils.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2019 Google LLC |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #ifndef TimeUtils_DEFINED |
6 | | #define TimeUtils_DEFINED |
7 | | |
8 | | #include "include/core/SkTypes.h" |
9 | | #include "include/private/base/SkFloatingPoint.h" |
10 | | |
11 | | #include <climits> |
12 | | #include <cmath> |
13 | | |
14 | | namespace TimeUtils { |
15 | | // 32 bit value to hold a millisecond duration |
16 | | using MSec = uint32_t; |
17 | | |
18 | | // Maximum representable milliseconds; 24d 20h 31m 23.647s |
19 | | static constexpr MSec MSecMax = INT32_MAX; |
20 | | |
21 | | // Returns 0 if the timer is stopped. Behavior is undefined if the timer |
22 | | // has been running longer than MSecMax. |
23 | 0 | static inline MSec NanosToMSec(double nanos) { |
24 | 0 | const double msec = nanos * 1e-6; |
25 | 0 | SkASSERT(MSecMax >= msec); |
26 | 0 | return static_cast<MSec>(msec); |
27 | 0 | } |
28 | | |
29 | 0 | static inline double NanosToSeconds(double nanos) { |
30 | 0 | return nanos * 1e-9; |
31 | 0 | } |
32 | | |
33 | | // Return the time scaled by "speed" and (if not zero) mod by period. |
34 | 0 | static inline float Scaled(float time, float speed, float period = 0) { |
35 | 0 | double value = time * speed; |
36 | 0 | if (period) { |
37 | 0 | value = ::fmod(value, (double)(period)); |
38 | 0 | } |
39 | 0 | return (float)value; |
40 | 0 | } |
41 | | |
42 | | // Transitions from ends->mid->ends linearly over period time. The phase |
43 | | // specifies a phase shift in time units. |
44 | | static inline float PingPong(double time, |
45 | | float period, |
46 | | float phase, |
47 | | float ends, |
48 | 0 | float mid) { |
49 | 0 | double value = ::fmod(time + phase, period); |
50 | 0 | double half = period / 2.0; |
51 | 0 | double diff = ::fabs(value - half); |
52 | 0 | return (float)(ends + (1.0 - diff / half) * (mid - ends)); |
53 | 0 | } |
54 | | |
55 | | static inline float SineWave(double time, |
56 | | float periodInSecs, |
57 | | float phaseInSecs, |
58 | | float min, |
59 | 0 | float max) { |
60 | 0 | if (periodInSecs < 0.f) { |
61 | 0 | return (min + max) / 2.f; |
62 | 0 | } |
63 | 0 | double t = NanosToSeconds(time) + phaseInSecs; |
64 | 0 | t *= 2 * SK_FloatPI / periodInSecs; |
65 | 0 | float halfAmplitude = (max - min) / 2.f; |
66 | 0 | return halfAmplitude * std::sin(t) + halfAmplitude + min; |
67 | 0 | } |
68 | | } // namespace TimeUtils |
69 | | #endif |