From 2a3c1e13fd90b2ecde7df434fe055259708818db Mon Sep 17 00:00:00 2001 From: Ygor Souza Date: Sat, 7 Sep 2024 23:07:43 +0200 Subject: [PATCH] Use a precomputed lookup table in Color32::from_unmultiplied This is about 50 times faster according to the benchmarks, at the expense of storing a 65KB lookup table in the program memory. --- crates/ecolor/Cargo.toml | 2 +- .../color32_from_unmultiplied_lookup_table | Bin 0 -> 65536 bytes crates/ecolor/src/color32.rs | 54 ++++++++++++------ 3 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 crates/ecolor/data/color32_from_unmultiplied_lookup_table diff --git a/crates/ecolor/Cargo.toml b/crates/ecolor/Cargo.toml index c1a10070c03f..88cae7a07a10 100644 --- a/crates/ecolor/Cargo.toml +++ b/crates/ecolor/Cargo.toml @@ -14,7 +14,7 @@ readme = "README.md" repository = "https://github.com/emilk/egui" categories = ["mathematics", "encoding"] keywords = ["gui", "color", "conversion", "gamedev", "images"] -include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"] +include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "data/*", "Cargo.toml"] [lints] workspace = true diff --git a/crates/ecolor/data/color32_from_unmultiplied_lookup_table b/crates/ecolor/data/color32_from_unmultiplied_lookup_table new file mode 100644 index 0000000000000000000000000000000000000000..42ba44980677b70bcdff5e717046d1153255aeee GIT binary patch literal 65536 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 Self { - if a == 255 { - Self::from_rgb(r, g, b) // common-case optimization - } else if a == 0 { - Self::TRANSPARENT // common-case optimization - } else { - let r_lin = linear_f32_from_gamma_u8(r); - let g_lin = linear_f32_from_gamma_u8(g); - let b_lin = linear_f32_from_gamma_u8(b); - let a_lin = linear_f32_from_linear_u8(a); - - let r = gamma_u8_from_linear_f32(r_lin * a_lin); - let g = gamma_u8_from_linear_f32(g_lin * a_lin); - let b = gamma_u8_from_linear_f32(b_lin * a_lin); - - Self::from_rgba_premultiplied(r, g, b, a) + match a { + // common-case optimization + 0 => Self::TRANSPARENT, + // common-case optimization + 255 => Self::from_rgb(r, g, b), + a => { + let [r, g, b] = [r, g, b].map(|value| { + FROM_UNMULTIPLIED_LUT[usize::from(u16::from_be_bytes([value, a]))] + }); + Self::from_rgba_premultiplied(r, g, b, a) + } } } @@ -250,3 +247,24 @@ impl Color32 { ) } } + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn from_unmultiplied_lookup_table_check() { + use crate::{ + gamma_u8_from_linear_f32, linear_f32_from_gamma_u8, linear_f32_from_linear_u8, + }; + for value in 0..=255u8 { + for alpha in 0..=255u8 { + let value_lin = linear_f32_from_gamma_u8(value); + let alpha_lin = linear_f32_from_linear_u8(alpha); + + let calculated = gamma_u8_from_linear_f32(value_lin * alpha_lin); + let lut = FROM_UNMULTIPLIED_LUT[usize::from(u16::from_be_bytes([value, alpha]))]; + assert_eq!(calculated, lut); + } + } + } +}