diff --git a/Terminal/Terminal.cpp b/Terminal/Terminal.cpp index 80928bc08c..853d2fcc0e 100644 --- a/Terminal/Terminal.cpp +++ b/Terminal/Terminal.cpp @@ -2,10 +2,13 @@ #include #include #include +#include #include #include #include +#define FAST_SCROLL + void Terminal::create_window() { auto& font = Font::defaultFont(); @@ -278,6 +281,13 @@ void Terminal::scroll_up() { if (m_cursor_row == (rows() - 1)) { memcpy(m_buffer, m_buffer + m_columns, m_columns * (m_rows - 1)); +#ifdef FAST_SCROLL + ++m_rows_to_scroll_backing_store; +#else + for (size_t i = 0; i < m_rows * m_columns; ++i) { + m_attributes[i].dirty = true; + } +#endif memset(&m_buffer[(m_rows - 1) * m_columns], ' ', m_columns); memcpy(m_attributes, m_attributes + m_columns, m_columns * (m_rows - 1) * sizeof(Attribute)); for (size_t i = 0; i < m_columns; ++i) @@ -390,14 +400,32 @@ void Terminal::paint() Rect rect { 0, 0, m_pixel_width, m_pixel_height }; Font& font = Font::defaultFont(); Painter painter(*m_backing); + int line_height = Font::defaultFont().glyphHeight() + m_line_spacing; +#ifdef FAST_SCROLL + if (m_rows_to_scroll_backing_store && m_rows_to_scroll_backing_store < m_rows) { + int first_scanline = m_inset; + int second_scanline = m_inset + (m_rows_to_scroll_backing_store * line_height); + int num_rows_to_memcpy = m_rows - m_rows_to_scroll_backing_store; + int scanlines_to_copy = (num_rows_to_memcpy * line_height) - m_line_spacing; + fast_dword_copy( + m_backing->scanline(first_scanline), + m_backing->scanline(second_scanline), + scanlines_to_copy * m_pixel_width + ); + } + m_rows_to_scroll_backing_store = 0; +#endif for (word row = 0; row < m_rows; ++row) { - int y = row * (font.glyphHeight() + m_line_spacing); + int y = row * line_height; for (word column = 0; column < m_columns; ++column) { - char ch = m_buffer[(row * m_columns) + (column)]; auto& attribute = m_attributes[(row * m_columns) + (column)]; + if (!attribute.dirty) + continue; + attribute.dirty = false; + char ch = m_buffer[(row * m_columns) + (column)]; int x = column * font.glyphWidth(); - Rect glyph_rect { x + m_inset, y + m_inset, font.glyphWidth(), font.glyphHeight() + m_line_spacing }; + Rect glyph_rect { x + m_inset, y + m_inset, font.glyphWidth(), line_height }; auto glyph_background = ansi_color(attribute.background_color); painter.fill_rect(glyph_rect, glyph_background); if (ch == ' ') diff --git a/Terminal/Terminal.h b/Terminal/Terminal.h index debbb1f19a..3600f24723 100644 --- a/Terminal/Terminal.h +++ b/Terminal/Terminal.h @@ -41,10 +41,12 @@ private: foreground_color = 7; background_color = 0; bold = false; + dirty = true; } unsigned foreground_color : 4; unsigned background_color : 4; bool bold : 1; + bool dirty : 1; }; byte* m_buffer { nullptr }; @@ -80,6 +82,7 @@ private: int m_pixel_width { 0 }; int m_pixel_height { 0 }; + int m_rows_to_scroll_backing_store { 0 }; int m_inset { 2 }; int m_line_spacing { 4 }; diff --git a/Terminal/main.cpp b/Terminal/main.cpp index 78f0ffd873..69343aec23 100644 --- a/Terminal/main.cpp +++ b/Terminal/main.cpp @@ -61,8 +61,6 @@ int main(int, char**) return 1; } - dbgprintf("ptm_fd = %d\n", ptm_fd); - make_shell(ptm_fd); int event_fd = open("/dev/gui_events", O_RDONLY | O_NONBLOCK); @@ -79,9 +77,8 @@ int main(int, char**) byte buffer[1024]; ssize_t ptm_nread = read(ptm_fd, buffer, sizeof(buffer)); if (ptm_nread > 0) { - for (ssize_t i = 0; i < ptm_nread; ++i) { + for (ssize_t i = 0; i < ptm_nread; ++i) terminal.on_char(buffer[i]); - } terminal.paint(); }