Kernel: Implement fast scrolling for TTY
This commit is contained in:
		
							parent
							
								
									010c2c934b
								
							
						
					
					
						commit
						42237a3bc8
					
				|  | @ -17,6 +17,10 @@ namespace Kernel | |||
| 
 | ||||
| 		void set_pixel(uint32_t x, uint32_t y, uint32_t rgb); | ||||
| 
 | ||||
| 		// positive rows -> empty pixels on bottom
 | ||||
| 		// negative rows -> empty pixels on top
 | ||||
| 		void scroll(int32_t rows, uint32_t rgb); | ||||
| 
 | ||||
| 		void sync_pixels_full(); | ||||
| 		void sync_pixels_linear(uint32_t first_pixel, uint32_t pixel_count); | ||||
| 		void sync_pixels_rectangle(uint32_t top_right_x, uint32_t top_right_y, uint32_t width, uint32_t height); | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ namespace Kernel | |||
| 		virtual uint32_t height() const override { return m_framebuffer_device->height() / font().height(); } | ||||
| 
 | ||||
| 		virtual void putchar_at(uint16_t, uint32_t, uint32_t, Color, Color) override; | ||||
| 		virtual bool scroll(Color) override; | ||||
| 		virtual void clear(Color) override; | ||||
| 
 | ||||
| 		virtual void set_cursor_position(uint32_t, uint32_t) override; | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ namespace Kernel | |||
| 		virtual uint32_t height() const = 0; | ||||
| 
 | ||||
| 		virtual void putchar_at(uint16_t, uint32_t, uint32_t, Color, Color) = 0; | ||||
| 		virtual bool scroll(Color) { return false; } | ||||
| 		virtual void clear(Color) = 0; | ||||
| 
 | ||||
| 		virtual void set_cursor_position(uint32_t, uint32_t) = 0; | ||||
|  |  | |||
|  | @ -135,6 +135,25 @@ namespace Kernel | |||
| 			video_buffer_u8[(y * m_width + x) * (BANAN_FB_BPP / 8) + 3] = rgb >> 24; | ||||
| 	} | ||||
| 
 | ||||
| 	void FramebufferDevice::scroll(int32_t rows, uint32_t rgb) | ||||
| 	{ | ||||
| 		if (rows == 0) | ||||
| 			return; | ||||
| 		rows = BAN::Math::clamp<int32_t>(rows, -m_height, m_height); | ||||
| 		const uint32_t abs_rows = BAN::Math::abs(rows); | ||||
| 
 | ||||
| 		auto* video_buffer_u8 = reinterpret_cast<uint8_t*>(m_video_buffer->vaddr()); | ||||
| 		uint8_t* src = (rows < 0) ? video_buffer_u8 : &video_buffer_u8[(abs_rows * m_width) * (BANAN_FB_BPP / 8)]; | ||||
| 		uint8_t* dst = (rows > 0) ? video_buffer_u8 : &video_buffer_u8[(abs_rows * m_width) * (BANAN_FB_BPP / 8)]; | ||||
| 		memmove(dst, src, (m_height - abs_rows) * m_width * (BANAN_FB_BPP / 8)); | ||||
| 
 | ||||
| 		uint32_t start_y = (rows < 0) ? 0 : m_height - abs_rows; | ||||
| 		uint32_t stop_y  = (rows < 0) ? abs_rows : m_height; | ||||
| 		for (uint32_t y = start_y; y < stop_y; y++) | ||||
| 			for (uint32_t x = 0; x < m_width; x++) | ||||
| 				set_pixel(x, y, rgb); | ||||
| 	} | ||||
| 
 | ||||
| 	void FramebufferDevice::sync_pixels_full() | ||||
| 	{ | ||||
| 		auto* video_memory_u8 = reinterpret_cast<uint8_t*>(m_video_memory_vaddr); | ||||
|  |  | |||
|  | @ -33,6 +33,13 @@ namespace Kernel | |||
| 		m_framebuffer_device->sync_pixels_rectangle(x, y, font().width(), font().height()); | ||||
| 	} | ||||
| 
 | ||||
| 	bool FramebufferTerminalDriver::scroll(Color color) | ||||
| 	{ | ||||
| 		m_framebuffer_device->scroll(font().height(), color.rgb); | ||||
| 		m_framebuffer_device->sync_pixels_full(); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	void FramebufferTerminalDriver::clear(Color color) | ||||
| 	{ | ||||
| 		for (uint32_t y = 0; y < m_framebuffer_device->height(); y++) | ||||
|  |  | |||
|  | @ -99,8 +99,8 @@ namespace Kernel | |||
| 			render_from_buffer(last_x, last_y); | ||||
| 		if (m_show_cursor) | ||||
| 			m_terminal_driver->set_cursor_position(x, y); | ||||
| 		last_x = m_column = x; | ||||
| 		last_y = m_row = y; | ||||
| 		last_x = x; | ||||
| 		last_y = y; | ||||
| 	} | ||||
| 
 | ||||
| 	void VirtualTTY::reset_ansi() | ||||
|  | @ -410,10 +410,18 @@ namespace Kernel | |||
| 			for (uint32_t x = 0; x < m_width; x++) | ||||
| 				m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' }; | ||||
| 
 | ||||
| 			// Render the whole buffer to the screen
 | ||||
| 			for (uint32_t y = 0; y < m_height; y++) | ||||
| 				for (uint32_t x = 0; x < m_width; x++) | ||||
| 					render_from_buffer(x, y); | ||||
| 			// hide cursor during scrolling
 | ||||
| 			bool old_show_cursor = m_show_cursor; | ||||
| 			m_show_cursor = false; | ||||
| 			set_cursor_position(0, 0); | ||||
| 			if (!m_terminal_driver->scroll(m_background)) | ||||
| 			{ | ||||
| 				// No fast scrolling, render the whole buffer to the screen
 | ||||
| 				for (uint32_t y = 0; y < m_height; y++) | ||||
| 					for (uint32_t x = 0; x < m_width; x++) | ||||
| 						render_from_buffer(x, y); | ||||
| 			} | ||||
| 			m_show_cursor = old_show_cursor; | ||||
| 
 | ||||
| 			m_column = 0; | ||||
| 			m_row--; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue