1
0
Fork 0
mirror of https://github.com/LadybirdBrowser/ladybird.git synced 2025-06-12 02:30:30 +09:00

LibWeb: Allow working on N+1 frame while N is rasterizing

This change allows us to overlap rasterization and rendering work across
threads: while the rasterization thread processes frame N, the main
thread can simultaneously work on producing the display list for frame
N+1.
This commit is contained in:
Aliaksandr Kalenik 2025-04-01 00:06:01 +02:00 committed by Jelle Raaijmakers
parent 7248748157
commit cb722ca18b
Notes: github-actions[bot] 2025-04-01 10:18:57 +00:00
3 changed files with 27 additions and 20 deletions

View file

@ -25,14 +25,25 @@ public:
void reallocate_backing_stores(Gfx::IntSize); void reallocate_backing_stores(Gfx::IntSize);
void restart_resize_timer(); void restart_resize_timer();
Web::Painting::BackingStore* back_store() { return m_back_store.ptr(); } struct BackingStore {
i32 front_id() const { return m_front_bitmap_id; } i32 bitmap_id { -1 };
Web::Painting::BackingStore* store { nullptr };
};
void swap_back_and_front(); BackingStore acquire_store_for_next_frame()
{
BackingStore backing_store;
backing_store.bitmap_id = m_back_bitmap_id;
backing_store.store = m_back_store.ptr();
swap_back_and_front();
return backing_store;
}
BackingStoreManager(PageClient&); BackingStoreManager(PageClient&);
private: private:
void swap_back_and_front();
// FIXME: We should come up with an ownership model for this class that makes the GC-checker happy // FIXME: We should come up with an ownership model for this class that makes the GC-checker happy
IGNORE_GC PageClient& m_page_client; IGNORE_GC PageClient& m_page_client;

View file

@ -81,12 +81,7 @@ PageClient::~PageClient() = default;
bool PageClient::is_ready_to_paint() const bool PageClient::is_ready_to_paint() const
{ {
return m_paint_state == PaintState::Ready; return m_number_of_queued_rasterization_tasks <= 1;
}
void PageClient::ready_to_paint()
{
m_paint_state = PaintState::Ready;
} }
void PageClient::visit_edges(JS::Cell::Visitor& visitor) void PageClient::visit_edges(JS::Cell::Visitor& visitor)
@ -220,18 +215,24 @@ void PageClient::process_screenshot_requests()
} }
} }
void PageClient::ready_to_paint()
{
m_number_of_queued_rasterization_tasks--;
VERIFY(m_number_of_queued_rasterization_tasks >= 0 && m_number_of_queued_rasterization_tasks < 2);
}
void PageClient::paint_next_frame() void PageClient::paint_next_frame()
{ {
auto back_store = m_backing_store_manager.back_store(); auto [backing_store_id, back_store] = m_backing_store_manager.acquire_store_for_next_frame();
if (!back_store) if (!back_store)
return; return;
m_paint_state = PaintState::WaitingForClient; VERIFY(m_number_of_queued_rasterization_tasks <= 1);
m_number_of_queued_rasterization_tasks++;
auto viewport_rect = page().css_to_device_rect(page().top_level_traversable()->viewport_rect()); auto viewport_rect = page().css_to_device_rect(page().top_level_traversable()->viewport_rect());
start_display_list_rendering(viewport_rect, *back_store, {}, [this, viewport_rect]() { start_display_list_rendering(viewport_rect, *back_store, {}, [this, viewport_rect, backing_store_id] {
m_backing_store_manager.swap_back_and_front(); client().async_did_paint(m_id, viewport_rect.to_type<int>(), backing_store_id);
client().async_did_paint(m_id, viewport_rect.to_type<int>(), m_backing_store_manager.front_id());
}); });
} }

View file

@ -190,12 +190,7 @@ private:
bool m_should_show_line_box_borders { false }; bool m_should_show_line_box_borders { false };
bool m_has_focus { false }; bool m_has_focus { false };
enum class PaintState { i32 m_number_of_queued_rasterization_tasks { 0 };
Ready,
WaitingForClient,
};
PaintState m_paint_state { PaintState::Ready };
struct ScreenshotTask { struct ScreenshotTask {
Optional<Web::UniqueNodeID> node_id; Optional<Web::UniqueNodeID> node_id;