diff options
author | Tom <tomut@yahoo.com> | 2021-07-10 10:42:04 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-10 21:24:52 +0200 |
commit | 02651f8dc608b062bc81ade8d6318b4d78f9a7cd (patch) | |
tree | cea7fafe5472f6ee0a14ff1b9b4baff5dca23ee6 | |
parent | e718de454e71f15e0284ecb2a725cfe3a8960c3b (diff) | |
download | serenity-02651f8dc608b062bc81ade8d6318b4d78f9a7cd.zip |
Kernel: Make VirtIO GPU buffer flipping more spec compliant
The spec requires a flush after setting the new buffer resource id,
which is required by QEMUs SDL backend but not the GTK backend. This
brings us in line with the spec and makes it work for the SDL backend.
-rw-r--r-- | Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.cpp | 14 | ||||
-rw-r--r-- | Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h | 1 |
2 files changed, 15 insertions, 0 deletions
diff --git a/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.cpp b/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.cpp index 6e8bbce64d..11dd307d15 100644 --- a/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.cpp +++ b/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.cpp @@ -128,6 +128,8 @@ void VirtIOFrameBufferDevice::set_buffer(int buffer_index) return; m_current_buffer = &buffer; m_gpu.set_scanout_resource(m_scanout.value(), buffer.resource_id, display_info().rect); + m_gpu.flush_displayed_image(buffer.dirty_rect, buffer.resource_id); // QEMU SDL backend requires this (as per spec) + buffer.dirty_rect = {}; } int VirtIOFrameBufferDevice::ioctl(FileDescription&, unsigned request, FlatPtr arg) @@ -196,6 +198,18 @@ int VirtIOFrameBufferDevice::ioctl(FileDescription&, unsigned request, FlatPtr a if (&buffer == m_current_buffer) { // Flushing directly to screen flush_displayed_image(dirty_rect, buffer); + buffer.dirty_rect = {}; + } else { + if (buffer.dirty_rect.width == 0 || buffer.dirty_rect.height == 0) { + buffer.dirty_rect = dirty_rect; + } else { + auto current_dirty_right = buffer.dirty_rect.x + buffer.dirty_rect.width; + auto current_dirty_bottom = buffer.dirty_rect.y + buffer.dirty_rect.height; + buffer.dirty_rect.x = min(buffer.dirty_rect.x, dirty_rect.x); + buffer.dirty_rect.y = min(buffer.dirty_rect.y, dirty_rect.y); + buffer.dirty_rect.width = max(current_dirty_right, dirty_rect.x + dirty_rect.width) - buffer.dirty_rect.x; + buffer.dirty_rect.height = max(current_dirty_bottom, dirty_rect.y + dirty_rect.height) - buffer.dirty_rect.y; + } } } } diff --git a/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h b/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h index 003ce823fd..323feecd93 100644 --- a/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h +++ b/Kernel/Graphics/VirtIOGPU/VirtIOFrameBufferDevice.h @@ -19,6 +19,7 @@ class VirtIOFrameBufferDevice final : public BlockDevice { size_t framebuffer_offset { 0 }; u8* framebuffer_data { nullptr }; VirtIOGPUResourceID resource_id { 0 }; + VirtIOGPURect dirty_rect {}; }; public: |