1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 09:24:57 +00:00

LibWebView+WebContent: Drive repainting from WebContent process

With this change, chrome no longer has to ask the WebContent process
to paint the next frame into a specified bitmap. Instead, it allocates
bitmaps and sends them to WebContent, which then lets chrome know when
the painting is done.

This work is a preparation to move the execution of painting commands
into a separate thread. Now, it is much easier to start working on the
next frame while the current one is still rendering. This is because
WebContent does not have to inform chrome that the current frame is
ready before it can request the next frame.

Additionally, as a side bonus, we can now eliminate the
did_invalidate_content_rect and did_change_selection IPC calls. These
were used solely for the purpose of informing chrome that it needed to
request a repaint.
This commit is contained in:
Aliaksandr Kalenik 2023-12-21 22:58:54 +01:00 committed by Andreas Kling
parent ac63d1e59d
commit 02936f6944
17 changed files with 68 additions and 152 deletions

View file

@ -51,9 +51,21 @@ PageClient::PageClient(PageHost& owner, u64 id)
, m_id(id)
{
setup_palette();
m_invalidation_coalescing_timer = Web::Platform::Timer::create_single_shot(0, [this] {
client().async_did_invalidate_content_rect({ m_invalidation_rect.x().value(), m_invalidation_rect.y().value(), m_invalidation_rect.width().value(), m_invalidation_rect.height().value() });
m_invalidation_rect = {};
m_repaint_timer = Web::Platform::Timer::create_single_shot(0, [this] {
if (!client().backing_stores().back_bitmap) {
warnln("Skip painting because back bitmap is not initialized");
return;
}
auto& back_bitmap = *client().backing_stores().back_bitmap;
auto viewport_rect = page().css_to_device_rect(page().top_level_traversable()->viewport_rect());
paint(viewport_rect, back_bitmap);
auto& backing_stores = client().backing_stores();
swap(backing_stores.front_bitmap, backing_stores.back_bitmap);
swap(backing_stores.front_bitmap_id, backing_stores.back_bitmap_id);
client().did_paint(viewport_rect.to_type<int>(), backing_stores.front_bitmap_id);
});
#ifdef HAS_ACCELERATED_GRAPHICS
@ -63,6 +75,12 @@ PageClient::PageClient(PageHost& owner, u64 id)
#endif
}
void PageClient::schedule_repaint()
{
if (!m_repaint_timer->is_active())
m_repaint_timer->start();
}
void PageClient::visit_edges(JS::Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
@ -194,18 +212,12 @@ void PageClient::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& ta
void PageClient::set_viewport_rect(Web::DevicePixelRect const& rect)
{
page().top_level_traversable()->set_viewport_rect(page().device_to_css_rect(rect));
schedule_repaint();
}
void PageClient::page_did_invalidate(Web::CSSPixelRect const& content_rect)
void PageClient::page_did_invalidate(Web::CSSPixelRect const&)
{
m_invalidation_rect = m_invalidation_rect.united(page().enclosing_device_rect(content_rect));
if (!m_invalidation_coalescing_timer->is_active())
m_invalidation_coalescing_timer->start();
}
void PageClient::page_did_change_selection()
{
client().async_did_change_selection();
schedule_repaint();
}
void PageClient::page_did_request_cursor_change(Gfx::StandardCursor cursor)