Title: [272178] trunk/Source
Revision
272178
Author
[email protected]
Date
2021-02-01 14:56:01 -0800 (Mon, 01 Feb 2021)

Log Message

Allow support for CAAnimationGroup
https://bugs.webkit.org/show_bug.cgi?id=221209

Reviewed by Dean Jackson, Sam Weinig and Simon Fraser.

In order to fix bug 219894, we need to use Core Animation's CAAnimationGroup and its
Source/WebCore:

setAnimations() method. This patch adds a new "Group" type to PlatformCAAnimation and
platform-specific integration for Windows and Cocoa ports.

* platform/graphics/ca/PlatformCAAnimation.cpp:
(WebCore::operator<<):
* platform/graphics/ca/PlatformCAAnimation.h:
* platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.h:
* platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:
(WebCore::PlatformCAAnimationCocoa::PlatformCAAnimationCocoa):
(WebCore::PlatformCAAnimationCocoa::keyPath const):
(WebCore::PlatformCAAnimationCocoa::setTimingFunction):
(WebCore::PlatformCAAnimationCocoa::isAdditive const):
(WebCore::PlatformCAAnimationCocoa::setAdditive):
(WebCore::PlatformCAAnimationCocoa::valueFunction const):
(WebCore::PlatformCAAnimationCocoa::setValueFunction):
(WebCore::PlatformCAAnimationCocoa::setFromValue):
(WebCore::PlatformCAAnimationCocoa::copyFromValueFrom):
(WebCore::PlatformCAAnimationCocoa::setToValue):
(WebCore::PlatformCAAnimationCocoa::copyToValueFrom):
(WebCore::PlatformCAAnimationCocoa::setValues):
(WebCore::PlatformCAAnimationCocoa::copyValuesFrom):
(WebCore::PlatformCAAnimationCocoa::setKeyTimes):
(WebCore::PlatformCAAnimationCocoa::copyKeyTimesFrom):
(WebCore::PlatformCAAnimationCocoa::setTimingFunctions):
(WebCore::PlatformCAAnimationCocoa::copyTimingFunctionsFrom):
(WebCore::PlatformCAAnimationCocoa::setAnimations):
(WebCore::PlatformCAAnimationCocoa::copyAnimationsFrom):
* platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
(WebCore::PlatformCALayerCocoa::addAnimationForKey):
(WebCore::PlatformCALayerCocoa::animationForKey):
* platform/graphics/ca/win/PlatformCAAnimationWin.cpp:
(PlatformCAAnimationWin::PlatformCAAnimationWin):
(PlatformCAAnimationWin::setAnimations):
(PlatformCAAnimationWin::copyAnimationsFrom):
* platform/graphics/ca/win/PlatformCAAnimationWin.h:

Source/WebKit:

setAnimations() method. Add support for the new "Group" PlatformCAAnimation type for
the remote animations.

* WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.h:
* WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.mm:
(WebKit::PlatformCAAnimationRemote::Properties::encode const):
(WebKit::PlatformCAAnimationRemote::Properties::decode):
(WebKit::PlatformCAAnimationRemote::copy const):
(WebKit::PlatformCAAnimationRemote::setAnimations):
(WebKit::PlatformCAAnimationRemote::copyAnimationsFrom):
(WebKit::createAnimation):
(WebKit::addAnimationToLayer):
(WebKit::operator<<):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (272177 => 272178)


