1 // Copyright 2018 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "third_party/blink/renderer/core/timing/time_clamper.h" 6 7 #include "base/bit_cast.h" 8 #include "base/rand_util.h" 9 #include "third_party/blink/renderer/platform/wtf/assertions.h" 10 11 #include <cmath> 12 13 namespace blink { 14 TimeClamper()15TimeClamper::TimeClamper() : secret_(base::RandUint64()) {} 16 ClampTimeResolution(double time_seconds) const17double TimeClamper::ClampTimeResolution(double time_seconds) const { 18 bool was_negative = false; 19 if (time_seconds < 0) { 20 was_negative = true; 21 time_seconds = -time_seconds; 22 } 23 double interval = floor(time_seconds / kResolutionSeconds); 24 double clamped_time = interval * kResolutionSeconds; 25 double tick_threshold = ThresholdFor(clamped_time); 26 27 if (time_seconds >= tick_threshold) 28 clamped_time = (interval + 1) * kResolutionSeconds; 29 if (was_negative) 30 clamped_time = -clamped_time; 31 return clamped_time; 32 } 33 ThresholdFor(double clamped_time) const34inline double TimeClamper::ThresholdFor(double clamped_time) const { 35 uint64_t time_hash = MurmurHash3(bit_cast<int64_t>(clamped_time) ^ secret_); 36 return clamped_time + kResolutionSeconds * ToDouble(time_hash); 37 } 38 39 // static ToDouble(uint64_t value)40inline double TimeClamper::ToDouble(uint64_t value) { 41 // Exponent for double values for [1.0 .. 2.0] 42 static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000}; 43 static const uint64_t kMantissaMask = uint64_t{0x000FFFFFFFFFFFFF}; 44 uint64_t random = (value & kMantissaMask) | kExponentBits; 45 return bit_cast<double>(random) - 1; 46 } 47 48 // static MurmurHash3(uint64_t value)49inline uint64_t TimeClamper::MurmurHash3(uint64_t value) { 50 value ^= value >> 33; 51 value *= uint64_t{0xFF51AFD7ED558CCD}; 52 value ^= value >> 33; 53 value *= uint64_t{0xC4CEB9FE1A85EC53}; 54 value ^= value >> 33; 55 return value; 56 } 57 58 } // namespace blink 59