Bug 186127

Summary: [iOS] Tranformation matrix not preserved when pausing complex animation with Bézier timing function
Product: WebKit Reporter: Frédéric Wang (:fredw) <fred.wang>
Component: AnimationsAssignee: Frédéric Wang (:fredw) <fred.wang>
Status: NEW ---    
Severity: Normal CC: dino, graouts, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
URL: https://codepen.io/anon/pen/bWGobG
See Also: https://github.com/web-platform-tests/wpt/pull/11279
Bug Depends on: 186045, 170784, 186129    
Bug Blocks:    
Attachments:
Description Flags
Testcase
none
Patch
none
Patch
none
Another testcase none

Description Frédéric Wang (:fredw) 2018-05-30 23:58:02 PDT
Extracted from bug 170784. With the patch for bug 170784, http://codepen.io/anon/pen/bWGobG can be paused but the rotation angle is lost.
Comment 1 Frédéric Wang (:fredw) 2018-05-31 00:00:36 PDT
Created attachment 341645 [details]
Testcase

Compare animations with linear timing function VS steps timing function.
Comment 2 Frédéric Wang (:fredw) 2018-05-31 05:11:01 PDT
Created attachment 341659 [details]
Patch
Comment 3 Frédéric Wang (:fredw) 2018-05-31 09:07:29 PDT
Submitted web-platform-tests pull request: https://github.com/web-platform-tests/wpt/pull/11279
Comment 4 Frédéric Wang (:fredw) 2018-06-08 02:42:07 PDT
Created attachment 342247 [details]
Patch

Improved test.
Comment 5 Frédéric Wang (:fredw) 2018-06-13 09:51:04 PDT
Created attachment 342666 [details]
Another testcase

So I tried to compare what happens on macOS and iOS and basically they both use CALayer's addAnimation to add two animations (translate and rotate) and later replace them by a zero-speed copy. Below are the output in PlatformCALayerCocoa::addAnimationForKey and PlatformCAAnimationRemote's addAnimationToLayer for the attached testcase. I don't see any obvious difference so my guess would be a bug in the iOS-implementation of the CALayer classes.

== macOS ==

(lldb)  p propertyAnimation.valueFunction.name
(__NSCFConstantString *) $30 = 0x00007fffadc428c0 @"translate"
(lldb) po propertyAnimation
<CABasicAnimation:0x7f8ba545a2c0; delegate = <WebAnimationDelegate: 0x7f8ba5630530>; toValue = (
    90,
    0,
    0
); fromValue = (
    0,
    0,
    0
); valueFunction = <CAValueFunction: 0x7f8ba562ea20>; timingFunction = linear; additive = 0; removedOnCompletion = 0; fillMode = forwards; autoreverses = 0; repeatCount = 1; timeOffset = 2.30686; speed = 0; duration = 5; WKPlatformCAAnimationExplicitBeginTimeFlag = false; beginTime = 4023.49; keyPath = transform>

(lldb)  p propertyAnimation.valueFunction.name
(__NSCFConstantString *) $34 = 0x00007fffadc42800 @"rotateZ"
(lldb) po propertyAnimation
<CABasicAnimation:0x7f8ba560c010; delegate = <WebAnimationDelegate: 0x7f8ba5630530>; toValue = 3.1415927410125732; fromValue = 0.0; valueFunction = <CAValueFunction: 0x7f8ba562ead0>; timingFunction = linear; additive = 1; removedOnCompletion = 0; fillMode = forwards; autoreverses = 0; repeatCount = 1; timeOffset = 2.30686; speed = 0; duration = 5; WKPlatformCAAnimationExplicitBeginTimeFlag = false; beginTime = 4023.49; keyPath = transform>

== iOS ==

(lldb) p properties.valueFunction
(const ValueFunctionType) $10 = Translate
(lldb) po caAnimation.get()
<CABasicAnimation:0x7fd694f9fd50; delegate = <WKAnimationDelegate: 0x7fd694eded40>; valueFunction = <CAValueFunction: 0x7fd694fd4d70>; fillMode = forwards; additive = 0; removedOnCompletion = 0; autoreverses = 0; speed = 0; repeatCount = 1; timeOffset = 2.30493; duration = 5; beginTime = 4494.56; timingFunction = linear; toValue = (
    90,
    0,
    0
); fromValue = (
    0,
    0,
    0
); keyPath = transform>

(lldb) p properties.valueFunction
(const ValueFunctionType) $12 = RotateZ
(lldb) po caAnimation.get()
<CABasicAnimation:0x7fd694feb1c0; delegate = <WKAnimationDelegate: 0x7fd694eded40>; valueFunction = <CAValueFunction: 0x7fd694fd43d0>; fillMode = forwards; additive = 1; removedOnCompletion = 0; autoreverses = 0; speed = 0; repeatCount = 1; timeOffset = 2.30493; duration = 5; beginTime = 4494.56; timingFunction = linear; toValue = 3.1415927410125732; fromValue = 0.0; keyPath = transform>
Comment 6 Frédéric Wang (:fredw) 2018-07-03 11:47:22 PDT
Just tried again after https://trac.webkit.org/changeset/233460/webkit and animations of the testcases can be paused but the rotation angle is lost. I'm testing a trunk build on the iOS simulator using the public SDK. As said in comment 5, I don't see any difference between iOS and macOS regarding how animations are set on the CALayer, so I wonder whether the issue is actually in proprietary code.

@Antoine Quint: Do you see the same bug with your setup? Do you think it's fixable in WebKit (maybe with a hack like the bug7311367Workaround function in GraphicsLayerCA)?
Comment 7 Radar WebKit Bug Importer 2018-10-12 14:35:28 PDT
<rdar://problem/45237786>
Comment 8 Simon Fraser (smfr) 2018-10-12 14:35:53 PDT
https://codepen.io/anon/pen/bWGobG still shows this bug on iOS.
Comment 9 Radar WebKit Bug Importer 2018-10-12 14:36:21 PDT
<rdar://problem/45237815>