summaryrefslogtreecommitdiff
path: root/Kernel
diff options
context:
space:
mode:
authorLiav A <liavalb@gmail.com>2022-12-19 14:57:03 +0200
committerAndrew Kaster <andrewdkaster@gmail.com>2022-12-31 05:13:21 -0700
commit883b0f1390449f92a098ebe8d7639c7d24ff4a75 (patch)
tree75ab9bcf83d2317b88059178c0c16ffe3479a4d7 /Kernel
parent658f9eec6a9284b7f2a5620630d2b3d5c726fcd9 (diff)
downloadserenity-883b0f1390449f92a098ebe8d7639c7d24ff4a75.zip
Kernel/Graphics: Restore VirtIO GPU framebuffer console functionality
This has been done in multiple ways: - Each time we modeset the resolution via the VirtIOGPU DisplayConnector we ensure that the framebuffer is updated with the new resolution. - Each time the cursor is updated we ensure that the framebuffer console is marked dirty so the IO Work Queue task which is scheduled to check if it is dirty, will flush the surface. - We only initialize a framebuffer console after we ensure that at the very least a DisplayConnector has being set with a known resolution. - We only call GenericFramebufferConsole::enable() when enabling the console after the important variables of the console (m_width, m_pitch and m_height) have been set.
Diffstat (limited to 'Kernel')
-rw-r--r--Kernel/Graphics/VirtIOGPU/Console.cpp39
-rw-r--r--Kernel/Graphics/VirtIOGPU/Console.h5
-rw-r--r--Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp7
-rw-r--r--Kernel/Graphics/VirtIOGPU/DisplayConnector.h5
-rw-r--r--Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp1
5 files changed, 50 insertions, 7 deletions
diff --git a/Kernel/Graphics/VirtIOGPU/Console.cpp b/Kernel/Graphics/VirtIOGPU/Console.cpp
index e2962fa858..5b2d5b8c9d 100644
--- a/Kernel/Graphics/VirtIOGPU/Console.cpp
+++ b/Kernel/Graphics/VirtIOGPU/Console.cpp
@@ -5,6 +5,7 @@
*/
#include <Kernel/Graphics/VirtIOGPU/Console.h>
+#include <Kernel/TTY/ConsoleManagement.h>
#include <Kernel/WorkQueue.h>
namespace Kernel::Graphics::VirtIOGPU {
@@ -21,12 +22,42 @@ Console::Console(VirtIODisplayConnector const& parent_display_connector, Display
: GenericFramebufferConsole(current_resolution.horizontal_active, current_resolution.vertical_active, current_resolution.horizontal_stride)
, m_parent_display_connector(parent_display_connector)
{
+ // NOTE: Clear the framebuffer, in case it's left with some garbage.
+ memset(framebuffer_data(), 0, current_resolution.horizontal_stride * current_resolution.vertical_active);
enqueue_refresh_timer();
}
-void Console::set_resolution(size_t, size_t, size_t)
+void Console::set_resolution(size_t width, size_t height, size_t pitch)
{
- // FIXME: Update some values here?
+ m_width = width;
+ m_height = height;
+ m_pitch = pitch;
+
+ // Just to start cleanly, we clean the entire framebuffer
+ memset(framebuffer_data(), 0, pitch * height);
+
+ ConsoleManagement::the().resolution_was_changed();
+}
+
+void Console::set_cursor(size_t x, size_t y)
+{
+ GenericFramebufferConsole::hide_cursor();
+ m_x = x;
+ m_y = y;
+ GenericFramebufferConsole::show_cursor();
+ m_dirty = true;
+}
+
+void Console::hide_cursor()
+{
+ GenericFramebufferConsole::hide_cursor();
+ m_dirty = true;
+}
+
+void Console::show_cursor()
+{
+ GenericFramebufferConsole::show_cursor();
+ m_dirty = true;
}
void Console::flush(size_t, size_t, size_t, size_t)
@@ -54,11 +85,13 @@ void Console::enqueue_refresh_timer()
void Console::enable()
{
+ // FIXME: Do we need some locking here to ensure the resolution doesn't change
+ // while we enable the console?
auto current_resolution = m_parent_display_connector->current_mode_setting();
- GenericFramebufferConsole::enable();
m_width = current_resolution.horizontal_active;
m_height = current_resolution.vertical_active;
m_pitch = current_resolution.horizontal_stride;
+ GenericFramebufferConsole::enable();
m_dirty = true;
}
diff --git a/Kernel/Graphics/VirtIOGPU/Console.h b/Kernel/Graphics/VirtIOGPU/Console.h
index d798eff1a2..744a640d89 100644
--- a/Kernel/Graphics/VirtIOGPU/Console.h
+++ b/Kernel/Graphics/VirtIOGPU/Console.h
@@ -20,10 +20,15 @@ public:
virtual void flush(size_t x, size_t y, size_t width, size_t height) override;
virtual void enable() override;
+ virtual void set_cursor(size_t x, size_t y) override;
+
private:
void enqueue_refresh_timer();
virtual u8* framebuffer_data() override;
+ virtual void hide_cursor() override;
+ virtual void show_cursor() override;
+
Console(VirtIODisplayConnector const& parent_display_connector, DisplayConnector::ModeSetting current_resolution);
NonnullLockRefPtr<VirtIODisplayConnector> m_parent_display_connector;
bool m_dirty { false };
diff --git a/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp b/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp
index bac91a30e3..d63d389678 100644
--- a/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp
+++ b/Kernel/Graphics/VirtIOGPU/DisplayConnector.cpp
@@ -20,7 +20,6 @@ NonnullLockRefPtr<VirtIODisplayConnector> VirtIODisplayConnector::must_create(Vi
auto device_or_error = DeviceManagement::try_create_device<VirtIODisplayConnector>(graphics_adapter, scanout_id);
VERIFY(!device_or_error.is_error());
auto connector = device_or_error.release_value();
- connector->initialize_console();
return connector;
}
@@ -33,9 +32,10 @@ VirtIODisplayConnector::VirtIODisplayConnector(VirtIOGraphicsAdapter& graphics_a
{
}
-void VirtIODisplayConnector::initialize_console()
+void VirtIODisplayConnector::initialize_console(Badge<VirtIOGraphicsAdapter>)
{
m_console = Kernel::Graphics::VirtIOGPU::Console::initialize(*this);
+ GraphicsManagement::the().set_console(*m_console);
}
void VirtIODisplayConnector::set_safe_mode_setting_after_initialization(Badge<VirtIOGraphicsAdapter>)
@@ -58,6 +58,9 @@ ErrorOr<void> VirtIODisplayConnector::set_mode_setting(ModeSetting const& mode_s
};
TRY(m_graphics_adapter->mode_set_resolution({}, *this, mode_setting.horizontal_active, mode_setting.vertical_active));
+
+ if (m_console)
+ m_console->set_resolution(info.rect.width, info.rect.height, info.rect.width * sizeof(u32));
DisplayConnector::ModeSetting mode_set {
.horizontal_stride = info.rect.width * sizeof(u32),
.pixel_clock_in_khz = 0, // Note: There's no pixel clock in paravirtualized hardware
diff --git a/Kernel/Graphics/VirtIOGPU/DisplayConnector.h b/Kernel/Graphics/VirtIOGPU/DisplayConnector.h
index 804286ac01..f59629a2e8 100644
--- a/Kernel/Graphics/VirtIOGPU/DisplayConnector.h
+++ b/Kernel/Graphics/VirtIOGPU/DisplayConnector.h
@@ -39,8 +39,9 @@ public:
void draw_ntsc_test_pattern(Badge<VirtIOGraphicsAdapter>);
+ void initialize_console(Badge<VirtIOGraphicsAdapter>);
+
private:
- void initialize_console();
virtual bool mutable_mode_setting_capable() const override { return true; }
virtual bool double_framebuffering_capable() const override { return false; }
virtual bool partial_flush_support() const override { return true; }
@@ -82,7 +83,7 @@ private:
Graphics::VirtIOGPU::ContextID m_kernel_context_id;
NonnullLockRefPtr<VirtIOGraphicsAdapter> m_graphics_adapter;
- LockRefPtr<Graphics::Console> m_console;
+ LockRefPtr<Graphics::VirtIOGPU::Console> m_console;
Graphics::VirtIOGPU::Protocol::DisplayInfoResponse::Display m_display_info {};
Graphics::VirtIOGPU::ScanoutID m_scanout_id;
diff --git a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp
index 8038258769..5e8872011f 100644
--- a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp
+++ b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp
@@ -47,6 +47,7 @@ ErrorOr<void> VirtIOGraphicsAdapter::initialize_adapter()
m_scanouts[index].display_connector = display_connector;
MUST(query_and_set_edid(index, *display_connector));
display_connector->set_safe_mode_setting_after_initialization({});
+ display_connector->initialize_console({});
}
return {};
}