diff options
author | Daniel Bertalan <dani@danielbertalan.dev> | 2021-06-05 08:55:33 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-10 17:18:02 +0200 |
commit | 221ba1aac89f9472bd8b50310f36a832efcba76b (patch) | |
tree | b537426a66914b8cae9804528a281518fa31af4c /Userland/Libraries | |
parent | fe58d15b5b860b060b5ef477095e5cd65ee84cf5 (diff) | |
download | serenity-221ba1aac89f9472bd8b50310f36a832efcba76b.zip |
LibVT: Improve scrolling performance
Previously, we would remove lines from the buffer, create new lines and
insert them into the buffer when we scrolled. Since scrolling does not
always happen at the last line, this meant `Line` objects were
pointlessly moved forwards, and then immediately backwards.
We now swap them in-place and clear those lines that are "inserted". As
a result, performance is better and scrolling is smoother in `vim` and
`nano`.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibVT/Terminal.cpp | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/Userland/Libraries/LibVT/Terminal.cpp b/Userland/Libraries/LibVT/Terminal.cpp index 1323bdac83..bb64076859 100644 --- a/Userland/Libraries/LibVT/Terminal.cpp +++ b/Userland/Libraries/LibVT/Terminal.cpp @@ -775,20 +775,28 @@ void Terminal::scroll_up(u16 region_top, u16 region_bottom, size_t count) // NOTE: We have to invalidate the cursor first. invalidate_cursor(); - if (!m_use_alternate_screen_buffer && max_history_size() != 0) + bool should_move_to_scrollback = !m_use_alternate_screen_buffer && max_history_size() != 0; + if (should_move_to_scrollback) { for (size_t i = 0; i < count; ++i) add_line_to_history(move(active_buffer().ptr_at(region_top + i))); + } - if (count == region_size) { - for (u16 row = region_top; row <= region_bottom; ++row) + // Move lines into their new place. + for (u16 row = region_top; row + count <= region_bottom; ++row) + swap(active_buffer().ptr_at(row), active_buffer().ptr_at(row + count)); + // Clear 'new' lines at the bottom. + if (should_move_to_scrollback) { + // Since we moved the previous lines into history, we can't just clear them. + for (u16 row = region_bottom + 1 - count; row <= region_bottom; ++row) + active_buffer().ptr_at(row) = make<Line>(columns()); + } else { + // The new lines haven't been moved and we don't want to leak memory. + for (u16 row = region_bottom + 1 - count; row <= region_bottom; ++row) active_buffer()[row].clear(Attribute()); - return; } - - active_buffer().remove(region_top, count); - for (size_t i = 0; i < count; ++i) - active_buffer().insert(region_bottom - count + i + 1, make<Line>(m_columns)); - for (u16 row = region_top; row <= region_bottom; ++row) + // Set dirty flag on swapped lines. + // The other lines have implicitly been set dirty by being cleared. + for (u16 row = region_top; row <= region_bottom - count; ++row) active_buffer()[row].set_dirty(true); if (!m_use_alternate_screen_buffer && max_history_size() != 0) m_client.terminal_history_changed(); @@ -806,16 +814,15 @@ void Terminal::scroll_down(u16 region_top, u16 region_bottom, size_t count) // NOTE: We have to invalidate the cursor first. invalidate_cursor(); - if (count == region_size) { - for (u16 row = region_top; row <= region_bottom; ++row) - active_buffer()[row].set_dirty(true); - return; - } - - active_buffer().remove(region_bottom - count + 1, count); - for (size_t i = 0; i < count; ++i) - active_buffer().insert(region_top, make<Line>(m_columns)); - for (u16 row = region_top; row <= region_bottom; ++row) + // Move lines into their new place. + for (int row = region_bottom; row >= static_cast<int>(region_top + count); --row) + swap(active_buffer().ptr_at(row), active_buffer().ptr_at(row - count)); + // Clear the 'new' lines at the top. + for (u16 row = region_top; row < region_top + count; ++row) + active_buffer()[row].clear(Attribute()); + // Set dirty flag on swapped lines. + // The other lines have implicitly been set dirty by being cleared. + for (u16 row = region_top + count; row <= region_bottom; ++row) active_buffer()[row].set_dirty(true); } |