Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Core Animation rendering engine partially supports time remapping keyframes #1648

Closed
smolskyaleksey opened this issue Jul 11, 2022 · 12 comments · Fixed by #2286
Closed
Labels
Core Animation rendering engine Regressions introduced by the Core Animation rendering engine

Comments

@smolskyaleksey
Copy link

version 3.4.0 master branch

Lottie/AnimationView.swift:1003: Assertion failed: Encountered Core Animation compatibility issues while setting up animation:
[Puke Splash_PRECOMP_02] The Core Animation rendering engine partially supports time remapping keyframes, but this is somewhat experimental and has some known issues. Since it doesn't work in all cases, we have to fall back to using the main thread engine when using RenderingEngineOption.automatic.
[Puke Splash_PRECOMP_02] The Core Animation rendering engine partially supports time remapping keyframes, but this is somewhat experimental and has some known issues. Since it doesn't work in all cases, we have to fall back to using the main thread engine when using RenderingEngineOption.automatic.

This animation cannot be rendered correctly by the Core Animation engine.
To resolve this issue, you can use RenderingEngineOption.automatic, which automatically falls back
to the Main Thread rendering engine when necessary, or just use RenderingEngineOption.mainThread.

@calda
Copy link
Member

calda commented Jul 11, 2022

The Core Animation rendering engine has a partial implementation of time remapping that works in some circumstances, but doesn't always work correctly. For now I'd suggest using LottieConfiguration(renderingEngine: .automatic), which will automatically fall back to using the main thread rendering engine for animations that use time remapping.

If you specifically want or need to use the Core Animation rendering engine for this animation, you can suppress this assertion by disabling the LottieLogger (either via LottieLogger.shared = .printToConsole or AnimationView(animation: myAnimation, logger: .printToConsole)).

@smolskyaleksey
Copy link
Author

Ok, thx, but the performance is still worse than 2.5.3 version. Do you have any idea why?

@calda
Copy link
Member

calda commented Jul 11, 2022

When using which rendering engine?

@smolskyaleksey
Copy link
Author

smolskyaleksey commented Jul 12, 2022

When using which rendering engine?

Yes. Any rendering engine worse than 2.5.3

@calda
Copy link
Member

calda commented Jul 12, 2022

Can you share your animation json?

@smolskyaleksey
Copy link
Author

Can you share your animation json?

gemmic.zip

@calda
Copy link
Member

calda commented Jul 12, 2022

Performance of these animations seems great when using the Core Animation engine (0% CPU utilization, and a high framerate), is there a specific issue you were encountering?

@smolskyaleksey
Copy link
Author

Performance of these animations seems great when using the Core Animation engine (0% CPU utilization, and a high framerate), is there a specific issue you were encountering?

When you add all of this to vertical collectionView, one per cell and try to scroll up/down fps rate will be decrease

@pejato
Copy link
Contributor

pejato commented Oct 20, 2022

Hey @calda , our designers like to use time remapping, so this is something I'd be interested in getting support for and would be willing to work on if feasible.

Do you have more info on what the outstanding issues here are?

@calda
Copy link
Member

calda commented Oct 20, 2022

We have an implementation of time remapping that sort of works, but only in simple cases.

Time remapping in Core Animation is complicated for a few reasons:

Every animation has keyframes with timing curves, which Core Animation uses to determine the current value of the property animated at any given time. You can think of these as an arbitrary function that takes the layer's current time value and outputs the value of the property at that time.

Time remapping is also a set of keyframes with timing curves. Time remapping is basically a function that takes a layer's current time value and outputs the remapped time value for its child layer.

To render this correctly, the time remapping of the parent has to be applied to the child every frame. The Core Animation engine doesn't currently operate on individual frames -- it only operates on the set of defined keyframes, and lets Core Animation itself interpolate the individual frames. But if we only apply the time remapping to the keyframes that we create, then the output is incorrect in complex cases. To fix this we would need to manually interpolate the keyframes so we know the value at each frame, and then apply the time remapping to each of those frames.

Another obstacle is the direction in which we have to apply the time remapping. Time remapping is specifically a function from the parent's "local time" to the child's "local time". An example of this -- say you want the child's animation to go twice as fast. When the parent layer is at frame 10, the child's frame is at time 20.

Because of the architecture of the Core Animation engine, I think we have to answer this question in reverse. In the same example of making the child's animation go twice as fast, when computing a value of the child layer at frame 20 we have to know that we should actually be using the value originally intended to be used at frame 10. This requires taking the inverse of the time remapping function, which I don't know how to do correctly (particularly when accounting for the timing curves).

@pejato
Copy link
Contributor

pejato commented Oct 21, 2022

Thanks for the informative reply Cal, it's very helpful 😄 Going to do a more thorough reading of Lottie's CA rendering code this weekend.

This requires taking the inverse of the time remapping function, which I don't know how to do correctly

I'm not sure this is even possible if the time remapping function isn't invertible, which is a possibility, e.g. if we reverse and replay some frames like the second animation here, right?

@calda
Copy link
Member

calda commented Jan 9, 2024

Fixed in #2286!

@calda calda added Core Animation rendering engine Regressions introduced by the Core Animation rendering engine and removed help wanted labels Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Core Animation rendering engine Regressions introduced by the Core Animation rendering engine
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants