Commit e8833bea authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Add TimeDelta::FromHz() and ToHz().

These are common operations that aren't necessarily obvious when
reading code, and it's easy to get them subtly wrong.

Before:

  TimeDelta frame_time =
      TimeDelta::FromSeconds(1) / monitor_refresh_rate_;
  TimeDelta duration =
      TimeDelta::FromSeconds(frame_count) / monitor_refresh_rate_;
  double framerate = TimeDelta::FromSeconds(1) / vsync_frame_interval_;
  double bps = 8.0 / time_per_byte_.InSecondsF();

After:

  TimeDelta frame_time = TimeDelta::FromHz(monitor_refresh_rate_);
  TimeDelta duration =
      frame_count * TimeDelta::FromHz(monitor_refresh_rate_);
  double framerate = vsync_frame_interval_.ToHz();
  double bps = time_per_byte_.ToHz() * 8;

Bug: 1104532
Change-Id: I0919738d841177c77294e8983256a0cd93c5338b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2337596
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarYuri Wiitala <miu@chromium.org>
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797128}
parent fb757dc1
...@@ -155,6 +155,9 @@ class BASE_EXPORT TimeDelta { ...@@ -155,6 +155,9 @@ class BASE_EXPORT TimeDelta {
static TimeDelta FromMachTime(uint64_t mach_time); static TimeDelta FromMachTime(uint64_t mach_time);
#endif // defined(OS_MAC) #endif // defined(OS_MAC)
// Converts a frequency in Hertz (cycles per second) into a period.
static constexpr TimeDelta FromHz(double frequency);
// From Go's doc at https://golang.org/pkg/time/#ParseDuration // From Go's doc at https://golang.org/pkg/time/#ParseDuration
// [ParseDuration] parses a duration string. A duration string is // [ParseDuration] parses a duration string. A duration string is
// a possibly signed sequence of decimal numbers, each with optional // a possibly signed sequence of decimal numbers, each with optional
...@@ -228,6 +231,10 @@ class BASE_EXPORT TimeDelta { ...@@ -228,6 +231,10 @@ class BASE_EXPORT TimeDelta {
ABI::Windows::Foundation::DateTime ToWinrtDateTime() const; ABI::Windows::Foundation::DateTime ToWinrtDateTime() const;
#endif #endif
// Returns the frequency in Hertz (cycles per second) that has a period of
// *this.
constexpr double ToHz() const { return FromSeconds(1) / *this; }
// Returns the time delta in some unit. Minimum argument values return as // Returns the time delta in some unit. Minimum argument values return as
// -inf for doubles and min type values otherwise. Maximum ones are treated as // -inf for doubles and min type values otherwise. Maximum ones are treated as
// +inf for doubles and max type values otherwise. Their results will produce // +inf for doubles and max type values otherwise. Their results will produce
...@@ -890,6 +897,11 @@ constexpr TimeDelta TimeDelta::FromNanosecondsD(double ns) { ...@@ -890,6 +897,11 @@ constexpr TimeDelta TimeDelta::FromNanosecondsD(double ns) {
return FromDouble(ns / Time::kNanosecondsPerMicrosecond); return FromDouble(ns / Time::kNanosecondsPerMicrosecond);
} }
// static
constexpr TimeDelta TimeDelta::FromHz(double frequency) {
return FromSeconds(1) / frequency;
}
constexpr int TimeDelta::InHours() const { constexpr int TimeDelta::InHours() const {
// saturated_cast<> is necessary since very large (but still less than // saturated_cast<> is necessary since very large (but still less than
// min/max) deltas would result in overflow. // min/max) deltas would result in overflow.
......
...@@ -1518,6 +1518,28 @@ TEST(TimeDelta, WindowsEpoch) { ...@@ -1518,6 +1518,28 @@ TEST(TimeDelta, WindowsEpoch) {
// only compute years starting from 1900. // only compute years starting from 1900.
} }
TEST(TimeDelta, Hz) {
static_assert(TimeDelta::FromHz(1) == TimeDelta::FromSeconds(1), "");
EXPECT_EQ(TimeDelta::FromHz(0), TimeDelta::Max());
static_assert(TimeDelta::FromHz(-1) == TimeDelta::FromSeconds(-1), "");
static_assert(TimeDelta::FromHz(1000) == TimeDelta::FromMilliseconds(1), "");
static_assert(TimeDelta::FromHz(0.5) == TimeDelta::FromSeconds(2), "");
EXPECT_EQ(TimeDelta::FromHz(std::numeric_limits<double>::infinity()),
TimeDelta());
static_assert(TimeDelta::FromSeconds(1).ToHz() == 1, "");
EXPECT_EQ(TimeDelta::Max().ToHz(), 0);
static_assert(TimeDelta::FromSeconds(-1).ToHz() == -1, "");
static_assert(TimeDelta::FromMilliseconds(1).ToHz() == 1000, "");
static_assert(TimeDelta::FromSeconds(2).ToHz() == 0.5, "");
EXPECT_EQ(TimeDelta().ToHz(), std::numeric_limits<double>::infinity());
// 60 Hz can't be represented exactly.
EXPECT_NE(TimeDelta::FromHz(60) * 60, TimeDelta::FromSeconds(1));
EXPECT_NE(TimeDelta::FromHz(60).ToHz(), 60);
EXPECT_EQ(base::ClampRound(TimeDelta::FromHz(60).ToHz()), 60);
}
// We could define this separately for Time, TimeTicks and TimeDelta but the // We could define this separately for Time, TimeTicks and TimeDelta but the
// definitions would be identical anyway. // definitions would be identical anyway.
template <class Any> template <class Any>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment