ladybird/Libraries/LibWebView/CompositorClient.cpp

54 lines
1.8 KiB
C++
Raw Permalink Normal View History

/*
* Copyright (c) 2026, the Ladybird developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWebView/CompositorClient.h>
#include <LibCore/EventLoop.h>
LibWebView+WebContent: Add feature-gated Compositor process backend 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.
2026-05-22 11:17:27 -03:00
#include <LibWebView/WebContentClient.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();
});
}
}
LibWebView+WebContent: Add feature-gated Compositor process backend 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.
2026-05-22 11:17:27 -03:00
void CompositorClient::did_allocate_backing_stores(Web::Compositor::CompositorContextId context_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store)
{
LibWebView+WebContent: Add feature-gated Compositor process backend 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.
2026-05-22 11:17:27 -03:00
auto web_content_client = WebContentClient::client_for_compositor_context_id(context_id);
if (!web_content_client.has_value())
return;
auto page_id = web_content_client->page_id_for_compositor_context_id(context_id);
VERIFY(page_id.has_value());
web_content_client->did_present_backing_stores(*page_id, front_bitmap_id, move(front_backing_store), back_bitmap_id, move(back_backing_store));
}
LibWebView+WebContent: Add feature-gated Compositor process backend 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.
2026-05-22 11:17:27 -03:00
void CompositorClient::did_present_frame(Web::Compositor::CompositorContextId context_id, Gfx::IntRect content_rect, i32 bitmap_id)
{
LibWebView+WebContent: Add feature-gated Compositor process backend 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.
2026-05-22 11:17:27 -03:00
auto web_content_client = WebContentClient::client_for_compositor_context_id(context_id);
if (web_content_client.has_value()) {
auto page_id = web_content_client->page_id_for_compositor_context_id(context_id);
VERIFY(page_id.has_value());
web_content_client->did_present_bitmap(*page_id, content_rect, bitmap_id);
return;
}
async_presented_bitmap_ready_to_paint(context_id, bitmap_id);
}
}