Skip to content
Permalink
Browse files
Use traits for animation timing functions
https://bugs.webkit.org/show_bug.cgi?id=181651
<rdar://problem/36525328>

Reviewed by Antoine Quint.

Use the type traits for TimingFunction classes, so
we can is<> and downcast<>.

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::createTimingFunctionValue):
* platform/animation/TimingFunction.cpp:
(WebCore::TimingFunction::transformTime const):
* platform/animation/TimingFunction.h:
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::animationHasStepsTimingFunction):
(WebCore::animationHasFramesTimingFunction):
* platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:
(WebCore::toCAMediaTimingFunction):

Canonical link: https://commits.webkit.org/197504@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226952 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
grorg committed Jan 15, 2018
1 parent bfdb154 commit d1dbfa6724f9cee2f2bcebcfa9df9a4ef4834eb0
Showing 6 changed files with 56 additions and 23 deletions.
@@ -1,3 +1,25 @@
2018-01-15 Dean Jackson <dino@apple.com>

Use traits for animation timing functions
https://bugs.webkit.org/show_bug.cgi?id=181651
<rdar://problem/36525328>

Reviewed by Antoine Quint.

Use the type traits for TimingFunction classes, so
we can is<> and downcast<>.

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::createTimingFunctionValue):
* platform/animation/TimingFunction.cpp:
(WebCore::TimingFunction::transformTime const):
* platform/animation/TimingFunction.h:
* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::animationHasStepsTimingFunction):
(WebCore::animationHasFramesTimingFunction):
* platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:
(WebCore::toCAMediaTimingFunction):

2018-01-15 Youenn Fablet <youenn@apple.com>