--- trunk/Source/WebCore/ChangeLog	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/ChangeLog	2021-02-01 22:56:01 UTC (rev 272178)
@@ -1,3 +1,47 @@
+2021-02-01  Antoine Quint  <[email protected]>
+
+        Allow support for CAAnimationGroup
+        https://bugs.webkit.org/show_bug.cgi?id=221209
+
+        Reviewed by Dean Jackson, Sam Weinig and Simon Fraser.
+
+        In order to fix bug 219894, we need to use Core Animation's CAAnimationGroup and its
+        setAnimations() method. This patch adds a new "Group" type to PlatformCAAnimation and
+        platform-specific integration for Windows and Cocoa ports.
+
+        * platform/graphics/ca/PlatformCAAnimation.cpp:
+        (WebCore::operator<<):
+        * platform/graphics/ca/PlatformCAAnimation.h:
+        * platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.h:
+        * platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm:
+        (WebCore::PlatformCAAnimationCocoa::PlatformCAAnimationCocoa):
+        (WebCore::PlatformCAAnimationCocoa::keyPath const):
+        (WebCore::PlatformCAAnimationCocoa::setTimingFunction):
+        (WebCore::PlatformCAAnimationCocoa::isAdditive const):
+        (WebCore::PlatformCAAnimationCocoa::setAdditive):
+        (WebCore::PlatformCAAnimationCocoa::valueFunction const):
+        (WebCore::PlatformCAAnimationCocoa::setValueFunction):
+        (WebCore::PlatformCAAnimationCocoa::setFromValue):
+        (WebCore::PlatformCAAnimationCocoa::copyFromValueFrom):
+        (WebCore::PlatformCAAnimationCocoa::setToValue):
+        (WebCore::PlatformCAAnimationCocoa::copyToValueFrom):
+        (WebCore::PlatformCAAnimationCocoa::setValues):
+        (WebCore::PlatformCAAnimationCocoa::copyValuesFrom):
+        (WebCore::PlatformCAAnimationCocoa::setKeyTimes):
+        (WebCore::PlatformCAAnimationCocoa::copyKeyTimesFrom):
+        (WebCore::PlatformCAAnimationCocoa::setTimingFunctions):
+        (WebCore::PlatformCAAnimationCocoa::copyTimingFunctionsFrom):
+        (WebCore::PlatformCAAnimationCocoa::setAnimations):
+        (WebCore::PlatformCAAnimationCocoa::copyAnimationsFrom):
+        * platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm:
+        (WebCore::PlatformCALayerCocoa::addAnimationForKey):
+        (WebCore::PlatformCALayerCocoa::animationForKey):
+        * platform/graphics/ca/win/PlatformCAAnimationWin.cpp:
+        (PlatformCAAnimationWin::PlatformCAAnimationWin):
+        (PlatformCAAnimationWin::setAnimations):
+        (PlatformCAAnimationWin::copyAnimationsFrom):
+        * platform/graphics/ca/win/PlatformCAAnimationWin.h:
+
 2021-02-01  Saam Barati  <[email protected]>
 
         Lazily create m_windowCloseWatchpoints so we don't mistakenly think we have a frame when re-associating a document to a given cached frame

Modified: trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.cpp (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.cpp	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.cpp	2021-02-01 22:56:01 UTC (rev 272178)
@@ -34,6 +34,7 @@
 {
     switch (type) {
     case PlatformCAAnimation::Basic: ts << "basic"; break;
+    case PlatformCAAnimation::Group: ts << "group"; break;
     case PlatformCAAnimation::Keyframe: ts << "keyframe"; break;
     case PlatformCAAnimation::Spring: ts << "spring"; break;
     }

Modified: trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/PlatformCAAnimation.h	2021-02-01 22:56:01 UTC (rev 272178)
@@ -42,7 +42,7 @@
 
 class PlatformCAAnimation : public RefCounted<PlatformCAAnimation> {
 public:
-    enum AnimationType { Basic, Keyframe, Spring };
+    enum AnimationType { Basic, Group, Keyframe, Spring };
     enum FillModeType { NoFillMode, Forwards, Backwards, Both };
     enum ValueFunctionType { NoValueFunction, RotateX, RotateY, RotateZ, ScaleX, ScaleY, ScaleZ, Scale, TranslateX, TranslateY, TranslateZ, Translate };
 
@@ -119,6 +119,10 @@
     virtual void setTimingFunctions(const Vector<const TimingFunction*>&, bool reverse = false) = 0;
     virtual void copyTimingFunctionsFrom(const PlatformCAAnimation&) = 0;
 
+    // Animation group properties.
+    virtual void setAnimations(const Vector<RefPtr<PlatformCAAnimation>>&) = 0;
+    virtual void copyAnimationsFrom(const PlatformCAAnimation&) = 0;
+
     void setActualStartTimeIfNeeded(CFTimeInterval t)
     {
         if (beginTime() <= 0)
@@ -126,7 +130,7 @@
     }
 
     bool isBasicAnimation() const;
-    
+
 protected:
     PlatformCAAnimation(AnimationType type = Basic)
         : m_type(type)
@@ -156,6 +160,7 @@
     using values = EnumValues<
         WebCore::PlatformCAAnimation::AnimationType,
         WebCore::PlatformCAAnimation::AnimationType::Basic,
+        WebCore::PlatformCAAnimation::AnimationType::Group,
         WebCore::PlatformCAAnimation::AnimationType::Keyframe,
         WebCore::PlatformCAAnimation::AnimationType::Spring
     >;

Modified: trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.h (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.h	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.h	2021-02-01 22:56:01 UTC (rev 272178)
@@ -35,7 +35,7 @@
 OBJC_CLASS CAPropertyAnimation;
 OBJC_CLASS NSString;
 
-typedef CAPropertyAnimation* PlatformAnimationRef;
+typedef CAAnimation* PlatformAnimationRef;
 
 namespace WebCore {
 
@@ -123,11 +123,15 @@
     void setTimingFunctions(const Vector<const TimingFunction*>&, bool reverse = false) override;
     void copyTimingFunctionsFrom(const PlatformCAAnimation&) override;
 
+    // Animation group properties.
+    void setAnimations(const Vector<RefPtr<PlatformCAAnimation>>&) final;
+    void copyAnimationsFrom(const PlatformCAAnimation&) final;
+
 private:
     PlatformCAAnimationCocoa(AnimationType, const String& keyPath);
     PlatformCAAnimationCocoa(PlatformAnimationRef);
 
-    RetainPtr<CAPropertyAnimation> m_animation;
+    RetainPtr<CAAnimation> m_animation;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCAAnimationCocoa.mm	2021-02-01 22:56:01 UTC (rev 272178)
@@ -167,6 +167,9 @@
     case Basic:
         m_animation = [CABasicAnimation animationWithKeyPath:keyPath];
         break;
+    case Group:
+        m_animation = [CAAnimationGroup animation];
+        break;
     case Keyframe:
         m_animation = [CAKeyframeAnimation animationWithKeyPath:keyPath];
         break;
@@ -178,19 +181,22 @@
 
 PlatformCAAnimationCocoa::PlatformCAAnimationCocoa(PlatformAnimationRef animation)
 {
-    if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CABasicAnimation class]]) {
-        if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CASpringAnimation class]])
+    auto caAnimation = static_cast<CAAnimation *>(animation);
+    if ([caAnimation isKindOfClass:[CABasicAnimation class]]) {
+        if ([caAnimation isKindOfClass:[CASpringAnimation class]])
             setType(Spring);
         else
             setType(Basic);
-    } else if ([static_cast<CAAnimation*>(animation) isKindOfClass:[CAKeyframeAnimation class]])
+    } else if ([caAnimation isKindOfClass:[CAKeyframeAnimation class]])
         setType(Keyframe);
+    else if ([caAnimation isKindOfClass:[CAAnimationGroup class]])
+        setType(Group);
     else {
         ASSERT_NOT_REACHED();
         return;
     }
     
-    m_animation = static_cast<CAPropertyAnimation*>(animation);
+    m_animation = caAnimation;
 }
 
 PlatformCAAnimationCocoa::~PlatformCAAnimationCocoa()
@@ -235,7 +241,11 @@
 
 String PlatformCAAnimationCocoa::keyPath() const
 {
-    return [m_animation keyPath];
+    if (animationType() == Group)
+        return emptyString();
+
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAPropertyAnimation class]]);
+    return [static_cast<CAPropertyAnimation *>(m_animation.get()) keyPath];
 }
 
 CFTimeInterval PlatformCAAnimationCocoa::beginTime() const
@@ -333,6 +343,8 @@
             springAnimation.initialVelocity = function.initialVelocity();
         }
         break;
+    case Group:
+        break;
     }
 }
 
@@ -353,22 +365,38 @@
 
 bool PlatformCAAnimationCocoa::isAdditive() const
 {
-    return [m_animation isAdditive];
+    if (animationType() == Group)
+        return false;
+
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAPropertyAnimation class]]);
+    return [static_cast<CAPropertyAnimation *>(m_animation.get()) isAdditive];
 }
 
 void PlatformCAAnimationCocoa::setAdditive(bool value)
 {
-    [m_animation setAdditive:value];
+    if (animationType() == Group)
+        return;
+
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAPropertyAnimation class]]);
+    return [static_cast<CAPropertyAnimation *>(m_animation.get()) setAdditive:value];
 }
 
 PlatformCAAnimation::ValueFunctionType PlatformCAAnimationCocoa::valueFunction() const
 {
-    return fromCAValueFunctionType([[m_animation valueFunction] name]);
+    if (animationType() == Group)
+        return NoValueFunction;
+
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAPropertyAnimation class]]);
+    return fromCAValueFunctionType([[static_cast<CAPropertyAnimation *>(m_animation.get()) valueFunction] name]);
 }
 
 void PlatformCAAnimationCocoa::setValueFunction(ValueFunctionType value)
 {
-    [m_animation setValueFunction:[CAValueFunction functionWithName:toCAValueFunctionType(value)]];
+    if (animationType() == Group)
+        return;
+
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAPropertyAnimation class]]);
+    return [static_cast<CAPropertyAnimation *>(m_animation.get()) setValueFunction:[CAValueFunction functionWithName:toCAValueFunctionType(value)]];
 }
 
 void PlatformCAAnimationCocoa::setFromValue(float value)
@@ -375,7 +403,7 @@
 {
     if (!isBasicAnimation())
         return;
-    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:@(value)];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setFromValue:@(value)];
 }
 
 void PlatformCAAnimationCocoa::setFromValue(const TransformationMatrix& value)
