Closed jonahwilliams closed 2 months ago
For example, suppose we have a 1000x1000 input texture. mip level 0 is 1000x1000, mip level 1 is 500x500, mip level 2 is 250x250. We compute that our desired size for a particular blur is 400x400. Today we create a new texture from the input that is 400x400, which uses the mip level 1 as an input.
Slight correction: Downsample scalars are already in the form of 1/x^2
(making reading from mipmaps easier 🤞 )
Interesting! does that means we're should always be computing an exact mip level?
Interesting! does that means we're should always be computing an exact mip level?
yep
I did that to reduce shimmer when downsampling so that we only drop in scalar size when the difference should be hidden with the higher level of blur.
Perfect, in that case using a lod clamp should be free real estate.
Here is a half working example of what we'd do: https://github.com/flutter/engine/pull/53541
actually wait, it might be working ish? Need to check fidelity. Memory is the same because of the ping pong. Looks like it doesn't really speed things up, but it doesn't cost anything either. I need to double check that I selected the right mip level, otherwise maybe this is just a change we should make for simplifcation.
TOT
Patched
Need to check android too.
Actually, thinking about it more - we don't even need the lod clamp - as long as we remove the downsample pass and base the blur pass sizes on the correct padded size.
It seems more impactful to drop the mips, though there may be opportunities to remove the downsample if the scalar is 1.
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v
and a minimal reproduction of the issue.
Right now the blur has a two stage downsample process, first we generate mipmaps for the input texture, then we perform a downsample to a computed size (The mips are important to ensure we don't drop rows/cols of data). However, from https://github.com/flutter/flutter/issues/142154 we can see that most of the blur overhead is due to texure fill ops - and not the blur itself.
We could potentially make this much cheaper (while reducing memory usage and increasing fidelity) by using a LOD clamp instead of a downsample (see https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSamplerCreateInfo.html minLod, or related iOS term).
For example, suppose we have a 1000x1000 input texture. mip level 0 is 1000x1000, mip level 1 is 500x500, mip level 2 is 250x250. We compute that our desired size for a particular blur is 400x400. Today we create a new texture from the input that is 400x400, which uses the mip level 1 as an input.
Instead, we would use the 1000x1000 input texure but clamp the LOD to 1. This would effectively give us a 500x500 input, while avoiding generating the new texture.
The reason we can't try this out today is that we currently base the size of the blur passes on the downsample pass: https://github.com/flutter/flutter/issues/150713 . So without the downsmaple we would end up creating 1000x1000 blur passes. I believe if this is fixed, it should be a straight forward experiment to try.
This needs to be optional though - Metal and Vulkan support lod clamping but OpenGLES does not.
FYI @gaaclarke