mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 14:08:14 +00:00
LibGfx/ICC: Add a one-element cache for CLUT conversions
Our current CLUT code is pretty slow. A one-element cache can make it quite a bit faster for images that have long runs of a single color, such as illustrations. It also seems to help with photos some (in `0000711.pdf` page 1) -- I suppose even them have enough repeating pixels for it to be worth it. Some numbers, with `pdf --render-bench`: `0000711.pdf --page 1` (high-res photo) before: 2.9s after: 2.43s `0000277.pdf --page 19` (my nemesis PDF, large-ish illustration) before: 2.17s after: 0.58s (!) `0000502.pdf --page 2` (wat hoe dat) before: 0.66s after: 0.27s `0000521.pdf --page 10 ` (japanese) before: 0.52s after: 0.29s `0000364.pdf --page 1` (4 min test case) before: 0.48s after: 0.19s Thanks to that last one, reduces the time for `time Meta/test_pdf.py ~/Downloads/0000` from 4m22s to 1m28s. Helps quite a bit with #23157 (but high-res photos are still too slow).
This commit is contained in:
parent
6a8e418e40
commit
27e369cd19
2 changed files with 26 additions and 4 deletions
|
@ -1219,14 +1219,21 @@ ErrorOr<FloatVector3> Profile::to_pcs_a_to_b(TagData const& tag_data, ReadonlyBy
|
||||||
// Assumes a "normal" device_class() (i.e. not DeviceLink).
|
// Assumes a "normal" device_class() (i.e. not DeviceLink).
|
||||||
VERIFY(number_of_components_in_color_space(connection_space()) == 3);
|
VERIFY(number_of_components_in_color_space(connection_space()) == 3);
|
||||||
|
|
||||||
|
if (m_to_pcs_clut_cache.has_value() && m_to_pcs_clut_cache->key == color)
|
||||||
|
return m_to_pcs_clut_cache->value;
|
||||||
|
|
||||||
|
FloatVector3 result;
|
||||||
|
|
||||||
switch (tag_data.type()) {
|
switch (tag_data.type()) {
|
||||||
case Lut16TagData::Type: {
|
case Lut16TagData::Type: {
|
||||||
auto const& a_to_b = static_cast<Lut16TagData const&>(tag_data);
|
auto const& a_to_b = static_cast<Lut16TagData const&>(tag_data);
|
||||||
return a_to_b.evaluate(data_color_space(), connection_space(), color);
|
result = TRY(a_to_b.evaluate(data_color_space(), connection_space(), color));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case Lut8TagData::Type: {
|
case Lut8TagData::Type: {
|
||||||
auto const& a_to_b = static_cast<Lut8TagData const&>(tag_data);
|
auto const& a_to_b = static_cast<Lut8TagData const&>(tag_data);
|
||||||
return a_to_b.evaluate(data_color_space(), connection_space(), color);
|
result = TRY(a_to_b.evaluate(data_color_space(), connection_space(), color));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case LutAToBTagData::Type: {
|
case LutAToBTagData::Type: {
|
||||||
auto const& a_to_b = static_cast<LutAToBTagData const&>(tag_data);
|
auto const& a_to_b = static_cast<LutAToBTagData const&>(tag_data);
|
||||||
|
@ -1236,10 +1243,19 @@ ErrorOr<FloatVector3> Profile::to_pcs_a_to_b(TagData const& tag_data, ReadonlyBy
|
||||||
if (a_to_b.number_of_output_channels() != number_of_components_in_color_space(connection_space()))
|
if (a_to_b.number_of_output_channels() != number_of_components_in_color_space(connection_space()))
|
||||||
return Error::from_string_literal("ICC::Profile::to_pcs_a_to_b: mAB output channel count does not match profile connection space size");
|
return Error::from_string_literal("ICC::Profile::to_pcs_a_to_b: mAB output channel count does not match profile connection space size");
|
||||||
|
|
||||||
return a_to_b.evaluate(connection_space(), color);
|
result = TRY(a_to_b.evaluate(connection_space(), color));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
VERIFY_NOT_REACHED();
|
|
||||||
|
if (!m_to_pcs_clut_cache.has_value())
|
||||||
|
m_to_pcs_clut_cache = OneElementCLUTCache {};
|
||||||
|
m_to_pcs_clut_cache->key = Vector<u8, 4>(color);
|
||||||
|
m_to_pcs_clut_cache->value = result;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<FloatVector3> Profile::to_pcs(ReadonlyBytes color) const
|
ErrorOr<FloatVector3> Profile::to_pcs(ReadonlyBytes color) const
|
||||||
|
|
|
@ -321,6 +321,12 @@ private:
|
||||||
FloatMatrix3x3 rgb_to_xyz_matrix() const;
|
FloatMatrix3x3 rgb_to_xyz_matrix() const;
|
||||||
|
|
||||||
mutable Optional<FloatMatrix3x3> m_cached_xyz_to_rgb_matrix;
|
mutable Optional<FloatMatrix3x3> m_cached_xyz_to_rgb_matrix;
|
||||||
|
|
||||||
|
struct OneElementCLUTCache {
|
||||||
|
Vector<u8, 4> key;
|
||||||
|
FloatVector3 value;
|
||||||
|
};
|
||||||
|
mutable Optional<OneElementCLUTCache> m_to_pcs_clut_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue