Compare commits
2 Commits
010c2c934b
...
1a844426c3
Author | SHA1 | Date |
---|---|---|
Bananymous | 1a844426c3 | |
Bananymous | 42237a3bc8 |
|
@ -17,6 +17,10 @@ namespace Kernel
|
||||||
|
|
||||||
void set_pixel(uint32_t x, uint32_t y, uint32_t rgb);
|
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_full();
|
||||||
void sync_pixels_linear(uint32_t first_pixel, uint32_t pixel_count);
|
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);
|
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 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 void putchar_at(uint16_t, uint32_t, uint32_t, Color, Color) override;
|
||||||
|
virtual bool scroll(Color) override;
|
||||||
virtual void clear(Color) override;
|
virtual void clear(Color) override;
|
||||||
|
|
||||||
virtual void set_cursor_position(uint32_t, uint32_t) override;
|
virtual void set_cursor_position(uint32_t, uint32_t) override;
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace Kernel
|
||||||
virtual uint32_t height() const = 0;
|
virtual uint32_t height() const = 0;
|
||||||
|
|
||||||
virtual void putchar_at(uint16_t, uint32_t, uint32_t, Color, Color) = 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 clear(Color) = 0;
|
||||||
|
|
||||||
virtual void set_cursor_position(uint32_t, uint32_t) = 0;
|
virtual void set_cursor_position(uint32_t, uint32_t) = 0;
|
||||||
|
|
|
@ -135,20 +135,28 @@ namespace Kernel
|
||||||
video_buffer_u8[(y * m_width + x) * (BANAN_FB_BPP / 8) + 3] = rgb >> 24;
|
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()
|
void FramebufferDevice::sync_pixels_full()
|
||||||
{
|
{
|
||||||
auto* video_memory_u8 = reinterpret_cast<uint8_t*>(m_video_memory_vaddr);
|
return sync_pixels_linear(0, m_width * m_height);
|
||||||
auto* video_buffer_u8 = reinterpret_cast<uint8_t*>(m_video_buffer->vaddr());
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < m_width * m_height; i++)
|
|
||||||
{
|
|
||||||
uint32_t row = i / m_width;
|
|
||||||
uint32_t idx = i % m_width;
|
|
||||||
|
|
||||||
video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[i * (BANAN_FB_BPP / 8) + 0];
|
|
||||||
video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[i * (BANAN_FB_BPP / 8) + 1];
|
|
||||||
video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[i * (BANAN_FB_BPP / 8) + 2];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferDevice::sync_pixels_linear(uint32_t first_pixel, uint32_t pixel_count)
|
void FramebufferDevice::sync_pixels_linear(uint32_t first_pixel, uint32_t pixel_count)
|
||||||
|
@ -161,6 +169,38 @@ namespace Kernel
|
||||||
auto* video_memory_u8 = reinterpret_cast<uint8_t*>(m_video_memory_vaddr);
|
auto* video_memory_u8 = reinterpret_cast<uint8_t*>(m_video_memory_vaddr);
|
||||||
auto* video_buffer_u8 = reinterpret_cast<uint8_t*>(m_video_buffer->vaddr());
|
auto* video_buffer_u8 = reinterpret_cast<uint8_t*>(m_video_buffer->vaddr());
|
||||||
|
|
||||||
|
if (m_bpp == BANAN_FB_BPP)
|
||||||
|
{
|
||||||
|
const uint32_t buffer_pitch = m_width * (BANAN_FB_BPP / 8);
|
||||||
|
|
||||||
|
uint32_t row = first_pixel / m_width;
|
||||||
|
if (auto rem = first_pixel % m_width)
|
||||||
|
{
|
||||||
|
const uint32_t to_copy = BAN::Math::min(pixel_count, m_width - rem);
|
||||||
|
memcpy(
|
||||||
|
&video_memory_u8[row * m_pitch + rem * (BANAN_FB_BPP / 8)],
|
||||||
|
&video_buffer_u8[row * buffer_pitch + rem * (BANAN_FB_BPP / 8)],
|
||||||
|
to_copy * (BANAN_FB_BPP / 8)
|
||||||
|
);
|
||||||
|
pixel_count -= to_copy;
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pixel_count)
|
||||||
|
{
|
||||||
|
const uint32_t to_copy = BAN::Math::min(pixel_count, m_width);
|
||||||
|
memcpy(
|
||||||
|
&video_memory_u8[row * m_pitch],
|
||||||
|
&video_buffer_u8[row * buffer_pitch],
|
||||||
|
to_copy * (BANAN_FB_BPP / 8)
|
||||||
|
);
|
||||||
|
pixel_count -= to_copy;
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < pixel_count; i++)
|
for (uint32_t i = 0; i < pixel_count; i++)
|
||||||
{
|
{
|
||||||
uint32_t row = (first_pixel + i) / m_width;
|
uint32_t row = (first_pixel + i) / m_width;
|
||||||
|
@ -181,18 +221,8 @@ namespace Kernel
|
||||||
if (top_right_y + height > m_height)
|
if (top_right_y + height > m_height)
|
||||||
height = m_height - top_right_y;
|
height = m_height - top_right_y;
|
||||||
|
|
||||||
auto* video_memory_u8 = reinterpret_cast<uint8_t*>(m_video_memory_vaddr);
|
|
||||||
auto* video_buffer_u8 = reinterpret_cast<uint8_t*>(m_video_buffer->vaddr());
|
|
||||||
|
|
||||||
for (uint32_t row = top_right_y; row < top_right_y + height; row++)
|
for (uint32_t row = top_right_y; row < top_right_y + height; row++)
|
||||||
{
|
sync_pixels_linear(row * m_width + top_right_x, width);
|
||||||
for (uint32_t idx = top_right_x; idx < top_right_x + width; idx++)
|
|
||||||
{
|
|
||||||
video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 0] = video_buffer_u8[(row * m_width + idx) * (BANAN_FB_BPP / 8) + 0];
|
|
||||||
video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 1] = video_buffer_u8[(row * m_width + idx) * (BANAN_FB_BPP / 8) + 1];
|
|
||||||
video_memory_u8[(row * m_pitch) + (idx * m_bpp / 8) + 2] = video_buffer_u8[(row * m_width + idx) * (BANAN_FB_BPP / 8) + 2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FramebufferMemoryRegion : public MemoryRegion
|
class FramebufferMemoryRegion : public MemoryRegion
|
||||||
|
|
|
@ -33,6 +33,13 @@ namespace Kernel
|
||||||
m_framebuffer_device->sync_pixels_rectangle(x, y, font().width(), font().height());
|
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)
|
void FramebufferTerminalDriver::clear(Color color)
|
||||||
{
|
{
|
||||||
for (uint32_t y = 0; y < m_framebuffer_device->height(); y++)
|
for (uint32_t y = 0; y < m_framebuffer_device->height(); y++)
|
||||||
|
|
|
@ -99,8 +99,8 @@ namespace Kernel
|
||||||
render_from_buffer(last_x, last_y);
|
render_from_buffer(last_x, last_y);
|
||||||
if (m_show_cursor)
|
if (m_show_cursor)
|
||||||
m_terminal_driver->set_cursor_position(x, y);
|
m_terminal_driver->set_cursor_position(x, y);
|
||||||
last_x = m_column = x;
|
last_x = x;
|
||||||
last_y = m_row = y;
|
last_y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VirtualTTY::reset_ansi()
|
void VirtualTTY::reset_ansi()
|
||||||
|
@ -410,10 +410,18 @@ namespace Kernel
|
||||||
for (uint32_t x = 0; x < m_width; x++)
|
for (uint32_t x = 0; x < m_width; x++)
|
||||||
m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
m_buffer[(m_height - 1) * m_width + x] = { .foreground = m_foreground, .background = m_background, .codepoint = ' ' };
|
||||||
|
|
||||||
// Render the whole buffer to the screen
|
// 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 y = 0; y < m_height; y++)
|
||||||
for (uint32_t x = 0; x < m_width; x++)
|
for (uint32_t x = 0; x < m_width; x++)
|
||||||
render_from_buffer(x, y);
|
render_from_buffer(x, y);
|
||||||
|
}
|
||||||
|
m_show_cursor = old_show_cursor;
|
||||||
|
|
||||||
m_column = 0;
|
m_column = 0;
|
||||||
m_row--;
|
m_row--;
|
||||||
|
|
Loading…
Reference in New Issue