Compositor+LibWebView+WebContent: Scaffold opt-in Compositor process
The compositor is moving into a dedicated helper process. That requires a process to launch, channels for Browser and WebContent to talk to it over, and client proxies on each side. Land all of that as an inert scaffold first, gated behind --enable-compositor-process, so the default rendering path is unchanged and later commits can fill in the protocol, the service-side state, and the runtime switch against a stable target.
This commit is contained in:
parent
4a34a60d93
commit
bfc9bf80d9
33 changed files with 489 additions and 1 deletions
|
|
@ -21,6 +21,7 @@
|
|||
#include <LibWeb/CSS/PropertyID.h>
|
||||
#include <LibWeb/Loader/UserAgent.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/CompositorClient.h>
|
||||
#include <LibWebView/CookieJar.h>
|
||||
#include <LibWebView/HeadlessWebView.h>
|
||||
#include <LibWebView/HelperProcess.h>
|
||||
|
|
@ -97,6 +98,8 @@ Application::~Application()
|
|||
// Explicitly delete the observers first, as the observer destructors will refer to Application::the().
|
||||
m_settings_observer.clear();
|
||||
m_bookmark_store_observer.clear();
|
||||
if (m_compositor_client)
|
||||
m_compositor_client->on_death = nullptr;
|
||||
|
||||
s_the = nullptr;
|
||||
}
|
||||
|
|
@ -164,6 +167,7 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
|
|||
bool disable_http_memory_cache = false;
|
||||
bool disable_http_disk_cache = false;
|
||||
bool disable_content_blocker = false;
|
||||
bool enable_compositor_process = false;
|
||||
Vector<StringView> content_blocker_list_paths;
|
||||
Optional<StringView> resource_substitution_map_path;
|
||||
bool enable_autoplay = false;
|
||||
|
|
@ -238,6 +242,7 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
|
|||
args_parser.add_option(disable_http_memory_cache, "Disable HTTP memory cache", "disable-http-memory-cache");
|
||||
args_parser.add_option(disable_http_disk_cache, "Disable HTTP disk cache", "disable-http-disk-cache");
|
||||
args_parser.add_option(disable_content_blocker, "Disable content blocker", "disable-content-blocker");
|
||||
args_parser.add_option(enable_compositor_process, "Enable the out-of-process compositor", "enable-compositor-process");
|
||||
args_parser.add_option(Core::ArgsParser::Option {
|
||||
.argument_mode = Core::ArgsParser::OptionArgumentMode::Required,
|
||||
.help_string = "Path to a content blocker list. May be specified multiple times.",
|
||||
|
|
@ -353,6 +358,7 @@ ErrorOr<void> Application::initialize(Main::Arguments const& arguments)
|
|||
: OptionalNone()),
|
||||
.devtools_port = devtools_port,
|
||||
.enable_content_blocker = disable_content_blocker ? EnableContentBlocker::No : EnableContentBlocker::Yes,
|
||||
.enable_compositor_process = enable_compositor_process ? EnableCompositorProcess::Yes : EnableCompositorProcess::No,
|
||||
.content_blocker_list_paths = move(content_blocker_list_paths_as_byte_strings),
|
||||
};
|
||||
|
||||
|
|
@ -481,10 +487,26 @@ static ErrorOr<NonnullRefPtr<WebContentClient>> create_web_content_client(Option
|
|||
|
||||
client->async_connect_to_request_server(move(request_server_handle));
|
||||
client->async_connect_to_image_decoder(move(image_decoder_handle));
|
||||
TRY(Application::the().connect_web_content_to_compositor(*client));
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
ErrorOr<void> Application::connect_web_content_to_compositor(WebContentClient& web_content_client)
|
||||
{
|
||||
if (m_browser_options.enable_compositor_process == EnableCompositorProcess::No)
|
||||
return {};
|
||||
if (web_content_client.compositor_connection_id({}).has_value())
|
||||
return {};
|
||||
|
||||
VERIFY(m_compositor_client);
|
||||
auto response = m_compositor_client->connect_web_content();
|
||||
|
||||
web_content_client.set_compositor_connection_id({}, response.web_content_connection_id());
|
||||
web_content_client.async_connect_to_compositor_process(response.take_handle());
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<WebContentClient>> Application::launch_web_content_process(ViewImplementation& view)
|
||||
{
|
||||
if (m_spare_web_content_process) {
|
||||
|
|
@ -582,6 +604,8 @@ ErrorOr<void> Application::launch_services()
|
|||
|
||||
TRY(launch_request_server());
|
||||
TRY(launch_image_decoder_server());
|
||||
if (m_browser_options.enable_compositor_process == EnableCompositorProcess::Yes)
|
||||
TRY(launch_compositor_process());
|
||||
|
||||
if (m_browser_options.devtools_port.has_value())
|
||||
TRY(launch_devtools_server());
|
||||
|
|
@ -589,6 +613,23 @@ ErrorOr<void> Application::launch_services()
|
|||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> Application::launch_compositor_process()
|
||||
{
|
||||
VERIFY(!m_compositor_client);
|
||||
m_compositor_client = TRY(WebView::launch_compositor_process());
|
||||
m_compositor_client->on_death = [this]() {
|
||||
m_compositor_client = nullptr;
|
||||
|
||||
if (Core::EventLoop::current().was_exit_requested())
|
||||
return;
|
||||
|
||||
dbgln("Compositor process died");
|
||||
VERIFY_NOT_REACHED();
|
||||
};
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> Application::launch_request_server()
|
||||
{
|
||||
m_request_server_client = TRY(launch_request_server_process());
|
||||
|
|
@ -806,6 +847,12 @@ void Application::process_did_exit(Process&& process, Optional<int> exit_status)
|
|||
dbgln_if(WEBVIEW_PROCESS_DEBUG, "Process {} died, type: {}", process.pid(), process_name_from_type(process.type()));
|
||||
|
||||
switch (process.type()) {
|
||||
case ProcessType::Compositor:
|
||||
if (auto client = process.client<CompositorClient>(); client.has_value()) {
|
||||
if (auto on_death = move(client->on_death))
|
||||
on_death();
|
||||
}
|
||||
break;
|
||||
case ProcessType::ImageDecoder:
|
||||
if (auto client = process.client<ImageDecoderClient::Client>(); client.has_value()) {
|
||||
dbgln_if(WEBVIEW_PROCESS_DEBUG, "Restart ImageDecoder process");
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ public:
|
|||
#endif
|
||||
|
||||
ErrorOr<NonnullRefPtr<WebContentClient>> launch_web_content_process(ViewImplementation&);
|
||||
ErrorOr<void> connect_web_content_to_compositor(WebContentClient&);
|
||||
|
||||
virtual Optional<ViewImplementation&> active_web_view() const { return {}; }
|
||||
virtual Optional<ViewImplementation&> open_blank_new_tab(Web::HTML::ActivateTab) const { return {}; }
|
||||
|
|
@ -207,6 +208,7 @@ protected:
|
|||
private:
|
||||
ErrorOr<void> launch_services();
|
||||
void launch_spare_web_content_process();
|
||||
ErrorOr<void> launch_compositor_process();
|
||||
ErrorOr<void> launch_request_server();
|
||||
ErrorOr<void> launch_image_decoder_server();
|
||||
ErrorOr<void> launch_devtools_server();
|
||||
|
|
@ -277,6 +279,7 @@ private:
|
|||
|
||||
RefPtr<Requests::RequestClient> m_request_server_client;
|
||||
RefPtr<ImageDecoderClient::Client> m_image_decoder_client;
|
||||
RefPtr<CompositorClient> m_compositor_client;
|
||||
|
||||
RefPtr<WebContentClient> m_spare_web_content_process;
|
||||
bool m_has_queued_task_to_launch_spare_web_content_process { false };
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ set(SOURCES
|
|||
WebUI/ProcessesUI.cpp
|
||||
WebUI/SettingsUI.cpp
|
||||
WebUI/VersionUI.cpp
|
||||
CompositorClient.cpp
|
||||
)
|
||||
|
||||
set(GENERATED_SOURCES ${CURRENT_LIB_GENERATED})
|
||||
|
|
@ -48,12 +49,18 @@ embed_as_string(
|
|||
compile_ipc(UIProcessServer.ipc UIProcessServerEndpoint.h)
|
||||
compile_ipc(UIProcessClient.ipc UIProcessClientEndpoint.h)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/Services/Compositor)
|
||||
|
||||
if (NOT APPLE AND NOT CMAKE_INSTALL_LIBEXECDIR STREQUAL "libexec")
|
||||
set_source_files_properties(Utilities.cpp PROPERTIES COMPILE_DEFINITIONS LADYBIRD_LIBEXECDIR="${CMAKE_INSTALL_LIBEXECDIR}")
|
||||
endif()
|
||||
|
||||
set(GENERATED_SOURCES
|
||||
${GENERATED_SOURCES}
|
||||
../../Services/Compositor/CompositorControlClientEndpoint.h
|
||||
../../Services/Compositor/CompositorControlServerEndpoint.h
|
||||
../../Services/Compositor/CompositorWebContentClientEndpoint.h
|
||||
../../Services/Compositor/CompositorWebContentServerEndpoint.h
|
||||
../../Services/RequestServer/RequestClientEndpoint.h
|
||||
../../Services/RequestServer/RequestServerEndpoint.h
|
||||
../../Services/WebContent/CompositorClientEndpoint.h
|
||||
|
|
@ -71,6 +78,10 @@ set(GENERATED_SOURCES
|
|||
UIProcessServerEndpoint.h
|
||||
)
|
||||
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/Compositor/CompositorControlClient.ipc ${CMAKE_BINARY_DIR}/Services/Compositor/CompositorControlClientEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/Compositor/CompositorControlServer.ipc ${CMAKE_BINARY_DIR}/Services/Compositor/CompositorControlServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/Compositor/CompositorWebContentClient.ipc ${CMAKE_BINARY_DIR}/Services/Compositor/CompositorWebContentClientEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/Compositor/CompositorWebContentServer.ipc ${CMAKE_BINARY_DIR}/Services/Compositor/CompositorWebContentServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/CompositorClient.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/CompositorClientEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/CompositorServer.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/CompositorServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebContentClient.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebContentClientEndpoint.h)
|
||||
|
|
|
|||
31
Libraries/LibWebView/CompositorClient.cpp
Normal file
31
Libraries/LibWebView/CompositorClient.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWebView/CompositorClient.h>
|
||||
|
||||
#include <LibCore/EventLoop.h>
|
||||
|
||||
namespace WebView {
|
||||
|
||||
CompositorClient::CompositorClient(NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionToServer<CompositorControlClientEndpoint, CompositorControlServerEndpoint>(*this, move(transport))
|
||||
{
|
||||
}
|
||||
|
||||
void CompositorClient::die()
|
||||
{
|
||||
if (auto callback = move(on_death)) {
|
||||
Core::deferred_invoke([callback = move(callback)]() mutable {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CompositorClient::did_connect_web_content(i32)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
35
Libraries/LibWebView/CompositorClient.h
Normal file
35
Libraries/LibWebView/CompositorClient.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <Compositor/CompositorControlClientEndpoint.h>
|
||||
#include <Compositor/CompositorControlServerEndpoint.h>
|
||||
#include <LibIPC/ConnectionToServer.h>
|
||||
#include <LibWebView/Forward.h>
|
||||
|
||||
namespace WebView {
|
||||
|
||||
class WEBVIEW_API CompositorClient final
|
||||
: public IPC::ConnectionToServer<CompositorControlClientEndpoint, CompositorControlServerEndpoint>
|
||||
, public CompositorControlClientEndpoint {
|
||||
C_OBJECT_ABSTRACT(CompositorClient)
|
||||
|
||||
public:
|
||||
using InitTransport = Messages::CompositorControlServer::InitTransport;
|
||||
|
||||
explicit CompositorClient(NonnullOwnPtr<IPC::Transport>);
|
||||
|
||||
Function<void()> on_death;
|
||||
|
||||
private:
|
||||
virtual void die() override;
|
||||
|
||||
virtual void did_connect_web_content(i32 web_content_connection_id) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ class Action;
|
|||
class Application;
|
||||
class Autocomplete;
|
||||
class BookmarkStore;
|
||||
class CompositorClient;
|
||||
class CookieJar;
|
||||
class HistoryStore;
|
||||
class Menu;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <LibCore/Process.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/CompositorClient.h>
|
||||
#include <LibWebView/HelperProcess.h>
|
||||
#include <LibWebView/Utilities.h>
|
||||
|
||||
|
|
@ -165,6 +166,25 @@ ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_image_decoder_process(
|
|||
return launch_server_process<ImageDecoderClient::Client>("ImageDecoder"sv, arguments);
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<WebView::CompositorClient>> launch_compositor_process()
|
||||
{
|
||||
auto const& web_content_options = WebView::Application::web_content_options();
|
||||
|
||||
Vector<ByteString> arguments;
|
||||
if (web_content_options.force_cpu_painting == WebView::ForceCPUPainting::Yes)
|
||||
arguments.append("--force-cpu-painting"sv);
|
||||
if (web_content_options.force_fontconfig == WebView::ForceFontconfig::Yes)
|
||||
arguments.append("--force-fontconfig"sv);
|
||||
if (web_content_options.enable_async_scrolling == EnableAsyncScrolling::No)
|
||||
arguments.append("--disable-async-scrolling"sv);
|
||||
if (auto server = mach_server_name(); server.has_value()) {
|
||||
arguments.append("--mach-server-name"sv);
|
||||
arguments.append(server.value());
|
||||
}
|
||||
|
||||
return launch_server_process<WebView::CompositorClient>("Compositor"sv, move(arguments));
|
||||
}
|
||||
|
||||
ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(Web::Bindings::AgentType type)
|
||||
{
|
||||
auto const& web_content_options = WebView::Application::web_content_options();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ WEBVIEW_API ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_web_content
|
|||
WEBVIEW_API ErrorOr<NonnullRefPtr<WebView::WebContentClient>> launch_spare_web_content_process();
|
||||
|
||||
WEBVIEW_API ErrorOr<NonnullRefPtr<ImageDecoderClient::Client>> launch_image_decoder_process();
|
||||
WEBVIEW_API ErrorOr<NonnullRefPtr<WebView::CompositorClient>> launch_compositor_process();
|
||||
WEBVIEW_API ErrorOr<NonnullRefPtr<Web::HTML::WebWorkerClient>> launch_web_worker_process(Web::Bindings::AgentType);
|
||||
WEBVIEW_API ErrorOr<NonnullRefPtr<Requests::RequestClient>> launch_request_server_process();
|
||||
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ enum class EnableContentBlocker {
|
|||
Yes,
|
||||
};
|
||||
|
||||
enum class EnableCompositorProcess {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
struct BrowserOptions {
|
||||
Vector<URL::URL> urls;
|
||||
Vector<ByteString> raw_urls;
|
||||
|
|
@ -92,6 +97,7 @@ struct BrowserOptions {
|
|||
Optional<DNSSettings> dns_settings {};
|
||||
Optional<u16> devtools_port;
|
||||
EnableContentBlocker enable_content_blocker { EnableContentBlocker::Yes };
|
||||
EnableCompositorProcess enable_compositor_process { EnableCompositorProcess::No };
|
||||
Vector<ByteString> content_blocker_list_paths {};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ ProcessType process_type_from_name(StringView name)
|
|||
{
|
||||
if (name == "Browser"sv)
|
||||
return ProcessType::Browser;
|
||||
if (name == "Compositor"sv)
|
||||
return ProcessType::Compositor;
|
||||
if (name == "WebContent"sv)
|
||||
return ProcessType::WebContent;
|
||||
if (name == "WebWorker"sv)
|
||||
|
|
@ -35,6 +37,8 @@ StringView process_name_from_type(ProcessType type)
|
|||
switch (type) {
|
||||
case ProcessType::Browser:
|
||||
return "Browser"sv;
|
||||
case ProcessType::Compositor:
|
||||
return "Compositor"sv;
|
||||
case ProcessType::WebContent:
|
||||
return "WebContent"sv;
|
||||
case ProcessType::WebWorker:
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ namespace WebView {
|
|||
|
||||
enum class ProcessType : u8 {
|
||||
Browser,
|
||||
Compositor,
|
||||
WebContent,
|
||||
WebWorker,
|
||||
RequestServer,
|
||||
|
|
|
|||
|
|
@ -128,6 +128,11 @@ void WebContentClient::assign_view(Badge<Application>, ViewImplementation& view)
|
|||
m_views.set(0, view);
|
||||
}
|
||||
|
||||
void WebContentClient::set_compositor_connection_id(Badge<Application>, i32 compositor_connection_id)
|
||||
{
|
||||
m_compositor_connection_id = compositor_connection_id;
|
||||
}
|
||||
|
||||
void WebContentClient::register_view(u64 page_id, ViewImplementation& view)
|
||||
{
|
||||
VERIFY(page_id > 0);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ public:
|
|||
~WebContentClient();
|
||||
|
||||
void assign_view(Badge<Application>, ViewImplementation&);
|
||||
void set_compositor_connection_id(Badge<Application>, i32);
|
||||
Optional<i32> compositor_connection_id(Badge<Application>) const { return m_compositor_connection_id; }
|
||||
void register_view(u64 page_id, ViewImplementation&);
|
||||
void unregister_view(u64 page_id);
|
||||
|
||||
|
|
@ -168,6 +170,7 @@ private:
|
|||
|
||||
HashMap<u64, NonnullRawPtr<ViewImplementation>> m_views;
|
||||
HashMap<u64, String> m_history_recorded_urls_for_current_load;
|
||||
Optional<i32> m_compositor_connection_id;
|
||||
|
||||
ProcessHandle m_process_handle;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
add_subdirectory(Compositor)
|
||||
add_subdirectory(ImageDecoder)
|
||||
add_subdirectory(RequestServer)
|
||||
add_subdirectory(WebContent)
|
||||
|
|
|
|||
28
Services/Compositor/CMakeLists.txt
Normal file
28
Services/Compositor/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
set(SOURCES
|
||||
ConnectionFromClient.cpp
|
||||
ConnectionFromWebContent.cpp
|
||||
)
|
||||
|
||||
set(GENERATED_SOURCES
|
||||
CompositorControlClientEndpoint.h
|
||||
CompositorControlServerEndpoint.h
|
||||
CompositorWebContentClientEndpoint.h
|
||||
CompositorWebContentServerEndpoint.h
|
||||
)
|
||||
|
||||
add_library(compositorservice STATIC ${SOURCES} ${GENERATED_SOURCES})
|
||||
ladybird_generated_sources(compositorservice)
|
||||
|
||||
add_executable(Compositor main.cpp)
|
||||
|
||||
target_include_directories(compositorservice PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../..)
|
||||
target_include_directories(compositorservice PRIVATE ${LADYBIRD_SOURCE_DIR}/Services/)
|
||||
|
||||
target_link_libraries(Compositor PRIVATE compositorservice LibCore LibGfx LibIPC LibMain LibWebView)
|
||||
target_link_libraries(compositorservice PRIVATE LibCore LibIPC)
|
||||
|
||||
if (WIN32)
|
||||
target_include_directories(Compositor PRIVATE $<BUILD_INTERFACE:${PTHREAD_INCLUDE_DIR}>)
|
||||
target_include_directories(compositorservice PRIVATE $<BUILD_INTERFACE:${PTHREAD_INCLUDE_DIR}>)
|
||||
ladybird_windows_bin(Compositor CONSOLE)
|
||||
endif()
|
||||
4
Services/Compositor/CompositorControlClient.ipc
Normal file
4
Services/Compositor/CompositorControlClient.ipc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
endpoint CompositorControlClient
|
||||
{
|
||||
did_connect_web_content(i32 web_content_connection_id) =|
|
||||
}
|
||||
8
Services/Compositor/CompositorControlServer.ipc
Normal file
8
Services/Compositor/CompositorControlServer.ipc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include <LibIPC/TransportHandle.h>
|
||||
|
||||
endpoint CompositorControlServer
|
||||
{
|
||||
init_transport(int peer_pid) => (int peer_pid)
|
||||
|
||||
connect_web_content() => (IPC::TransportHandle handle, i32 web_content_connection_id)
|
||||
}
|
||||
4
Services/Compositor/CompositorWebContentClient.ipc
Normal file
4
Services/Compositor/CompositorWebContentClient.ipc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
endpoint CompositorWebContentClient
|
||||
{
|
||||
did_connect() =|
|
||||
}
|
||||
4
Services/Compositor/CompositorWebContentServer.ipc
Normal file
4
Services/Compositor/CompositorWebContentServer.ipc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
endpoint CompositorWebContentServer
|
||||
{
|
||||
ping() =|
|
||||
}
|
||||
47
Services/Compositor/ConnectionFromClient.cpp
Normal file
47
Services/Compositor/ConnectionFromClient.cpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Compositor/ConnectionFromClient.h>
|
||||
#include <Compositor/ConnectionFromWebContent.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/Transport.h>
|
||||
|
||||
namespace Compositor {
|
||||
|
||||
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionFromClient<CompositorControlClientEndpoint, CompositorControlServerEndpoint>(*this, move(transport), 1)
|
||||
{
|
||||
}
|
||||
|
||||
void ConnectionFromClient::die()
|
||||
{
|
||||
Core::EventLoop::current().quit(0);
|
||||
}
|
||||
|
||||
Messages::CompositorControlServer::InitTransportResponse ConnectionFromClient::init_transport([[maybe_unused]] int peer_pid)
|
||||
{
|
||||
#ifdef AK_OS_WINDOWS
|
||||
m_transport->set_peer_pid(peer_pid);
|
||||
return Core::System::getpid();
|
||||
#endif
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
Messages::CompositorControlServer::ConnectWebContentResponse ConnectionFromClient::connect_web_content()
|
||||
{
|
||||
auto paired_transport = MUST(IPC::Transport::create_paired());
|
||||
auto web_content_connection_id = m_next_web_content_connection_id++;
|
||||
auto connection = ConnectionFromWebContent::construct(move(paired_transport.local), web_content_connection_id);
|
||||
connection->on_death = [this](auto& dead) {
|
||||
m_web_content_connections.remove(dead.client_id());
|
||||
};
|
||||
m_web_content_connections.set(web_content_connection_id, move(connection));
|
||||
async_did_connect_web_content(web_content_connection_id);
|
||||
return { move(paired_transport.remote_handle), web_content_connection_id };
|
||||
}
|
||||
|
||||
}
|
||||
35
Services/Compositor/ConnectionFromClient.h
Normal file
35
Services/Compositor/ConnectionFromClient.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <Compositor/CompositorControlClientEndpoint.h>
|
||||
#include <Compositor/CompositorControlServerEndpoint.h>
|
||||
#include <Compositor/Forward.h>
|
||||
#include <LibIPC/ConnectionFromClient.h>
|
||||
|
||||
namespace Compositor {
|
||||
|
||||
class ConnectionFromClient final
|
||||
: public IPC::ConnectionFromClient<CompositorControlClientEndpoint, CompositorControlServerEndpoint> {
|
||||
C_OBJECT(ConnectionFromClient)
|
||||
|
||||
public:
|
||||
virtual void die() override;
|
||||
|
||||
private:
|
||||
explicit ConnectionFromClient(NonnullOwnPtr<IPC::Transport>);
|
||||
|
||||
virtual Messages::CompositorControlServer::InitTransportResponse init_transport(int peer_pid) override;
|
||||
virtual Messages::CompositorControlServer::ConnectWebContentResponse connect_web_content() override;
|
||||
|
||||
i32 m_next_web_content_connection_id { 1 };
|
||||
HashMap<i32, NonnullRefPtr<ConnectionFromWebContent>> m_web_content_connections;
|
||||
};
|
||||
|
||||
}
|
||||
26
Services/Compositor/ConnectionFromWebContent.cpp
Normal file
26
Services/Compositor/ConnectionFromWebContent.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Compositor/ConnectionFromWebContent.h>
|
||||
|
||||
namespace Compositor {
|
||||
|
||||
ConnectionFromWebContent::ConnectionFromWebContent(NonnullOwnPtr<IPC::Transport> transport, int client_id)
|
||||
: IPC::ConnectionFromClient<CompositorWebContentClientEndpoint, CompositorWebContentServerEndpoint>(*this, move(transport), client_id)
|
||||
{
|
||||
}
|
||||
|
||||
void ConnectionFromWebContent::die()
|
||||
{
|
||||
if (on_death)
|
||||
on_death(*this);
|
||||
}
|
||||
|
||||
void ConnectionFromWebContent::ping()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
31
Services/Compositor/ConnectionFromWebContent.h
Normal file
31
Services/Compositor/ConnectionFromWebContent.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <Compositor/CompositorWebContentClientEndpoint.h>
|
||||
#include <Compositor/CompositorWebContentServerEndpoint.h>
|
||||
#include <LibIPC/ConnectionFromClient.h>
|
||||
|
||||
namespace Compositor {
|
||||
|
||||
class ConnectionFromWebContent final
|
||||
: public IPC::ConnectionFromClient<CompositorWebContentClientEndpoint, CompositorWebContentServerEndpoint> {
|
||||
C_OBJECT(ConnectionFromWebContent)
|
||||
|
||||
public:
|
||||
virtual void die() override;
|
||||
|
||||
Function<void(ConnectionFromWebContent&)> on_death;
|
||||
|
||||
private:
|
||||
explicit ConnectionFromWebContent(NonnullOwnPtr<IPC::Transport>, int client_id);
|
||||
|
||||
virtual void ping() override;
|
||||
};
|
||||
|
||||
}
|
||||
14
Services/Compositor/Forward.h
Normal file
14
Services/Compositor/Forward.h
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Compositor {
|
||||
|
||||
class ConnectionFromClient;
|
||||
class ConnectionFromWebContent;
|
||||
|
||||
}
|
||||
53
Services/Compositor/main.cpp
Normal file
53
Services/Compositor/main.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <Compositor/ConnectionFromClient.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/Process.h>
|
||||
#include <LibGfx/Font/FontDatabase.h>
|
||||
#include <LibGfx/Font/PathFontProvider.h>
|
||||
#include <LibGfx/SkiaBackendContext.h>
|
||||
#include <LibIPC/SingleServer.h>
|
||||
#include <LibMain/Main.h>
|
||||
#include <LibWebView/Utilities.h>
|
||||
|
||||
ErrorOr<int> ladybird_main(Main::Arguments arguments)
|
||||
{
|
||||
AK::set_rich_debug_enabled(true);
|
||||
|
||||
StringView mach_server_name;
|
||||
bool wait_for_debugger = false;
|
||||
bool force_cpu_painting = false;
|
||||
bool force_fontconfig = false;
|
||||
bool disable_async_scrolling = false;
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_option(mach_server_name, "Mach server name", "mach-server-name", 0, "mach_server_name");
|
||||
args_parser.add_option(wait_for_debugger, "Wait for debugger", "wait-for-debugger");
|
||||
args_parser.add_option(force_cpu_painting, "Force CPU painting", "force-cpu-painting");
|
||||
args_parser.add_option(force_fontconfig, "Force using fontconfig for font loading", "force-fontconfig");
|
||||
args_parser.add_option(disable_async_scrolling, "Disable async scrolling", "disable-async-scrolling");
|
||||
args_parser.parse(arguments);
|
||||
|
||||
if (wait_for_debugger)
|
||||
Core::Process::wait_for_debugger_and_break();
|
||||
|
||||
WebView::platform_init();
|
||||
auto& font_provider = static_cast<Gfx::PathFontProvider&>(Gfx::FontDatabase::the().install_system_font_provider(make<Gfx::PathFontProvider>()));
|
||||
if (force_fontconfig)
|
||||
font_provider.set_name_but_fixme_should_create_custom_system_font_provider("FontConfig"_string);
|
||||
|
||||
if (!force_cpu_painting)
|
||||
Gfx::SkiaBackendContext::initialize_gpu_backend();
|
||||
|
||||
Core::EventLoop event_loop;
|
||||
auto client = TRY(IPC::take_over_accepted_client_from_system_server<Compositor::ConnectionFromClient>(mach_server_name));
|
||||
(void)client;
|
||||
(void)disable_async_scrolling;
|
||||
|
||||
return event_loop.exec();
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
include(audio)
|
||||
|
||||
set(SOURCES
|
||||
CompositorConnection.cpp
|
||||
ConnectionFromClient.cpp
|
||||
ConsoleGlobalEnvironmentExtensions.cpp
|
||||
DevToolsConsoleClient.cpp
|
||||
|
|
|
|||
24
Services/WebContent/CompositorConnection.cpp
Normal file
24
Services/WebContent/CompositorConnection.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <WebContent/CompositorConnection.h>
|
||||
|
||||
namespace WebContent {
|
||||
|
||||
CompositorConnection::CompositorConnection(NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionToServer<CompositorWebContentClientEndpoint, CompositorWebContentServerEndpoint>(*this, move(transport))
|
||||
{
|
||||
}
|
||||
|
||||
void CompositorConnection::die()
|
||||
{
|
||||
}
|
||||
|
||||
void CompositorConnection::did_connect()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
29
Services/WebContent/CompositorConnection.h
Normal file
29
Services/WebContent/CompositorConnection.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2026, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Compositor/CompositorWebContentClientEndpoint.h>
|
||||
#include <Compositor/CompositorWebContentServerEndpoint.h>
|
||||
#include <LibIPC/ConnectionToServer.h>
|
||||
|
||||
namespace WebContent {
|
||||
|
||||
class CompositorConnection final
|
||||
: public IPC::ConnectionToServer<CompositorWebContentClientEndpoint, CompositorWebContentServerEndpoint>
|
||||
, public CompositorWebContentClientEndpoint {
|
||||
C_OBJECT_ABSTRACT(CompositorConnection)
|
||||
|
||||
public:
|
||||
explicit CompositorConnection(NonnullOwnPtr<IPC::Transport>);
|
||||
|
||||
private:
|
||||
virtual void die() override;
|
||||
|
||||
virtual void did_connect() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -61,6 +61,7 @@
|
|||
#include <LibWeb/Worker/WebWorkerClient.h>
|
||||
#include <LibWebView/Attribute.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
#include <WebContent/CompositorConnection.h>
|
||||
#include <WebContent/ConnectionFromClient.h>
|
||||
#include <WebContent/PageClient.h>
|
||||
#include <WebContent/PageHost.h>
|
||||
|
|
@ -155,6 +156,11 @@ void ConnectionFromClient::connect_to_compositor(IPC::TransportHandle handle)
|
|||
m_page_host->attach_compositor_ui_client(move(handle));
|
||||
}
|
||||
|
||||
void ConnectionFromClient::connect_to_compositor_process(IPC::TransportHandle handle)
|
||||
{
|
||||
(void)handle;
|
||||
}
|
||||
|
||||
void ConnectionFromClient::connect_to_request_server(IPC::TransportHandle handle)
|
||||
{
|
||||
if (on_request_server_connection)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Queue.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <LibCore/AnonymousBuffer.h>
|
||||
#include <LibGC/Root.h>
|
||||
|
|
@ -68,6 +69,7 @@ private:
|
|||
virtual void connect_to_request_server(IPC::TransportHandle handle) override;
|
||||
virtual void connect_to_image_decoder(IPC::TransportHandle handle) override;
|
||||
virtual void connect_to_compositor(IPC::TransportHandle handle) override;
|
||||
virtual void connect_to_compositor_process(IPC::TransportHandle handle) override;
|
||||
virtual void update_system_theme(u64 page_id, Core::AnonymousBuffer) override;
|
||||
virtual void update_screen_rects(u64 page_id, Vector<Web::DevicePixelRect>, u32) override;
|
||||
virtual void load_url(u64 page_id, URL::URL) override;
|
||||
|
|
@ -185,6 +187,7 @@ private:
|
|||
void enqueue_input_event(Web::QueuedInputEvent);
|
||||
|
||||
Queue<Web::QueuedInputEvent> m_input_event_queue;
|
||||
RefPtr<CompositorConnection> m_compositor_connection;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
namespace WebContent {
|
||||
|
||||
class CompositorConnection;
|
||||
class ConnectionFromClient;
|
||||
class ConsoleGlobalEnvironmentExtensions;
|
||||
class DevToolsConsoleClient;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ endpoint WebContentServer
|
|||
connect_to_request_server(IPC::TransportHandle handle) =|
|
||||
connect_to_image_decoder(IPC::TransportHandle handle) =|
|
||||
connect_to_compositor(IPC::TransportHandle handle) =|
|
||||
connect_to_compositor_process(IPC::TransportHandle handle) =|
|
||||
|
||||
update_system_theme(u64 page_id, Core::AnonymousBuffer theme_buffer) =|
|
||||
update_screen_rects(u64 page_id, Vector<Web::DevicePixelRect> rects, u32 main_screen_index) =|
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ else()
|
|||
)
|
||||
endif()
|
||||
|
||||
set(ladybird_helper_processes ImageDecoder RequestServer WebContent WebWorker)
|
||||
set(ladybird_helper_processes Compositor ImageDecoder RequestServer WebContent WebWorker)
|
||||
|
||||
add_dependencies(ladybird ${ladybird_helper_processes})
|
||||
# FIXME: Increase support for building targets on Windows
|
||||
|
|
|
|||
Loading…
Reference in a new issue