Commit e37e738a authored by Stephen McGruer's avatar Stephen McGruer Committed by Commit Bot

Introduce AnimationTimeDelta class

This class is intended to be used to facilitate the transition of Blink
animations from double-based times to TimeDelta-based times. This CL
introduces a dual-compiled class, AnimationTimeDelta, which is compiled
by default as double-based but can also be compiled to use
base::TimeDelta as the underlying value.

Bug: 737867
Change-Id: Ibba92d9eb860b20659b0897c505000a91d042988
Reviewed-on: https://chromium-review.googlesource.com/1175859Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Commit-Queue: Stephen McGruer <smcgruer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#584547}
parent 1811f49c
......@@ -31,6 +31,9 @@ config("config") {
if (is_chromecast) {
defines += [ "BLINK_MEDIA_LOG=LOG(INFO)" ]
}
if (blink_animation_use_time_delta) {
defines += [ "BLINK_ANIMATION_USE_TIME_DELTA" ]
}
}
config("core_include_dirs") {
......@@ -1690,6 +1693,7 @@ jumbo_source_set("unit_tests") {
"animation/animation_test.cc",
"animation/animation_test_helper.cc",
"animation/animation_test_helper.h",
"animation/animation_time_delta_test.cc",
"animation/compositor_animations_test.cc",
"animation/css/css_animations_test.cc",
"animation/css/css_transition_data_test.cc",
......@@ -2208,6 +2212,10 @@ jumbo_source_set("unit_tests") {
if (use_default_render_theme) {
sources += [ "scroll/scrollbar_theme_aura_test.cc" ]
}
if (blink_animation_use_time_delta) {
defines = [ "BLINK_ANIMATION_USE_TIME_DELTA" ]
}
}
jumbo_source_set("perf_tests") {
......
......@@ -25,6 +25,8 @@ blink_core_sources("animation") {
"animation_effect_owner.h",
"animation_input_helpers.cc",
"animation_input_helpers.h",
"animation_time_delta.cc",
"animation_time_delta.h",
"animation_timeline.h",
"basic_shape_interpolation_functions.cc",
"basic_shape_interpolation_functions.h",
......
// 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 "third_party/blink/renderer/core/animation/animation_time_delta.h"
namespace blink {
#if !defined(BLINK_ANIMATION_USE_TIME_DELTA)
std::ostream& operator<<(std::ostream& os, AnimationTimeDelta time) {
return os << time.InSecondsF() << " s";
}
#endif
} // namespace blink
// 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIME_DELTA_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIME_DELTA_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include <limits>
#include <ostream>
#if defined(BLINK_ANIMATION_USE_TIME_DELTA)
#include "third_party/blink/renderer/platform/wtf/time.h"
#endif
namespace blink {
// AnimationTimeDelta exists to ease the transition of Blink animations from
// double-based time values to base::TimeDelta-based time values (see
// http://crbug.com/737867.
//
// It represents a delta between two times, analogous to base::TimeDelta. It is
// provided in two modes, based on a compiler flag. The first is the traditional
// (and default) double mode, where time deltas are represented using seconds in
// double-precision. The second mode uses base::TimeDelta to represent time
// instead.
#if !defined(BLINK_ANIMATION_USE_TIME_DELTA)
// The double-based version of AnimationTimeDelta. Internally, time is stored as
// double-precision seconds.
//
// This class is modelled on the API from base::TimeDelta, with a lot of
// unnecessary methods stripped out.
class CORE_EXPORT AnimationTimeDelta {
USING_FAST_MALLOC(AnimationTimeDelta);
public:
constexpr AnimationTimeDelta() : delta_(0) {}
static AnimationTimeDelta FromSecondsD(double time_s) {
DCHECK(!std::isnan(time_s));
return AnimationTimeDelta(time_s);
}
static AnimationTimeDelta FromMillisecondsD(double time_ms) {
DCHECK(!std::isnan(time_ms));
return AnimationTimeDelta(time_ms / 1000);
}
static constexpr AnimationTimeDelta Max() {
return AnimationTimeDelta(std::numeric_limits<double>::infinity());
}
double InSecondsF() const { return delta_; }
double InMillisecondsF() const { return delta_ * 1000; }
bool is_max() const {
return delta_ == std::numeric_limits<double>::infinity();
}
bool is_zero() const { return delta_ == 0; }
AnimationTimeDelta operator+(AnimationTimeDelta other) const {
return AnimationTimeDelta(delta_ + other.delta_);
}
AnimationTimeDelta& operator+=(AnimationTimeDelta other) {
return *this = (*this + other);
}
template <typename T>
AnimationTimeDelta operator*(T a) const {
return AnimationTimeDelta(delta_ * a);
}
template <typename V>
AnimationTimeDelta& operator*=(V a) {
return *this = (*this * a);
}
protected:
constexpr explicit AnimationTimeDelta(double delta) : delta_(delta) {}
// The time delta represented by this |AnimationTimeDelta|, in seconds. May be
// negative, in which case the end of the delta is before the start.
double delta_;
};
template <typename T>
AnimationTimeDelta operator*(T a, AnimationTimeDelta td) {
return td * a;
}
// Comparison operators on AnimationTimeDelta.
constexpr bool CORE_EXPORT operator==(const AnimationTimeDelta& lhs,
const AnimationTimeDelta& rhs) {
return lhs.InSecondsF() == rhs.InSecondsF();
}
constexpr bool CORE_EXPORT operator!=(const AnimationTimeDelta& lhs,
const AnimationTimeDelta& rhs) {
return lhs.InSecondsF() != rhs.InSecondsF();
}
constexpr bool CORE_EXPORT operator>(const AnimationTimeDelta& lhs,
const AnimationTimeDelta& rhs) {
return lhs.InSecondsF() > rhs.InSecondsF();
}
constexpr bool CORE_EXPORT operator>=(const AnimationTimeDelta& lhs,
const AnimationTimeDelta& rhs) {
return lhs.InSecondsF() >= rhs.InSecondsF();
}
constexpr bool CORE_EXPORT operator<=(const AnimationTimeDelta& lhs,
const AnimationTimeDelta& rhs) {
return lhs.InSecondsF() <= rhs.InSecondsF();
}
// Defined to allow DCHECK_EQ/etc to work with the class.
CORE_EXPORT std::ostream& operator<<(std::ostream& os, AnimationTimeDelta time);
#else // !defined(BLINK_ANIMATION_USE_TIME_DELTA)
// When compiling in TimeDelta-based mode, AnimationTimeDelta is equivalent to
// base::TimeDelta.
using AnimationTimeDelta = TimeDelta;
#endif
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_ANIMATION_TIME_DELTA_H_
// 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 "third_party/blink/renderer/core/animation/animation_time_delta.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <limits>
namespace blink {
TEST(AnimationTimeDeltaTest, Construction) {
// The default constructor is a zero-length delta.
EXPECT_EQ(AnimationTimeDelta(), AnimationTimeDelta::FromSecondsD(0));
EXPECT_EQ(AnimationTimeDelta(), AnimationTimeDelta::FromMillisecondsD(0));
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5.5),
AnimationTimeDelta::FromMillisecondsD(5500));
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(-2),
AnimationTimeDelta::FromMillisecondsD(-2000));
}
TEST(AnimationTimeDeltaTest, Conversion) {
AnimationTimeDelta delta = AnimationTimeDelta::FromSecondsD(5);
EXPECT_EQ(delta.InSecondsF(), 5);
EXPECT_EQ(delta.InMillisecondsF(), 5000);
delta = AnimationTimeDelta::FromMillisecondsD(1234);
EXPECT_EQ(delta.InSecondsF(), 1.234);
EXPECT_EQ(delta.InMillisecondsF(), 1234);
}
TEST(AnimationTimeDeltaTest, Max) {
AnimationTimeDelta max_delta = AnimationTimeDelta::Max();
EXPECT_TRUE(max_delta.is_max());
EXPECT_EQ(max_delta, AnimationTimeDelta::Max());
EXPECT_GT(max_delta, AnimationTimeDelta::FromSecondsD(365 * 24 * 60 * 60));
EXPECT_EQ(max_delta.InSecondsF(), std::numeric_limits<double>::infinity());
EXPECT_EQ(max_delta.InMillisecondsF(),
std::numeric_limits<double>::infinity());
}
TEST(AnimationTimeDeltaTest, Zero) {
EXPECT_TRUE(AnimationTimeDelta().is_zero());
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(0).is_zero());
EXPECT_TRUE(AnimationTimeDelta::FromMillisecondsD(0).is_zero());
EXPECT_FALSE(AnimationTimeDelta::FromSecondsD(54.5).is_zero());
EXPECT_FALSE(AnimationTimeDelta::FromSecondsD(-0.5).is_zero());
EXPECT_FALSE(AnimationTimeDelta::FromMillisecondsD(123.45).is_zero());
}
TEST(AnimationTimeDeltaTest, Computation) {
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(4.5) +
AnimationTimeDelta::FromMillisecondsD(500),
AnimationTimeDelta::FromSecondsD(5));
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(100) +
AnimationTimeDelta::FromMillisecondsD(-850),
AnimationTimeDelta::FromSecondsD(99.15));
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(5) * 20,
AnimationTimeDelta::FromSecondsD(100));
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(10) * 1.5,
AnimationTimeDelta::FromSecondsD(15));
EXPECT_EQ(AnimationTimeDelta::FromSecondsD(2.5) * -2,
AnimationTimeDelta::FromSecondsD(-5));
EXPECT_EQ(20 * AnimationTimeDelta::FromSecondsD(5),
AnimationTimeDelta::FromSecondsD(100));
}
TEST(AnimationTimeDeltaTest, Comparison) {
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(10) ==
AnimationTimeDelta::FromSecondsD(10));
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(10) !=
AnimationTimeDelta::FromSecondsD(50));
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) >
AnimationTimeDelta::FromSecondsD(49.999));
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) >=
AnimationTimeDelta::FromSecondsD(49.999));
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) >=
AnimationTimeDelta::FromSecondsD(50));
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) <=
AnimationTimeDelta::FromSecondsD(50));
EXPECT_TRUE(AnimationTimeDelta::FromSecondsD(50) <=
AnimationTimeDelta::FromSecondsD(100));
}
} // namespace blink
......@@ -125,3 +125,9 @@ set_defaults("blink_core_sources") {
# support, for lower Windows build times.
configs += [ "//third_party/blink/renderer/core:blink_core_pch" ]
}
declare_args() {
# Use base::TimeDelta to represent time in renderer/core/animations. See
# http://crbug.com/737867
blink_animation_use_time_delta = false
}
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