mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-26 11:18:59 +00:00
WebContent: Move screenshot requests handling into repaint loop
This change ensures that if a screenshot is requested between teardown of paintable tree and relayout, we will wait for layout to complete before taking a screenshot.
This commit is contained in:
parent
6014727c20
commit
cbbe49cdf0
Notes:
sideshowbarker
2024-07-17 03:03:44 +09:00
Author: https://github.com/kalenikaliaksandr
Commit: cbbe49cdf0
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/233
Reviewed-by: https://github.com/ADKaster
Reviewed-by: https://github.com/bugaevc
3 changed files with 35 additions and 25 deletions
|
@ -754,19 +754,7 @@ void ConnectionFromClient::take_document_screenshot(u64 page_id)
|
||||||
if (!page.has_value())
|
if (!page.has_value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto* document = page->page().top_level_browsing_context().active_document();
|
page->queue_screenshot_task({});
|
||||||
if (!document || !document->document_element()) {
|
|
||||||
async_did_take_screenshot(page_id, {});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const& content_size = page->content_size();
|
|
||||||
Web::DevicePixelRect rect { { 0, 0 }, content_size };
|
|
||||||
|
|
||||||
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type<int>()).release_value_but_fixme_should_propagate_errors();
|
|
||||||
page->paint(rect, *bitmap);
|
|
||||||
|
|
||||||
async_did_take_screenshot(page_id, bitmap->to_shareable_bitmap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionFromClient::take_dom_node_screenshot(u64 page_id, i32 node_id)
|
void ConnectionFromClient::take_dom_node_screenshot(u64 page_id, i32 node_id)
|
||||||
|
@ -775,18 +763,7 @@ void ConnectionFromClient::take_dom_node_screenshot(u64 page_id, i32 node_id)
|
||||||
if (!page.has_value())
|
if (!page.has_value())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto* dom_node = Web::DOM::Node::from_unique_id(node_id);
|
page->queue_screenshot_task(node_id);
|
||||||
if (!dom_node || !dom_node->paintable_box()) {
|
|
||||||
async_did_take_screenshot(page_id, {});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rect = page->page().enclosing_device_rect(dom_node->paintable_box()->absolute_border_box_rect());
|
|
||||||
|
|
||||||
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type<int>()).release_value_but_fixme_should_propagate_errors();
|
|
||||||
page->paint(rect, *bitmap, { .paint_overlay = Web::PaintOptions::PaintOverlay::No });
|
|
||||||
|
|
||||||
async_did_take_screenshot(page_id, bitmap->to_shareable_bitmap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Messages::WebContentServer::DumpGcGraphResponse ConnectionFromClient::dump_gc_graph(u64)
|
Messages::WebContentServer::DumpGcGraphResponse ConnectionFromClient::dump_gc_graph(u64)
|
||||||
|
|
|
@ -196,6 +196,26 @@ Web::Layout::Viewport* PageClient::layout_root()
|
||||||
|
|
||||||
void PageClient::paint_next_frame()
|
void PageClient::paint_next_frame()
|
||||||
{
|
{
|
||||||
|
while (!m_screenshot_tasks.is_empty()) {
|
||||||
|
auto task = m_screenshot_tasks.dequeue();
|
||||||
|
if (task.node_id.has_value()) {
|
||||||
|
auto* dom_node = Web::DOM::Node::from_unique_id(*task.node_id);
|
||||||
|
if (!dom_node || !dom_node->paintable_box()) {
|
||||||
|
client().async_did_take_screenshot(m_id, {});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto rect = page().enclosing_device_rect(dom_node->paintable_box()->absolute_border_box_rect());
|
||||||
|
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type<int>()).release_value_but_fixme_should_propagate_errors();
|
||||||
|
paint(rect, *bitmap, { .paint_overlay = Web::PaintOptions::PaintOverlay::No });
|
||||||
|
client().async_did_take_screenshot(m_id, bitmap->to_shareable_bitmap());
|
||||||
|
} else {
|
||||||
|
Web::DevicePixelRect rect { { 0, 0 }, content_size() };
|
||||||
|
auto bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, rect.size().to_type<int>()).release_value_but_fixme_should_propagate_errors();
|
||||||
|
paint(rect, *bitmap);
|
||||||
|
client().async_did_take_screenshot(m_id, bitmap->to_shareable_bitmap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_backing_stores.back_bitmap) {
|
if (!m_backing_stores.back_bitmap) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -731,4 +751,10 @@ Web::PaintingCommandExecutorType PageClient::painting_command_executor_type() co
|
||||||
return Web::PaintingCommandExecutorType::CPU;
|
return Web::PaintingCommandExecutorType::CPU;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PageClient::queue_screenshot_task(Optional<i32> node_id)
|
||||||
|
{
|
||||||
|
m_screenshot_tasks.enqueue({ node_id });
|
||||||
|
page().top_level_traversable()->set_needs_display();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,8 @@ public:
|
||||||
|
|
||||||
virtual Web::PaintingCommandExecutorType painting_command_executor_type() const override;
|
virtual Web::PaintingCommandExecutorType painting_command_executor_type() const override;
|
||||||
|
|
||||||
|
void queue_screenshot_task(Optional<i32> node_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PageClient(PageHost&, u64 id);
|
PageClient(PageHost&, u64 id);
|
||||||
|
|
||||||
|
@ -186,6 +188,11 @@ private:
|
||||||
|
|
||||||
PaintState m_paint_state { PaintState::Ready };
|
PaintState m_paint_state { PaintState::Ready };
|
||||||
|
|
||||||
|
struct ScreenshotTask {
|
||||||
|
Optional<i32> node_id;
|
||||||
|
};
|
||||||
|
Queue<ScreenshotTask> m_screenshot_tasks;
|
||||||
|
|
||||||
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
|
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
|
||||||
Web::CSS::PreferredContrast m_preferred_contrast { Web::CSS::PreferredContrast::NoPreference };
|
Web::CSS::PreferredContrast m_preferred_contrast { Web::CSS::PreferredContrast::NoPreference };
|
||||||
Web::CSS::PreferredMotion m_preferred_motion { Web::CSS::PreferredMotion::NoPreference };
|
Web::CSS::PreferredMotion m_preferred_motion { Web::CSS::PreferredMotion::NoPreference };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue