diff options
Diffstat (limited to 'Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h')
-rw-r--r-- | Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h b/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h index 7cfea5dcc8..003ce823fd 100644 --- a/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h +++ b/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h @@ -14,6 +14,13 @@ namespace Kernel::Graphics { class VirtIOFrameBufferDevice final : public BlockDevice { + friend class VirtIOGPUConsole; + struct Buffer { + size_t framebuffer_offset { 0 }; + u8* framebuffer_data { nullptr }; + VirtIOGPUResourceID resource_id { 0 }; + }; + public: VirtIOFrameBufferDevice(VirtIOGPU& virtio_gpu, VirtIOGPUScanoutID); virtual ~VirtIOFrameBufferDevice() override; @@ -22,23 +29,23 @@ public: virtual void activate_writes(); bool try_to_set_resolution(size_t width, size_t height); - void clear_to_black(); + void clear_to_black(Buffer&); size_t width() const { return display_info().rect.width; } size_t height() const { return display_info().rect.height; } size_t pitch() const { return display_info().rect.width * 4; } - size_t size_in_bytes() const; static size_t calculate_framebuffer_size(size_t width, size_t height) { - return sizeof(u32) * width * height; + // VirtIO resources can only map on page boundaries! + return page_round_up(sizeof(u32) * width * height); } - void flush_dirty_window(VirtIOGPURect const&); - void transfer_framebuffer_data_to_host(VirtIOGPURect const&); - void flush_displayed_image(VirtIOGPURect const&); + void flush_dirty_window(VirtIOGPURect const&, Buffer&); + void transfer_framebuffer_data_to_host(VirtIOGPURect const&, Buffer&); + void flush_displayed_image(VirtIOGPURect const&, Buffer&); - void draw_ntsc_test_pattern(); + void draw_ntsc_test_pattern(Buffer&); u8* framebuffer_data(); @@ -49,6 +56,8 @@ private: VirtIOGPURespDisplayInfo::VirtIOGPUDisplayOne& display_info(); void create_framebuffer(); + void create_buffer(Buffer&, size_t, size_t); + void set_buffer(int); virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override; virtual KResultOr<Region*> mmap(Process&, FileDescription&, const Range&, u64 offset, int prot, bool shared) override; @@ -61,11 +70,26 @@ private: virtual mode_t required_mode() const override { return 0666; } virtual String device_name() const override { return String::formatted("fb{}", minor()); } + static bool is_valid_buffer_index(int buffer_index) + { + return buffer_index == 0 || buffer_index == 1; + } + + Buffer& buffer_from_index(int buffer_index) + { + return buffer_index == 0 ? m_main_buffer : m_back_buffer; + } + Buffer& current_buffer() const { return *m_current_buffer; } + VirtIOGPU& m_gpu; const VirtIOGPUScanoutID m_scanout; - VirtIOGPUResourceID m_resource_id { 0 }; + Buffer* m_current_buffer { nullptr }; + Atomic<int, AK::memory_order_relaxed> m_last_set_buffer_index { 0 }; + Buffer m_main_buffer; + Buffer m_back_buffer; OwnPtr<Region> m_framebuffer; RefPtr<VMObject> m_framebuffer_sink_vmobject; + size_t m_buffer_size { 0 }; bool m_are_writes_active { true }; // FIXME: This needs to be cleaned up if the WindowServer exits while we are in a tty WeakPtr<Region> m_userspace_mmap_region; |