JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
16.03k stars 1.16k forks source link

[1.7.0-alpha01] GraphicsLayer do not seems to like being drawn multiple times #5066

Closed chrisbanes closed 2 weeks ago

chrisbanes commented 3 months ago

Describe the bug This morning I've be updating my Haze library to CMP 1.7.0-alpha01, which gives us access to the new GraphicsLayer APIs. My Android implementation already used RenderNode (which is basically the same), so I've moved that impl over to commonMain and now have a single implementation for all platforms.

It works as expected on Android, but on Skiko backed platforms it seems to have issues when you have multiple child layers drawing another layer. The first child layer is drawn fine, but others are not

I've also seen issues when a layer's position is outside the window bounds, the layer just doesn't draw anything.

Haze is a bit of a stress test for the graphics layers integration, so it might be worth investigating. The sample app is an easy way to see play around. https://github.com/chrisbanes/haze/pull/250

Affected platforms Skiko-backed platforms (JVM, iOS, etc)

Versions

chrisbanes commented 3 months ago

Went a bit deeper into this today.

The way Haze works is by drawing the main content into a graphics layer (and keeping that around), and then creating more graphics layers for each blurred area (which have the main content drawn into them). This works fine on Android, but on the Skiko platforms the layer stops drawing at certain positions. You can see the issue in the videos below.

https://github.com/JetBrains/compose-multiplatform/assets/227486/6fb2c3a9-4d52-43ed-beca-4f72f431e572

https://github.com/JetBrains/compose-multiplatform/assets/227486/347db3b1-15ce-44dc-a979-e8b18caa944e

chrisbanes commented 3 months ago

Ok, I've worked out the trigger for this.

My current code updates the layer's topLeft property, to tell it where to draw. If I stop setting the topLeft, and instead use GraphicsLayer.translationX/Y (or a Canvas translate when drawing the graphics layer) it works fine.

My guess is that somewhere in PictureRecorder (or below) is coercing or rejecting the bounds if they become too far out of the size?

My workaround commit: https://github.com/chrisbanes/haze/pull/250/commits/9c0bf63d6c37a67588305435136421be4a00e515

okushnikov commented 2 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

MatkovIvan commented 2 weeks ago

Fixed by https://github.com/JetBrains/compose-multiplatform-core/pull/1541