@@ -382,7 +410,7 @@
 {
     if (!isBasicAnimation())
         return;
-    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:[NSValue valueWithCATransform3D:value]];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setFromValue:[NSValue valueWithCATransform3D:value]];
 }
 
 void PlatformCAAnimationCocoa::setFromValue(const FloatPoint3D& value)
@@ -389,7 +417,7 @@
 {
     if (!isBasicAnimation())
         return;
-    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:@[ @(value.x()), @(value.y()), @(value.z()) ]];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setFromValue:@[ @(value.x()), @(value.y()), @(value.z()) ]];
 }
 
 void PlatformCAAnimationCocoa::setFromValue(const Color& value)
@@ -397,13 +425,13 @@
     if (!isBasicAnimation())
         return;
     auto [r, g, b, a] = value.toSRGBALossy<uint8_t>();
-    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:@[@(r), @(g), @(b), @(a)]];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setFromValue:@[@(r), @(g), @(b), @(a)]];
 }
 
 void PlatformCAAnimationCocoa::setFromValue(const FilterOperation* operation, int internalFilterPropertyIndex)
 {
     auto value = PlatformCAFilters::filterValueForOperation(operation, internalFilterPropertyIndex);
-    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:value.get()];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setFromValue:value.get()];
 }
 
 void PlatformCAAnimationCocoa::copyFromValueFrom(const PlatformCAAnimation& value)
@@ -410,8 +438,8 @@
 {
     if (!isBasicAnimation() || !value.isBasicAnimation())
         return;
-    auto otherAnimation = static_cast<CABasicAnimation*>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
-    [static_cast<CABasicAnimation*>(m_animation.get()) setFromValue:[otherAnimation fromValue]];
+    auto otherAnimation = static_cast<CABasicAnimation *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
+    [static_cast<CABasicAnimation *>(m_animation.get()) setFromValue:[otherAnimation fromValue]];
 }
 
 void PlatformCAAnimationCocoa::setToValue(float value)
@@ -418,7 +446,7 @@
 {
     if (!isBasicAnimation())
         return;
-    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:@(value)];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setToValue:@(value)];
 }
 
 void PlatformCAAnimationCocoa::setToValue(const TransformationMatrix& value)
@@ -425,7 +453,7 @@
 {
     if (!isBasicAnimation())
         return;
-    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:[NSValue valueWithCATransform3D:value]];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setToValue:[NSValue valueWithCATransform3D:value]];
 }
 
 void PlatformCAAnimationCocoa::setToValue(const FloatPoint3D& value)
@@ -432,7 +460,7 @@
 {
     if (!isBasicAnimation())
         return;
-    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:@[ @(value.x()), @(value.y()), @(value.z()) ]];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setToValue:@[ @(value.x()), @(value.y()), @(value.z()) ]];
 }
 
 void PlatformCAAnimationCocoa::setToValue(const Color& value)
@@ -440,13 +468,13 @@
     if (!isBasicAnimation())
         return;
     auto [r, g, b, a] = value.toSRGBALossy<uint8_t>();
-    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:@[@(r), @(g), @(b), @(a)]];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setToValue:@[@(r), @(g), @(b), @(a)]];
 }
 
 void PlatformCAAnimationCocoa::setToValue(const FilterOperation* operation, int internalFilterPropertyIndex)
 {
     auto value = PlatformCAFilters::filterValueForOperation(operation, internalFilterPropertyIndex);
-    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:value.get()];
+    [static_cast<CABasicAnimation *>(m_animation.get()) setToValue:value.get()];
 }
 
 void PlatformCAAnimationCocoa::copyToValueFrom(const PlatformCAAnimation& value)
@@ -454,8 +482,8 @@
     if (!isBasicAnimation() || !value.isBasicAnimation())
         return;
 
-    auto otherAnimation = static_cast<CABasicAnimation*>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
-    [static_cast<CABasicAnimation*>(m_animation.get()) setToValue:[otherAnimation toValue]];
+    auto otherAnimation = static_cast<CABasicAnimation *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
+    [static_cast<CABasicAnimation *>(m_animation.get()) setToValue:[otherAnimation toValue]];
 }
 
 
@@ -465,7 +493,7 @@
     if (animationType() != Keyframe)
         return;
 
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:createNSArray(value, [] (float number) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setValues:createNSArray(value, [] (float number) {
         return @(number);
     }).get()];
 }
@@ -475,7 +503,7 @@
     if (animationType() != Keyframe)
         return;
 
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:createNSArray(value, [] (auto& matrix) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setValues:createNSArray(value, [] (auto& matrix) {
         return [NSValue valueWithCATransform3D:matrix];
     }).get()];
 }
