mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:17:44 +00:00
Kernel/Graphics: Propagate errors properly around in the VirtIO driver
This happens to be a sad truth for the VirtIOGPU driver - it lacked any error propagation measures and generally relied on clunky assumptions that most operations with the GPU device are infallible, although in reality much of them could fail, so we do need to handle errors. To fix this, synchronous GPU commands no longer rely on the wait queue mechanism anymore, so instead we introduce a timeout-based mechanism, similar to how other Kernel drivers use a polling based mechanism with the assumption that hardware could get stuck in an error state and we could abort gracefully. Then, we change most of the VirtIOGraphicsAdapter methods to propagate errors properly to the original callers, to ensure that if a synchronous GPU command failed, either the Kernel or userspace could do something meaningful about this situation.
This commit is contained in:
parent
12d4bbbd11
commit
efae6e2270
5 changed files with 176 additions and 151 deletions
|
@ -122,9 +122,9 @@ ErrorOr<void> VirtIODisplayConnector::flush_rectangle(size_t buffer_index, FBRec
|
|||
.height = rect.height
|
||||
};
|
||||
|
||||
m_graphics_adapter->transfer_framebuffer_data_to_host({}, *this, dirty_rect, true);
|
||||
TRY(m_graphics_adapter->transfer_framebuffer_data_to_host({}, *this, dirty_rect, true));
|
||||
// Flushing directly to screen
|
||||
flush_displayed_image(dirty_rect, true);
|
||||
TRY(flush_displayed_image(dirty_rect, true));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -139,9 +139,9 @@ ErrorOr<void> VirtIODisplayConnector::flush_first_surface()
|
|||
.height = m_display_info.rect.height
|
||||
};
|
||||
|
||||
m_graphics_adapter->transfer_framebuffer_data_to_host({}, *this, dirty_rect, true);
|
||||
TRY(m_graphics_adapter->transfer_framebuffer_data_to_host({}, *this, dirty_rect, true));
|
||||
// Flushing directly to screen
|
||||
flush_displayed_image(dirty_rect, true);
|
||||
TRY(flush_displayed_image(dirty_rect, true));
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -241,10 +241,11 @@ void VirtIODisplayConnector::draw_ntsc_test_pattern(Badge<VirtIOGraphicsAdapter>
|
|||
dbgln_if(VIRTIO_DEBUG, "Finish drawing the pattern");
|
||||
}
|
||||
|
||||
void VirtIODisplayConnector::flush_displayed_image(Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect, bool main_buffer)
|
||||
ErrorOr<void> VirtIODisplayConnector::flush_displayed_image(Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect, bool main_buffer)
|
||||
{
|
||||
VERIFY(m_graphics_adapter->operation_lock().is_locked());
|
||||
m_graphics_adapter->flush_displayed_image({}, *this, dirty_rect, main_buffer);
|
||||
TRY(m_graphics_adapter->flush_displayed_image({}, *this, dirty_rect, main_buffer));
|
||||
return {};
|
||||
}
|
||||
|
||||
void VirtIODisplayConnector::set_dirty_displayed_rect(Graphics::VirtIOGPU::Protocol::Rect const& dirty_rect, bool main_buffer)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue