ladybird/Libraries/LibWeb/Compositor/CompositorHost.cpp
Aliaksandr Kalenik d96dc6535f LibWeb+Compositor+WebContent: Simplify nested context composition
Nested navigables were represented through compositor surface ids owned
by the parent context. That forced CompositorState and ContextState to
maintain bidirectional attach/detach bookkeeping, publish child
snapshots into a surface map, and keep presentation mode variants just
to distinguish UI presentation from parent composition.

Record the child compositor context id directly in the display list and
let the compositor resolve it against the painting parent at playback
time. Child contexts now keep their parent context id and latest
rendered surface, while parents no longer track child maps or compositor
surface ids. UI presentation is represented separately from parent
composition, so closing a page only stops client presentation and nested
contexts keep using set_parent_context.
2026-06-18 07:08:34 +02:00

102 lines
3.6 KiB
C++

/*
* Copyright (c) 2026-present, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/PaintingSurface.h>
#include <LibWeb/Compositor/CompositorHost.h>
#include <LibWeb/Painting/DisplayList.h>
namespace Web::Compositor {
CompositorContextHandle::CompositorContextHandle(CompositorHost& host, CompositorContextId context_id)
: m_host(host)
, m_context_id(context_id)
{
}
CompositorContextHandle::~CompositorContextHandle()
{
m_host.destroy_context(m_context_id);
}
void CompositorContextHandle::set_parent_context(Optional<CompositorContextId> parent_context_id)
{
m_host.set_parent_context(m_context_id, parent_context_id);
}
void CompositorContextHandle::stop_presenting_to_client()
{
m_host.stop_presenting_to_client(m_context_id);
}
void CompositorContextHandle::update_display_list(NonnullRefPtr<Painting::DisplayList> display_list, Painting::AccumulatedVisualContextTree visual_context_tree, Painting::DisplayListResourceTransaction&& resource_transaction, Painting::ScrollStateSnapshot&& scroll_state_snapshot)
{
m_host.update_display_list(m_context_id, move(display_list), move(visual_context_tree), move(resource_transaction), move(scroll_state_snapshot));
}
void CompositorContextHandle::update_visual_context_tree(Painting::AccumulatedVisualContextTree visual_context_tree)
{
m_host.update_visual_context_tree(m_context_id, move(visual_context_tree));
}
void CompositorContextHandle::update_video_frame(Painting::VideoFrameResourceId frame_id, NonnullRefPtr<Media::VideoFrame const> frame)
{
m_host.update_video_frame(m_context_id, frame_id, move(frame));
}
void CompositorContextHandle::clear_video_frame(Painting::VideoFrameResourceId frame_id)
{
m_host.clear_video_frame(m_context_id, frame_id);
}
void CompositorContextHandle::update_scroll_state(Painting::ScrollStateSnapshot&& scroll_state_snapshot)
{
m_host.update_scroll_state(m_context_id, move(scroll_state_snapshot));
}
void CompositorContextHandle::invalidate_wheel_event_listener_state(u64 generation)
{
m_host.invalidate_wheel_event_listener_state(m_context_id, generation);
}
AsyncScrollEnqueueResult CompositorContextHandle::async_scroll_by(UniqueNodeID expected_document_id, Gfx::FloatPoint position,
Gfx::FloatPoint delta_in_device_pixels, Gfx::IntRect viewport_rect, AsyncScrollOperationTracking operation_tracking)
{
return m_host.async_scroll_by(m_context_id, expected_document_id, position, delta_in_device_pixels, viewport_rect, operation_tracking);
}
bool CompositorContextHandle::should_defer_main_thread_present_for_async_scroll() const
{
return m_host.should_defer_main_thread_present_for_async_scroll(m_context_id);
}
PendingAsyncScrollUpdates CompositorContextHandle::take_pending_async_scroll_updates()
{
return m_host.take_pending_async_scroll_updates(m_context_id);
}
void CompositorContextHandle::viewport_size_updated(Gfx::IntSize viewport_size, WindowResizingInProgress window_resize_in_progress)
{
m_host.viewport_size_updated(m_context_id, viewport_size, window_resize_in_progress);
}
void CompositorContextHandle::present_frame(Gfx::IntRect viewport_rect)
{
m_host.present_frame(m_context_id, viewport_rect);
}
void CompositorContextHandle::request_screenshot(NonnullRefPtr<Gfx::PaintingSurface> target_surface, Function<void()>&& callback)
{
m_host.request_screenshot(m_context_id, move(target_surface), move(callback));
}
CompositorHost::~CompositorHost() = default;
OwnPtr<CompositorContextHandle> CompositorHost::create_context(CompositorContextId context_id)
{
return adopt_own(*new CompositorContextHandle(*this, context_id));
}
}