1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 04:40:03 -04:00
Files
egui/crates
Keith 38c4ab7b3d Simplify and optimize Color32::from_rgba_unmultiplied (#8427)
So I first noticed that this function was using a large lookup table
behind a OnceLock. I initially thought about just making it a const, but
when looking at things further. I realized it could be made much
simpler.

If we just treated the numbers as fixed point we can get rid of any of
the floating point calculations and especially divisions. You can see
how efficiently this can compile down here:
https://llvm.godbolt.org/z/K83jEjvdq

You can see all three versions here: https://godbolt.org/z/nWc1as1nq
* First one is basically the original essentially being called by:
`ColorImage::from_rgba_unmultiplied()`
* Second is the const Lookup table instead of the OnceLock and runtime
generation.
* Third is the fixed point implementation.

At least looking at the bytes reported compiler explorer the OnceLock
and the const Table results are in similar size, and the const table is
surprisingly smaller when I compile to a binary object in compiler
explorer. However though the oncelock is producing a lot SIMD
instructions for initialization so I guess not too surprised. The fixed
point math is much smaller than both.

The const table is probably faster, but does bloat the binary images,
and again when it's this fast to compute:
https://llvm.godbolt.org/z/K83jEjvdq I am not sure the extra bytes are
worth it.

Next, what I did was merge `from_rgba_unmultiplied` and
`from_rgba_unmultiplied_const`. Moreover with the fixed point math the
`from_rgba_unmultiplied_const` is probably not necessary anymore, but
it's part of the public API so I left it. Lastly, I just added a sanity
test to make sure the math checks out which it does. You can even sweep
the 2^16 inputs to be sure.
2026-08-20 20:36:39 +00:00
..