chrisbanes / haze

A blurring modifier for Compose Multiplatform / Jetpack Compose
https://chrisbanes.github.io/haze/
Apache License 2.0
913 stars 25 forks source link

Blur frozen on Android API 31 #77

Open jakobulbrich opened 6 months ago

jakobulbrich commented 6 months ago

On Android 12 (API 31) the blur is frozen while scrolling. Only when the bottom navigation appears or disappears the blur quickly updates and is then frozen again.

Seems like HazeNode31.onObservedReadsChanged() is not called. Probably a bug in Compose or can we do something about it?

See attached video of the android-jetpack sample on API 31. It is working as expected on API 32.

https://github.com/chrisbanes/haze/assets/16408565/efc8f36b-0637-4e3f-b132-13311aca464b

chrisbanes commented 6 months ago

So it seems that the draw() function isn't being called consistently on API 31, but is on API 32+. I'll raise on the Compose Issue Tracker.

chrisbanes commented 6 months ago

https://issuetracker.google.com/issues/318679450

chrisbanes commented 6 months ago

I'll have another play tomorrow and see if I can get something working. If not I'll probably have to bump up the min SDK level for the blur impl to 32 for now.

gleb-skobinsky commented 4 months ago

I hope I can add some context as to the origins and the reason why this bug happens. It appears that everything is okay on the Compose side. The issue here is with the RenderNode. My hypothesis is that on API 31, it fails to refresh on the JNI side if its position has not updated since the latest draw call. More specifically, in this part of the code:

private fun Effect.updateRenderNodePosition() {
    renderNode.setPosition(0, 0, bounds.width.toInt(), bounds.height.toInt())
    renderNode.translationX = bounds.left
    renderNode.translationY = bounds.top
    renderNodeDirty = false
  }

If we feed different positions at each call, the RenderNode is updated successfully. It is not acceptable to use in the library, of course, but I wrote a little dirty hack to reproduce this behavour: https://github.com/gleb-skobinsky/haze/blob/main/haze/src/androidMain/kotlin/dev/chrisbanes/haze/AndroidHazeNode.kt

https://github.com/chrisbanes/haze/assets/90451272/7853ba32-dc82-471d-99f7-3ce7c6020a79

gleb-skobinsky commented 4 months ago

The video is so short because github does not accept long screen recordings :)

gleb-skobinsky commented 4 months ago

UPD: I managed to remove the freeze on SDK level 31 without the hacks! Just applied the translation to the setPosition method instead of translation in the record lambda. Check out the source code

gleb-skobinsky commented 4 months ago

It took hours to debug this...

chrisbanes commented 4 months ago

Great detective work @gleb-skobinsky! Send a PR over?

gleb-skobinsky commented 4 months ago

Yes, I will create a PR today