diff options
author | Andreas Kling <kling@serenityos.org> | 2022-04-10 18:41:24 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-04-10 21:35:55 +0200 |
commit | 908d42d0ba0e205a94b54a187cae0d5a4a48f7c3 (patch) | |
tree | eece74d2eed6684703af452dcaab06bc879ae077 /Userland/Libraries/LibGfx/AntiAliasingPainter.cpp | |
parent | b4c3882d9cb20da650a96c232c36981c85f6c2d8 (diff) | |
download | serenity-908d42d0ba0e205a94b54a187cae0d5a4a48f7c3.zip |
LibGfx: Add fast path to AA line drawing with simple 2D transform
If the effective 2D transform is just a basic translation, we now simply
translate the underlying painter before & after drawing AA lines.
This avoids all the extra math that otherwise has to happen when mapping
points through an affine transform.
This noticeably increase "mousing around" performance on Wikipedia. :^)
Diffstat (limited to 'Userland/Libraries/LibGfx/AntiAliasingPainter.cpp')
-rw-r--r-- | Userland/Libraries/LibGfx/AntiAliasingPainter.cpp | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp b/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp index b4a3bcd001..93016b62b8 100644 --- a/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp +++ b/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp @@ -12,8 +12,8 @@ // Base algorithm from https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm, // because there seems to be no other known method for drawing AA'd lines (?) -template<Gfx::AntiAliasingPainter::AntiAliasPolicy policy> -void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color) +template<Gfx::AntiAliasingPainter::AntiAliasPolicy policy, typename TransformPoint> +void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color, TransformPoint transform_point) { // FIXME: Implement this :P VERIFY(style == Painter::LineStyle::Solid); @@ -21,8 +21,8 @@ void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_f auto corrected_thickness = thickness > 1 ? thickness - 1 : thickness; auto size = IntSize(corrected_thickness, corrected_thickness); auto plot = [&](int x, int y, float c) { - auto center = m_transform.map(Gfx::IntPoint(x, y)).to_type<int>(); - m_underlying_painter.fill_rect(IntRect::centered_on(center, size), color.with_alpha(color.alpha() * c)); + transform_point(x, y, m_transform); + m_underlying_painter.fill_rect(IntRect::centered_on({ x, y }, size), color.with_alpha(color.alpha() * c)); }; auto integer_part = [](float x) { return floorf(x); }; @@ -112,14 +112,37 @@ void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_f draw_line(actual_from.x(), actual_from.y(), actual_to.x(), actual_to.y()); } +static ALWAYS_INLINE void no_transform(int&, int&, Gfx::AffineTransform const&) +{ +} + +static ALWAYS_INLINE void full_transform(int& x, int& y, Gfx::AffineTransform const& transform) +{ + auto mapped = transform.map(Gfx::IntPoint { x, y }); + x = mapped.x(); + y = mapped.y(); +} + void Gfx::AntiAliasingPainter::draw_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color) { - draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color); + if (m_transform.is_identity_or_translation()) { + m_underlying_painter.translate(m_transform.e(), m_transform.f()); + draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color, no_transform); + m_underlying_painter.translate(-m_transform.e(), -m_transform.f()); + } else { + draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color, full_transform); + } } void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color) { - draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color); + if (m_transform.is_identity_or_translation()) { + m_underlying_painter.translate(m_transform.e(), m_transform.f()); + draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color, no_transform); + m_underlying_painter.translate(-m_transform.e(), -m_transform.f()); + } else { + draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color, full_transform); + } } void Gfx::AntiAliasingPainter::fill_path(Path& path, Color color, Painter::WindingRule rule) |