We are moving toward an architecture where the browser owns a single
process that holds the GPU context, so Skia resources can be shared
across every renderer and WebContent processes can be sandboxed away
from direct GPU access. A dedicated Compositor helper process is the
first step. The earlier commits laid the foundation; this one turns the
helper on as a selectable backend, gated behind
--enable-compositor-process so the existing in-process path stays the
shipping default.
Default topology -- one compositor per WebContent, in-process:
+---------+
| Browser |
+---------+
/ | \
v v v
+---+ +---+ +---+ each WebContent runs its own
|WC | |WC | |WC | CompositorThread on a dedicated
|+C+| |+C+| |+C+| thread, with its own GPU context.
+---+ +---+ +---+
Opt-in topology -- one single-threaded Compositor, shared by all WCs:
+---------+ control +-------------------+
| Browser |<----------->| Compositor |
+---------+ | (single thread, |
/ | \ | single GPU ctx, |
v v v data | shared by all |
[WC] [WC] [WC] ---------->| connected WCs) |
+-------------------+
Three IPC channels carry the work in the opt-in topology. The
existing Browser<->WebContent channel gains context allocation.
A new Browser<->Compositor channel carries context lifetime,
viewport, UI input, and presentation acks plus backing-store and
frame upcalls. A new WebContent<->Compositor channel carries
display lists, scroll state, video, compositor surfaces, async
scrolling, presentation, and screenshots, with upcalls for
delegated input and compositor loss.
63 lines
1.7 KiB
C++
63 lines
1.7 KiB
C++
/*
|
|
* Copyright (c) 2020-2023, Andreas Kling <andreas@ladybird.org>
|
|
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
|
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibIPC/TransportHandle.h>
|
|
#include <LibWeb/Bindings/MainThreadVM.h>
|
|
#include <LibWeb/Compositor/CompositorHost.h>
|
|
#include <LibWeb/HTML/TraversableNavigable.h>
|
|
#include <WebContent/ConnectionFromClient.h>
|
|
#include <WebContent/PageClient.h>
|
|
#include <WebContent/PageHost.h>
|
|
#include <WebContent/WebContentCompositorHost.h>
|
|
#include <WebContent/WebDriverConnection.h>
|
|
|
|
namespace WebContent {
|
|
|
|
PageHost::PageHost(ConnectionFromClient& client)
|
|
: m_client(client)
|
|
{
|
|
auto& first_page = create_page();
|
|
Web::HTML::TraversableNavigable::create_a_fresh_top_level_traversable(first_page.page(), URL::about_blank());
|
|
}
|
|
|
|
PageClient& PageHost::create_page()
|
|
{
|
|
m_pages.set(m_next_id, PageClient::create(Web::Bindings::main_thread_vm(), *this, m_next_id));
|
|
++m_next_id;
|
|
return *m_pages.get(m_next_id - 1).value();
|
|
}
|
|
|
|
void PageHost::remove_page(Badge<PageClient>, u64 index)
|
|
{
|
|
m_pages.remove(index);
|
|
}
|
|
|
|
Optional<PageClient&> PageHost::page(u64 index)
|
|
{
|
|
return m_pages.get(index).map([](auto& value) -> PageClient& {
|
|
return *value;
|
|
});
|
|
}
|
|
|
|
PageHost::~PageHost() = default;
|
|
|
|
void PageHost::ensure_compositor_host(Web::DisplayListPlayerType display_list_player_type)
|
|
{
|
|
if (m_compositor_host)
|
|
return;
|
|
m_compositor_host = create_web_content_compositor_host(m_client);
|
|
m_compositor_host->start(display_list_player_type);
|
|
}
|
|
|
|
void PageHost::attach_compositor_ui_client(IPC::TransportHandle handle)
|
|
{
|
|
if (m_compositor_host)
|
|
m_compositor_host->attach_ui_client(move(handle));
|
|
}
|
|
|
|
}
|