-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
Today we use f16 as the pixel format for the surface and offscreen buffers if wide gamut is enabled. We found a bug in the Plus blend where you could get alpha values greater than 1. That was fixed by moving the plus blend to a fragment shader in flutter/engine#51589.
Using a fragment shader for Plus blending is not ideal because:
- It's slower
- It requires more resources (vram for sure, sampler?)
- Its code is more complicated
We may be able to eliminate the need for the advanced shader if we instead switch to using apples BGRA10_XR pixel format. That format does clamp the alpha channel to 1.0, so it would have eliminated the bug that we saw that predicated the advanced blend.
Here are some concerns that need to be sorted out to implement this:
- Skia would need to be patched to implement bgra10_xr for layer.toImage to work. We have patched Skia already to support BGR10_XR, so presumably they would be open to this and it wouldn't be that much more work.
- BGR10_XR clamps the color channels to 1.25098, that's outside the range of the displays we are rendering to. Could that cause odd outputs when stacking blends? Enough to care?
I was concerned about maybe a clash with our texture formats, but I verified we already use BGR10_XR for opaque images, f16 for transparent images, so there shouldn't be any dependency on the surface pixel formats for those to work.
Using BGRA10_XR also has the added benefit of hiding any errors in shaders that are being covered up with the implicit clamps of sRGB. This has happened in the past.
This is complicated but I'm 80% sure this would work. It will require some attention and testing to make sure. It should be 30% (1 - 5 / 3.8) faster.
Jonah already started drafting a PR in flutter/engine#51748