Make it possible to use and create a custom `BlurController`
Why
Hi!
In expo-blur we would like to create our own version of PreDrawBlurController unfortunately a lot of stuff has been made package private. Making it impossible to do without creating a fork of the library.
How
I've split the PR into three commits:
-
Allow setting up with a custom blur controller - Adds one more constructor to the BlurView, which accepts the desired blur controller. I also changed the other constructors to use it, and made the blurController protected so that views, which extend the
BlurViewcan access it. -
Expose methods necessary for custom BlurControllers - The idea was to make it possible to copy contents of
PreDrawBlurControllerinto another package and still have it working. This mostly requires changes in theSizeScalerclass where a lot of the methods were package private, and making thesetContextmethod of theRenderEffectBlurpublic. -
Make it possible to extend
PreDrawBlurController- I'm not sure if you will be ok with these changes, we can manage without them, but it would be quite a bit easier for us if we could extendPreDrawBlurController. Makes the class non-final and changes the access of some variables and methods toprotectedso inheriting classes have access to them.
The first two commits would be necessary for us to do what we want, the third one is nice to have. Can you let me know if you would be ok with those changes?
Test Plan
Tested in the included test app and our react-native library.
Thanks for the PR and thoughtful description. Out of curiosity, what's your use case for extending/changing the blur controller?
During screen transitions made by react-native-screens the blur view stops working. I'm suspecting that it is an issue with hardware acceleration during the transition, since AFAIK it's not possible to capture contents of hardware-accelerated layers. Our use case would be to detect the transition and pause blur updates to until they are finished. It's not optimal but should fix some of the most jarring issues.
We have to check it inside of the updateBlur method of the controller. Using setAutoBlurUpdate from an independent listener is not fast enough and we still do one invalid draw in that case.
Normally the Views would fall back to software rendering when needed, even if they have a hardware layer set. You can test this by setting a hardware layer to any View in the sample app and see it still getting blurred.
Overall I'm fine with merging this PR, but maybe I could help investigate the root cause of your issue instead. If you have an example project I could debug, I could take a look
@Dimezis Solving the root cause would be great, I'll check it, maybe my theory was wrong 🤔
@behenate Any updates on this?
@Dimezis Sorry, recently I didn't really have time to keep working on this. While I was still working on it I talked with react-native-screens developers and I learned that the library (which is present in pretty much every react-native project) somehow ignores the fallback to software rendering and keeps the hardware acceleration on, so it's nothing on the side of your library. I'm not sure if they can do anything about it without breaking stuff on their side. Hopefully I find some time in the near future to get back to this issue.
For what it's worth, version 3.0.0 should fix this, but only on API 31+
I'm closing this PR, as there was a PR submitted to expo-blur that seems to fix our issue.
https://github.com/expo/expo/pull/37904
We'll most likely be migrating to v3 soon as well