diff options
Diffstat (limited to 'chromium/ui/latency/fixed_point.cc')
-rw-r--r-- | chromium/ui/latency/fixed_point.cc | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/chromium/ui/latency/fixed_point.cc b/chromium/ui/latency/fixed_point.cc new file mode 100644 index 00000000000..fafcf9ee85e --- /dev/null +++ b/chromium/ui/latency/fixed_point.cc @@ -0,0 +1,61 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/latency/fixed_point.h" + +#include <cmath> +#include <limits> + +#include "base/logging.h" + +namespace ui { +namespace frame_metrics { + +namespace { + +constexpr uint64_t k2Pow32{1ULL << 32}; +constexpr uint64_t k32LsbMask{0xFFFFFFFF}; + +} // namespace + +Accumulator96b::Accumulator96b(uint32_t value_to_square, uint32_t weight) { + uint64_t square = static_cast<uint64_t>(value_to_square) * value_to_square; + uint64_t ms64b_temp = (square >> 32) * weight; + uint64_t ls32b_temp = (square & k32LsbMask) * weight; + ms64b = ms64b_temp + (ls32b_temp >> 32); + ls32b = ls32b_temp & k32LsbMask; +} + +void Accumulator96b::Add(const Accumulator96b& rhs) { + uint64_t ls32b_temp = static_cast<uint64_t>(ls32b) + rhs.ls32b; + DCHECK_LT((ls32b_temp >> 32), + std::numeric_limits<decltype(ms64b)>::max() - rhs.ms64b) + << "Accumulator96b overflow."; + uint64_t ms64b_add = rhs.ms64b + (ls32b_temp >> 32); + DCHECK_LT(ms64b_add, std::numeric_limits<decltype(ms64b)>::max() - ms64b) + << "Accumulator96b overflow."; + ms64b += ms64b_add; + ls32b = ls32b_temp & k32LsbMask; +} + +void Accumulator96b::Subtract(const Accumulator96b& rhs) { + uint64_t ls32b_temp = ls32b; + if (ls32b < rhs.ls32b) { + // Borrow from ms64b to ls32b. + ms64b--; + ls32b_temp |= k2Pow32; + } + DCHECK_GE(ms64b, rhs.ms64b) << "Accumulator96b underflow."; + DCHECK_GE(ls32b_temp, static_cast<uint64_t>(rhs.ls32b)) + << "Accumulator96b underflow."; + ms64b -= rhs.ms64b; + ls32b = ls32b_temp - rhs.ls32b; +} + +double Accumulator96b::ToDouble() const { + return (static_cast<double>(ms64b) * k2Pow32) + ls32b; +} + +} // namespace frame_metrics +} // namespace ui |