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

Animation looks differently with different rendering mode #1876

Open
Banck opened this issue Dec 21, 2022 · 4 comments
Open

Animation looks differently with different rendering mode #1876

Banck opened this issue Dec 21, 2022 · 4 comments
Labels
bug Core Animation rendering engine Regressions introduced by the Core Animation rendering engine

Comments

@Banck
Copy link

Banck commented Dec 21, 2022

Hello!
I'm trying Lottie 4.0.1 and animation broken with rendering mode automatic. I attached json file and screenshot how this file looks:
Web Preview:
image

iOS with mainThread:
image

iOS with automatic rendering mode:
image

As you can see on the Web Preview animation looks cool, but on iOS with mainThread there is some glitches on the top, on iOS with automatic rendering mode animation is broken.

NoConnectionLight.json.zip

@calda calda added the bug label Dec 21, 2022
@calda
Copy link
Member

calda commented Jan 5, 2023

Thanks for the report. I've investigated some and understand why this issue is happening, but don't know a good way to fix it. Leaving some notes for future reference:

The Tower Poles shape has a structure like this:

  • Group
    • Larger Rectangle
    • Shape transform
  • Group
    • Smaller Rectangle
    • Shape transform
  • Red Fill

In the main thread rendering engine, the two rectangles are combined into a single CGPath that is that rendered with the red fill. Drawing the two shapes as a single CGPath causes the small rectangle to be subtracted from the larger rectangle, which is effective rendered as a red outlined triangle.

The Core Animation rendering engine converts each Group into a CAShapeLayer drawing a single CGPath with the red fill. This means both paths are opaque and are just drawn on top of each other (rather than smaller rectangle being subtracted from the larger rectangle). Each path has its own transform, and we currently only apply transforms to CAShapeLayers, so we don't currently have a way to correctly apply the transform before then merging the shapes.

I'm not sure there's a way to fix this without substantially rewriting how groups are handled by the Core Animation rendering engine, and I'm not sure we have a good way to detect this unsupported case without having too many false-positives.

A workaround would be to either:

  1. manually use the main thread rendering engine for this animation
  2. update the animation to just use a single path shape for the Tower Poles item (specifically drawing just the tower outline) instead of multiple shapes that have to be combined at runtime.

@Banck
Copy link
Author

Banck commented Jan 7, 2023

Thanks for the report. I've investigated some and understand why this issue is happening, but don't know a good way to fix it. Leaving some notes for future reference:

The Tower Poles shape has a structure like this:

  • Group

    • Larger Rectangle
    • Shape transform
  • Group

    • Smaller Rectangle
    • Shape transform
  • Red Fill

In the main thread rendering engine, the two rectangles are combined into a single CGPath that is that rendered with the red fill. Drawing the two shapes as a single CGPath causes the small rectangle to be subtracted from the larger rectangle, which is effective rendered as a red outlined triangle.

The Core Animation rendering engine converts each Group into a CAShapeLayer drawing a single CGPath with the red fill. This means both paths are opaque and are just drawn on top of each other (rather than smaller rectangle being subtracted from the larger rectangle). Each path has its own transform, and we currently only apply transforms to CAShapeLayers, so we don't currently have a way to correctly apply the transform before then merging the shapes.

I'm not sure there's a way to fix this without substantially rewriting how groups are handled by the Core Animation rendering engine, and I'm not sure we have a good way to detect this unsupported case without having too many false-positives.

A workaround would be to either:

  1. manually use the main thread rendering engine for this animation
  2. update the animation to just use a single path shape for the Tower Poles item (specifically drawing just the tower outline) instead of multiple shapes that have to be combined at runtime.

Hey!
Thanks for your comment. So if Core animation engine can’t handle animations with such structure - .automatic mode should select main thread, isn’t it?

@calda
Copy link
Member

calda commented Jan 7, 2023

Yes, that's the intended behavior of .automatic. We'd just have to manually implement a step that checks for this specific unsupported configuration. When implementing new checks like this we just need to make sure there aren't any false positives (e.g. animations marked as unsupported even though they render correctly). This can be difficult in complex cases.

The problem here is that there are a lot of Lottie animations in our test suite that have a similar structure to this animation but still render correctly. A compatibility check would need to be able to tell the difference between these cases.

@calda calda added the Core Animation rendering engine Regressions introduced by the Core Animation rendering engine label Mar 4, 2023
@calda
Copy link
Member

calda commented Aug 24, 2023

Here's another example of this issue: #2085

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Core Animation rendering engine Regressions introduced by the Core Animation rendering engine
Projects
None yet
Development

No branches or pull requests

2 participants