1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 16:37:35 +00:00

LibGfx: Move Color::mixed_with() inline

This seems to give a small speedup to gradient painting and removes
Color::mixed_with() (which was 10% of the time) from the profile.
This commit is contained in:
MacDue 2023-02-17 19:02:03 +00:00 committed by Jelle Raaijmakers
parent 8a94c7a7f7
commit e5a39d134b
2 changed files with 23 additions and 25 deletions

View file

@ -315,30 +315,6 @@ Optional<Color> Color::from_string(StringView string)
return Color(r.value(), g.value(), b.value(), a.value());
}
Color Color::mixed_with(Color other, float weight) const
{
if (alpha() == other.alpha() || with_alpha(0) == other.with_alpha(0)) {
return Gfx::Color {
round_to<u8>(mix<float>(red(), other.red(), weight)),
round_to<u8>(mix<float>(green(), other.green(), weight)),
round_to<u8>(mix<float>(blue(), other.blue(), weight)),
round_to<u8>(mix<float>(alpha(), other.alpha(), weight)),
};
}
// Fallback to slower, but more visually pleasing premultiplied alpha mix.
// This is needed for linear-gradient()s in LibWeb.
auto mixed_alpha = mix<float>(alpha(), other.alpha(), weight);
auto premultiplied_mix_channel = [&](float channel, float other_channel, float weight) {
return round_to<u8>(mix<float>(channel * alpha(), other_channel * other.alpha(), weight) / mixed_alpha);
};
return Gfx::Color {
premultiplied_mix_channel(red(), other.red(), weight),
premultiplied_mix_channel(green(), other.green(), weight),
premultiplied_mix_channel(blue(), other.blue(), weight),
round_to<u8>(mixed_alpha),
};
}
Vector<Color> Color::shades(u32 steps, float max) const
{
float shade = 1.f;

View file

@ -237,7 +237,29 @@ public:
#endif
}
Color mixed_with(Color other, float weight) const;
Color mixed_with(Color other, float weight) const
{
if (alpha() == other.alpha() || with_alpha(0) == other.with_alpha(0)) {
return Gfx::Color {
round_to<u8>(mix<float>(red(), other.red(), weight)),
round_to<u8>(mix<float>(green(), other.green(), weight)),
round_to<u8>(mix<float>(blue(), other.blue(), weight)),
round_to<u8>(mix<float>(alpha(), other.alpha(), weight)),
};
}
// Fallback to slower, but more visually pleasing premultiplied alpha mix.
// This is needed for linear-gradient()s in LibWeb.
auto mixed_alpha = mix<float>(alpha(), other.alpha(), weight);
auto premultiplied_mix_channel = [&](float channel, float other_channel, float weight) {
return round_to<u8>(mix<float>(channel * alpha(), other_channel * other.alpha(), weight) / mixed_alpha);
};
return Gfx::Color {
premultiplied_mix_channel(red(), other.red(), weight),
premultiplied_mix_channel(green(), other.green(), weight),
premultiplied_mix_channel(blue(), other.blue(), weight),
round_to<u8>(mixed_alpha),
};
}
Color interpolate(Color other, float weight) const noexcept
{