1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 05:57:44 +00:00

Kernel/Graphics: Apply DisplayConnector design on the VirtIO driver

This commit is contained in:
Liav A 2022-04-30 13:56:29 +03:00 committed by Andreas Kling
parent 4ff6150f1b
commit c27c414ed1
13 changed files with 729 additions and 886 deletions

View file

@ -5,7 +5,6 @@
*/
#include <Kernel/Graphics/VirtIOGPU/Console.h>
#include <Kernel/Graphics/VirtIOGPU/FramebufferDevice.h>
#include <Kernel/WorkQueue.h>
namespace Kernel::Graphics::VirtIOGPU {
@ -30,22 +29,22 @@ void DirtyRect::union_rect(size_t x, size_t y, size_t width, size_t height)
}
}
NonnullRefPtr<Console> Console::initialize(RefPtr<FramebufferDevice> const& framebuffer_device)
NonnullRefPtr<Console> Console::initialize(VirtIODisplayConnector& parent_display_connector)
{
return adopt_ref(*new Console(framebuffer_device));
auto current_resolution = parent_display_connector.current_mode_setting();
return adopt_ref(*new Console(parent_display_connector, current_resolution));
}
Console::Console(RefPtr<FramebufferDevice> const& framebuffer_device)
: GenericFramebufferConsole(framebuffer_device->width(), framebuffer_device->height(), framebuffer_device->pitch())
, m_framebuffer_device(framebuffer_device)
Console::Console(VirtIODisplayConnector const& parent_display_connector, DisplayConnector::ModeSetting current_resolution)
: GenericFramebufferConsole(current_resolution.horizontal_active, current_resolution.vertical_active, current_resolution.horizontal_stride)
, m_parent_display_connector(parent_display_connector)
{
enqueue_refresh_timer();
}
void Console::set_resolution(size_t width, size_t height, size_t pitch)
void Console::set_resolution(size_t, size_t, size_t)
{
auto did_set_resolution = m_framebuffer_device->set_head_resolution(0, width, height, pitch);
VERIFY(!did_set_resolution.is_error());
// FIXME: Update some values here?
}
void Console::flush(size_t x, size_t y, size_t width, size_t height)
@ -58,16 +57,12 @@ void Console::enqueue_refresh_timer()
NonnullRefPtr<Timer> refresh_timer = adopt_ref(*new Timer());
refresh_timer->setup(CLOCK_MONOTONIC, refresh_interval, [this]() {
auto rect = m_dirty_rect;
if (rect.is_dirty()) {
Protocol::Rect dirty_rect {
.x = (u32)rect.x(),
.y = (u32)rect.y(),
.width = (u32)rect.width(),
.height = (u32)rect.height(),
};
// FIXME: Do something sanely here if we can't allocate a work queue?
MUST(g_io_work->try_queue([this, dirty_rect]() {
m_framebuffer_device->flush_dirty_window(dirty_rect, m_framebuffer_device->current_buffer());
if (m_enabled.load() && rect.is_dirty()) {
MUST(g_io_work->try_queue([this]() {
{
MutexLocker locker(m_parent_display_connector->m_flushing_lock);
MUST(m_parent_display_connector->flush_first_surface());
}
m_dirty_rect.clear();
}));
}
@ -78,16 +73,17 @@ void Console::enqueue_refresh_timer()
void Console::enable()
{
auto current_resolution = m_parent_display_connector->current_mode_setting();
GenericFramebufferConsole::enable();
m_width = m_framebuffer_device->width();
m_height = m_framebuffer_device->height();
m_pitch = m_framebuffer_device->pitch();
m_width = current_resolution.horizontal_active;
m_height = current_resolution.vertical_active;
m_pitch = current_resolution.horizontal_stride;
m_dirty_rect.union_rect(0, 0, m_width, m_height);
}
u8* Console::framebuffer_data()
{
return m_framebuffer_device->framebuffer_data();
return m_parent_display_connector->framebuffer_data();
}
}