@@ -485,7 +513,7 @@
     if (animationType() != Keyframe)
         return;
 
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:createNSArray(value, [] (auto& point) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setValues:createNSArray(value, [] (auto& point) {
         return @[@(point.x()), @(point.y()), @(point.z())];
     }).get()];
 }
@@ -495,7 +523,7 @@
     if (animationType() != Keyframe)
         return;
 
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:createNSArray(value, [] (auto& color) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setValues:createNSArray(value, [] (auto& color) {
         auto [r, g, b, a] = color.template toSRGBALossy<uint8_t>();
         return @[@(r), @(g), @(b), @(a)];
     }).get()];
@@ -506,7 +534,7 @@
     if (animationType() != Keyframe)
         return;
 
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:createNSArray(values, [&] (auto& value) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setValues:createNSArray(values, [&] (auto& value) {
         return PlatformCAFilters::filterValueForOperation(value.get(), internalFilterPropertyIndex);
     }).get()];
 }
@@ -516,13 +544,13 @@
     if (animationType() != Keyframe || value.animationType() != Keyframe)
         return;
 
-    auto otherAnimation = static_cast<CAKeyframeAnimation*>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setValues:[otherAnimation values]];
+    auto otherAnimation = static_cast<CAKeyframeAnimation *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setValues:[otherAnimation values]];
 }
 
 void PlatformCAAnimationCocoa::setKeyTimes(const Vector<float>& value)
 {
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setKeyTimes:createNSArray(value, [] (float time) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setKeyTimes:createNSArray(value, [] (float time) {
         return @(time);
     }).get()];
 }
@@ -529,13 +557,13 @@
 
 void PlatformCAAnimationCocoa::copyKeyTimesFrom(const PlatformCAAnimation& value)
 {
-    auto other = static_cast<CAKeyframeAnimation*>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setKeyTimes:[other keyTimes]];
+    auto other = static_cast<CAKeyframeAnimation *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setKeyTimes:[other keyTimes]];
 }
 
 void PlatformCAAnimationCocoa::setTimingFunctions(const Vector<const TimingFunction*>& value, bool reverse)
 {
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setTimingFunctions:createNSArray(value, [&] (auto& function) {
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setTimingFunctions:createNSArray(value, [&] (auto& function) {
         return toCAMediaTimingFunction(function, reverse);
     }).get()];
 }
@@ -542,8 +570,31 @@
 
 void PlatformCAAnimationCocoa::copyTimingFunctionsFrom(const PlatformCAAnimation& value)
 {
-    auto other = static_cast<CAKeyframeAnimation*>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
-    [static_cast<CAKeyframeAnimation*>(m_animation.get()) setTimingFunctions:[other timingFunctions]];
+    auto other = static_cast<CAKeyframeAnimation *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
+    [static_cast<CAKeyframeAnimation *>(m_animation.get()) setTimingFunctions:[other timingFunctions]];
 }
 
+void PlatformCAAnimationCocoa::setAnimations(const Vector<RefPtr<PlatformCAAnimation>>& value)
+{
+    ASSERT(animationType() == Group);
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAAnimationGroup class]]);
+
+    [static_cast<CAAnimationGroup *>(m_animation.get()) setAnimations:createNSArray(value, [&] (auto& animation) -> CAAnimation * {
+        if (is<PlatformCAAnimationCocoa>(animation.get()))
+            return downcast<PlatformCAAnimationCocoa>(animation.get())->m_animation.get();
+        return nil;
+    }).get()];
+}
+
+void PlatformCAAnimationCocoa::copyAnimationsFrom(const PlatformCAAnimation& value)
+{
+    ASSERT(animationType() == Group);
+    ASSERT(value.animationType() == Group);
+    ASSERT([static_cast<CAAnimation *>(m_animation.get()) isKindOfClass:[CAAnimationGroup class]]);
+    ASSERT([static_cast<CAAnimation *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get()) isKindOfClass:[CAAnimationGroup class]]);
+
+    auto other = static_cast<CAAnimationGroup *>(downcast<PlatformCAAnimationCocoa>(value).m_animation.get());
+    [static_cast<CAAnimationGroup *>(m_animation.get()) setAnimations:[other animations]];
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/cocoa/PlatformCALayerCocoa.mm	2021-02-01 22:56:01 UTC (rev 272178)
@@ -511,7 +511,7 @@
         [webAnimationDelegate setOwner:this];
     }
     
-    CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>(downcast<PlatformCAAnimationCocoa>(animation).platformAnimation());
+    CAAnimation *propertyAnimation = static_cast<CAAnimation *>(downcast<PlatformCAAnimationCocoa>(animation).platformAnimation());
     if (![propertyAnimation delegate])
         [propertyAnimation setDelegate:static_cast<id>(m_delegate.get())];
 
@@ -529,7 +529,7 @@
 
 RefPtr<PlatformCAAnimation> PlatformCALayerCocoa::animationForKey(const String& key)
 {
-    CAPropertyAnimation* propertyAnimation = static_cast<CAPropertyAnimation*>([m_layer animationForKey:key]);
+    CAAnimation *propertyAnimation = static_cast<CAAnimation *>([m_layer animationForKey:key]);
     if (!propertyAnimation)
         return nullptr;
     return PlatformCAAnimationCocoa::create(propertyAnimation);

Modified: trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp	2021-02-01 22:56:01 UTC (rev 272178)
@@ -157,8 +157,10 @@
 {
     if (type == Basic)
         m_animation = adoptCF(CACFAnimationCreate(kCACFBasicAnimation));
-    else
+    else if (type == Keyframe)
         m_animation = adoptCF(CACFAnimationCreate(kCACFKeyframeAnimation));
+    else if (type == Group)
+        m_animation = adoptCF(CACFAnimationCreate(kCACFAnimationGroup));
     
     CACFAnimationSetKeyPath(m_animation.get(), keyPath.createCFString().get());
 }
@@ -169,6 +171,8 @@
         setType(Basic);
     else if (CACFAnimationGetClass(animation) == kCACFKeyframeAnimation)
         setType(Keyframe);
+    else if (CACFAnimationGetClass(animation) == kCACFAnimationGroup)
+        setType(Group);
     else {
         ASSERT_NOT_REACHED();
         return;
@@ -553,4 +557,20 @@
     CACFAnimationSetTimingFunctions(m_animation.get(), CACFAnimationGetTimingFunctions(downcast<PlatformCAAnimationWin>(value).platformAnimation()));
 }
 
+void PlatformCAAnimationWin::setAnimations(const Vector<RefPtr<PlatformCAAnimation>>& value)
+{
+    auto array = adoptCF(CFArrayCreateMutable(0, value.size(), &kCFTypeArrayCallBacks));
+    for (auto& animation : value) {
+        if (is<PlatformCAAnimationWin>(animation.get()))
+            CFArrayAppendValue(array.get(), downcast<PlatformCAAnimationWin>(*animation).m_animation.get());
+    }
+
+    CACFAnimationSetAnimations(m_animation.get(), array.get());
+}
+
+void PlatformCAAnimationWin::copyAnimationsFrom(const PlatformCAAnimation& value)
+{
+    CACFAnimationSetAnimations(m_animation.get(), CACFAnimationGetAnimations(downcast<PlatformCAAnimationWin>(value).platformAnimation()));
+}
+
 #endif // PLATFORM(WIN)

Modified: trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.h (272177 => 272178)


--- trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.h	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.h	2021-02-01 22:56:01 UTC (rev 272178)
@@ -113,6 +113,10 @@
     void setTimingFunctions(const Vector<const TimingFunction*>&, bool reverse = false) override;
     void copyTimingFunctionsFrom(const PlatformCAAnimation&) override;
 
+    // Animation group properties.
+    void setAnimations(const Vector<RefPtr<PlatformCAAnimation>>&) final;
+    void copyAnimationsFrom(const PlatformCAAnimation&) final;
+
 private:
     PlatformCAAnimationWin(AnimationType, const String& keyPath);
     PlatformCAAnimationWin(PlatformAnimationRef);

Modified: trunk/Source/WebKit/ChangeLog (272177 => 272178)


--- trunk/Source/WebKit/ChangeLog	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebKit/ChangeLog	2021-02-01 22:56:01 UTC (rev 272178)
@@ -1,3 +1,25 @@
+2021-02-01  Antoine Quint  <[email protected]>
+
+        Allow support for CAAnimationGroup
+        https://bugs.webkit.org/show_bug.cgi?id=221209
+
+        Reviewed by Dean Jackson, Sam Weinig and Simon Fraser.
+
+        In order to fix bug 219894, we need to use Core Animation's CAAnimationGroup and its
+        setAnimations() method. Add support for the new "Group" PlatformCAAnimation type for
+        the remote animations.
+
+        * WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.h:
+        * WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.mm:
+        (WebKit::PlatformCAAnimationRemote::Properties::encode const):
+        (WebKit::PlatformCAAnimationRemote::Properties::decode):
+        (WebKit::PlatformCAAnimationRemote::copy const):
+        (WebKit::PlatformCAAnimationRemote::setAnimations):
+        (WebKit::PlatformCAAnimationRemote::copyAnimationsFrom):
+        (WebKit::createAnimation):
+        (WebKit::addAnimationToLayer):
+        (WebKit::operator<<):
+
 2021-02-01  Wenson Hsieh  <[email protected]>
 
         Add a cross-platform helper method to generate shareable bitmaps from rendered images

Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.h (272177 => 272178)


--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.h	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.h	2021-02-01 22:56:01 UTC (rev 272178)
@@ -119,6 +119,10 @@
     void setTimingFunctions(const Vector<const WebCore::TimingFunction*>&, bool reverse = false) override;
     void copyTimingFunctionsFrom(const WebCore::PlatformCAAnimation&) override;
 
+    // Animation group properties.
+    void setAnimations(const Vector<RefPtr<PlatformCAAnimation>>&) final;
+    void copyAnimationsFrom(const PlatformCAAnimation&) final;
+
     AnimationType animationType() const { return m_properties.animationType; }
     void setHasExplicitBeginTime(bool hasExplicitBeginTime) { m_properties.hasExplicitBeginTime = hasExplicitBeginTime; }
     bool hasExplicitBeginTime() const { return m_properties.hasExplicitBeginTime; }
@@ -289,6 +293,8 @@
         Vector<KeyframeValue> keyValues;
         Vector<float> keyTimes;
         Vector<RefPtr<WebCore::TimingFunction>> timingFunctions;
+
+        Vector<Properties> animations;
     };
 
     const Properties& properties() const { return m_properties; }

