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:
parent
7248748157
commit
cb722ca18b
Notes:
github-actions[bot]
2025-04-01 10:18:57 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: cb722ca18b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4163
Reviewed-by: https://github.com/gmta ✅
3 changed files with 27 additions and 20 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue