mirror of
https://github.com/SerenityOS/serenity
synced 2024-07-21 10:05:32 +00:00
LibWeb+WebContent: Change event loop to synchronously paint next frame
...instead of scheduling repaint timer in PageClient. This change fixes flickering on Discord that happened because: - Event loop schedules repainting by activating repaint timer - `Document::tear_down_layout_tree()` destroys paintable tree - Repaint timer invokes callback and renders an empty frame because paintable tree was destroyed
This commit is contained in:
parent
e806136116
commit
b8d18ebcf7
|
@ -327,7 +327,10 @@ void EventLoop::process()
|
|||
if (navigable && navigable->needs_repaint()) {
|
||||
auto* browsing_context = document.browsing_context();
|
||||
auto& page = browsing_context->page();
|
||||
page.client().schedule_repaint();
|
||||
if (navigable->is_traversable()) {
|
||||
VERIFY(page.client().is_ready_to_paint());
|
||||
page.client().paint_next_frame();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -2133,8 +2133,9 @@ void Navigable::paint(Painting::RecordingPainter& recording_painter, PaintConfig
|
|||
auto background_color = document->background_color();
|
||||
|
||||
recording_painter.fill_rect(bitmap_rect, background_color);
|
||||
if (!document->paintable())
|
||||
return;
|
||||
if (!document->paintable()) {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Web::PaintContext context(recording_painter, page.palette(), page.client().device_pixels_per_css_pixel());
|
||||
context.set_device_viewport_rect(viewport_rect);
|
||||
|
|
|
@ -247,6 +247,7 @@ public:
|
|||
virtual DevicePixelRect screen_rect() const = 0;
|
||||
virtual double device_pixels_per_css_pixel() const = 0;
|
||||
virtual CSS::PreferredColorScheme preferred_color_scheme() const = 0;
|
||||
virtual void paint_next_frame() = 0;
|
||||
virtual void paint(DevicePixelRect const&, Gfx::Bitmap&, PaintOptions = {}) = 0;
|
||||
virtual void page_did_change_title(ByteString const&) { }
|
||||
virtual void page_did_change_url(URL::URL const&) { }
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
virtual double device_pixels_per_css_pixel() const override { return 1.0; }
|
||||
virtual CSS::PreferredColorScheme preferred_color_scheme() const override { return m_host_page->client().preferred_color_scheme(); }
|
||||
virtual void request_file(FileRequest) override { }
|
||||
virtual void paint_next_frame() override { }
|
||||
virtual void paint(DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override { }
|
||||
virtual void schedule_repaint() override { }
|
||||
virtual bool is_ready_to_paint() const override { return true; }
|
||||
|
|
|
@ -57,23 +57,6 @@ PageClient::PageClient(PageHost& owner, u64 id)
|
|||
{
|
||||
setup_palette();
|
||||
|
||||
m_repaint_timer = Web::Platform::Timer::create_single_shot(0, [this] {
|
||||
if (!m_backing_stores.back_bitmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& back_bitmap = *m_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 = m_backing_stores;
|
||||
swap(backing_stores.front_bitmap, backing_stores.back_bitmap);
|
||||
swap(backing_stores.front_bitmap_id, backing_stores.back_bitmap_id);
|
||||
|
||||
m_paint_state = PaintState::WaitingForClient;
|
||||
client().async_did_paint(m_id, viewport_rect.to_type<int>(), backing_stores.front_bitmap_id);
|
||||
});
|
||||
|
||||
#ifdef HAS_ACCELERATED_GRAPHICS
|
||||
if (s_use_gpu_painter) {
|
||||
auto context = AccelGfx::Context::create();
|
||||
|
@ -92,9 +75,6 @@ void PageClient::schedule_repaint()
|
|||
m_paint_state = PaintState::PaintWhenReady;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_repaint_timer->is_active())
|
||||
m_repaint_timer->start();
|
||||
}
|
||||
|
||||
bool PageClient::is_ready_to_paint() const
|
||||
|
@ -197,6 +177,24 @@ Web::Layout::Viewport* PageClient::layout_root()
|
|||
return document->layout_node();
|
||||
}
|
||||
|
||||
void PageClient::paint_next_frame()
|
||||
{
|
||||
if (!m_backing_stores.back_bitmap) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto& back_bitmap = *m_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 = m_backing_stores;
|
||||
swap(backing_stores.front_bitmap, backing_stores.back_bitmap);
|
||||
swap(backing_stores.front_bitmap_id, backing_stores.back_bitmap_id);
|
||||
|
||||
m_paint_state = PaintState::WaitingForClient;
|
||||
client().async_did_paint(m_id, viewport_rect.to_type<int>(), backing_stores.front_bitmap_id);
|
||||
}
|
||||
|
||||
void PageClient::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& target, Web::PaintOptions paint_options)
|
||||
{
|
||||
Web::Painting::CommandList painting_commands;
|
||||
|
|
|
@ -39,6 +39,7 @@ public:
|
|||
|
||||
ErrorOr<void> connect_to_webdriver(ByteString const& webdriver_ipc_path);
|
||||
|
||||
virtual void paint_next_frame() override;
|
||||
virtual void paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap&, Web::PaintOptions = {}) override;
|
||||
|
||||
void set_palette_impl(Gfx::PaletteImpl&);
|
||||
|
@ -177,7 +178,6 @@ private:
|
|||
};
|
||||
|
||||
PaintState m_paint_state { PaintState::Ready };
|
||||
RefPtr<Web::Platform::Timer> m_repaint_timer;
|
||||
|
||||
Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto };
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ public:
|
|||
virtual Web::DevicePixelRect screen_rect() const override;
|
||||
virtual double device_pixels_per_css_pixel() const override;
|
||||
virtual Web::CSS::PreferredColorScheme preferred_color_scheme() const override;
|
||||
virtual void paint_next_frame() override {};
|
||||
virtual void paint(Web::DevicePixelRect const&, Gfx::Bitmap&, Web::PaintOptions = {}) override;
|
||||
virtual void request_file(Web::FileRequest) override;
|
||||
virtual void schedule_repaint() override {};
|
||||
|
|
Loading…
Reference in a new issue