Modified: trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.mm (272177 => 272178)


--- trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.mm	2021-02-01 22:02:00 UTC (rev 272177)
+++ trunk/Source/WebKit/WebProcess/WebPage/RemoteLayerTree/PlatformCAAnimationRemote.mm	2021-02-01 22:56:01 UTC (rev 272178)
@@ -241,6 +241,8 @@
     encoder << static_cast<uint64_t>(timingFunctions.size());
     for (const auto& timingFunction : timingFunctions)
         encodeTimingFunction(encoder, timingFunction.get());
+
+    encoder << animations;
 }
 
 Optional<PlatformCAAnimationRemote::Properties> PlatformCAAnimationRemote::Properties::decode(IPC::Decoder& decoder)
@@ -320,6 +322,9 @@
         }
     }
 
+    if (!decoder.decode(properties.animations))
+        return WTF::nullopt;
+
     return WTFMove(properties);
 }
     
@@ -355,7 +360,9 @@
         animation->copyFromValueFrom(*this);
         animation->copyToValueFrom(*this);
     }
-    
+
+    animation->copyAnimationsFrom(*this);
+
     return animation;
 }
 
@@ -711,6 +718,19 @@
     m_properties.reverseTimingFunctions = other.m_properties.reverseTimingFunctions;
 }
 
+void PlatformCAAnimationRemote::setAnimations(const Vector<RefPtr<PlatformCAAnimation>>& values)
+{
+    m_properties.animations = values.map([](auto& value) {
+        return downcast<PlatformCAAnimationRemote>(value.get())->properties();
+    });
+}
+
+void PlatformCAAnimationRemote::copyAnimationsFrom(const PlatformCAAnimation& value)
+{
+    const PlatformCAAnimationRemote& other = downcast<PlatformCAAnimationRemote>(value);
+    m_properties.animations = other.m_properties.animations;
+}
+
 static NSObject* animationValueFromKeyframeValue(const PlatformCAAnimationRemote::KeyframeValue& keyframeValue)
 {
     switch (keyframeValue.keyframeType()) {
@@ -734,13 +754,13 @@
     }
 }
 
-static void addAnimationToLayer(CALayer *layer, RemoteLayerTreeHost* layerTreeHost, const String& key, const PlatformCAAnimationRemote::Properties& properties)
+static RetainPtr<CAAnimation> createAnimation(CALayer *layer, RemoteLayerTreeHost* layerTreeHost, const PlatformCAAnimationRemote::Properties& properties)
 {
-    RetainPtr<CAPropertyAnimation> caAnimation;
+    RetainPtr<CAAnimation> caAnimation;
     switch (properties.animationType) {
     case PlatformCAAnimation::Basic: {
         auto basicAnimation = [CABasicAnimation animationWithKeyPath:properties.keyPath];
-        
+
         if (properties.keyValues.size() > 1) {
             [basicAnimation setFromValue:animationValueFromKeyframeValue(properties.keyValues[0])];
             [basicAnimation setToValue:animationValueFromKeyframeValue(properties.keyValues[1])];
@@ -752,6 +772,18 @@
         caAnimation = basicAnimation;
         break;
     }
+    case PlatformCAAnimation::Group: {
+        auto animationGroup = [CAAnimationGroup animation];
+
+        if (properties.animations.size()) {
+            [animationGroup setAnimations:createNSArray(properties.animations, [&] (auto& animationProperties) {
+                return createAnimation(layer, layerTreeHost, animationProperties).get();
+            }).get()];
+        }
+
+        caAnimation = animationGroup;
+        break;
+    }
     case PlatformCAAnimation::Keyframe: {
         auto keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:properties.keyPath];
 
@@ -775,18 +807,18 @@
                 return toCAMediaTimingFunction(function.get(), properties.reverseTimingFunctions);
             }).get()];
         }
-        
+
         caAnimation = keyframeAnimation;
         break;
     }
     case PlatformCAAnimation::Spring: {
         auto springAnimation = [CASpringAnimation animationWithKeyPath:properties.keyPath];
-        
+
         if (properties.keyValues.size() > 1) {
             [springAnimation setFromValue:animationValueFromKeyframeValue(properties.keyValues[0])];
             [springAnimation setToValue:animationValueFromKeyframeValue(properties.keyValues[1])];
         }
-        
+
         if (properties.timingFunctions.size()) {
             auto& timingFunction = properties.timingFunctions[0];
             if (timingFunction->isSpringTimingFunction()) {
@@ -801,7 +833,7 @@
         break;
     }
     }
-    
+
     [caAnimation setBeginTime:properties.beginTime];
     [caAnimation setDuration:properties.duration];
     [caAnimation setTimeOffset:properties.timeOffset];
@@ -809,20 +841,22 @@
     [caAnimation setSpeed:properties.speed];
     [caAnimation setAutoreverses:properties.autoReverses];
     [caAnimation setRemovedOnCompletion:properties.removedOnCompletion];
-    [caAnimation setAdditive:properties.additive];
-    
+
+    if ([caAnimation isKindOfClass:[CAPropertyAnimation class]]) {
+        [(CAPropertyAnimation *)caAnimation setAdditive:properties.additive];
+        if (properties.valueFunction != PlatformCAAnimation::NoValueFunction)
+            [(CAPropertyAnimation *)caAnimation setValueFunction:[CAValueFunction functionWithName:toCAValueFunctionType(properties.valueFunction)]];
+    }
+
     if (properties.fillMode != PlatformCAAnimation::NoFillMode)
         [caAnimation setFillMode:toCAFillModeType(properties.fillMode)];
 
-    if (properties.valueFunction != PlatformCAAnimation::NoValueFunction)
-        [caAnimation setValueFunction:[CAValueFunction functionWithName:toCAValueFunctionType(properties.valueFunction)]];
-    
     if (properties.hasExplicitBeginTime)
         [caAnimation setValue:@YES forKey:WKExplicitBeginTimeFlag];
-    
+
     if (layerTreeHost) {
         GraphicsLayer::PlatformLayerID layerID = RemoteLayerTreeNode::layerID(layer);
-    
+
         RetainPtr<WKAnimationDelegate>& delegate = layerTreeHost->animationDelegates().add(layerID, nullptr).iterator->value;
         if (!delegate)
             delegate = adoptNS([[WKAnimationDelegate alloc] initWithLayerID:layerID layerTreeHost:layerTreeHost]);
@@ -829,10 +863,15 @@
 
         [caAnimation setDelegate:delegate.get()];
     }
-    
-    [layer addAnimation:caAnimation.get() forKey:key];
+
+    return caAnimation;
 }
 
+static void addAnimationToLayer(CALayer *layer, RemoteLayerTreeHost* layerTreeHost, const String& key, const PlatformCAAnimationRemote::Properties& properties)
+{
+    [layer addAnimation:createAnimation(layer, layerTreeHost, properties).get() forKey:key];
+}
+
 void PlatformCAAnimationRemote::updateLayerAnimations(CALayer *layer, RemoteLayerTreeHost* layerTreeHost, const AnimationsList& animationsToAdd, const HashSet<String>& animationsToRemove)
 {
     BEGIN_BLOCK_OBJC_EXCEPTIONS
@@ -943,6 +982,24 @@
     ts.decreaseIndent();
     ts.decreaseIndent();
 
+    if (!animation.animations.isEmpty()) {
+        ts << "\n";
+        ts.increaseIndent();
+        ts.writeIndent();
+        ts << "(" << "animations";
+        ts.increaseIndent();
+
+        for (auto& childAnimation : animation.animations) {
+            ts << "\n";
+            ts.writeIndent();
+            ts << "(animation " << childAnimation;
+            ts << ")";
+        }
+
+        ts.decreaseIndent();
+        ts.decreaseIndent();
+    }
+
     return ts;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to