RealtimeMediaSource should be ThreadSafeRefCounted
@@ -1542,7 +1542,7 @@ static Ref<CSSValue> createTimingFunctionValue(const TimingFunction& timingFunct
{
switch (timingFunction.type()) {
case TimingFunction::CubicBezierFunction: {
auto& function = static_cast<const CubicBezierTimingFunction&>(timingFunction);
auto& function = downcast<const CubicBezierTimingFunction>(timingFunction);
if (function.timingFunctionPreset() != CubicBezierTimingFunction::Custom) {
CSSValueID valueId = CSSValueInvalid;
switch (function.timingFunctionPreset()) {
@@ -1565,15 +1565,15 @@ static Ref<CSSValue> createTimingFunctionValue(const TimingFunction& timingFunct
return CSSCubicBezierTimingFunctionValue::create(function.x1(), function.y1(), function.x2(), function.y2());
}
case TimingFunction::StepsFunction: {
auto& function = static_cast<const StepsTimingFunction&>(timingFunction);
auto& function = downcast<const StepsTimingFunction>(timingFunction);
return CSSStepsTimingFunctionValue::create(function.numberOfSteps(), function.stepAtStart());
}
case TimingFunction::FramesFunction: {
auto& function = static_cast<const FramesTimingFunction&>(timingFunction);
auto& function = downcast<const FramesTimingFunction>(timingFunction);
return CSSFramesTimingFunctionValue::create(function.numberOfFrames());
}
case TimingFunction::SpringFunction: {
auto& function = static_cast<const SpringTimingFunction&>(timingFunction);
auto& function = downcast<const SpringTimingFunction>(timingFunction);
return CSSSpringTimingFunctionValue::create(function.mass(), function.stiffness(), function.damping(), function.initialVelocity());
}
default:
@@ -66,22 +66,22 @@ double TimingFunction::transformTime(double inputTime, double duration) const
{
switch (m_type) {
case TimingFunction::CubicBezierFunction: {
auto& function = *static_cast<const CubicBezierTimingFunction*>(this);
auto& function = *downcast<const CubicBezierTimingFunction>(this);
// The epsilon value we pass to UnitBezier::solve given that the animation is going to run over |dur| seconds. The longer the
// animation, the more precision we need in the timing function result to avoid ugly discontinuities.
auto epsilon = 1.0 / (200.0 * duration);
return UnitBezier(function.x1(), function.y1(), function.x2(), function.y2()).solve(inputTime, epsilon);
}
case TimingFunction::StepsFunction: {
auto& function = *static_cast<const StepsTimingFunction*>(this);
auto& function = *downcast<const StepsTimingFunction>(this);
auto numberOfSteps = function.numberOfSteps();
if (function.stepAtStart())
return std::min(1.0, (std::floor(numberOfSteps * inputTime) + 1) / numberOfSteps);
return std::floor(numberOfSteps * inputTime) / numberOfSteps;
}
case TimingFunction::FramesFunction: {
// https://drafts.csswg.org/css-timing/#frames-timing-functions
auto& function = *static_cast<const FramesTimingFunction*>(this);
auto& function = *downcast<const FramesTimingFunction>(this);
auto numberOfFrames = function.numberOfFrames();
ASSERT(numberOfFrames > 1);
auto outputTime = std::floor(inputTime * numberOfFrames) / (numberOfFrames - 1);
@@ -90,7 +90,7 @@ double TimingFunction::transformTime(double inputTime, double duration) const
return outputTime;
}
case TimingFunction::SpringFunction: {
auto& function = *static_cast<const SpringTimingFunction*>(this);
auto& function = *downcast<const SpringTimingFunction>(this);
return SpringSolver(function.mass(), function.stiffness(), function.damping(), function.initialVelocity()).solve(inputTime * duration);
}
case TimingFunction::LinearFunction:
@@ -72,7 +72,7 @@ class LinearTimingFunction final : public TimingFunction {

bool operator==(const TimingFunction& other) const final
{
return other.isLinearTimingFunction();
return is<LinearTimingFunction>(other);
}

private:
@@ -121,9 +121,9 @@ class CubicBezierTimingFunction final : public TimingFunction {

bool operator==(const TimingFunction& other) const final
{
if (!other.isCubicBezierTimingFunction())
if (!is<CubicBezierTimingFunction>(other))
return false;
auto& otherCubic = static_cast<const CubicBezierTimingFunction&>(other);
auto& otherCubic = downcast<const CubicBezierTimingFunction>(other);
if (m_timingFunctionPreset != otherCubic.m_timingFunctionPreset)
return false;
if (m_timingFunctionPreset != Custom)
@@ -194,9 +194,9 @@ class StepsTimingFunction final : public TimingFunction {

bool operator==(const TimingFunction& other) const final
{
if (!other.isStepsTimingFunction())
if (!is<StepsTimingFunction>(other))
return false;
auto& otherSteps = static_cast<const StepsTimingFunction&>(other);
auto& otherSteps = downcast<const StepsTimingFunction>(other);
return m_steps == otherSteps.m_steps && m_stepAtStart == otherSteps.m_stepAtStart;
}

@@ -236,9 +236,9 @@ class FramesTimingFunction final : public TimingFunction {

bool operator==(const TimingFunction& other) const final
{
if (!other.isFramesTimingFunction())
if (is<FramesTimingFunction>(other))
return false;
auto& otherFrames = static_cast<const FramesTimingFunction&>(other);
auto& otherFrames = downcast<const FramesTimingFunction>(other);
return m_frames == otherFrames.m_frames;
}

@@ -276,9 +276,9 @@ class SpringTimingFunction final : public TimingFunction {

bool operator==(const TimingFunction& other) const final
{
if (!other.isSpringTimingFunction())
if (!is<SpringTimingFunction>(other))
return false;
auto& otherSpring = static_cast<const SpringTimingFunction&>(other);
auto& otherSpring = downcast<const SpringTimingFunction>(other);
return m_mass == otherSpring.m_mass && m_stiffness == otherSpring.m_stiffness && m_damping == otherSpring.m_damping && m_initialVelocity == otherSpring.m_initialVelocity;
}

@@ -319,3 +319,14 @@ class SpringTimingFunction final : public TimingFunction {
WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const TimingFunction&);

} // namespace WebCore

#define SPECIALIZE_TYPE_TRAITS_TIMINGFUNCTION(ToValueTypeName, predicate) \
SPECIALIZE_TYPE_TRAITS_BEGIN(ToValueTypeName) \
static bool isType(const WebCore::TimingFunction& function) { return function.predicate; } \
SPECIALIZE_TYPE_TRAITS_END()

SPECIALIZE_TYPE_TRAITS_TIMINGFUNCTION(WebCore::LinearTimingFunction, isLinearTimingFunction())
SPECIALIZE_TYPE_TRAITS_TIMINGFUNCTION(WebCore::CubicBezierTimingFunction, isCubicBezierTimingFunction())
SPECIALIZE_TYPE_TRAITS_TIMINGFUNCTION(WebCore::StepsTimingFunction, isStepsTimingFunction())
SPECIALIZE_TYPE_TRAITS_TIMINGFUNCTION(WebCore::FramesTimingFunction, isFramesTimingFunction())
SPECIALIZE_TYPE_TRAITS_TIMINGFUNCTION(WebCore::SpringTimingFunction, isSpringTimingFunction())
@@ -270,12 +270,12 @@ static String animationIdentifier(const String& animationName, AnimatedPropertyI

static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
{
if (anim->timingFunction()->isStepsTimingFunction())
if (is<StepsTimingFunction>(anim->timingFunction()))
return true;

for (unsigned i = 0; i < valueList.size(); ++i) {
if (const TimingFunction* timingFunction = valueList.at(i).timingFunction()) {
if (timingFunction->isStepsTimingFunction())
if (is<StepsTimingFunction>(timingFunction))
return true;
}
}
@@ -285,12 +285,12 @@ static bool animationHasStepsTimingFunction(const KeyframeValueList& valueList,

static bool animationHasFramesTimingFunction(const KeyframeValueList& valueList, const Animation* anim)
{
if (anim->timingFunction()->isFramesTimingFunction())
if (is<FramesTimingFunction>(anim->timingFunction()))
return true;

for (unsigned i = 0; i < valueList.size(); ++i) {
if (const TimingFunction* timingFunction = valueList.at(i).timingFunction()) {
if (timingFunction->isFramesTimingFunction())
if (is<FramesTimingFunction>(timingFunction))
return true;
}
}
@@ -129,9 +129,9 @@
CAMediaTimingFunction* WebCore::toCAMediaTimingFunction(const TimingFunction* timingFunction, bool reverse)
{
ASSERT(timingFunction);
if (timingFunction->isCubicBezierTimingFunction()) {
if (is<CubicBezierTimingFunction>(timingFunction)) {
RefPtr<CubicBezierTimingFunction> reversed;
const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction);
const CubicBezierTimingFunction* ctf = downcast<const CubicBezierTimingFunction>(timingFunction);

if (reverse) {
reversed = ctf->createReversed();

0 comments on commit d1dbfa6

Please sign in to comment.