Rename IOCompositor to Paint (#41176)

For a long time, the "Compositor" hasn't done any compositing. This is
handled by WebRender. In addition the "Compositor" does many other
tasks. This change renames `IOCompositor` to `Paint`.

`Paint` is Servo's paint subsystem and contains multiple `Painter`s.
This change does not rename the crate; that will be done in a
followup change.

Testing: This just renames types and updates comments, so no new tests
are necessary.

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson
2025-12-10 16:09:49 +01:00
committed by GitHub
parent 0e1ab937b3
commit 824f551f03
61 changed files with 592 additions and 629 deletions

View File

@@ -4,7 +4,7 @@
use base::Epoch; use base::Epoch;
use canvas_traits::canvas::*; use canvas_traits::canvas::*;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use euclid::default::{Point2D, Rect, Size2D, Transform2D}; use euclid::default::{Point2D, Rect, Size2D, Transform2D};
use pixels::Snapshot; use pixels::Snapshot;
use webrender_api::ImageKey; use webrender_api::ImageKey;
@@ -23,28 +23,28 @@ pub(crate) enum Filter {
pub(crate) struct CanvasData<DrawTarget: GenericDrawTarget> { pub(crate) struct CanvasData<DrawTarget: GenericDrawTarget> {
draw_target: DrawTarget, draw_target: DrawTarget,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
image_key: Option<ImageKey>, image_key: Option<ImageKey>,
} }
impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> { impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
pub(crate) fn new( pub(crate) fn new(
size: Size2D<u64>, size: Size2D<u64>,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
) -> CanvasData<DrawTarget> { ) -> CanvasData<DrawTarget> {
CanvasData { CanvasData {
draw_target: DrawTarget::new(size.max(MIN_WR_IMAGE_SIZE).cast()), draw_target: DrawTarget::new(size.max(MIN_WR_IMAGE_SIZE).cast()),
compositor_api, paint_api,
image_key: None, image_key: None,
} }
} }
pub(crate) fn set_image_key(&mut self, image_key: ImageKey) { pub(crate) fn set_image_key(&mut self, image_key: ImageKey) {
let (descriptor, data) = self.draw_target.image_descriptor_and_serializable_data(); let (descriptor, data) = self.draw_target.image_descriptor_and_serializable_data();
self.compositor_api.add_image(image_key, descriptor, data); self.paint_api.add_image(image_key, descriptor, data);
if let Some(old_image_key) = self.image_key.replace(image_key) { if let Some(old_image_key) = self.image_key.replace(image_key) {
self.compositor_api.delete_image(old_image_key); self.paint_api.delete_image(old_image_key);
} }
} }
@@ -322,7 +322,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
self.draw_target.image_descriptor_and_serializable_data() self.draw_target.image_descriptor_and_serializable_data()
}; };
self.compositor_api self.paint_api
.update_image(image_key, descriptor, data, canvas_epoch); .update_image(image_key, descriptor, data, canvas_epoch);
} }
@@ -440,7 +440,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
impl<D: GenericDrawTarget> Drop for CanvasData<D> { impl<D: GenericDrawTarget> Drop for CanvasData<D> {
fn drop(&mut self) { fn drop(&mut self) {
if let Some(image_key) = self.image_key { if let Some(image_key) = self.image_key {
self.compositor_api.delete_image(image_key); self.paint_api.delete_image(image_key);
} }
} }
} }

View File

@@ -9,7 +9,7 @@ use base::generic_channel::GenericSender;
use base::{Epoch, generic_channel}; use base::{Epoch, generic_channel};
use canvas_traits::ConstellationCanvasMsg; use canvas_traits::ConstellationCanvasMsg;
use canvas_traits::canvas::*; use canvas_traits::canvas::*;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use crossbeam_channel::{Sender, select, unbounded}; use crossbeam_channel::{Sender, select, unbounded};
use euclid::default::{Rect, Size2D, Transform2D}; use euclid::default::{Rect, Size2D, Transform2D};
use log::warn; use log::warn;
@@ -22,22 +22,22 @@ use crate::canvas_data::*;
pub struct CanvasPaintThread { pub struct CanvasPaintThread {
canvases: FxHashMap<CanvasId, Canvas>, canvases: FxHashMap<CanvasId, Canvas>,
next_canvas_id: CanvasId, next_canvas_id: CanvasId,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
} }
impl CanvasPaintThread { impl CanvasPaintThread {
fn new(compositor_api: CrossProcessCompositorApi) -> CanvasPaintThread { fn new(paint_api: CrossProcessPaintApi) -> CanvasPaintThread {
CanvasPaintThread { CanvasPaintThread {
canvases: FxHashMap::default(), canvases: FxHashMap::default(),
next_canvas_id: CanvasId(0), next_canvas_id: CanvasId(0),
compositor_api: compositor_api.clone(), paint_api: paint_api.clone(),
} }
} }
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to /// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
/// communicate with it. /// communicate with it.
pub fn start( pub fn start(
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) { ) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
let (ipc_sender, ipc_receiver) = generic_channel::channel::<CanvasMsg>().unwrap(); let (ipc_sender, ipc_receiver) = generic_channel::channel::<CanvasMsg>().unwrap();
let msg_receiver = ipc_receiver.route_preserving_errors(); let msg_receiver = ipc_receiver.route_preserving_errors();
@@ -46,7 +46,7 @@ impl CanvasPaintThread {
.name("Canvas".to_owned()) .name("Canvas".to_owned())
.spawn(move || { .spawn(move || {
let mut canvas_paint_thread = CanvasPaintThread::new( let mut canvas_paint_thread = CanvasPaintThread::new(
compositor_api); paint_api);
loop { loop {
select! { select! {
recv(msg_receiver) -> msg => { recv(msg_receiver) -> msg => {
@@ -97,7 +97,7 @@ impl CanvasPaintThread {
let canvas_id = self.next_canvas_id; let canvas_id = self.next_canvas_id;
self.next_canvas_id.0 += 1; self.next_canvas_id.0 += 1;
let canvas = Canvas::new(size, self.compositor_api.clone())?; let canvas = Canvas::new(size, self.paint_api.clone())?;
self.canvases.insert(canvas_id, canvas); self.canvases.insert(canvas_id, canvas);
Some(canvas_id) Some(canvas_id)
@@ -298,17 +298,15 @@ enum Canvas {
} }
impl Canvas { impl Canvas {
fn new(size: Size2D<u64>, compositor_api: CrossProcessCompositorApi) -> Option<Self> { fn new(size: Size2D<u64>, paint_api: CrossProcessPaintApi) -> Option<Self> {
match servo_config::pref!(dom_canvas_backend) match servo_config::pref!(dom_canvas_backend)
.to_lowercase() .to_lowercase()
.as_str() .as_str()
{ {
#[cfg(feature = "vello_cpu")] #[cfg(feature = "vello_cpu")]
"" | "auto" | "vello_cpu" => { "" | "auto" | "vello_cpu" => Some(Self::VelloCPU(CanvasData::new(size, paint_api))),
Some(Self::VelloCPU(CanvasData::new(size, compositor_api)))
},
#[cfg(feature = "vello")] #[cfg(feature = "vello")]
"" | "auto" | "vello" => Some(Self::Vello(CanvasData::new(size, compositor_api))), "" | "auto" | "vello" => Some(Self::Vello(CanvasData::new(size, paint_api))),
s => { s => {
warn!("Unknown 2D canvas backend: `{s}`"); warn!("Unknown 2D canvas backend: `{s}`");
None None

View File

@@ -8,7 +8,7 @@ use std::cell::Cell;
use std::rc::Rc; use std::rc::Rc;
use base::generic_channel::RoutedReceiver; use base::generic_channel::RoutedReceiver;
use compositing_traits::{CompositorMsg, CompositorProxy}; use compositing_traits::{PaintMessage, PaintProxy};
use constellation_traits::EmbedderToConstellationMessage; use constellation_traits::EmbedderToConstellationMessage;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use embedder_traits::{EventLoopWaker, ShutdownState}; use embedder_traits::{EventLoopWaker, ShutdownState};
@@ -16,13 +16,13 @@ use profile_traits::{mem, time};
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]
use webxr::WebXrRegistry; use webxr::WebXrRegistry;
pub use crate::compositor::{IOCompositor, WebRenderDebugOption}; pub use crate::paint::{Paint, WebRenderDebugOption};
#[macro_use] #[macro_use]
mod tracing; mod tracing;
mod compositor;
mod largest_contentful_paint_calculator; mod largest_contentful_paint_calculator;
mod paint;
mod painter; mod painter;
mod pinch_zoom; mod pinch_zoom;
mod pipeline_details; mod pipeline_details;
@@ -33,12 +33,12 @@ mod touch;
mod webrender_external_images; mod webrender_external_images;
mod webview_renderer; mod webview_renderer;
/// Data used to construct a compositor. /// Data used to initialize the `Paint` subsystem.
pub struct InitialCompositorState { pub struct InitialPaintState {
/// A channel to the compositor. /// A channel to `Paint`.
pub compositor_proxy: CompositorProxy, pub paint_proxy: PaintProxy,
/// A port on which messages inbound to the compositor can be received. /// A port on which messages inbound to `Paint` can be received.
pub receiver: RoutedReceiver<CompositorMsg>, pub receiver: RoutedReceiver<PaintMessage>,
/// A channel to the constellation. /// A channel to the constellation.
pub embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>, pub embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
/// A channel to the time profiler thread. /// A channel to the time profiler thread.

View File

@@ -15,7 +15,7 @@ use bitflags::bitflags;
use canvas_traits::webgl::{WebGLContextId, WebGLThreads}; use canvas_traits::webgl::{WebGLContextId, WebGLThreads};
use compositing_traits::rendering_context::RenderingContext; use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{ use compositing_traits::{
CompositorMsg, CompositorProxy, PainterSurfmanDetails, PainterSurfmanDetailsMap, PaintMessage, PaintProxy, PainterSurfmanDetails, PainterSurfmanDetailsMap,
WebRenderExternalImageIdManager, WebViewTrait, WebRenderExternalImageIdManager, WebViewTrait,
}; };
use constellation_traits::EmbedderToConstellationMessage; use constellation_traits::EmbedderToConstellationMessage;
@@ -47,7 +47,7 @@ use webrender::{CaptureBits, MemoryReport};
use webrender_api::units::{DevicePixel, DevicePoint}; use webrender_api::units::{DevicePixel, DevicePoint};
use webrender_api::{FontInstanceKey, FontKey, ImageKey}; use webrender_api::{FontInstanceKey, FontKey, ImageKey};
use crate::InitialCompositorState; use crate::InitialPaintState;
use crate::painter::Painter; use crate::painter::Painter;
use crate::webview_renderer::UnknownWebView; use crate::webview_renderer::UnknownWebView;
@@ -59,26 +59,46 @@ pub enum WebRenderDebugOption {
RenderTargetDebug, RenderTargetDebug,
} }
/// NB: Never block on the constellation, because sometimes the constellation blocks on us. /// [`Paint`] is Servo's rendering subsystem. It has a few responsibilities:
pub struct IOCompositor { ///
/// All of the [`Painters`] for this [`IOCompositor`]. Each [`Painter`] handles painting to /// 1. Maintain a WebRender instance for each [`RenderingContext`] that Servo knows about.
/// [`RenderingContext`]s are per-`WebView`, but more than one `WebView` can use the same
/// [`RenderingContext`]. This allows multiple `WebView`s to share the same WebRender
/// instance which is more efficient. This is useful for tabbed web browsers.
/// 2. Receive display lists from the layout of all of the currently active `Pipeline`s
/// (frames). These display lists are sent to WebRender, and new frames are generated.
/// Once the frame is ready the [`Painter`] for the WebRender instance will ask libservo
/// to inform the embedder that a new frame is ready so that it can trigger a paint.
/// 3. Drive animation and animation callback updates. Animation updates should ideally be
/// coordinated with the system vsync signal, so the `RefreshDriver` is exposed in the
/// API to allow the embedder to do this. The [`Painter`] then asks its `WebView`s to
/// update their rendering, which triggers layouts.
/// 4. Eagerly handle scrolling and touch events. In order to avoid latency when handling
/// these kind of actions, each [`Painter`] will eagerly process touch events and
/// perform panning and zooming operations on their WebRender contents -- informing the
/// WebView contents asynchronously.
///
/// `Paint` and all of its contained structs should **never** block on the Constellation,
/// because sometimes the Constellation blocks on us.
pub struct Paint {
/// All of the [`Painters`] for this [`Paint`]. Each [`Painter`] handles painting to
/// a single [`RenderingContext`]. /// a single [`RenderingContext`].
painters: Vec<Rc<RefCell<Painter>>>, painters: Vec<Rc<RefCell<Painter>>>,
/// A [`CompositorProxy`] which can be used to allow other parts of Servo to communicate /// A [`PaintProxy`] which can be used to allow other parts of Servo to communicate
/// with this [`IOCompositor`]. /// with this [`Paint`].
pub(crate) compositor_proxy: CompositorProxy, pub(crate) paint_proxy: PaintProxy,
/// An [`EventLoopWaker`] used to wake up the main embedder event loop when the renderer needs /// An [`EventLoopWaker`] used to wake up the main embedder event loop when the renderer needs
/// to run. /// to run.
pub(crate) event_loop_waker: Box<dyn EventLoopWaker>, pub(crate) event_loop_waker: Box<dyn EventLoopWaker>,
/// Tracks whether we are in the process of shutting down, or have shut down and should close /// Tracks whether we are in the process of shutting down, or have shut down and
/// the compositor. This is shared with the `Servo` instance. /// should shut down `Paint`. This is shared with the `Servo` instance.
shutdown_state: Rc<Cell<ShutdownState>>, shutdown_state: Rc<Cell<ShutdownState>>,
/// The port on which we receive messages. /// The port on which we receive messages.
compositor_receiver: RoutedReceiver<CompositorMsg>, paint_receiver: RoutedReceiver<PaintMessage>,
/// The channel on which messages can be sent to the constellation. /// The channel on which messages can be sent to the constellation.
pub(crate) embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>, pub(crate) embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
@@ -136,12 +156,12 @@ bitflags! {
} }
} }
impl IOCompositor { impl Paint {
pub fn new(state: InitialCompositorState) -> Rc<RefCell<Self>> { pub fn new(state: InitialPaintState) -> Rc<RefCell<Self>> {
let registration = state.mem_profiler_chan.prepare_memory_reporting( let registration = state.mem_profiler_chan.prepare_memory_reporting(
"compositor".into(), "paint".into(),
state.compositor_proxy.clone(), state.paint_proxy.clone(),
CompositorMsg::CollectMemoryReport, PaintMessage::CollectMemoryReport,
); );
let webrender_external_image_id_manager = WebRenderExternalImageIdManager::default(); let webrender_external_image_id_manager = WebRenderExternalImageIdManager::default();
@@ -153,7 +173,7 @@ impl IOCompositor {
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]
webxr_layer_grand_manager, webxr_layer_grand_manager,
} = WebGLComm::new( } = WebGLComm::new(
state.compositor_proxy.cross_process_compositor_api.clone(), state.paint_proxy.cross_process_paint_api.clone(),
webrender_external_image_id_manager.clone(), webrender_external_image_id_manager.clone(),
painter_surfman_details_map.clone(), painter_surfman_details_map.clone(),
); );
@@ -174,12 +194,12 @@ impl IOCompositor {
webxr_main_thread webxr_main_thread
}; };
Rc::new(RefCell::new(IOCompositor { Rc::new(RefCell::new(Paint {
painters: Default::default(), painters: Default::default(),
compositor_proxy: state.compositor_proxy, paint_proxy: state.paint_proxy,
event_loop_waker: state.event_loop_waker, event_loop_waker: state.event_loop_waker,
shutdown_state: state.shutdown_state, shutdown_state: state.shutdown_state,
compositor_receiver: state.receiver, paint_receiver: state.receiver,
embedder_to_constellation_sender: state.embedder_to_constellation_sender.clone(), embedder_to_constellation_sender: state.embedder_to_constellation_sender.clone(),
webrender_external_image_id_manager, webrender_external_image_id_manager,
webgl_threads, webgl_threads,
@@ -308,9 +328,9 @@ impl IOCompositor {
} }
pub fn finish_shutting_down(&self) { pub fn finish_shutting_down(&self) {
// Drain compositor port, sometimes messages contain channels that are blocking // Drain paint port, sometimes messages contain channels that are blocking
// another thread from finishing (i.e. SetFrameTree). // another thread from finishing (i.e. SetFrameTree).
while self.compositor_receiver.try_recv().is_ok() {} while self.paint_receiver.try_recv().is_ok() {}
let (webgl_exit_sender, webgl_exit_receiver) = let (webgl_exit_sender, webgl_exit_receiver) =
ipc::channel().expect("Failed to create IPC channel!"); ipc::channel().expect("Failed to create IPC channel!");
@@ -330,7 +350,7 @@ impl IOCompositor {
} }
} }
fn handle_browser_message(&self, msg: CompositorMsg) { fn handle_browser_message(&self, msg: PaintMessage) {
trace_msg_from_constellation!(msg, "{msg:?}"); trace_msg_from_constellation!(msg, "{msg:?}");
match self.shutdown_state() { match self.shutdown_state() {
@@ -340,16 +360,16 @@ impl IOCompositor {
return; return;
}, },
ShutdownState::FinishedShuttingDown => { ShutdownState::FinishedShuttingDown => {
// Messages to the compositor are ignored after shutdown is complete. // Messages to Paint are ignored after shutdown is complete.
return; return;
}, },
} }
match msg { match msg {
CompositorMsg::CollectMemoryReport(sender) => { PaintMessage::CollectMemoryReport(sender) => {
self.collect_memory_report(sender); self.collect_memory_report(sender);
}, },
CompositorMsg::ChangeRunningAnimationsState( PaintMessage::ChangeRunningAnimationsState(
webview_id, webview_id,
pipeline_id, pipeline_id,
animation_state, animation_state,
@@ -362,30 +382,30 @@ impl IOCompositor {
); );
} }
}, },
CompositorMsg::SetFrameTreeForWebView(webview_id, frame_tree) => { PaintMessage::SetFrameTreeForWebView(webview_id, frame_tree) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.set_frame_tree_for_webview(&frame_tree); painter.set_frame_tree_for_webview(&frame_tree);
} }
}, },
CompositorMsg::SetThrottled(webview_id, pipeline_id, throttled) => { PaintMessage::SetThrottled(webview_id, pipeline_id, throttled) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.set_throttled(webview_id, pipeline_id, throttled); painter.set_throttled(webview_id, pipeline_id, throttled);
} }
}, },
CompositorMsg::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => { PaintMessage::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source); painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source);
} }
}, },
CompositorMsg::NewWebRenderFrameReady(..) => { PaintMessage::NewWebRenderFrameReady(..) => {
unreachable!("New WebRender frames should be handled in the caller."); unreachable!("New WebRender frames should be handled in the caller.");
}, },
CompositorMsg::SendInitialTransaction(webview_id, pipeline_id) => { PaintMessage::SendInitialTransaction(webview_id, pipeline_id) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.send_initial_pipeline_transaction(webview_id, pipeline_id); painter.send_initial_pipeline_transaction(webview_id, pipeline_id);
} }
}, },
CompositorMsg::ScrollNodeByDelta( PaintMessage::ScrollNodeByDelta(
webview_id, webview_id,
pipeline_id, pipeline_id,
offset, offset,
@@ -400,12 +420,12 @@ impl IOCompositor {
); );
} }
}, },
CompositorMsg::ScrollViewportByDelta(webview_id, delta) => { PaintMessage::ScrollViewportByDelta(webview_id, delta) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.scroll_viewport_by_delta(webview_id, delta); painter.scroll_viewport_by_delta(webview_id, delta);
} }
}, },
CompositorMsg::UpdateEpoch { PaintMessage::UpdateEpoch {
webview_id, webview_id,
pipeline_id, pipeline_id,
epoch, epoch,
@@ -414,7 +434,7 @@ impl IOCompositor {
painter.update_epoch(webview_id, pipeline_id, epoch); painter.update_epoch(webview_id, pipeline_id, epoch);
} }
}, },
CompositorMsg::SendDisplayList { PaintMessage::SendDisplayList {
webview_id, webview_id,
display_list_descriptor, display_list_descriptor,
display_list_receiver, display_list_receiver,
@@ -427,25 +447,25 @@ impl IOCompositor {
); );
} }
}, },
CompositorMsg::GenerateFrame(painter_ids) => { PaintMessage::GenerateFrame(painter_ids) => {
for painter_id in painter_ids { for painter_id in painter_ids {
if let Some(mut painter) = self.maybe_painter_mut(painter_id) { if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
painter.generate_frame_for_script(); painter.generate_frame_for_script();
} }
} }
}, },
CompositorMsg::GenerateImageKey(webview_id, result_sender) => { PaintMessage::GenerateImageKey(webview_id, result_sender) => {
self.handle_generate_image_key(webview_id, result_sender); self.handle_generate_image_key(webview_id, result_sender);
}, },
CompositorMsg::GenerateImageKeysForPipeline(webview_id, pipeline_id) => { PaintMessage::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id); self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id);
}, },
CompositorMsg::UpdateImages(painter_id, updates) => { PaintMessage::UpdateImages(painter_id, updates) => {
if let Some(mut painter) = self.maybe_painter_mut(painter_id) { if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
painter.update_images(updates); painter.update_images(updates);
} }
}, },
CompositorMsg::DelayNewFrameForCanvas( PaintMessage::DelayNewFrameForCanvas(
webview_id, webview_id,
pipeline_id, pipeline_id,
canvas_epoch, canvas_epoch,
@@ -455,21 +475,21 @@ impl IOCompositor {
painter.delay_new_frames_for_canvas(pipeline_id, canvas_epoch, image_keys); painter.delay_new_frames_for_canvas(pipeline_id, canvas_epoch, image_keys);
} }
}, },
CompositorMsg::AddFont(painter_id, font_key, data, index) => { PaintMessage::AddFont(painter_id, font_key, data, index) => {
debug_assert!(painter_id == font_key.into()); debug_assert!(painter_id == font_key.into());
if let Some(mut painter) = self.maybe_painter_mut(painter_id) { if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
painter.add_font(font_key, data, index); painter.add_font(font_key, data, index);
} }
}, },
CompositorMsg::AddSystemFont(painter_id, font_key, native_handle) => { PaintMessage::AddSystemFont(painter_id, font_key, native_handle) => {
debug_assert!(painter_id == font_key.into()); debug_assert!(painter_id == font_key.into());
if let Some(mut painter) = self.maybe_painter_mut(painter_id) { if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
painter.add_system_font(font_key, native_handle); painter.add_system_font(font_key, native_handle);
} }
}, },
CompositorMsg::AddFontInstance( PaintMessage::AddFontInstance(
painter_id, painter_id,
font_instance_key, font_instance_key,
font_key, font_key,
@@ -484,12 +504,12 @@ impl IOCompositor {
painter.add_font_instance(font_instance_key, font_key, size, flags, variations); painter.add_font_instance(font_instance_key, font_key, size, flags, variations);
} }
}, },
CompositorMsg::RemoveFonts(painter_id, keys, instance_keys) => { PaintMessage::RemoveFonts(painter_id, keys, instance_keys) => {
if let Some(mut painter) = self.maybe_painter_mut(painter_id) { if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
painter.remove_fonts(keys, instance_keys); painter.remove_fonts(keys, instance_keys);
} }
}, },
CompositorMsg::GenerateFontKeys( PaintMessage::GenerateFontKeys(
number_of_font_keys, number_of_font_keys,
number_of_font_instance_keys, number_of_font_instance_keys,
result_sender, result_sender,
@@ -502,17 +522,17 @@ impl IOCompositor {
painter_id, painter_id,
); );
}, },
CompositorMsg::Viewport(webview_id, viewport_description) => { PaintMessage::Viewport(webview_id, viewport_description) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.set_viewport_description(webview_id, viewport_description); painter.set_viewport_description(webview_id, viewport_description);
} }
}, },
CompositorMsg::ScreenshotReadinessReponse(webview_id, pipelines_and_epochs) => { PaintMessage::ScreenshotReadinessReponse(webview_id, pipelines_and_epochs) => {
if let Some(painter) = self.maybe_painter(webview_id.into()) { if let Some(painter) = self.maybe_painter(webview_id.into()) {
painter.handle_screenshot_readiness_reply(webview_id, pipelines_and_epochs); painter.handle_screenshot_readiness_reply(webview_id, pipelines_and_epochs);
} }
}, },
CompositorMsg::SendLCPCandidate(lcp_candidate, webview_id, pipeline_id, epoch) => { PaintMessage::SendLCPCandidate(lcp_candidate, webview_id, pipeline_id, epoch) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.append_lcp_candidate(lcp_candidate, webview_id, pipeline_id, epoch); painter.append_lcp_candidate(lcp_candidate, webview_id, pipeline_id, epoch);
} }
@@ -565,7 +585,7 @@ impl IOCompositor {
.map(|painter| painter.borrow().scroll_trees_memory_usage(ops)) .map(|painter| painter.borrow().scroll_trees_memory_usage(ops))
.sum(); .sum();
reports.push(Report { reports.push(Report {
path: path!["compositor", "scroll-tree"], path: path!["paint", "scroll-tree"],
kind: ReportKind::ExplicitJemallocHeapSize, kind: ReportKind::ExplicitJemallocHeapSize,
size: scroll_trees_memory_usage, size: scroll_trees_memory_usage,
}); });
@@ -574,29 +594,29 @@ impl IOCompositor {
sender.send(ProcessReports::new(reports)); sender.send(ProcessReports::new(reports));
} }
/// Handle messages sent to the compositor during the shutdown process. In general, /// Handle messages sent to `Paint` during the shutdown process. In general,
/// the things the compositor can do in this state are limited. It's very important to /// the things `Paint` can do in this state are limited. It's very important to
/// answer any synchronous messages though as other threads might be waiting on the /// answer any synchronous messages though as other threads might be waiting on the
/// results to finish their own shut down process. We try to do as little as possible /// results to finish their own shut down process. We try to do as little as possible
/// during this time. /// during this time.
/// ///
/// When that involves generating WebRender ids, our approach here is to simply /// When that involves generating WebRender ids, our approach here is to simply
/// generate them, but assume they will never be used, since once shutting down the /// generate them, but assume they will never be used, since once shutting down
/// compositor no longer does any WebRender frame generation. /// `Paint` no longer does any WebRender frame generation.
fn handle_browser_message_while_shutting_down(&self, msg: CompositorMsg) { fn handle_browser_message_while_shutting_down(&self, msg: PaintMessage) {
match msg { match msg {
CompositorMsg::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => { PaintMessage::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) { if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source); painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source);
} }
}, },
CompositorMsg::GenerateImageKey(webview_id, result_sender) => { PaintMessage::GenerateImageKey(webview_id, result_sender) => {
self.handle_generate_image_key(webview_id, result_sender); self.handle_generate_image_key(webview_id, result_sender);
}, },
CompositorMsg::GenerateImageKeysForPipeline(webview_id, pipeline_id) => { PaintMessage::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id); self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id);
}, },
CompositorMsg::GenerateFontKeys( PaintMessage::GenerateFontKeys(
number_of_font_keys, number_of_font_keys,
number_of_font_instance_keys, number_of_font_instance_keys,
result_sender, result_sender,
@@ -668,20 +688,20 @@ impl IOCompositor {
.render(&self.time_profiler_chan); .render(&self.time_profiler_chan);
} }
/// Get the message receiver for this [`IOCompositor`]. /// Get the message receiver for this [`Paint`].
pub fn receiver(&self) -> &RoutedReceiver<CompositorMsg> { pub fn receiver(&self) -> &RoutedReceiver<PaintMessage> {
&self.compositor_receiver &self.paint_receiver
} }
#[servo_tracing::instrument(skip_all)] #[servo_tracing::instrument(skip_all)]
pub fn handle_messages(&self, mut messages: Vec<CompositorMsg>) { pub fn handle_messages(&self, mut messages: Vec<PaintMessage>) {
// Pull out the `NewWebRenderFrameReady` messages from the list of messages and handle them // Pull out the `NewWebRenderFrameReady` messages from the list of messages and handle them
// at the end of this function. This prevents overdraw when more than a single message of // at the end of this function. This prevents overdraw when more than a single message of
// this type of received. In addition, if any of these frames need a repaint, that reflected // this type of received. In addition, if any of these frames need a repaint, that reflected
// when calling `handle_new_webrender_frame_ready`. // when calling `handle_new_webrender_frame_ready`.
let mut saw_webrender_frame_ready_for_painter = HashMap::new(); let mut saw_webrender_frame_ready_for_painter = HashMap::new();
messages.retain(|message| match message { messages.retain(|message| match message {
CompositorMsg::NewWebRenderFrameReady(painter_id, _document_id, need_repaint) => { PaintMessage::NewWebRenderFrameReady(painter_id, _document_id, need_repaint) => {
if let Some(painter) = self.maybe_painter(*painter_id) { if let Some(painter) = self.maybe_painter(*painter_id) {
painter.decrement_pending_frames(); painter.decrement_pending_frames();
*saw_webrender_frame_ready_for_painter *saw_webrender_frame_ready_for_painter

View File

@@ -10,7 +10,7 @@ use std::sync::Arc;
use base::Epoch; use base::Epoch;
use base::cross_process_instant::CrossProcessInstant; use base::cross_process_instant::CrossProcessInstant;
use base::id::{PainterId, PipelineId, WebViewId}; use base::id::{PainterId, PipelineId, WebViewId};
use compositing_traits::display_list::{CompositorDisplayListInfo, ScrollType}; use compositing_traits::display_list::{PaintDisplayListInfo, ScrollType};
use compositing_traits::largest_contentful_paint_candidate::LCPCandidate; use compositing_traits::largest_contentful_paint_candidate::LCPCandidate;
use compositing_traits::rendering_context::RenderingContext; use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::viewport_description::ViewportDescription; use compositing_traits::viewport_description::ViewportDescription;
@@ -22,7 +22,7 @@ use constellation_traits::{EmbedderToConstellationMessage, PaintMetricEvent};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use dpi::PhysicalSize; use dpi::PhysicalSize;
use embedder_traits::{ use embedder_traits::{
CompositorHitTestResult, InputEvent, InputEventAndId, InputEventId, InputEventResult, InputEvent, InputEventAndId, InputEventId, InputEventResult, PaintHitTestResult,
ScreenshotCaptureError, Scroll, ViewportDetails, WebViewPoint, WebViewRect, ScreenshotCaptureError, Scroll, ViewportDetails, WebViewPoint, WebViewRect,
}; };
use euclid::{Point2D, Rect, Scale, Size2D}; use euclid::{Point2D, Rect, Scale, Size2D};
@@ -54,9 +54,9 @@ use webrender_api::{
}; };
use wr_malloc_size_of::MallocSizeOfOps; use wr_malloc_size_of::MallocSizeOfOps;
use crate::IOCompositor; use crate::Paint;
use crate::compositor::{RepaintReason, WebRenderDebugOption};
use crate::largest_contentful_paint_calculator::LargestContentfulPaintCalculator; use crate::largest_contentful_paint_calculator::LargestContentfulPaintCalculator;
use crate::paint::{RepaintReason, WebRenderDebugOption};
use crate::refresh_driver::{AnimationRefreshDriverObserver, BaseRefreshDriver}; use crate::refresh_driver::{AnimationRefreshDriverObserver, BaseRefreshDriver};
use crate::render_notifier::RenderNotifier; use crate::render_notifier::RenderNotifier;
use crate::screenshot::ScreenshotTaker; use crate::screenshot::ScreenshotTaker;
@@ -141,10 +141,7 @@ impl Drop for Painter {
} }
impl Painter { impl Painter {
pub(crate) fn new( pub(crate) fn new(rendering_context: Rc<dyn RenderingContext>, paint: &Paint) -> Self {
rendering_context: Rc<dyn RenderingContext>,
compositor: &IOCompositor,
) -> Self {
let webrender_gl = rendering_context.gleam_gl_api(); let webrender_gl = rendering_context.gleam_gl_api();
// Make sure the gl context is made current. // Make sure the gl context is made current.
@@ -153,31 +150,29 @@ impl Painter {
} }
debug_assert_eq!(webrender_gl.get_error(), gleam::gl::NO_ERROR,); debug_assert_eq!(webrender_gl.get_error(), gleam::gl::NO_ERROR,);
let id_manager = compositor.webrender_external_image_id_manager(); let id_manager = paint.webrender_external_image_id_manager();
let mut external_image_handlers = Box::new(WebRenderExternalImageHandlers::new(id_manager)); let mut external_image_handlers = Box::new(WebRenderExternalImageHandlers::new(id_manager));
// Set WebRender external image handler for WebGL textures. // Set WebRender external image handler for WebGL textures.
let image_handler = Box::new(WebGLExternalImages::new( let image_handler = Box::new(WebGLExternalImages::new(
compositor.webgl_threads(), paint.webgl_threads(),
rendering_context.clone(), rendering_context.clone(),
compositor.swap_chains.clone(), paint.swap_chains.clone(),
compositor.busy_webgl_contexts_map.clone(), paint.busy_webgl_contexts_map.clone(),
)); ));
external_image_handlers.set_handler(image_handler, WebRenderImageHandlerType::WebGl); external_image_handlers.set_handler(image_handler, WebRenderImageHandlerType::WebGl);
#[cfg(feature = "webgpu")] #[cfg(feature = "webgpu")]
external_image_handlers.set_handler( external_image_handlers.set_handler(
Box::new(webgpu::WebGpuExternalImages::new( Box::new(webgpu::WebGpuExternalImages::new(paint.webgpu_image_map())),
compositor.webgpu_image_map(),
)),
WebRenderImageHandlerType::WebGpu, WebRenderImageHandlerType::WebGpu,
); );
WindowGLContext::initialize_image_handler(&mut external_image_handlers); WindowGLContext::initialize_image_handler(&mut external_image_handlers);
let embedder_to_constellation_sender = compositor.embedder_to_constellation_sender.clone(); let embedder_to_constellation_sender = paint.embedder_to_constellation_sender.clone();
let refresh_driver = Rc::new(BaseRefreshDriver::new( let refresh_driver = Rc::new(BaseRefreshDriver::new(
compositor.event_loop_waker.clone_box(), paint.event_loop_waker.clone_box(),
rendering_context.refresh_driver(), rendering_context.refresh_driver(),
)); ));
let animation_refresh_driver_observer = Rc::new(AnimationRefreshDriverObserver::new( let animation_refresh_driver_observer = Rc::new(AnimationRefreshDriverObserver::new(
@@ -215,10 +210,7 @@ impl Painter {
let painter_id = PainterId::next(); let painter_id = PainterId::next();
let (mut webrender, webrender_api_sender) = webrender::create_webrender_instance( let (mut webrender, webrender_api_sender) = webrender::create_webrender_instance(
webrender_gl.clone(), webrender_gl.clone(),
Box::new(RenderNotifier::new( Box::new(RenderNotifier::new(painter_id, paint.paint_proxy.clone())),
painter_id,
compositor.compositor_proxy.clone(),
)),
webrender::WebRenderOptions { webrender::WebRenderOptions {
// We force the use of optimized shaders here because rendering is broken // We force the use of optimized shaders here because rendering is broken
// on Android emulators with unoptimized shaders. This is due to a known // on Android emulators with unoptimized shaders. This is due to a known
@@ -391,7 +383,7 @@ impl Painter {
self.rendering_context.prepare_for_rendering(); self.rendering_context.prepare_for_rendering();
time_profile!( time_profile!(
ProfilerCategory::Compositing, ProfilerCategory::Painting,
None, None,
time_profiler_channel.clone(), time_profiler_channel.clone(),
|| { || {
@@ -454,7 +446,7 @@ impl Painter {
match pipeline.first_paint_metric.get() { match pipeline.first_paint_metric.get() {
// We need to check whether the current epoch is later, because // We need to check whether the current epoch is later, because
// CrossProcessCompositorMessage::SendInitialTransaction sends an // CrossProcessPaintMessage::SendInitialTransaction sends an
// empty display list to WebRender which can happen before we receive // empty display list to WebRender which can happen before we receive
// the first "real" display list. // the first "real" display list.
PaintMetricState::Seen(epoch, first_reflow) if epoch <= current_epoch => { PaintMetricState::Seen(epoch, first_reflow) if epoch <= current_epoch => {
@@ -545,7 +537,7 @@ impl Painter {
webrender_api: &RenderApi, webrender_api: &RenderApi,
webrender_document: DocumentId, webrender_document: DocumentId,
point: DevicePoint, point: DevicePoint,
) -> Vec<CompositorHitTestResult> { ) -> Vec<PaintHitTestResult> {
// DevicePoint and WorldPoint are the same for us. // DevicePoint and WorldPoint are the same for us.
let world_point = WorldPoint::from_untyped(point.to_untyped()); let world_point = WorldPoint::from_untyped(point.to_untyped());
let results = webrender_api.hit_test(webrender_document, world_point); let results = webrender_api.hit_test(webrender_document, world_point);
@@ -556,7 +548,7 @@ impl Painter {
.map(|item| { .map(|item| {
let pipeline_id = item.pipeline.into(); let pipeline_id = item.pipeline.into();
let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline); let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline);
CompositorHitTestResult { PaintHitTestResult {
pipeline_id, pipeline_id,
point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()), point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()),
external_scroll_id, external_scroll_id,
@@ -819,7 +811,7 @@ impl Painter {
pipeline_id: PipelineId, pipeline_id: PipelineId,
pipeline_exit_source: PipelineExitSource, pipeline_exit_source: PipelineExitSource,
) { ) {
debug!("Compositor got pipeline exited: {webview_id:?} {pipeline_id:?}",); debug!("Paint got pipeline exited: {webview_id:?} {pipeline_id:?}",);
if let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) { if let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) {
webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source); webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source);
} }
@@ -932,13 +924,13 @@ impl Painter {
return warn!("Could not receive display list info: {error}"); return warn!("Could not receive display list info: {error}");
}, },
}; };
let display_list_info: CompositorDisplayListInfo = let display_list_info: PaintDisplayListInfo = match bincode::deserialize(&display_list_info)
match bincode::deserialize(&display_list_info) { {
Ok(display_list_info) => display_list_info, Ok(display_list_info) => display_list_info,
Err(error) => { Err(error) => {
return warn!("Could not deserialize display list info: {error}"); return warn!("Could not deserialize display list info: {error}");
}, },
}; };
let items_data = match display_list_receiver.recv() { let items_data = match display_list_receiver.recv() {
Ok(display_list_data) => display_list_data, Ok(display_list_data) => display_list_data,
Err(error) => { Err(error) => {
@@ -965,8 +957,7 @@ impl Painter {
}, },
display_list_descriptor, display_list_descriptor,
); );
let _span = let _span = profile_traits::trace_span!("PaintMessage::SendDisplayList",).entered();
profile_traits::trace_span!("ScriptToCompositorMsg::BuiltDisplayList",).entered();
let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) else { let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) else {
return warn!("Could not find WebView for incoming display list"); return warn!("Could not find WebView for incoming display list");
}; };

View File

@@ -30,8 +30,8 @@ pub(crate) struct PipelineDetails {
/// Whether to use less resources by stopping animations. /// Whether to use less resources by stopping animations.
pub throttled: bool, pub throttled: bool,
/// The compositor-side [ScrollTree]. This is used to allow finding and scrolling /// The `Paint`-side [ScrollTree]. This is used to allow finding and scrolling
/// nodes in the compositor before forwarding new offsets to WebRender. /// nodes in `Paint` before forwarding new offsets to WebRender.
pub scroll_tree: ScrollTree, pub scroll_tree: ScrollTree,
/// The paint metric status of the first paint. /// The paint metric status of the first paint.

View File

@@ -202,7 +202,7 @@ impl Default for TimerRefreshDriver {
fn default() -> Self { fn default() -> Self {
let (sender, receiver) = crossbeam_channel::unbounded::<TimerThreadMessage>(); let (sender, receiver) = crossbeam_channel::unbounded::<TimerThreadMessage>();
let join_handle = thread::Builder::new() let join_handle = thread::Builder::new()
.name(String::from("CompositorTimerThread")) .name(String::from("PaintTimerThread"))
.spawn(move || { .spawn(move || {
let mut scheduler = TimerScheduler::default(); let mut scheduler = TimerScheduler::default();

View File

@@ -3,20 +3,20 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base::id::PainterId; use base::id::PainterId;
use compositing_traits::{CompositorMsg, CompositorProxy}; use compositing_traits::{PaintMessage, PaintProxy};
use webrender_api::{DocumentId, FramePublishId, FrameReadyParams}; use webrender_api::{DocumentId, FramePublishId, FrameReadyParams};
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct RenderNotifier { pub(crate) struct RenderNotifier {
painter_id: PainterId, painter_id: PainterId,
compositor_proxy: CompositorProxy, paint_proxy: PaintProxy,
} }
impl RenderNotifier { impl RenderNotifier {
pub(crate) fn new(painter_id: PainterId, compositor_proxy: CompositorProxy) -> RenderNotifier { pub(crate) fn new(painter_id: PainterId, paint_proxy: PaintProxy) -> RenderNotifier {
RenderNotifier { RenderNotifier {
painter_id, painter_id,
compositor_proxy, paint_proxy,
} }
} }
} }
@@ -25,7 +25,7 @@ impl webrender_api::RenderNotifier for RenderNotifier {
fn clone(&self) -> Box<dyn webrender_api::RenderNotifier> { fn clone(&self) -> Box<dyn webrender_api::RenderNotifier> {
Box::new(RenderNotifier::new( Box::new(RenderNotifier::new(
self.painter_id, self.painter_id,
self.compositor_proxy.clone(), self.paint_proxy.clone(),
)) ))
} }
@@ -37,11 +37,10 @@ impl webrender_api::RenderNotifier for RenderNotifier {
_: FramePublishId, _: FramePublishId,
frame_ready_params: &FrameReadyParams, frame_ready_params: &FrameReadyParams,
) { ) {
self.compositor_proxy self.paint_proxy.send(PaintMessage::NewWebRenderFrameReady(
.send(CompositorMsg::NewWebRenderFrameReady( self.painter_id,
self.painter_id, document_id,
document_id, frame_ready_params.render,
frame_ready_params.render, ));
));
} }
} }

View File

@@ -13,7 +13,7 @@ use image::RgbaImage;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use webrender_api::units::{DeviceIntRect, DeviceRect}; use webrender_api::units::{DeviceIntRect, DeviceRect};
use crate::compositor::RepaintReason; use crate::paint::RepaintReason;
use crate::painter::Painter; use crate::painter::Painter;
pub(crate) struct ScreenshotRequest { pub(crate) struct ScreenshotRequest {

View File

@@ -6,7 +6,7 @@ use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
use base::id::WebViewId; use base::id::WebViewId;
use embedder_traits::{CompositorHitTestResult, InputEventId, Scroll, TouchEventType, TouchId}; use embedder_traits::{InputEventId, PaintHitTestResult, Scroll, TouchEventType, TouchId};
use euclid::{Point2D, Scale, Vector2D}; use euclid::{Point2D, Scale, Vector2D};
use log::{debug, error, warn}; use log::{debug, error, warn};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
@@ -14,7 +14,7 @@ use style_traits::CSSPixel;
use webrender_api::units::{DevicePixel, DevicePoint, DeviceVector2D}; use webrender_api::units::{DevicePixel, DevicePoint, DeviceVector2D};
use self::TouchSequenceState::*; use self::TouchSequenceState::*;
use crate::compositor::RepaintReason; use crate::paint::RepaintReason;
use crate::painter::Painter; use crate::painter::Painter;
use crate::refresh_driver::{BaseRefreshDriver, RefreshDriverObserver}; use crate::refresh_driver::{BaseRefreshDriver, RefreshDriverObserver};
use crate::webview_renderer::{ScrollEvent, ScrollZoomEvent, WebViewRenderer}; use crate::webview_renderer::{ScrollEvent, ScrollZoomEvent, WebViewRenderer};
@@ -76,11 +76,11 @@ pub enum TouchMoveAllowed {
Pending, Pending,
} }
/// A cached [`CompositorHitTestResult`] to use during a touch sequence. This /// A cached [`PaintHitTestResult`] to use during a touch sequence. This
/// is kept so that the renderer doesn't have to constantly keep making hit tests /// is kept so that the renderer doesn't have to constantly keep making hit tests
/// while during panning and flinging actions. /// while during panning and flinging actions.
struct HitTestResultCache { struct HitTestResultCache {
value: CompositorHitTestResult, value: PaintHitTestResult,
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>, device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
} }
@@ -627,7 +627,7 @@ impl TouchHandler {
} }
} }
pub(crate) fn get_hit_test_result_cache_value(&self) -> Option<CompositorHitTestResult> { pub(crate) fn get_hit_test_result_cache_value(&self) -> Option<PaintHitTestResult> {
let sequence = self.touch_sequence_map.get(&self.current_sequence_id)?; let sequence = self.touch_sequence_map.get(&self.current_sequence_id)?;
if sequence.state == Finished { if sequence.state == Finished {
return None; return None;
@@ -640,7 +640,7 @@ impl TouchHandler {
pub(crate) fn set_hit_test_result_cache_value( pub(crate) fn set_hit_test_result_cache_value(
&mut self, &mut self,
value: CompositorHitTestResult, value: PaintHitTestResult,
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>, device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
) { ) {
if let Some(sequence) = self.touch_sequence_map.get_mut(&self.current_sequence_id) { if let Some(sequence) = self.touch_sequence_map.get_mut(&self.current_sequence_id) {

View File

@@ -3,8 +3,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/// Log an event from constellation at trace level. /// Log an event from constellation at trace level.
/// - To disable tracing: RUST_LOG='compositor<constellation@=off' /// - To disable tracing: RUST_LOG='paint<constellation@=off'
/// - To enable tracing: RUST_LOG='compositor<constellation@' /// - To enable tracing: RUST_LOG='paint<constellation@'
macro_rules! trace_msg_from_constellation { macro_rules! trace_msg_from_constellation {
// This macro only exists to put the docs in the same file as the target prefix, // This macro only exists to put the docs in the same file as the target prefix,
// so the macro definition is always the same. // so the macro definition is always the same.
@@ -23,11 +23,11 @@ mod from_constellation {
macro_rules! target { macro_rules! target {
($($name:literal)+) => { ($($name:literal)+) => {
concat!("compositor<constellation@", $($name),+) concat!("paint<constellation@", $($name),+)
}; };
} }
impl LogTarget for compositing_traits::CompositorMsg { impl LogTarget for compositing_traits::PaintMessage {
fn log_target(&self) -> &'static str { fn log_target(&self) -> &'static str {
match self { match self {
Self::ChangeRunningAnimationsState(..) => target!("ChangeRunningAnimationsState"), Self::ChangeRunningAnimationsState(..) => target!("ChangeRunningAnimationsState"),

View File

@@ -15,8 +15,8 @@ use compositing_traits::{PipelineExitSource, SendableFrameTree, WebViewTrait};
use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType}; use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType};
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use embedder_traits::{ use embedder_traits::{
AnimationState, CompositorHitTestResult, InputEvent, InputEventAndId, InputEventId, AnimationState, InputEvent, InputEventAndId, InputEventId, InputEventResult, MouseButton,
InputEventResult, MouseButton, MouseButtonAction, MouseButtonEvent, MouseMoveEvent, Scroll, MouseButtonAction, MouseButtonEvent, MouseMoveEvent, PaintHitTestResult, Scroll,
ScrollEvent as EmbedderScrollEvent, TouchEvent, TouchEventType, ViewportDetails, WebViewPoint, ScrollEvent as EmbedderScrollEvent, TouchEvent, TouchEventType, ViewportDetails, WebViewPoint,
WheelEvent, WheelEvent,
}; };
@@ -30,7 +30,7 @@ use webrender::RenderApi;
use webrender_api::units::{DevicePixel, DevicePoint, DeviceRect, DeviceVector2D, LayoutVector2D}; use webrender_api::units::{DevicePixel, DevicePoint, DeviceRect, DeviceVector2D, LayoutVector2D};
use webrender_api::{DocumentId, ExternalScrollId, ScrollLocation}; use webrender_api::{DocumentId, ExternalScrollId, ScrollLocation};
use crate::compositor::RepaintReason; use crate::paint::RepaintReason;
use crate::painter::Painter; use crate::painter::Painter;
use crate::pinch_zoom::PinchZoom; use crate::pinch_zoom::PinchZoom;
use crate::pipeline_details::PipelineDetails; use crate::pipeline_details::PipelineDetails;
@@ -59,7 +59,7 @@ pub(crate) enum ScrollZoomEvent {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct ScrollResult { pub(crate) struct ScrollResult {
pub hit_test_result: CompositorHitTestResult, pub hit_test_result: PaintHitTestResult,
/// The [`ExternalScrollId`] of the node that was actually scrolled. /// The [`ExternalScrollId`] of the node that was actually scrolled.
/// ///
/// Note that this is an inclusive ancestor of `external_scroll_id` in /// Note that this is an inclusive ancestor of `external_scroll_id` in
@@ -88,7 +88,7 @@ pub(crate) struct WebViewRenderer {
pub root_pipeline_id: Option<PipelineId>, pub root_pipeline_id: Option<PipelineId>,
/// The rectangle of the [`WebView`] in device pixels, which is the viewport. /// The rectangle of the [`WebView`] in device pixels, which is the viewport.
pub rect: DeviceRect, pub rect: DeviceRect,
/// Tracks details about each active pipeline that the compositor knows about. /// Tracks details about each active pipeline that `Paint` knows about.
pub pipelines: FxHashMap<PipelineId, PipelineDetails>, pub pipelines: FxHashMap<PipelineId, PipelineDetails>,
/// Pending scroll/zoom events. /// Pending scroll/zoom events.
pending_scroll_zoom_events: Vec<ScrollZoomEvent>, pending_scroll_zoom_events: Vec<ScrollZoomEvent>,
@@ -154,11 +154,7 @@ impl WebViewRenderer {
} }
} }
fn hit_test( fn hit_test(&self, webrender_api: &RenderApi, point: DevicePoint) -> Vec<PaintHitTestResult> {
&self,
webrender_api: &RenderApi,
point: DevicePoint,
) -> Vec<CompositorHitTestResult> {
Painter::hit_test_at_point_with_api_and_document( Painter::hit_test_at_point_with_api_and_document(
webrender_api, webrender_api,
self.webrender_document, self.webrender_document,
@@ -893,7 +889,7 @@ impl WebViewRenderer {
return (pinch_zoom_result, vec![]); return (pinch_zoom_result, vec![]);
}; };
let hit_test_result = CompositorHitTestResult { let hit_test_result = PaintHitTestResult {
pipeline_id: root_pipeline_id, pipeline_id: root_pipeline_id,
// It's difficult to get a good value for this as it needs to be piped // It's difficult to get a good value for this as it needs to be piped
// all the way through script and back here. // all the way through script and back here.
@@ -915,7 +911,7 @@ impl WebViewRenderer {
fn dispatch_scroll_event( fn dispatch_scroll_event(
&self, &self,
external_id: ExternalScrollId, external_id: ExternalScrollId,
hit_test_result: CompositorHitTestResult, hit_test_result: PaintHitTestResult,
) { ) {
let event = InputEvent::Scroll(EmbedderScrollEvent { external_id }).into(); let event = InputEvent::Scroll(EmbedderScrollEvent { external_id }).into();
let msg = EmbedderToConstellationMessage::ForwardInputEvent( let msg = EmbedderToConstellationMessage::ForwardInputEvent(

View File

@@ -42,10 +42,10 @@
//! +------------+ +------------+ //! +------------+ +------------+
//! ``` //! ```
// //
//! The constellation also maintains channels to threads, including: //! The constellation also maintains channels to other parts of Servo, including:
//! //!
//! * The script thread. //! * The script thread.
//! * The graphics compositor. //! * The `Paint` subsystem, which runs in the same thread as the `Servo` instance.
//! * The font cache, image cache, and resource manager, which load //! * The font cache, image cache, and resource manager, which load
//! and cache shared fonts, images, or other resources. //! and cache shared fonts, images, or other resources.
//! * The service worker manager. //! * The service worker manager.
@@ -66,7 +66,7 @@
//! sender to send some data. Servo tries to achieve deadlock-freedom by using the following //! sender to send some data. Servo tries to achieve deadlock-freedom by using the following
//! can-block-on relation: //! can-block-on relation:
//! //!
//! * Constellation can block on compositor //! * Constellation can block on `Paint`
//! * Constellation can block on embedder //! * Constellation can block on embedder
//! * Script can block on anything (other than script) //! * Script can block on anything (other than script)
//! * Blocking is transitive (if T1 can block on T2 and T2 can block on T3 then T1 can block on T3) //! * Blocking is transitive (if T1 can block on T2 and T2 can block on T3 then T1 can block on T3)
@@ -113,7 +113,7 @@ use canvas_traits::ConstellationCanvasMsg;
use canvas_traits::canvas::{CanvasId, CanvasMsg}; use canvas_traits::canvas::{CanvasId, CanvasMsg};
use canvas_traits::webgl::WebGLThreads; use canvas_traits::webgl::WebGLThreads;
use compositing_traits::{ use compositing_traits::{
CompositorMsg, CompositorProxy, PipelineExitSource, SendableFrameTree, PaintMessage, PaintProxy, PipelineExitSource, SendableFrameTree,
WebRenderExternalImageIdManager, WebRenderExternalImageIdManager,
}; };
use constellation_traits::{ use constellation_traits::{
@@ -133,11 +133,12 @@ use devtools_traits::{
use embedder_traits::resources::{self, Resource}; use embedder_traits::resources::{self, Resource};
use embedder_traits::user_content_manager::UserContentManager; use embedder_traits::user_content_manager::UserContentManager;
use embedder_traits::{ use embedder_traits::{
AnimationState, CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, AnimationState, EmbedderControlId, EmbedderControlResponse, EmbedderMsg, EmbedderProxy,
EmbedderMsg, EmbedderProxy, FocusSequenceNumber, InputEvent, InputEventAndId, JSValue, FocusSequenceNumber, InputEvent, InputEventAndId, JSValue, JavaScriptEvaluationError,
JavaScriptEvaluationError, JavaScriptEvaluationId, KeyboardEvent, MediaSessionActionType, JavaScriptEvaluationId, KeyboardEvent, MediaSessionActionType, MediaSessionEvent,
MediaSessionEvent, MediaSessionPlaybackState, MouseButton, MouseButtonAction, MouseButtonEvent, MediaSessionPlaybackState, MouseButton, MouseButtonAction, MouseButtonEvent,
Theme, ViewportDetails, WebDriverCommandMsg, WebDriverLoadStatus, WebDriverScriptCommand, PaintHitTestResult, Theme, ViewportDetails, WebDriverCommandMsg, WebDriverLoadStatus,
WebDriverScriptCommand,
}; };
use euclid::Size2D; use euclid::Size2D;
use euclid::default::Size2D as UntypedSize2D; use euclid::default::Size2D as UntypedSize2D;
@@ -323,8 +324,8 @@ pub struct Constellation<STF, SWF> {
pub(crate) embedder_proxy: EmbedderProxy, pub(crate) embedder_proxy: EmbedderProxy,
/// A channel (the implementation of which is port-specific) for the /// A channel (the implementation of which is port-specific) for the
/// constellation to send messages to the compositor thread. /// constellation to send messages to `Paint`.
pub(crate) compositor_proxy: CompositorProxy, pub(crate) paint_proxy: PaintProxy,
/// Bookkeeping data for all webviews in the constellation. /// Bookkeeping data for all webviews in the constellation.
webviews: FxHashMap<WebViewId, ConstellationWebView>, webviews: FxHashMap<WebViewId, ConstellationWebView>,
@@ -514,8 +515,8 @@ pub struct InitialConstellationState {
/// A channel through which messages can be sent to the embedder. /// A channel through which messages can be sent to the embedder.
pub embedder_proxy: EmbedderProxy, pub embedder_proxy: EmbedderProxy,
/// A channel through which messages can be sent to the compositor in-process. /// A channel through which messages can be sent to `Paint` in-process.
pub compositor_proxy: CompositorProxy, pub paint_proxy: PaintProxy,
/// A channel to the developer tools, if applicable. /// A channel to the developer tools, if applicable.
pub devtools_sender: Option<Sender<DevtoolsControlMsg>>, pub devtools_sender: Option<Sender<DevtoolsControlMsg>>,
@@ -567,10 +568,10 @@ pub struct InitialConstellationState {
pub async_runtime: Box<dyn AsyncRuntime>, pub async_runtime: Box<dyn AsyncRuntime>,
} }
/// When we are exiting a pipeline, we can either force exiting or not. /// When we are exiting a pipeline, we can either force exiting or not. A normal exit
/// A normal exit waits for the compositor to update its state before /// waits for `Paint` to update its state before exiting, and delegates layout exit to
/// exiting, and delegates layout exit to script. A forced exit does /// script. A forced exit does not notify `Paint`, and exits layout without involving
/// not notify the compositor, and exits layout without involving script. /// script.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
enum ExitPipelineMode { enum ExitPipelineMode {
Normal, Normal,
@@ -685,7 +686,7 @@ where
embedder_to_constellation_receiver, embedder_to_constellation_receiver,
layout_factory, layout_factory,
embedder_proxy: state.embedder_proxy, embedder_proxy: state.embedder_proxy,
compositor_proxy: state.compositor_proxy, paint_proxy: state.paint_proxy,
webviews: Default::default(), webviews: Default::default(),
devtools_sender: state.devtools_sender, devtools_sender: state.devtools_sender,
script_to_devtools_callback: Default::default(), script_to_devtools_callback: Default::default(),
@@ -1220,7 +1221,7 @@ where
self.pending_changes.push(change); self.pending_changes.push(change);
} }
/// Handles loading pages, navigation, and granting access to the compositor /// Handles loading pages, navigation, and granting access to `Paint`.
#[servo_tracing::instrument(skip_all)] #[servo_tracing::instrument(skip_all)]
fn handle_request(&mut self) { fn handle_request(&mut self) {
#[expect(clippy::large_enum_variant)] #[expect(clippy::large_enum_variant)]
@@ -1229,12 +1230,12 @@ where
PipelineNamespace(PipelineNamespaceRequest), PipelineNamespace(PipelineNamespaceRequest),
Script((WebViewId, PipelineId, ScriptToConstellationMessage)), Script((WebViewId, PipelineId, ScriptToConstellationMessage)),
BackgroundHangMonitor(HangMonitorAlert), BackgroundHangMonitor(HangMonitorAlert),
Compositor(EmbedderToConstellationMessage), Embedder(EmbedderToConstellationMessage),
FromSWManager(SWManagerMsg), FromSWManager(SWManagerMsg),
RemoveProcess(usize), RemoveProcess(usize),
} }
// Get one incoming request. // Get one incoming request.
// This is one of the few places where the compositor is // This is one of the few places where `Paint` is
// allowed to panic. If one of the receiver.recv() calls // allowed to panic. If one of the receiver.recv() calls
// fails, it is because the matching sender has been // fails, it is because the matching sender has been
// reclaimed, but this can't happen in normal execution // reclaimed, but this can't happen in normal execution
@@ -1271,9 +1272,9 @@ where
.recv(&self.background_hang_monitor_receiver) .recv(&self.background_hang_monitor_receiver)
.expect("Unexpected BHM channel panic in constellation") .expect("Unexpected BHM channel panic in constellation")
.map(Request::BackgroundHangMonitor), .map(Request::BackgroundHangMonitor),
3 => Ok(Request::Compositor( 3 => Ok(Request::Embedder(
oper.recv(&self.embedder_to_constellation_receiver) oper.recv(&self.embedder_to_constellation_receiver)
.expect("Unexpected compositor channel panic in constellation"), .expect("Unexpected embedder channel panic in constellation"),
)), )),
4 => oper 4 => oper
.recv(&self.swmanager_receiver) .recv(&self.swmanager_receiver)
@@ -1297,7 +1298,7 @@ where
Request::PipelineNamespace(message) => { Request::PipelineNamespace(message) => {
self.handle_request_for_pipeline_namespace(message) self.handle_request_for_pipeline_namespace(message)
}, },
Request::Compositor(message) => self.handle_request_from_compositor(message), Request::Embedder(message) => self.handle_request_from_embedder(message),
Request::Script(message) => { Request::Script(message) => {
self.handle_request_from_script(message); self.handle_request_from_script(message);
}, },
@@ -1341,8 +1342,8 @@ where
} }
#[servo_tracing::instrument(skip_all)] #[servo_tracing::instrument(skip_all)]
fn handle_request_from_compositor(&mut self, message: EmbedderToConstellationMessage) { fn handle_request_from_embedder(&mut self, message: EmbedderToConstellationMessage) {
trace_msg_from_compositor!(message, "{message:?}"); trace_msg_from_embedder!(message, "{message:?}");
match message { match message {
EmbedderToConstellationMessage::Exit => { EmbedderToConstellationMessage::Exit => {
self.handle_exit(); self.handle_exit();
@@ -2024,7 +2025,7 @@ where
}; };
let webgpu_chan = match browsing_context_group.webgpus.entry(host) { let webgpu_chan = match browsing_context_group.webgpus.entry(host) {
Entry::Vacant(v) => start_webgpu_thread( Entry::Vacant(v) => start_webgpu_thread(
self.compositor_proxy.cross_process_compositor_api.clone(), self.paint_proxy.cross_process_paint_api.clone(),
self.webrender_wgpu self.webrender_wgpu
.webrender_external_image_id_manager .webrender_external_image_id_manager
.clone(), .clone(),
@@ -2446,7 +2447,7 @@ where
resource_threads: self.public_resource_threads.clone(), resource_threads: self.public_resource_threads.clone(),
own_sender: own_sender.clone(), own_sender: own_sender.clone(),
receiver, receiver,
compositor_api: self.compositor_proxy.cross_process_compositor_api.clone(), paint_api: self.paint_proxy.cross_process_paint_api.clone(),
system_font_service_sender: self.system_font_service.to_sender(), system_font_service_sender: self.system_font_service.to_sender(),
}; };
@@ -2737,9 +2738,9 @@ where
}; };
// Now that the Script and Constellation parts of Servo no longer have a reference to // Now that the Script and Constellation parts of Servo no longer have a reference to
// this pipeline, tell the compositor that it has shut down. This is delayed until the // this pipeline, tell `Paint` that it has shut down. This is delayed until the
// last moment. // last moment.
self.compositor_proxy.send(CompositorMsg::PipelineExited( self.paint_proxy.send(PaintMessage::PipelineExited(
pipeline.webview_id, pipeline.webview_id,
pipeline.id, pipeline.id,
PipelineExitSource::Constellation, PipelineExitSource::Constellation,
@@ -2962,7 +2963,7 @@ where
&mut self, &mut self,
webview_id: WebViewId, webview_id: WebViewId,
event: InputEventAndId, event: InputEventAndId,
hit_test_result: Option<CompositorHitTestResult>, hit_test_result: Option<PaintHitTestResult>,
) { ) {
if let InputEvent::MouseButton(event) = &event.event { if let InputEvent::MouseButton(event) = &event.event {
self.update_pressed_mouse_buttons(event); self.update_pressed_mouse_buttons(event);
@@ -3303,7 +3304,7 @@ where
webview_id, webview_id,
None, None,
script_sender, script_sender,
self.compositor_proxy.clone(), self.paint_proxy.clone(),
is_parent_throttled, is_parent_throttled,
load_info.load_data, load_info.load_data,
); );
@@ -3380,7 +3381,7 @@ where
new_webview_id, new_webview_id,
Some(opener_browsing_context_id), Some(opener_browsing_context_id),
script_sender, script_sender,
self.compositor_proxy.clone(), self.paint_proxy.clone(),
is_opener_throttled, is_opener_throttled,
load_data, load_data,
); );
@@ -3446,8 +3447,8 @@ where
if let Some(pipeline) = self.pipelines.get_mut(&pipeline_id) { if let Some(pipeline) = self.pipelines.get_mut(&pipeline_id) {
if pipeline.animation_state != animation_state { if pipeline.animation_state != animation_state {
pipeline.animation_state = animation_state; pipeline.animation_state = animation_state;
self.compositor_proxy self.paint_proxy
.send(CompositorMsg::ChangeRunningAnimationsState( .send(PaintMessage::ChangeRunningAnimationsState(
pipeline.webview_id, pipeline.webview_id,
pipeline_id, pipeline_id,
animation_state, animation_state,
@@ -5042,8 +5043,8 @@ where
) )
}) })
.collect(); .collect();
self.compositor_proxy self.paint_proxy
.send(CompositorMsg::ScreenshotReadinessReponse( .send(PaintMessage::ScreenshotReadinessReponse(
screenshot_request.webview_id, screenshot_request.webview_id,
pipelines_and_epochs, pipelines_and_epochs,
)); ));
@@ -5393,7 +5394,7 @@ where
self.pending_changes.remove(pending_index); self.pending_changes.remove(pending_index);
} }
// Inform script, compositor that this pipeline has exited. // Inform script and paint that this pipeline has exited.
pipeline.send_exit_message_to_script(dbc); pipeline.send_exit_message_to_script(dbc);
self.send_screenshot_readiness_requests_to_pipelines(); self.send_screenshot_readiness_requests_to_pipelines();
@@ -5451,7 +5452,7 @@ where
.expect("Unknown top-level browsing context") .expect("Unknown top-level browsing context")
} }
// Convert a browsing context to a sendable form to pass to the compositor // Convert a browsing context to a sendable form to pass to `Paint`
#[servo_tracing::instrument(skip_all)] #[servo_tracing::instrument(skip_all)]
fn browsing_context_to_sendable( fn browsing_context_to_sendable(
&self, &self,
@@ -5481,7 +5482,7 @@ where
}) })
} }
/// Send the frame tree for the given webview to the compositor. /// Send the frame tree for the given webview to `Paint`.
#[servo_tracing::instrument(skip_all)] #[servo_tracing::instrument(skip_all)]
fn set_frame_tree_for_webview(&mut self, webview_id: WebViewId) { fn set_frame_tree_for_webview(&mut self, webview_id: WebViewId) {
// Note that this function can panic, due to ipc-channel creation failure. // Note that this function can panic, due to ipc-channel creation failure.
@@ -5490,10 +5491,8 @@ where
let browsing_context_id = BrowsingContextId::from(webview_id); let browsing_context_id = BrowsingContextId::from(webview_id);
if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) { if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) {
debug!("{}: Sending frame tree", browsing_context_id); debug!("{}: Sending frame tree", browsing_context_id);
self.compositor_proxy self.paint_proxy
.send(CompositorMsg::SetFrameTreeForWebView( .send(PaintMessage::SetFrameTreeForWebView(webview_id, frame_tree));
webview_id, frame_tree,
));
} }
} }
@@ -5567,7 +5566,7 @@ where
fn create_canvas_paint_thread( fn create_canvas_paint_thread(
&self, &self,
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) { ) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
CanvasPaintThread::start(self.compositor_proxy.cross_process_compositor_api.clone()) CanvasPaintThread::start(self.paint_proxy.cross_process_paint_api.clone())
} }
fn handle_embedder_control_response( fn handle_embedder_control_response(

View File

@@ -104,10 +104,7 @@ impl EventLoop {
constellation_to_script_sender: script_chan, constellation_to_script_sender: script_chan,
constellation_to_script_receiver: script_port, constellation_to_script_receiver: script_port,
pipeline_namespace_id: constellation.next_pipeline_namespace_id(), pipeline_namespace_id: constellation.next_pipeline_namespace_id(),
cross_process_compositor_api: constellation cross_process_paint_api: constellation.paint_proxy.cross_process_paint_api.clone(),
.compositor_proxy
.cross_process_compositor_api
.clone(),
webgl_chan: constellation webgl_chan: constellation
.webgl_threads .webgl_threads
.as_ref() .as_ref()

View File

@@ -73,7 +73,7 @@ impl Log for FromScriptLogger {
fn flush(&self) {} fn flush(&self) {}
} }
/// A logger directed at the constellation from the compositor /// A logger directed at the constellation from `Paint`.
#[derive(Clone)] #[derive(Clone)]
pub struct FromEmbedderLogger { pub struct FromEmbedderLogger {
/// A channel to the constellation /// A channel to the constellation

View File

@@ -6,7 +6,7 @@ use std::collections::HashSet;
use std::rc::Rc; use std::rc::Rc;
use base::id::{BrowsingContextId, HistoryStateId, PipelineId, WebViewId}; use base::id::{BrowsingContextId, HistoryStateId, PipelineId, WebViewId};
use compositing_traits::{CompositionPipeline, CompositorMsg, CompositorProxy}; use compositing_traits::{CompositionPipeline, PaintMessage, PaintProxy};
use constellation_traits::{LoadData, ServiceWorkerManagerFactory}; use constellation_traits::{LoadData, ServiceWorkerManagerFactory};
use embedder_traits::{AnimationState, FocusSequenceNumber}; use embedder_traits::{AnimationState, FocusSequenceNumber};
use ipc_channel::Error; use ipc_channel::Error;
@@ -37,8 +37,8 @@ pub struct Pipeline {
/// The event loop handling this pipeline. /// The event loop handling this pipeline.
pub event_loop: Rc<EventLoop>, pub event_loop: Rc<EventLoop>,
/// A channel to the compositor. /// A channel to `Paint`.
pub compositor_proxy: CompositorProxy, pub paint_proxy: PaintProxy,
/// The most recently loaded URL in this pipeline. /// The most recently loaded URL in this pipeline.
/// Note that this URL can change, for example if the page navigates /// Note that this URL can change, for example if the page navigates
@@ -91,7 +91,7 @@ impl Pipeline {
new_pipeline_info.webview_id, new_pipeline_info.webview_id,
new_pipeline_info.opener, new_pipeline_info.opener,
event_loop, event_loop,
constellation.compositor_proxy.clone(), constellation.paint_proxy.clone(),
throttled, throttled,
new_pipeline_info.load_data, new_pipeline_info.load_data,
)) ))
@@ -105,7 +105,7 @@ impl Pipeline {
webview_id: WebViewId, webview_id: WebViewId,
opener: Option<BrowsingContextId>, opener: Option<BrowsingContextId>,
event_loop: Rc<EventLoop>, event_loop: Rc<EventLoop>,
compositor_proxy: CompositorProxy, paint_proxy: PaintProxy,
throttled: bool, throttled: bool,
load_data: LoadData, load_data: LoadData,
) -> Self { ) -> Self {
@@ -115,7 +115,7 @@ impl Pipeline {
webview_id, webview_id,
opener, opener,
event_loop, event_loop,
compositor_proxy, paint_proxy,
url: load_data.url.clone(), url: load_data.url.clone(),
children: vec![], children: vec![],
animation_state: AnimationState::NoAnimationsPresent, animation_state: AnimationState::NoAnimationsPresent,
@@ -155,7 +155,7 @@ impl Pipeline {
} }
} }
/// The compositor's view of a pipeline. /// `Paint`'s view of a pipeline.
pub fn to_sendable(&self) -> CompositionPipeline { pub fn to_sendable(&self) -> CompositionPipeline {
CompositionPipeline { CompositionPipeline {
id: self.id, id: self.id,
@@ -191,11 +191,11 @@ impl Pipeline {
/// running timers at a heavily limited rate. /// running timers at a heavily limited rate.
pub fn set_throttled(&self, throttled: bool) { pub fn set_throttled(&self, throttled: bool) {
let script_msg = ScriptThreadMessage::SetThrottled(self.webview_id, self.id, throttled); let script_msg = ScriptThreadMessage::SetThrottled(self.webview_id, self.id, throttled);
let compositor_msg = CompositorMsg::SetThrottled(self.webview_id, self.id, throttled); let paint_message = PaintMessage::SetThrottled(self.webview_id, self.id, throttled);
let err = self.event_loop.send(script_msg); let err = self.event_loop.send(script_msg);
if let Err(e) = err { if let Err(e) = err {
warn!("Sending SetThrottled to script failed ({}).", e); warn!("Sending SetThrottled to script failed ({}).", e);
} }
self.compositor_proxy.send(compositor_msg); self.paint_proxy.send(paint_message);
} }
} }

View File

@@ -2,14 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/// Log an event from compositor at trace level. /// Log an event from embedder at trace level.
/// - To disable tracing: RUST_LOG='constellation<compositor@=off' /// - To disable tracing: RUST_LOG='constellation<embedder@=off'
/// - To enable tracing: RUST_LOG='constellation<compositor@' /// - To enable tracing: RUST_LOG='constellation<embedder@'
/// - Recommended filters when tracing is enabled: /// - Recommended filters when tracing is enabled:
/// - constellation<compositor@ForwardEvent(MouseMoveEvent)=off /// - constellation<embedder@ForwardEvent(MouseMoveEvent)=off
/// - constellation<compositor@LogEntry=off /// - constellation<embedder@LogEntry=off
/// - constellation<compositor@ReadyToPresent=off /// - constellation<embedder@ReadyToPresent=off
macro_rules! trace_msg_from_compositor { macro_rules! trace_msg_from_embedder {
// This macro only exists to put the docs in the same file as the target prefix, // This macro only exists to put the docs in the same file as the target prefix,
// so the macro definition is always the same. // so the macro definition is always the same.
($event:expr, $($rest:tt)+) => { ($event:expr, $($rest:tt)+) => {
@@ -35,14 +35,14 @@ pub(crate) trait LogTarget {
fn log_target(&self) -> &'static str; fn log_target(&self) -> &'static str;
} }
mod from_compositor { mod from_embedder {
use embedder_traits::{InputEvent, InputEventAndId}; use embedder_traits::{InputEvent, InputEventAndId};
use super::LogTarget; use super::LogTarget;
macro_rules! target { macro_rules! target {
($($name:literal)+) => { ($($name:literal)+) => {
concat!("constellation<compositor@", $($name),+) concat!("constellation<embedder@", $($name),+)
}; };
} }

View File

@@ -11,7 +11,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use app_units::Au; use app_units::Au;
use base::id::{PainterId, WebViewId}; use base::id::{PainterId, WebViewId};
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use content_security_policy::Violation; use content_security_policy::Violation;
use fonts_traits::{ use fonts_traits::{
CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
@@ -81,8 +81,8 @@ pub struct FontContext {
resource_threads: Mutex<CoreResourceThread>, resource_threads: Mutex<CoreResourceThread>,
/// A sender that can send messages and receive replies from the compositor. /// A sender that can send messages and receive replies from `Paint`.
compositor_api: Mutex<CrossProcessCompositorApi>, paint_api: Mutex<CrossProcessPaintApi>,
/// The actual instances of fonts ie a [`FontTemplate`] combined with a size and /// The actual instances of fonts ie a [`FontTemplate`] combined with a size and
/// other font properties, along with the font data and a platform font instance. /// other font properties, along with the font data and a platform font instance.
@@ -143,14 +143,14 @@ impl Clone for WebFontDocumentContext {
impl FontContext { impl FontContext {
pub fn new( pub fn new(
system_font_service_proxy: Arc<SystemFontServiceProxy>, system_font_service_proxy: Arc<SystemFontServiceProxy>,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
resource_threads: ResourceThreads, resource_threads: ResourceThreads,
) -> Self { ) -> Self {
#[allow(clippy::default_constructed_unit_structs)] #[allow(clippy::default_constructed_unit_structs)]
Self { Self {
system_font_service_proxy, system_font_service_proxy,
resource_threads: Mutex::new(resource_threads.core_thread), resource_threads: Mutex::new(resource_threads.core_thread),
compositor_api: Mutex::new(compositor_api), paint_api: Mutex::new(paint_api),
fonts: Default::default(), fonts: Default::default(),
resolved_font_groups: Default::default(), resolved_font_groups: Default::default(),
web_fonts: Default::default(), web_fonts: Default::default(),
@@ -361,7 +361,7 @@ impl FontContext {
.entry(identifier.clone()) .entry(identifier.clone())
.or_insert_with(|| { .or_insert_with(|| {
let font_key = self.system_font_service_proxy.generate_font_key(painter_id); let font_key = self.system_font_service_proxy.generate_font_key(painter_id);
self.compositor_api.lock().add_font( self.paint_api.lock().add_font(
font_key, font_key,
font_data.as_ipc_shared_memory(), font_data.as_ipc_shared_memory(),
identifier.index(), identifier.index(),
@@ -383,7 +383,7 @@ impl FontContext {
let font_instance_key = self let font_instance_key = self
.system_font_service_proxy .system_font_service_proxy
.generate_font_instance_key(painter_id); .generate_font_instance_key(painter_id);
self.compositor_api.lock().add_font_instance( self.paint_api.lock().add_font_instance(
font_instance_key, font_instance_key,
font_key, font_key,
pt_size.to_f32_px(), pt_size.to_f32_px(),

View File

@@ -9,7 +9,7 @@ use std::thread;
use app_units::Au; use app_units::Au;
use base::id::PainterId; use base::id::PainterId;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use fonts_traits::{ use fonts_traits::{
FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, LowercaseFontFamilyName, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, LowercaseFontFamilyName,
SystemFontServiceMessage, SystemFontServiceProxySender, SystemFontServiceMessage, SystemFontServiceProxySender,
@@ -58,21 +58,21 @@ struct FontInstancesMapKey {
pub struct SystemFontService { pub struct SystemFontService {
port: IpcReceiver<SystemFontServiceMessage>, port: IpcReceiver<SystemFontServiceMessage>,
local_families: FontStore, local_families: FontStore,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
// keys already have the IdNamespace for webrender // keys already have the IdNamespace for webrender
webrender_fonts: HashMap<(FontIdentifier, PainterId), FontKey>, webrender_fonts: HashMap<(FontIdentifier, PainterId), FontKey>,
font_instances: HashMap<FontInstancesMapKey, FontInstanceKey>, font_instances: HashMap<FontInstancesMapKey, FontInstanceKey>,
generic_fonts: ResolvedGenericFontFamilies, generic_fonts: ResolvedGenericFontFamilies,
/// This is an optimization that allows the [`SystemFontService`] to send font data to /// This is an optimization that allows the [`SystemFontService`] to send font data to
/// the compositor asynchronously for creating WebRender fonts, while immediately /// `Paint` asynchronously for creating WebRender fonts, while immediately
/// returning a font key for that data. Once the free keys are exhausted, the /// returning a font key for that data. Once the free keys are exhausted, the
/// [`SystemFontService`] will fetch a new batch. /// [`SystemFontService`] will fetch a new batch.
/// TODO: We currently do not delete the free keys if a `WebView` is removed. /// TODO: We currently do not delete the free keys if a `WebView` is removed.
free_font_keys: FxHashMap<PainterId, Vec<FontKey>>, free_font_keys: FxHashMap<PainterId, Vec<FontKey>>,
/// This is an optimization that allows the [`SystemFontService`] to create WebRender font /// This is an optimization that allows the [`SystemFontService`] to create WebRender font
/// instances in the compositor asynchronously, while immediately returning a font /// instances in `Paint` asynchronously, while immediately returning a font
/// instance key for the instance. Once the free keys are exhausted, the /// instance key for the instance. Once the free keys are exhausted, the
/// [`SystemFontService`] will fetch a new batch. /// [`SystemFontService`] will fetch a new batch.
free_font_instance_keys: FxHashMap<PainterId, Vec<FontInstanceKey>>, free_font_instance_keys: FxHashMap<PainterId, Vec<FontInstanceKey>>,
@@ -80,7 +80,7 @@ pub struct SystemFontService {
impl SystemFontService { impl SystemFontService {
pub fn spawn( pub fn spawn(
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
memory_profiler_sender: ProfilerChan, memory_profiler_sender: ProfilerChan,
) -> SystemFontServiceProxySender { ) -> SystemFontServiceProxySender {
let (sender, receiver) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap();
@@ -93,7 +93,7 @@ impl SystemFontService {
let mut cache = SystemFontService { let mut cache = SystemFontService {
port: receiver, port: receiver,
local_families: Default::default(), local_families: Default::default(),
compositor_api, paint_api,
webrender_fonts: HashMap::new(), webrender_fonts: HashMap::new(),
font_instances: HashMap::new(), font_instances: HashMap::new(),
generic_fonts: Default::default(), generic_fonts: Default::default(),
@@ -204,7 +204,7 @@ impl SystemFontService {
const FREE_FONT_KEYS_BATCH_SIZE: usize = 40; const FREE_FONT_KEYS_BATCH_SIZE: usize = 40;
const FREE_FONT_INSTANCE_KEYS_BATCH_SIZE: usize = 40; const FREE_FONT_INSTANCE_KEYS_BATCH_SIZE: usize = 40;
let (mut new_font_keys, mut new_font_instance_keys) = self.compositor_api.fetch_font_keys( let (mut new_font_keys, mut new_font_instance_keys) = self.paint_api.fetch_font_keys(
FREE_FONT_KEYS_BATCH_SIZE - self.free_font_keys.len(), FREE_FONT_KEYS_BATCH_SIZE - self.free_font_keys.len(),
FREE_FONT_INSTANCE_KEYS_BATCH_SIZE - self.free_font_instance_keys.len(), FREE_FONT_INSTANCE_KEYS_BATCH_SIZE - self.free_font_instance_keys.len(),
painter_id, painter_id,
@@ -278,7 +278,7 @@ impl SystemFontService {
) -> FontInstanceKey { ) -> FontInstanceKey {
self.fetch_font_keys_if_needed(painter_id); self.fetch_font_keys_if_needed(painter_id);
let compositor_api = &self.compositor_api; let paint_api = &self.paint_api;
let webrender_fonts = &mut self.webrender_fonts; let webrender_fonts = &mut self.webrender_fonts;
let font_key = *webrender_fonts let font_key = *webrender_fonts
@@ -293,8 +293,7 @@ impl SystemFontService {
let FontIdentifier::Local(local_font_identifier) = identifier else { let FontIdentifier::Local(local_font_identifier) = identifier else {
unreachable!("Should never have a web font in the system font service"); unreachable!("Should never have a web font in the system font service");
}; };
compositor_api paint_api.add_system_font(font_key, local_font_identifier.native_font_handle());
.add_system_font(font_key, local_font_identifier.native_font_handle());
font_key font_key
}); });
@@ -312,7 +311,7 @@ impl SystemFontService {
.expect("We just filled the keys") .expect("We just filled the keys")
.pop() .pop()
.unwrap(); .unwrap();
compositor_api.add_font_instance( paint_api.add_font_instance(
font_instance_key, font_instance_key,
font_key, font_key,
pt_size.to_f32_px(), pt_size.to_f32_px(),

View File

@@ -14,7 +14,7 @@ mod font_context {
use std::thread; use std::thread;
use app_units::Au; use app_units::Au;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use fonts::platform::font::PlatformFont; use fonts::platform::font::PlatformFont;
use fonts::{ use fonts::{
FallbackFontSelectionOptions, FontContext, FontDescriptor, FontFamilyDescriptor, FallbackFontSelectionOptions, FontContext, FontDescriptor, FontFamilyDescriptor,
@@ -50,14 +50,14 @@ mod font_context {
let (system_font_service, system_font_service_proxy) = MockSystemFontService::spawn(); let (system_font_service, system_font_service_proxy) = MockSystemFontService::spawn();
let (core_sender, _) = ipc::channel().unwrap(); let (core_sender, _) = ipc::channel().unwrap();
let mock_resource_threads = ResourceThreads::new(core_sender); let mock_resource_threads = ResourceThreads::new(core_sender);
let mock_compositor_api = CrossProcessCompositorApi::dummy(); let mock_paint_api = CrossProcessPaintApi::dummy();
let proxy_clone = Arc::new(system_font_service_proxy.to_sender().to_proxy()); let proxy_clone = Arc::new(system_font_service_proxy.to_sender().to_proxy());
INIT.call_once(|| { INIT.call_once(|| {
start_fetch_thread(); start_fetch_thread();
}); });
Self { Self {
context: FontContext::new(proxy_clone, mock_compositor_api, mock_resource_threads), context: FontContext::new(proxy_clone, mock_paint_api, mock_resource_threads),
system_font_service, system_font_service,
system_font_service_proxy, system_font_service_proxy,
} }

View File

@@ -65,11 +65,7 @@ impl<'a> BackgroundPainter<'a> {
if &BackgroundAttachment::Fixed == if &BackgroundAttachment::Fixed ==
get_cyclic(&background.background_attachment.0, layer_index) get_cyclic(&background.background_attachment.0, layer_index)
{ {
return builder return builder.paint_info.viewport_details.layout_size().into();
.compositor_info
.viewport_details
.layout_size()
.into();
} }
match get_cyclic(&background.background_clip.0, layer_index) { match get_cyclic(&background.background_clip.0, layer_index) {
@@ -153,11 +149,7 @@ impl<'a> BackgroundPainter<'a> {
Origin::PaddingBox => *fragment_builder.padding_rect(), Origin::PaddingBox => *fragment_builder.padding_rect(),
Origin::BorderBox => fragment_builder.border_rect, Origin::BorderBox => fragment_builder.border_rect,
}, },
BackgroundAttachment::Fixed => builder BackgroundAttachment::Fixed => builder.paint_info.viewport_details.layout_size().into(),
.compositor_info
.viewport_details
.layout_size()
.into(),
} }
} }
} }

View File

@@ -101,7 +101,7 @@ impl<'a> HitTest<'a> {
let transform = self let transform = self
.stacking_context_tree .stacking_context_tree
.compositor_info .paint_info
.scroll_tree .scroll_tree
.cumulative_root_to_node_transform(scroll_tree_node_id)?; .cumulative_root_to_node_transform(scroll_tree_node_id)?;
@@ -268,7 +268,7 @@ impl Fragment {
if is_root_element { if is_root_element {
let viewport_size = hit_test let viewport_size = hit_test
.stacking_context_tree .stacking_context_tree
.compositor_info .paint_info
.viewport_details .viewport_details
.size; .size;
let viewport_rect = LayoutRect::from_origin_and_size( let viewport_rect = LayoutRect::from_origin_and_size(

View File

@@ -17,7 +17,7 @@ pub(crate) struct LargestContentfulPaintCandidateCollector {
/// The rect of viewport. /// The rect of viewport.
pub viewport_rect: LayoutRect, pub viewport_rect: LayoutRect,
/// Flag to indicate if there is an update to LCP candidate. /// Flag to indicate if there is an update to LCP candidate.
/// This is used to avoid sending duplicate LCP candidates to the compositor. /// This is used to avoid sending duplicate LCP candidates to `Paint`.
pub did_lcp_candidate_update: bool, pub did_lcp_candidate_update: bool,
} }

View File

@@ -8,7 +8,7 @@ use std::sync::Arc;
use app_units::{AU_PER_PX, Au}; use app_units::{AU_PER_PX, Au};
use base::id::ScrollTreeNodeId; use base::id::ScrollTreeNodeId;
use clip::{Clip, ClipId}; use clip::{Clip, ClipId};
use compositing_traits::display_list::{CompositorDisplayListInfo, SpatialTreeNodeInfo}; use compositing_traits::display_list::{PaintDisplayListInfo, SpatialTreeNodeInfo};
use compositing_traits::largest_contentful_paint_candidate::{ use compositing_traits::largest_contentful_paint_candidate::{
LCPCandidateID, LargestContentfulPaintType, LCPCandidateID, LargestContentfulPaintType,
}; };
@@ -99,8 +99,8 @@ pub(crate) struct DisplayListBuilder<'a> {
/// The [`wr::DisplayListBuilder`] for this Servo [`DisplayListBuilder`]. /// The [`wr::DisplayListBuilder`] for this Servo [`DisplayListBuilder`].
pub webrender_display_list_builder: &'a mut wr::DisplayListBuilder, pub webrender_display_list_builder: &'a mut wr::DisplayListBuilder,
/// The [`CompositorDisplayListInfo`] used to collect display list items and metadata. /// The [`PaintDisplayListInfo`] used to collect display list items and metadata.
pub compositor_info: &'a mut CompositorDisplayListInfo, pub paint_info: &'a mut PaintDisplayListInfo,
/// Data about the fragments that are highlighted by the inspector, if any. /// Data about the fragments that are highlighted by the inspector, if any.
/// ///
@@ -176,8 +176,8 @@ impl DisplayListBuilder<'_> {
lcp_candidate_collector: Option<&mut LargestContentfulPaintCandidateCollector>, lcp_candidate_collector: Option<&mut LargestContentfulPaintCandidateCollector>,
) -> BuiltDisplayList { ) -> BuiltDisplayList {
// Build the rest of the display list which inclues all of the WebRender primitives. // Build the rest of the display list which inclues all of the WebRender primitives.
let compositor_info = &mut stacking_context_tree.compositor_info; let paint_info = &mut stacking_context_tree.paint_info;
let pipeline_id = compositor_info.pipeline_id; let pipeline_id = paint_info.pipeline_id;
let mut webrender_display_list_builder = let mut webrender_display_list_builder =
webrender_api::DisplayListBuilder::new(pipeline_id); webrender_api::DisplayListBuilder::new(pipeline_id);
webrender_display_list_builder.begin(); webrender_display_list_builder.begin();
@@ -192,11 +192,11 @@ impl DisplayListBuilder<'_> {
let _span = profile_traits::trace_span!("DisplayListBuilder::build").entered(); let _span = profile_traits::trace_span!("DisplayListBuilder::build").entered();
let mut builder = DisplayListBuilder { let mut builder = DisplayListBuilder {
current_scroll_node_id: compositor_info.root_reference_frame_id, current_scroll_node_id: paint_info.root_reference_frame_id,
current_reference_frame_scroll_node_id: compositor_info.root_reference_frame_id, current_reference_frame_scroll_node_id: paint_info.root_reference_frame_id,
current_clip_id: ClipId::INVALID, current_clip_id: ClipId::INVALID,
webrender_display_list_builder: &mut webrender_display_list_builder, webrender_display_list_builder: &mut webrender_display_list_builder,
compositor_info, paint_info,
inspector_highlight: highlighted_dom_node.map(InspectorHighlight::for_node), inspector_highlight: highlighted_dom_node.map(InspectorHighlight::for_node),
paint_body_background: true, paint_body_background: true,
clip_map: Default::default(), clip_map: Default::default(),
@@ -213,8 +213,8 @@ impl DisplayListBuilder<'_> {
// Add a single hit test that covers the entire viewport, so that WebRender knows // Add a single hit test that covers the entire viewport, so that WebRender knows
// which pipeline it hits when doing hit testing. // which pipeline it hits when doing hit testing.
let pipeline_id = builder.compositor_info.pipeline_id; let pipeline_id = builder.paint_info.pipeline_id;
let viewport_size = builder.compositor_info.viewport_details.size; let viewport_size = builder.paint_info.viewport_details.size;
let viewport_rect = LayoutRect::from_size(viewport_size.cast_unit()); let viewport_rect = LayoutRect::from_size(viewport_size.cast_unit());
builder.wr().push_hit_test( builder.wr().push_hit_test(
viewport_rect, viewport_rect,
@@ -241,15 +241,15 @@ impl DisplayListBuilder<'_> {
} }
fn pipeline_id(&mut self) -> wr::PipelineId { fn pipeline_id(&mut self) -> wr::PipelineId {
self.compositor_info.pipeline_id self.paint_info.pipeline_id
} }
fn mark_is_contentful(&mut self) { fn mark_is_contentful(&mut self) {
self.compositor_info.is_contentful = true; self.paint_info.is_contentful = true;
} }
fn spatial_id(&self, id: ScrollTreeNodeId) -> SpatialId { fn spatial_id(&self, id: ScrollTreeNodeId) -> SpatialId {
self.compositor_info.scroll_tree.webrender_id(id) self.paint_info.scroll_tree.webrender_id(id)
} }
fn clip_chain_id(&self, id: ClipId) -> ClipChainId { fn clip_chain_id(&self, id: ClipId) -> ClipChainId {
@@ -267,7 +267,7 @@ impl DisplayListBuilder<'_> {
// list. This is merely to ensure that the currently-unused SpatialTreeItemKey // list. This is merely to ensure that the currently-unused SpatialTreeItemKey
// produced for every SpatialTree node is unique. // produced for every SpatialTree node is unique.
let mut spatial_tree_count = 0; let mut spatial_tree_count = 0;
let mut scroll_tree = std::mem::take(&mut self.compositor_info.scroll_tree); let mut scroll_tree = std::mem::take(&mut self.paint_info.scroll_tree);
let mut mapping = Vec::with_capacity(scroll_tree.nodes.len()); let mut mapping = Vec::with_capacity(scroll_tree.nodes.len());
mapping.push(SpatialId::root_reference_frame(self.pipeline_id())); mapping.push(SpatialId::root_reference_frame(self.pipeline_id()));
@@ -330,7 +330,7 @@ impl DisplayListBuilder<'_> {
} }
scroll_tree.update_mapping(mapping); scroll_tree.update_mapping(mapping);
self.compositor_info.scroll_tree = scroll_tree; self.paint_info.scroll_tree = scroll_tree;
} }
/// Add the given [`Clip`] to the WebRender display list and create a mapping from /// Add the given [`Clip`] to the WebRender display list and create a mapping from
@@ -532,7 +532,7 @@ impl DisplayListBuilder<'_> {
) { ) {
if let Some(lcp_collector) = &mut self.lcp_candidate_collector { if let Some(lcp_collector) = &mut self.lcp_candidate_collector {
let transform = self let transform = self
.compositor_info .paint_info
.scroll_tree .scroll_tree
.cumulative_node_to_root_transform(self.current_scroll_node_id); .cumulative_node_to_root_transform(self.current_scroll_node_id);
lcp_collector.add_or_update_candidate( lcp_collector.add_or_update_candidate(
@@ -1137,7 +1137,7 @@ impl<'a> BuilderForBoxFragment<'a> {
fn build_hit_test(&self, builder: &mut DisplayListBuilder, rect: LayoutRect) { fn build_hit_test(&self, builder: &mut DisplayListBuilder, rect: LayoutRect) {
let external_scroll_node_id = builder let external_scroll_node_id = builder
.compositor_info .paint_info
.external_scroll_id_for_scroll_tree_node(builder.current_scroll_node_id); .external_scroll_id_for_scroll_tree_node(builder.current_scroll_node_id);
let mut common = builder.common_properties(rect, &self.fragment.style); let mut common = builder.common_properties(rect, &self.fragment.style);

View File

@@ -11,7 +11,7 @@ use app_units::Au;
use base::id::ScrollTreeNodeId; use base::id::ScrollTreeNodeId;
use base::print_tree::PrintTree; use base::print_tree::PrintTree;
use compositing_traits::display_list::{ use compositing_traits::display_list::{
AxesScrollSensitivity, CompositorDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo, AxesScrollSensitivity, PaintDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo,
SpatialTreeNodeInfo, StickyNodeInfo, SpatialTreeNodeInfo, StickyNodeInfo,
}; };
use embedder_traits::ViewportDetails; use embedder_traits::ViewportDetails;
@@ -106,11 +106,11 @@ pub(crate) struct StackingContextTree {
/// The root stacking context of this [`StackingContextTree`]. /// The root stacking context of this [`StackingContextTree`].
pub root_stacking_context: StackingContext, pub root_stacking_context: StackingContext,
/// The information about the WebRender display list that the compositor /// The information about the WebRender display list that `Paint`
/// consumes. This curerntly contains the out-of-band hit testing information /// consumes. This curerntly contains the out-of-band hit testing information
/// data structure that the compositor uses to map hit tests to information /// data structure that `Paint` uses to map hit tests to information
/// about the item hit. /// about the item hit.
pub compositor_info: CompositorDisplayListInfo, pub paint_info: PaintDisplayListInfo,
/// All of the clips collected for this [`StackingContextTree`]. These are added /// All of the clips collected for this [`StackingContextTree`]. These are added
/// for things like `overflow`. More clips may be created later during WebRender /// for things like `overflow`. More clips may be created later during WebRender
@@ -135,7 +135,7 @@ impl StackingContextTree {
)); ));
let viewport_size = viewport_details.layout_size(); let viewport_size = viewport_details.layout_size();
let compositor_info = CompositorDisplayListInfo::new( let paint_info = PaintDisplayListInfo::new(
viewport_details, viewport_details,
scrollable_overflow, scrollable_overflow,
pipeline_id, pipeline_id,
@@ -145,7 +145,7 @@ impl StackingContextTree {
first_reflow, first_reflow,
); );
let root_scroll_node_id = compositor_info.root_scroll_node_id; let root_scroll_node_id = paint_info.root_scroll_node_id;
let cb_for_non_fixed_descendants = ContainingBlock::new( let cb_for_non_fixed_descendants = ContainingBlock::new(
fragment_tree.initial_containing_block, fragment_tree.initial_containing_block,
root_scroll_node_id, root_scroll_node_id,
@@ -154,7 +154,7 @@ impl StackingContextTree {
); );
let cb_for_fixed_descendants = ContainingBlock::new( let cb_for_fixed_descendants = ContainingBlock::new(
fragment_tree.initial_containing_block, fragment_tree.initial_containing_block,
compositor_info.root_reference_frame_id, paint_info.root_reference_frame_id,
None, None,
ClipId::INVALID, ClipId::INVALID,
); );
@@ -174,7 +174,7 @@ impl StackingContextTree {
let mut stacking_context_tree = Self { let mut stacking_context_tree = Self {
// This is just a temporary value that will be replaced once we have finished building the tree. // This is just a temporary value that will be replaced once we have finished building the tree.
root_stacking_context: StackingContext::create_root(root_scroll_node_id, debug), root_stacking_context: StackingContext::create_root(root_scroll_node_id, debug),
compositor_info, paint_info,
clip_store: Default::default(), clip_store: Default::default(),
}; };
@@ -209,7 +209,7 @@ impl StackingContextTree {
transform: LayoutTransform, transform: LayoutTransform,
kind: wr::ReferenceFrameKind, kind: wr::ReferenceFrameKind,
) -> ScrollTreeNodeId { ) -> ScrollTreeNodeId {
self.compositor_info.scroll_tree.add_scroll_tree_node( self.paint_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id), Some(parent_scroll_node_id),
SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo { SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo {
origin, origin,
@@ -229,7 +229,7 @@ impl StackingContextTree {
clip_rect: LayoutRect, clip_rect: LayoutRect,
scroll_sensitivity: AxesScrollSensitivity, scroll_sensitivity: AxesScrollSensitivity,
) -> ScrollTreeNodeId { ) -> ScrollTreeNodeId {
self.compositor_info.scroll_tree.add_scroll_tree_node( self.paint_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id), Some(parent_scroll_node_id),
SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo { SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo {
external_id, external_id,
@@ -250,7 +250,7 @@ impl StackingContextTree {
vertical_offset_bounds: StickyOffsetBounds, vertical_offset_bounds: StickyOffsetBounds,
horizontal_offset_bounds: StickyOffsetBounds, horizontal_offset_bounds: StickyOffsetBounds,
) -> ScrollTreeNodeId { ) -> ScrollTreeNodeId {
self.compositor_info.scroll_tree.add_scroll_tree_node( self.paint_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id), Some(parent_scroll_node_id),
SpatialTreeNodeInfo::Sticky(StickyNodeInfo { SpatialTreeNodeInfo::Sticky(StickyNodeInfo {
frame_rect, frame_rect,
@@ -1505,7 +1505,7 @@ impl BoxFragment {
let tag = self.base.tag?; let tag = self.base.tag?;
let external_scroll_id = wr::ExternalScrollId( let external_scroll_id = wr::ExternalScrollId(
tag.to_display_list_fragment_id(), tag.to_display_list_fragment_id(),
stacking_context_tree.compositor_info.pipeline_id, stacking_context_tree.paint_info.pipeline_id,
); );
let sensitivity = AxesScrollSensitivity { let sensitivity = AxesScrollSensitivity {
@@ -1546,7 +1546,7 @@ impl BoxFragment {
None => { None => {
// This is a direct descendant of a reference frame. // This is a direct descendant of a reference frame.
&stacking_context_tree &stacking_context_tree
.compositor_info .paint_info
.viewport_details .viewport_details
.layout_size() .layout_size()
}, },

View File

@@ -15,7 +15,7 @@ use app_units::Au;
use base::generic_channel::GenericSender; use base::generic_channel::GenericSender;
use base::id::{PipelineId, WebViewId}; use base::id::{PipelineId, WebViewId};
use bitflags::bitflags; use bitflags::bitflags;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use compositing_traits::display_list::ScrollType; use compositing_traits::display_list::ScrollType;
use cssparser::ParserInput; use cssparser::ParserInput;
use embedder_traits::{Theme, ViewportDetails}; use embedder_traits::{Theme, ViewportDetails};
@@ -192,8 +192,8 @@ pub struct LayoutThread {
/// The executors for paint worklets. /// The executors for paint worklets.
registered_painters: RegisteredPaintersImpl, registered_painters: RegisteredPaintersImpl,
/// Cross-process access to the Compositor API. /// Cross-process access to the `Paint` API.
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
/// Debug options, copied from configuration to this `LayoutThread` in order /// Debug options, copied from configuration to this `LayoutThread` in order
/// to avoid having to constantly access the thread-safe global options. /// to avoid having to constantly access the thread-safe global options.
@@ -221,11 +221,8 @@ impl Drop for LayoutThread {
let (keys, instance_keys) = self let (keys, instance_keys) = self
.font_context .font_context
.collect_unused_webrender_resources(true /* all */); .collect_unused_webrender_resources(true /* all */);
self.compositor_api.remove_unused_font_resources( self.paint_api
self.webview_id.into(), .remove_unused_font_resources(self.webview_id.into(), keys, instance_keys)
keys,
instance_keys,
)
} }
} }
@@ -392,7 +389,7 @@ impl Layout for LayoutThread {
let stacking_context_tree = stacking_context_tree let stacking_context_tree = stacking_context_tree
.as_ref() .as_ref()
.expect("Should always have a StackingContextTree for offset parent queries"); .expect("Should always have a StackingContextTree for offset parent queries");
process_offset_parent_query(&stacking_context_tree.compositor_info.scroll_tree, node) process_offset_parent_query(&stacking_context_tree.paint_info.scroll_tree, node)
.unwrap_or_default() .unwrap_or_default()
} }
@@ -600,7 +597,7 @@ impl Layout for LayoutThread {
}; };
stacking_context_tree stacking_context_tree
.compositor_info .paint_info
.scroll_tree .scroll_tree
.set_all_scroll_offsets(scroll_states); .set_all_scroll_offsets(scroll_states);
} }
@@ -609,7 +606,7 @@ impl Layout for LayoutThread {
self.stacking_context_tree self.stacking_context_tree
.borrow_mut() .borrow_mut()
.as_mut() .as_mut()
.and_then(|tree| tree.compositor_info.scroll_tree.scroll_offset(id)) .and_then(|tree| tree.paint_info.scroll_tree.scroll_offset(id))
} }
fn needs_new_display_list(&self) -> bool { fn needs_new_display_list(&self) -> bool {
@@ -711,7 +708,7 @@ impl LayoutThread {
fn new(config: LayoutConfig) -> LayoutThread { fn new(config: LayoutConfig) -> LayoutThread {
// Let webrender know about this pipeline by sending an empty display list. // Let webrender know about this pipeline by sending an empty display list.
config config
.compositor_api .paint_api
.send_initial_transaction(config.webview_id, config.id.into()); .send_initial_transaction(config.webview_id, config.id.into());
let mut font = Font::initial_values(); let mut font = Font::initial_values();
@@ -753,7 +750,7 @@ impl LayoutThread {
box_tree: Default::default(), box_tree: Default::default(),
fragment_tree: Default::default(), fragment_tree: Default::default(),
stacking_context_tree: Default::default(), stacking_context_tree: Default::default(),
compositor_api: config.compositor_api, paint_api: config.paint_api,
stylist: Stylist::new(device, QuirksMode::NoQuirks), stylist: Stylist::new(device, QuirksMode::NoQuirks),
resolved_images_cache: Default::default(), resolved_images_cache: Default::default(),
debug: opts::get().debug.clone(), debug: opts::get().debug.clone(),
@@ -1222,7 +1219,7 @@ impl LayoutThread {
let mut stacking_context_tree = self.stacking_context_tree.borrow_mut(); let mut stacking_context_tree = self.stacking_context_tree.borrow_mut();
let old_scroll_offsets = stacking_context_tree let old_scroll_offsets = stacking_context_tree
.as_ref() .as_ref()
.map(|tree| tree.compositor_info.scroll_tree.scroll_offsets()); .map(|tree| tree.paint_info.scroll_tree.scroll_offsets());
// Build the StackingContextTree. This turns the `FragmentTree` into a // Build the StackingContextTree. This turns the `FragmentTree` into a
// tree of fragments in CSS painting order and also creates all // tree of fragments in CSS painting order and also creates all
@@ -1240,14 +1237,14 @@ impl LayoutThread {
// adjusted by any new scroll constraints. // adjusted by any new scroll constraints.
if let Some(old_scroll_offsets) = old_scroll_offsets { if let Some(old_scroll_offsets) = old_scroll_offsets {
new_stacking_context_tree new_stacking_context_tree
.compositor_info .paint_info
.scroll_tree .scroll_tree
.set_all_scroll_offsets(&old_scroll_offsets); .set_all_scroll_offsets(&old_scroll_offsets);
} }
if self.debug.scroll_tree { if self.debug.scroll_tree {
new_stacking_context_tree new_stacking_context_tree
.compositor_info .paint_info
.scroll_tree .scroll_tree
.debug_print(); .debug_print();
} }
@@ -1289,9 +1286,9 @@ impl LayoutThread {
return false; return false;
} }
// TODO: Eventually this should be set when `compositor_info` is created, but that requires // TODO: Eventually this should be set when `paint_info` is created, but that requires
// ensuring that the Epoch is passed to any method that can creates `StackingContextTree`. // ensuring that the Epoch is passed to any method that can creates `StackingContextTree`.
stacking_context_tree.compositor_info.epoch = reflow_request.epoch; stacking_context_tree.paint_info.epoch = reflow_request.epoch;
let mut lcp_candidate_collector = self.lcp_candidate_collector.borrow_mut(); let mut lcp_candidate_collector = self.lcp_candidate_collector.borrow_mut();
if pref!(largest_contentful_paint_enabled) { if pref!(largest_contentful_paint_enabled) {
@@ -1299,7 +1296,7 @@ impl LayoutThread {
if lcp_candidate_collector.is_none() { if lcp_candidate_collector.is_none() {
*lcp_candidate_collector = Some(LargestContentfulPaintCandidateCollector::new( *lcp_candidate_collector = Some(LargestContentfulPaintCandidateCollector::new(
stacking_context_tree stacking_context_tree
.compositor_info .paint_info
.viewport_details .viewport_details
.layout_size(), .layout_size(),
)); ));
@@ -1317,19 +1314,19 @@ impl LayoutThread {
&self.debug, &self.debug,
lcp_candidate_collector.as_mut(), lcp_candidate_collector.as_mut(),
); );
self.compositor_api.send_display_list( self.paint_api.send_display_list(
self.webview_id, self.webview_id,
&stacking_context_tree.compositor_info, &stacking_context_tree.paint_info,
built_display_list, built_display_list,
); );
if let Some(lcp_candidate_collector) = lcp_candidate_collector.as_mut() { if let Some(lcp_candidate_collector) = lcp_candidate_collector.as_mut() {
if lcp_candidate_collector.did_lcp_candidate_update { if lcp_candidate_collector.did_lcp_candidate_update {
if let Some(lcp_candidate) = lcp_candidate_collector.largest_contentful_paint() { if let Some(lcp_candidate) = lcp_candidate_collector.largest_contentful_paint() {
self.compositor_api.send_lcp_candidate( self.paint_api.send_lcp_candidate(
lcp_candidate, lcp_candidate,
self.webview_id, self.webview_id,
self.id, self.id,
stacking_context_tree.compositor_info.epoch, stacking_context_tree.paint_info.epoch,
); );
lcp_candidate_collector.did_lcp_candidate_update = false; lcp_candidate_collector.did_lcp_candidate_update = false;
} }
@@ -1339,11 +1336,8 @@ impl LayoutThread {
let (keys, instance_keys) = self let (keys, instance_keys) = self
.font_context .font_context
.collect_unused_webrender_resources(false /* all */); .collect_unused_webrender_resources(false /* all */);
self.compositor_api.remove_unused_font_resources( self.paint_api
self.webview_id.into(), .remove_unused_font_resources(self.webview_id.into(), keys, instance_keys);
keys,
instance_keys,
);
self.have_ever_generated_display_list.set(true); self.have_ever_generated_display_list.set(true);
self.need_new_display_list.set(false); self.need_new_display_list.set(false);
@@ -1363,7 +1357,7 @@ impl LayoutThread {
}; };
if let Some(offset) = stacking_context_tree if let Some(offset) = stacking_context_tree
.compositor_info .paint_info
.scroll_tree .scroll_tree
.set_scroll_offset_for_node_with_external_scroll_id( .set_scroll_offset_for_node_with_external_scroll_id(
external_scroll_id, external_scroll_id,
@@ -1371,7 +1365,7 @@ impl LayoutThread {
ScrollType::Script, ScrollType::Script,
) )
{ {
self.compositor_api.scroll_node_by_delta( self.paint_api.scroll_node_by_delta(
self.webview_id, self.webview_id,
self.id.into(), self.id.into(),
offset, offset,

View File

@@ -116,7 +116,7 @@ pub(crate) fn process_box_area_request(
} }
let Some(transform) = let Some(transform) =
root_transform_for_layout_node(&stacking_context_tree.compositor_info.scroll_tree, node) root_transform_for_layout_node(&stacking_context_tree.paint_info.scroll_tree, node)
else { else {
return Some(Rect::new(rect_union.origin, Size2D::zero())); return Some(Rect::new(rect_union.origin, Size2D::zero()));
}; };
@@ -136,7 +136,7 @@ pub(crate) fn process_box_areas_request(
.map(|rect| rect.to_untyped()); .map(|rect| rect.to_untyped());
let Some(transform) = let Some(transform) =
root_transform_for_layout_node(&stacking_context_tree.compositor_info.scroll_tree, node) root_transform_for_layout_node(&stacking_context_tree.paint_info.scroll_tree, node)
else { else {
return box_areas return box_areas
.map(|rect| Rect::new(rect.origin, Size2D::zero())) .map(|rect| Rect::new(rect.origin, Size2D::zero()))

View File

@@ -11,7 +11,7 @@ use std::{mem, thread};
use base::id::{PipelineId, WebViewId}; use base::id::{PipelineId, WebViewId};
use base::threadpool::ThreadPool; use base::threadpool::ThreadPool;
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData}; use compositing_traits::{CrossProcessPaintApi, ImageUpdate, SerializableImageData};
use imsz::imsz_from_reader; use imsz::imsz_from_reader;
use log::{debug, warn}; use log::{debug, warn};
use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps}; use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps};
@@ -121,7 +121,7 @@ fn decode_bytes_sync(
} }
fn set_webrender_image_key( fn set_webrender_image_key(
compositor_api: &CrossProcessCompositorApi, paint_api: &CrossProcessPaintApi,
image: &mut RasterImage, image: &mut RasterImage,
image_key: WebRenderImageKey, image_key: WebRenderImageKey,
) { ) {
@@ -132,7 +132,7 @@ fn set_webrender_image_key(
let (descriptor, ipc_shared_memory) = image.webrender_image_descriptor_and_data_for_frame(0); let (descriptor, ipc_shared_memory) = image.webrender_image_descriptor_and_data_for_frame(0);
let data = SerializableImageData::Raw(ipc_shared_memory); let data = SerializableImageData::Raw(ipc_shared_memory);
compositor_api.add_image(image_key, descriptor, data); paint_api.add_image(image_key, descriptor, data);
image.id = Some(image_key); image.id = Some(image_key);
} }
@@ -461,9 +461,9 @@ struct ImageCacheStore {
#[conditional_malloc_size_of] #[conditional_malloc_size_of]
broken_image_icon_image: OnceCell<Option<Arc<RasterImage>>>, broken_image_icon_image: OnceCell<Option<Arc<RasterImage>>>,
/// Cross-process compositor API instance. /// Cross-process `Paint` API instance.
#[ignore_malloc_size_of = "Channel from another crate"] #[ignore_malloc_size_of = "Channel from another crate"]
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
/// The [`WebView`] of the `Webview` associated with this [`ImageCache`]. /// The [`WebView`] of the `Webview` associated with this [`ImageCache`].
webview_id: WebViewId, webview_id: WebViewId,
@@ -481,11 +481,11 @@ impl ImageCacheStore {
fn set_key_and_finish_load(&mut self, pending_image: PendingKey, image_key: WebRenderImageKey) { fn set_key_and_finish_load(&mut self, pending_image: PendingKey, image_key: WebRenderImageKey) {
match pending_image { match pending_image {
PendingKey::RasterImage((pending_id, mut raster_image)) => { PendingKey::RasterImage((pending_id, mut raster_image)) => {
set_webrender_image_key(&self.compositor_api, &mut raster_image, image_key); set_webrender_image_key(&self.paint_api, &mut raster_image, image_key);
self.complete_load(pending_id, LoadResult::LoadedRasterImage(raster_image)); self.complete_load(pending_id, LoadResult::LoadedRasterImage(raster_image));
}, },
PendingKey::Svg((pending_id, mut raster_image, requested_size)) => { PendingKey::Svg((pending_id, mut raster_image, requested_size)) => {
set_webrender_image_key(&self.compositor_api, &mut raster_image, image_key); set_webrender_image_key(&self.paint_api, &mut raster_image, image_key);
self.complete_load_svg(raster_image, pending_id, requested_size); self.complete_load_svg(raster_image, pending_id, requested_size);
}, },
} }
@@ -512,7 +512,7 @@ impl ImageCacheStore {
fn fetch_more_image_keys(&mut self) { fn fetch_more_image_keys(&mut self) {
self.key_cache.cache = KeyCacheState::PendingBatch; self.key_cache.cache = KeyCacheState::PendingBatch;
self.compositor_api self.paint_api
.generate_image_key_async(self.webview_id, self.pipeline_id); .generate_image_key_async(self.webview_id, self.pipeline_id);
} }
@@ -533,7 +533,7 @@ impl ImageCacheStore {
self.load_image_with_keycache(key); self.load_image_with_keycache(key);
} }
if !self.key_cache.images_pending_keys.is_empty() { if !self.key_cache.images_pending_keys.is_empty() {
self.compositor_api self.paint_api
.generate_image_key_async(self.webview_id, self.pipeline_id); .generate_image_key_async(self.webview_id, self.pipeline_id);
self.key_cache.cache = KeyCacheState::PendingBatch self.key_cache.cache = KeyCacheState::PendingBatch
} }
@@ -689,7 +689,7 @@ impl ImageCacheFactory for ImageCacheFactoryImpl {
&self, &self,
webview_id: WebViewId, webview_id: WebViewId,
pipeline_id: PipelineId, pipeline_id: PipelineId,
compositor_api: &CrossProcessCompositorApi, paint_api: &CrossProcessPaintApi,
) -> Arc<dyn ImageCache> { ) -> Arc<dyn ImageCache> {
Arc::new(ImageCacheImpl { Arc::new(ImageCacheImpl {
store: Arc::new(Mutex::new(ImageCacheStore { store: Arc::new(Mutex::new(ImageCacheStore {
@@ -698,7 +698,7 @@ impl ImageCacheFactory for ImageCacheFactoryImpl {
vector_images: FxHashMap::default(), vector_images: FxHashMap::default(),
rasterized_vector_images: FxHashMap::default(), rasterized_vector_images: FxHashMap::default(),
broken_image_icon_image: OnceCell::new(), broken_image_icon_image: OnceCell::new(),
compositor_api: compositor_api.clone(), paint_api: paint_api.clone(),
pipeline_id, pipeline_id,
webview_id, webview_id,
key_cache: KeyCache::new(), key_cache: KeyCache::new(),
@@ -744,7 +744,7 @@ impl ImageCache for ImageCacheImpl {
} }
store store
.compositor_api .paint_api
.generate_image_key_blocking(store.webview_id) .generate_image_key_blocking(store.webview_id)
} }
@@ -1073,10 +1073,10 @@ impl ImageCache for ImageCacheImpl {
let mut image = load_from_memory(&self.broken_image_icon_data, CorsStatus::Unsafe) let mut image = load_from_memory(&self.broken_image_icon_data, CorsStatus::Unsafe)
.or_else(|| load_from_memory(FALLBACK_RIPPY, CorsStatus::Unsafe))?; .or_else(|| load_from_memory(FALLBACK_RIPPY, CorsStatus::Unsafe))?;
let image_key = store let image_key = store
.compositor_api .paint_api
.generate_image_key_blocking(store.webview_id) .generate_image_key_blocking(store.webview_id)
.expect("Could not generate image key for broken image icon"); .expect("Could not generate image key for broken image icon");
set_webrender_image_key(&store.compositor_api, &mut image, image_key); set_webrender_image_key(&store.paint_api, &mut image, image_key);
Some(Arc::new(image)) Some(Arc::new(image))
}) })
.clone() .clone()
@@ -1100,7 +1100,7 @@ impl Drop for ImageCacheStore {
.filter_map(|task| task.result.as_ref()?.id.map(ImageUpdate::DeleteImage)), .filter_map(|task| task.result.as_ref()?.id.map(ImageUpdate::DeleteImage)),
) )
.collect(); .collect();
self.compositor_api self.paint_api
.update_images(self.webview_id.into(), image_updates); .update_images(self.webview_id.into(), image_updates);
} }
} }

View File

@@ -6,7 +6,7 @@ use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use base::id::{PipelineId, TEST_PIPELINE_ID, TEST_WEBVIEW_ID}; use base::id::{PipelineId, TEST_PIPELINE_ID, TEST_WEBVIEW_ID};
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use crossbeam_channel::{Receiver, Sender, unbounded}; use crossbeam_channel::{Receiver, Sender, unbounded};
use net::image_cache::ImageCacheFactoryImpl; use net::image_cache::ImageCacheFactoryImpl;
use net_traits::image_cache::{ use net_traits::image_cache::{
@@ -26,17 +26,15 @@ use crate::mock_origin;
fn create_test_image_cache() -> (Arc<dyn ImageCache>, Receiver<PipelineId>) { fn create_test_image_cache() -> (Arc<dyn ImageCache>, Receiver<PipelineId>) {
let (sender, receiver) = unbounded(); let (sender, receiver) = unbounded();
let compositor_api = let paint_api = CrossProcessPaintApi::dummy_with_callback(Some(Box::new(move |msg| {
CrossProcessCompositorApi::dummy_with_callback(Some(Box::new(move |msg| { if let compositing_traits::PaintMessage::GenerateImageKeysForPipeline(_, pipeline_id) = msg
if let compositing_traits::CompositorMsg::GenerateImageKeysForPipeline(_, pipeline_id) = {
msg let _ = sender.send(pipeline_id);
{ }
let _ = sender.send(pipeline_id); })));
}
})));
let factory = ImageCacheFactoryImpl::new(vec![]); let factory = ImageCacheFactoryImpl::new(vec![]);
let cache = factory.create(TEST_WEBVIEW_ID, TEST_PIPELINE_ID, &compositor_api); let cache = factory.create(TEST_WEBVIEW_ID, TEST_PIPELINE_ID, &paint_api);
(cache, receiver) (cache, receiver)
} }

View File

@@ -375,7 +375,7 @@ pub(crate) struct Document {
/// Whether we're in the process of running animation callbacks. /// Whether we're in the process of running animation callbacks.
/// ///
/// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid /// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid
/// sending needless `ChangeRunningAnimationsState` messages to the compositor. /// sending needless `ChangeRunningAnimationsState` messages to `Paint`.
running_animation_callbacks: Cell<bool>, running_animation_callbacks: Cell<bool>,
/// Tracks all outstanding loads related to this document. /// Tracks all outstanding loads related to this document.
loader: DomRefCell<DocumentLoader>, loader: DomRefCell<DocumentLoader>,
@@ -2801,7 +2801,7 @@ impl Document {
if !image_keys.is_empty() { if !image_keys.is_empty() {
results.insert(ReflowPhasesRun::UpdatedImageData); results.insert(ReflowPhasesRun::UpdatedImageData);
self.waiting_on_canvas_image_updates.set(true); self.waiting_on_canvas_image_updates.set(true);
self.window().compositor_api().delay_new_frame_for_canvas( self.window().paint_api().delay_new_frame_for_canvas(
self.webview_id(), self.webview_id(),
self.window().pipeline_id(), self.window().pipeline_id(),
current_rendering_epoch, current_rendering_epoch,
@@ -2811,7 +2811,7 @@ impl Document {
let results = results.union(self.window().reflow(ReflowGoal::UpdateTheRendering)); let results = results.union(self.window().reflow(ReflowGoal::UpdateTheRendering));
self.window().compositor_api().update_epoch( self.window().paint_api().update_epoch(
self.webview_id(), self.webview_id(),
pipeline_id, pipeline_id,
current_rendering_epoch, current_rendering_epoch,

View File

@@ -70,9 +70,9 @@ pub(crate) struct DocumentEventHandler {
window: Dom<Window>, window: Dom<Window>,
/// Pending input events, to be handled at the next rendering opportunity. /// Pending input events, to be handled at the next rendering opportunity.
#[no_trace] #[no_trace]
#[ignore_malloc_size_of = "CompositorEvent contains data from outside crates"] #[ignore_malloc_size_of = "InputEvent contains data from outside crates"]
pending_input_events: DomRefCell<Vec<ConstellationInputEvent>>, pending_input_events: DomRefCell<Vec<ConstellationInputEvent>>,
/// The index of the last mouse move event in the pending compositor events queue. /// The index of the last mouse move event in the pending input events queue.
mouse_move_event_index: DomRefCell<Option<usize>>, mouse_move_event_index: DomRefCell<Option<usize>>,
/// <https://w3c.github.io/uievents/#event-type-dblclick> /// <https://w3c.github.io/uievents/#event-type-dblclick>
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
@@ -115,24 +115,24 @@ impl DocumentEventHandler {
} }
} }
/// Note a pending compositor event, to be processed at the next `update_the_rendering` task. /// Note a pending input event, to be processed at the next `update_the_rendering` task.
pub(crate) fn note_pending_input_event(&self, event: ConstellationInputEvent) { pub(crate) fn note_pending_input_event(&self, event: ConstellationInputEvent) {
let mut pending_compositor_events = self.pending_input_events.borrow_mut(); let mut pending_input_events = self.pending_input_events.borrow_mut();
if matches!(event.event.event, InputEvent::MouseMove(..)) { if matches!(event.event.event, InputEvent::MouseMove(..)) {
// First try to replace any existing mouse move event. // First try to replace any existing mouse move event.
if let Some(mouse_move_event) = self if let Some(mouse_move_event) = self
.mouse_move_event_index .mouse_move_event_index
.borrow() .borrow()
.and_then(|index| pending_compositor_events.get_mut(index)) .and_then(|index| pending_input_events.get_mut(index))
{ {
*mouse_move_event = event; *mouse_move_event = event;
return; return;
} }
*self.mouse_move_event_index.borrow_mut() = Some(pending_compositor_events.len()); *self.mouse_move_event_index.borrow_mut() = Some(pending_input_events.len());
} }
pending_compositor_events.push(event); pending_input_events.push(event);
} }
/// Whether or not this [`Document`] has any pending input events to be processed during /// Whether or not this [`Document`] has any pending input events to be processed during
@@ -466,8 +466,8 @@ impl DocumentEventHandler {
); );
} }
// Send mousemove event to topmost target, unless it's an iframe, in which case the // Send mousemove event to topmost target, unless it's an iframe, in which case
// compositor should have also sent an event to the inner document. // `Paint` should have also sent an event to the inner document.
MouseEvent::new_simple( MouseEvent::new_simple(
&self.window, &self.window,
FireMouseEventType::Move, FireMouseEventType::Move,
@@ -1605,7 +1605,7 @@ impl DocumentEventHandler {
if scrolling_box.is_viewport() && parent_pipeline.is_none() { if scrolling_box.is_viewport() && parent_pipeline.is_none() {
let (_, delta) = calculate_current_scroll_offset_and_delta(); let (_, delta) = calculate_current_scroll_offset_and_delta();
self.window self.window
.compositor_api() .paint_api()
.scroll_viewport_by_delta(self.window.webview_id(), delta); .scroll_viewport_by_delta(self.window.webview_id(), delta);
} }

View File

@@ -10,7 +10,7 @@ use std::time::{Duration, Instant};
use std::{f64, mem}; use std::{f64, mem};
use base::id::WebViewId; use base::id::WebViewId;
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData}; use compositing_traits::{CrossProcessPaintApi, ImageUpdate, SerializableImageData};
use content_security_policy::sandboxing_directive::SandboxingFlagSet; use content_security_policy::sandboxing_directive::SandboxingFlagSet;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState}; use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState};
@@ -171,7 +171,7 @@ pub(crate) struct MediaFrameRenderer {
webview_id: WebViewId, webview_id: WebViewId,
player_id: Option<usize>, player_id: Option<usize>,
glplayer_id: Option<u64>, glplayer_id: Option<u64>,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
#[ignore_malloc_size_of = "Defined in other crates"] #[ignore_malloc_size_of = "Defined in other crates"]
player_context: WindowGLContext, player_context: WindowGLContext,
current_frame: Option<MediaFrame>, current_frame: Option<MediaFrame>,
@@ -185,14 +185,14 @@ pub(crate) struct MediaFrameRenderer {
impl MediaFrameRenderer { impl MediaFrameRenderer {
fn new( fn new(
webview_id: WebViewId, webview_id: WebViewId,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
player_context: WindowGLContext, player_context: WindowGLContext,
) -> Self { ) -> Self {
Self { Self {
webview_id, webview_id,
player_id: None, player_id: None,
glplayer_id: None, glplayer_id: None,
compositor_api, paint_api,
player_context, player_context,
current_frame: None, current_frame: None,
old_frame: None, old_frame: None,
@@ -295,7 +295,7 @@ impl MediaFrameRenderer {
} }
if !updates.is_empty() { if !updates.is_empty() {
self.compositor_api self.paint_api
.update_images(self.webview_id.into(), updates); .update_images(self.webview_id.into(), updates);
} }
} }
@@ -361,9 +361,8 @@ impl VideoFrameRenderer for MediaFrameRenderer {
Some(current_frame) => { Some(current_frame) => {
self.old_frame = Some(current_frame.image_key); self.old_frame = Some(current_frame.image_key);
let Some(new_image_key) = self let Some(new_image_key) =
.compositor_api self.paint_api.generate_image_key_blocking(self.webview_id)
.generate_image_key_blocking(self.webview_id)
else { else {
return; return;
}; };
@@ -397,9 +396,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data)); updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data));
}, },
None => { None => {
let Some(image_key) = self let Some(image_key) = self.paint_api.generate_image_key_blocking(self.webview_id)
.compositor_api
.generate_image_key_blocking(self.webview_id)
else { else {
return; return;
}; };
@@ -432,7 +429,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data)); updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data));
}, },
} }
self.compositor_api self.paint_api
.update_images(self.webview_id.into(), updates); .update_images(self.webview_id.into(), updates);
} }
} }
@@ -649,7 +646,7 @@ impl HTMLMediaElement {
player: Default::default(), player: Default::default(),
video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new( video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
document.webview_id(), document.webview_id(),
document.window().compositor_api().clone(), document.window().paint_api().clone(),
document.window().get_player_context(), document.window().get_player_context(),
))), ))),
audio_renderer: Default::default(), audio_renderer: Default::default(),

View File

@@ -144,7 +144,7 @@ impl HTMLMetaElement {
if let Ok(viewport) = ViewportDescription::from_str(&content.value()) { if let Ok(viewport) = ViewportDescription::from_str(&content.value()) {
self.owner_window() self.owner_window()
.compositor_api() .paint_api()
.viewport(self.owner_window().webview_id(), viewport); .viewport(self.owner_window().webview_id(), viewport);
} }
} }

View File

@@ -120,7 +120,7 @@ impl InputEventMethods<crate::DomTypeHolder> for InputEvent {
} }
/// A [`HitTestResult`] that is the result of doing a hit test based on a less-fine-grained /// A [`HitTestResult`] that is the result of doing a hit test based on a less-fine-grained
/// `CompositorHitTestResult` against our current layout. /// `PaintHitTestResult` against our current layout.
pub(crate) struct HitTestResult { pub(crate) struct HitTestResult {
pub node: DomRoot<Node>, pub node: DomRoot<Node>,
pub cursor: Cursor, pub cursor: Cursor,

View File

@@ -23,7 +23,7 @@ use base64::Engine;
#[cfg(feature = "bluetooth")] #[cfg(feature = "bluetooth")]
use bluetooth_traits::BluetoothRequest; use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLChan; use canvas_traits::webgl::WebGLChan;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use constellation_traits::{ use constellation_traits::{
LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse, LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData, ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
@@ -407,10 +407,10 @@ pub(crate) struct Window {
/// Flag to identify whether mutation observers are present(true)/absent(false) /// Flag to identify whether mutation observers are present(true)/absent(false)
exists_mut_observer: Cell<bool>, exists_mut_observer: Cell<bool>,
/// Cross-process access to the compositor. /// Cross-process access to `Paint`.
#[ignore_malloc_size_of = "Wraps an IpcSender"] #[ignore_malloc_size_of = "Wraps an IpcSender"]
#[no_trace] #[no_trace]
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
/// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete. /// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete.
/// It is used to avoid sending idle message more than once, which is unnecessary. /// It is used to avoid sending idle message more than once, which is unnecessary.
@@ -744,8 +744,8 @@ impl Window {
let _ = std::mem::replace(&mut *self.pending_image_callbacks.borrow_mut(), images); let _ = std::mem::replace(&mut *self.pending_image_callbacks.borrow_mut(), images);
} }
pub(crate) fn compositor_api(&self) -> &CrossProcessCompositorApi { pub(crate) fn paint_api(&self) -> &CrossProcessPaintApi {
&self.compositor_api &self.paint_api
} }
pub(crate) fn userscripts(&self) -> &[UserScript] { pub(crate) fn userscripts(&self) -> &[UserScript] {
@@ -2399,7 +2399,7 @@ impl Window {
let reflow_phases_run = let reflow_phases_run =
self.reflow(ReflowGoal::UpdateScrollNode(scroll_id, Vector2D::new(x, y))); self.reflow(ReflowGoal::UpdateScrollNode(scroll_id, Vector2D::new(x, y)));
if reflow_phases_run.needs_frame() { if reflow_phases_run.needs_frame() {
self.compositor_api() self.paint_api()
.generate_frame(vec![self.webview_id().into()]); .generate_frame(vec![self.webview_id().into()]);
} }
@@ -2657,7 +2657,7 @@ impl Window {
// //
// See <https://github.com/servo/servo/issues/14719> // See <https://github.com/servo/servo/issues/14719>
if self.Document().update_the_rendering().needs_frame() { if self.Document().update_the_rendering().needs_frame() {
self.compositor_api() self.paint_api()
.generate_frame(vec![self.webview_id().into()]); .generate_frame(vec![self.webview_id().into()]);
} }
} }
@@ -3155,7 +3155,7 @@ impl Window {
// Set the window proxy to be this object. // Set the window proxy to be this object.
self.window_proxy().set_currently_active(self, can_gc); self.window_proxy().set_currently_active(self, can_gc);
// Push the document title to the compositor since we are // Push the document title to `Paint` since we are
// activating this document due to a navigation. // activating this document due to a navigation.
self.Document().title_changed(); self.Document().title_changed();
} }
@@ -3440,7 +3440,7 @@ impl Window {
navigation_start: CrossProcessInstant, navigation_start: CrossProcessInstant,
webgl_chan: Option<WebGLChan>, webgl_chan: Option<WebGLChan>,
#[cfg(feature = "webxr")] webxr_registry: Option<webxr_api::Registry>, #[cfg(feature = "webxr")] webxr_registry: Option<webxr_api::Registry>,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
unminify_js: bool, unminify_js: bool,
unminify_css: bool, unminify_css: bool,
local_script_source: Option<String>, local_script_source: Option<String>,
@@ -3523,7 +3523,7 @@ impl Window {
test_worklet: Default::default(), test_worklet: Default::default(),
paint_worklet: Default::default(), paint_worklet: Default::default(),
exists_mut_observer: Cell::new(false), exists_mut_observer: Cell::new(false),
compositor_api, paint_api,
has_sent_idle_message: Cell::new(false), has_sent_idle_message: Cell::new(false),
unminify_css, unminify_css,
user_content_manager, user_content_manager,

View File

@@ -79,7 +79,7 @@ impl ImageAnimationManager {
}) })
.collect(); .collect();
window window
.compositor_api() .paint_api()
.update_images(window.webview_id().into(), updates); .update_images(window.webview_id().into(), updates);
self.maybe_schedule_update(window, now); self.maybe_schedule_update(window, now);

View File

@@ -40,7 +40,7 @@ use base::id::{
}; };
use canvas_traits::webgl::WebGLPipeline; use canvas_traits::webgl::WebGLPipeline;
use chrono::{DateTime, Local}; use chrono::{DateTime, Local};
use compositing_traits::{CrossProcessCompositorApi, PipelineExitSource}; use compositing_traits::{CrossProcessPaintApi, PipelineExitSource};
use constellation_traits::{ use constellation_traits::{
JsEvalResult, LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse, JsEvalResult, LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData, ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
@@ -306,9 +306,9 @@ pub struct ScriptThread {
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack> /// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
custom_element_reaction_stack: Rc<CustomElementReactionStack>, custom_element_reaction_stack: Rc<CustomElementReactionStack>,
/// Cross-process access to the compositor's API. /// Cross-process access to `Paint`'s API.
#[no_trace] #[no_trace]
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
/// Periodically print out on which events script threads spend their processing time. /// Periodically print out on which events script threads spend their processing time.
profile_script_events: bool, profile_script_events: bool,
@@ -963,7 +963,7 @@ impl ScriptThread {
worklet_thread_pool: Default::default(), worklet_thread_pool: Default::default(),
docs_with_no_blocking_loads: Default::default(), docs_with_no_blocking_loads: Default::default(),
custom_element_reaction_stack: Rc::new(CustomElementReactionStack::new()), custom_element_reaction_stack: Rc::new(CustomElementReactionStack::new()),
compositor_api: state.cross_process_compositor_api, paint_api: state.cross_process_paint_api,
profile_script_events: opts.debug.profile_script_events, profile_script_events: opts.debug.profile_script_events,
print_pwm: opts.print_pwm, print_pwm: opts.print_pwm,
unminify_js: opts.unminify_js, unminify_js: opts.unminify_js,
@@ -1018,15 +1018,15 @@ impl ScriptThread {
debug!("Stopped script thread."); debug!("Stopped script thread.");
} }
/// Process compositor events as part of a "update the rendering task". /// Process input events as part of a "update the rendering task".
fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) { fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) {
let Some(document) = self.documents.borrow().find_document(pipeline_id) else { let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
warn!("Processing pending compositor events for closed pipeline {pipeline_id}."); warn!("Processing pending input events for closed pipeline {pipeline_id}.");
return; return;
}; };
// Do not handle events if the BC has been, or is being, discarded // Do not handle events if the BC has been, or is being, discarded
if document.window().Closed() { if document.window().Closed() {
warn!("Compositor event sent to a pipeline with a closed window {pipeline_id}."); warn!("Input event sent to a pipeline with a closed window {pipeline_id}.");
return; return;
} }
@@ -1122,7 +1122,7 @@ impl ScriptThread {
// TODO(#31581): The steps in the "Revealing the document" section need to be implemented // TODO(#31581): The steps in the "Revealing the document" section need to be implemented
// `process_pending_input_events` handles the focusing steps as well as other events // `process_pending_input_events` handles the focusing steps as well as other events
// from the compositor. // from `Paint`.
// TODO: Should this be broken and to match the specification more closely? For instance see // TODO: Should this be broken and to match the specification more closely? For instance see
// https://html.spec.whatwg.org/multipage/#flush-autofocus-candidates. // https://html.spec.whatwg.org/multipage/#flush-autofocus-candidates.
@@ -1205,7 +1205,7 @@ impl ScriptThread {
let should_generate_frame = !painters_generating_frames.is_empty(); let should_generate_frame = !painters_generating_frames.is_empty();
if should_generate_frame { if should_generate_frame {
self.compositor_api self.paint_api
.generate_frame(painters_generating_frames.into_iter().collect()); .generate_frame(painters_generating_frames.into_iter().collect());
} }
@@ -2960,7 +2960,7 @@ impl ScriptThread {
)) ))
.ok(); .ok();
self.compositor_api self.paint_api
.pipeline_exited(webview_id, pipeline_id, PipelineExitSource::Script); .pipeline_exited(webview_id, pipeline_id, PipelineExitSource::Script);
debug!("{pipeline_id}: Finished pipeline exit"); debug!("{pipeline_id}: Finished pipeline exit");
@@ -3128,14 +3128,14 @@ impl ScriptThread {
let font_context = Arc::new(FontContext::new( let font_context = Arc::new(FontContext::new(
self.system_font_service.clone(), self.system_font_service.clone(),
self.compositor_api.clone(), self.paint_api.clone(),
self.resource_threads.clone(), self.resource_threads.clone(),
)); ));
let image_cache = self.image_cache_factory.create( let image_cache = self.image_cache_factory.create(
incomplete.webview_id, incomplete.webview_id,
incomplete.pipeline_id, incomplete.pipeline_id,
&self.compositor_api, &self.paint_api,
); );
let layout_config = LayoutConfig { let layout_config = LayoutConfig {
@@ -3147,7 +3147,7 @@ impl ScriptThread {
image_cache: image_cache.clone(), image_cache: image_cache.clone(),
font_context: font_context.clone(), font_context: font_context.clone(),
time_profiler_chan: self.senders.time_profiler_sender.clone(), time_profiler_chan: self.senders.time_profiler_sender.clone(),
compositor_api: self.compositor_api.clone(), paint_api: self.paint_api.clone(),
viewport_details: incomplete.viewport_details, viewport_details: incomplete.viewport_details,
theme: incomplete.theme, theme: incomplete.theme,
}; };
@@ -3185,7 +3185,7 @@ impl ScriptThread {
self.webgl_chan.as_ref().map(|chan| chan.channel()), self.webgl_chan.as_ref().map(|chan| chan.channel()),
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]
self.webxr_registry.clone(), self.webxr_registry.clone(),
self.compositor_api.clone(), self.paint_api.clone(),
self.unminify_js, self.unminify_js,
self.unminify_css, self.unminify_css,
self.local_script_source.clone(), self.local_script_source.clone(),
@@ -3400,8 +3400,7 @@ impl ScriptThread {
} }
} }
/// Queue compositor events for later dispatching as part of a /// Queue input events for later dispatching as part of a `update_the_rendering` task.
/// `update_the_rendering` task.
fn handle_input_event( fn handle_input_event(
&self, &self,
webview_id: WebViewId, webview_id: WebViewId,
@@ -3409,7 +3408,7 @@ impl ScriptThread {
event: ConstellationInputEvent, event: ConstellationInputEvent,
) { ) {
let Some(document) = self.documents.borrow().find_document(pipeline_id) else { let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
warn!("Compositor event sent to closed pipeline {pipeline_id}."); warn!("Input event sent to closed pipeline {pipeline_id}.");
let _ = self let _ = self
.senders .senders
.pipeline_to_embedder_sender .pipeline_to_embedder_sender

View File

@@ -508,7 +508,7 @@ impl ServiceWorkerManagerFactory for ServiceWorkerManager {
receiver, receiver,
swmanager_sender: constellation_sender, swmanager_sender: constellation_sender,
system_font_service_sender, system_font_service_sender,
compositor_api, paint_api,
} = sw_senders; } = sw_senders;
let from_constellation = receiver.route_preserving_errors(); let from_constellation = receiver.route_preserving_errors();
@@ -519,7 +519,7 @@ impl ServiceWorkerManagerFactory for ServiceWorkerManager {
let font_context = Arc::new(FontContext::new( let font_context = Arc::new(FontContext::new(
Arc::new(system_font_service_sender.to_proxy()), Arc::new(system_font_service_sender.to_proxy()),
compositor_api, paint_api,
resource_threads, resource_threads,
)); ));

View File

@@ -17,9 +17,9 @@ use base::id::{PipelineNamespace, PipelineNamespaceId};
use bluetooth::BluetoothThreadFactory; use bluetooth::BluetoothThreadFactory;
#[cfg(feature = "bluetooth")] #[cfg(feature = "bluetooth")]
use bluetooth_traits::BluetoothRequest; use bluetooth_traits::BluetoothRequest;
use compositing::{IOCompositor, InitialCompositorState}; use compositing::{InitialPaintState, Paint};
pub use compositing_traits::rendering_context::RenderingContext; pub use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{CompositorMsg, CompositorProxy, CrossProcessCompositorApi}; use compositing_traits::{CrossProcessPaintApi, PaintMessage, PaintProxy};
#[cfg(all( #[cfg(all(
not(target_os = "windows"), not(target_os = "windows"),
not(target_os = "ios"), not(target_os = "ios"),
@@ -135,7 +135,7 @@ mod media_platform {
struct ServoInner { struct ServoInner {
delegate: RefCell<Rc<dyn ServoDelegate>>, delegate: RefCell<Rc<dyn ServoDelegate>>,
compositor: Rc<RefCell<IOCompositor>>, paint: Rc<RefCell<Paint>>,
constellation_proxy: ConstellationProxy, constellation_proxy: ConstellationProxy,
embedder_receiver: Receiver<EmbedderMsg>, embedder_receiver: Receiver<EmbedderMsg>,
public_resource_threads: ResourceThreads, public_resource_threads: ResourceThreads,
@@ -172,20 +172,20 @@ impl ServoInner {
} }
{ {
let compositor = self.compositor.borrow(); let paint = self.paint.borrow();
let mut messages = Vec::new(); let mut messages = Vec::new();
while let Ok(message) = compositor.receiver().try_recv() { while let Ok(message) = paint.receiver().try_recv() {
match message { match message {
Ok(message) => messages.push(message), Ok(message) => messages.push(message),
Err(error) => { Err(error) => {
warn!("Router deserialization error: {error}. Ignoring this CompositorMsg.") warn!("Router deserialization error: {error}. Ignoring this PaintMessage.")
}, },
} }
} }
compositor.handle_messages(messages); paint.handle_messages(messages);
} }
// Only handle incoming embedder messages if the compositor hasn't already started shutting down. // Only handle incoming embedder messages if `Paint` hasn't already started shutting down.
while let Ok(message) = self.embedder_receiver.try_recv() { while let Ok(message) = self.embedder_receiver.try_recv() {
self.handle_embedder_message(message); self.handle_embedder_message(message);
@@ -200,7 +200,7 @@ impl ServoInner {
.notify_error(ServoError::LostConnectionWithBackend); .notify_error(ServoError::LostConnectionWithBackend);
} }
self.compositor.borrow_mut().perform_updates(); self.paint.borrow_mut().perform_updates();
self.send_new_frame_ready_messages(); self.send_new_frame_ready_messages();
self.handle_delegate_errors(); self.handle_delegate_errors();
self.clean_up_destroyed_webview_handles(); self.clean_up_destroyed_webview_handles();
@@ -213,7 +213,7 @@ impl ServoInner {
} }
fn send_new_frame_ready_messages(&self) { fn send_new_frame_ready_messages(&self) {
let webviews_needing_repaint = self.compositor.borrow().webviews_needing_repaint(); let webviews_needing_repaint = self.paint.borrow().webviews_needing_repaint();
for webview in webviews_needing_repaint for webview in webviews_needing_repaint
.iter() .iter()
@@ -242,7 +242,7 @@ impl ServoInner {
fn finish_shutting_down(&self) { fn finish_shutting_down(&self) {
debug!("Servo received message that Constellation shutdown is complete"); debug!("Servo received message that Constellation shutdown is complete");
self.shutdown_state.set(ShutdownState::FinishedShuttingDown); self.shutdown_state.set(ShutdownState::FinishedShuttingDown);
self.compositor.borrow_mut().finish_shutting_down(); self.paint.borrow_mut().finish_shutting_down();
} }
fn handle_embedder_message(&self, message: EmbedderMsg) { fn handle_embedder_message(&self, message: EmbedderMsg) {
@@ -364,7 +364,7 @@ impl ServoInner {
.finish_evaluation(evaluation_id, result); .finish_evaluation(evaluation_id, result);
}, },
EmbedderMsg::InputEventHandled(webview_id, input_event_id, result) => { EmbedderMsg::InputEventHandled(webview_id, input_event_id, result) => {
self.compositor.borrow_mut().notify_input_event_handled( self.paint.borrow_mut().notify_input_event_handled(
webview_id, webview_id,
input_event_id, input_event_id,
result, result,
@@ -682,12 +682,11 @@ impl Servo {
PipelineNamespace::install(PipelineNamespaceId(0)); PipelineNamespace::install(PipelineNamespaceId(0));
// Get both endpoints of a special channel for communication between // Get both endpoints of a special channel for communication between
// the client window and the compositor. This channel is unique because // the client window and `Paint`. This channel is unique because
// messages to client may need to pump a platform-specific event loop // messages to client may need to pump a platform-specific event loop
// to deliver the message. // to deliver the message.
let event_loop_waker = builder.event_loop_waker; let event_loop_waker = builder.event_loop_waker;
let (compositor_proxy, compositor_receiver) = let (paint_proxy, paint_receiver) = create_paint_channel(event_loop_waker.clone());
create_compositor_channel(event_loop_waker.clone());
let (constellation_proxy, embedder_to_constellation_receiver) = ConstellationProxy::new(); let (constellation_proxy, embedder_to_constellation_receiver) = ConstellationProxy::new();
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone()); let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
let time_profiler_chan = profile_time::Profiler::create( let time_profiler_chan = profile_time::Profiler::create(
@@ -718,12 +717,12 @@ impl Servo {
let mut protocols = ProtocolRegistry::with_internal_protocols(); let mut protocols = ProtocolRegistry::with_internal_protocols();
protocols.merge(builder.protocol_registry); protocols.merge(builder.protocol_registry);
// The compositor coordinates with the client window to create the final // The `Paint` coordinates with the client window to create the final
// rendered page and display it somewhere. // rendered page and display it somewhere.
let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown)); let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown));
let compositor = IOCompositor::new(InitialCompositorState { let paint = Paint::new(InitialPaintState {
compositor_proxy: compositor_proxy.clone(), paint_proxy: paint_proxy.clone(),
receiver: compositor_receiver, receiver: paint_receiver,
embedder_to_constellation_sender: constellation_proxy.sender().clone(), embedder_to_constellation_sender: constellation_proxy.sender().clone(),
time_profiler_chan: time_profiler_chan.clone(), time_profiler_chan: time_profiler_chan.clone(),
mem_profiler_chan: mem_profiler_chan.clone(), mem_profiler_chan: mem_profiler_chan.clone(),
@@ -748,10 +747,10 @@ impl Servo {
create_constellation( create_constellation(
embedder_to_constellation_receiver, embedder_to_constellation_receiver,
&compositor.borrow(), &paint.borrow(),
opts.config_dir.clone(), opts.config_dir.clone(),
embedder_proxy, embedder_proxy,
compositor_proxy.clone(), paint_proxy.clone(),
time_profiler_chan, time_profiler_chan,
mem_profiler_chan, mem_profiler_chan,
devtools_sender, devtools_sender,
@@ -768,7 +767,7 @@ impl Servo {
Servo(Rc::new(ServoInner { Servo(Rc::new(ServoInner {
delegate: RefCell::new(Rc::new(DefaultServoDelegate)), delegate: RefCell::new(Rc::new(DefaultServoDelegate)),
compositor, paint,
javascript_evaluator: Rc::new(RefCell::new(JavaScriptEvaluator::new( javascript_evaluator: Rc::new(RefCell::new(JavaScriptEvaluator::new(
constellation_proxy.clone(), constellation_proxy.clone(),
))), ))),
@@ -799,9 +798,9 @@ impl Servo {
/// Spin the Servo event loop, which: /// Spin the Servo event loop, which:
/// ///
/// - Performs updates in the compositor, such as queued pinch zoom events /// - Performs updates in `Paint`, such as queued pinch zoom events
/// - Runs delebgate methods on all `WebView`s and `Servo` itself /// - Runs delebgate methods on all `WebView`s and `Servo` itself
/// - Maybe update the rendered compositor output, but *without* swapping buffers. /// - Maybe update the rendered `Paint` output, but *without* swapping buffers.
pub fn spin_event_loop(&self) { pub fn spin_event_loop(&self) {
self.0.spin_event_loop(); self.0.spin_event_loop();
} }
@@ -846,12 +845,12 @@ impl Servo {
self.0.private_resource_threads.clear_cookies(); self.0.private_resource_threads.clear_cookies();
} }
pub(crate) fn compositor<'a>(&'a self) -> Ref<'a, IOCompositor> { pub(crate) fn paint<'a>(&'a self) -> Ref<'a, Paint> {
self.0.compositor.borrow() self.0.paint.borrow()
} }
pub(crate) fn compositor_mut<'a>(&'a self) -> RefMut<'a, IOCompositor> { pub(crate) fn paint_mut<'a>(&'a self) -> RefMut<'a, Paint> {
self.0.compositor.borrow_mut() self.0.paint.borrow_mut()
} }
pub(crate) fn webviews_mut<'a>( pub(crate) fn webviews_mut<'a>(
@@ -882,14 +881,14 @@ fn create_embedder_channel(
) )
} }
fn create_compositor_channel( fn create_paint_channel(
event_loop_waker: Box<dyn EventLoopWaker>, event_loop_waker: Box<dyn EventLoopWaker>,
) -> (CompositorProxy, RoutedReceiver<CompositorMsg>) { ) -> (PaintProxy, RoutedReceiver<PaintMessage>) {
let (sender, receiver) = unbounded(); let (sender, receiver) = unbounded();
let sender_clone = sender.clone(); let sender_clone = sender.clone();
let event_loop_waker_clone = event_loop_waker.clone(); let event_loop_waker_clone = event_loop_waker.clone();
// This callback is equivalent to `CompositorProxy::send` // This callback is equivalent to `PaintProxy::send`
let result_callback = move |msg: Result<CompositorMsg, ipc_channel::Error>| { let result_callback = move |msg: Result<PaintMessage, ipc_channel::Error>| {
if let Err(err) = sender_clone.send(msg) { if let Err(err) = sender_clone.send(msg) {
warn!("Failed to send response ({:?}).", err); warn!("Failed to send response ({:?}).", err);
} }
@@ -898,23 +897,23 @@ fn create_compositor_channel(
let generic_callback = let generic_callback =
GenericCallback::new(result_callback).expect("Failed to create callback"); GenericCallback::new(result_callback).expect("Failed to create callback");
let cross_process_compositor_api = CrossProcessCompositorApi::new(generic_callback); let cross_process_paint_api = CrossProcessPaintApi::new(generic_callback);
let compositor_proxy = CompositorProxy { let paint_proxy = PaintProxy {
sender, sender,
cross_process_compositor_api, cross_process_paint_api,
event_loop_waker, event_loop_waker,
}; };
(compositor_proxy, receiver) (paint_proxy, receiver)
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn create_constellation( fn create_constellation(
embedder_to_constellation_receiver: Receiver<EmbedderToConstellationMessage>, embedder_to_constellation_receiver: Receiver<EmbedderToConstellationMessage>,
compositor: &IOCompositor, paint: &Paint,
config_dir: Option<PathBuf>, config_dir: Option<PathBuf>,
embedder_proxy: EmbedderProxy, embedder_proxy: EmbedderProxy,
compositor_proxy: CompositorProxy, paint_proxy: PaintProxy,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan, mem_profiler_chan: mem::ProfilerChan,
devtools_sender: Option<Sender<devtools_traits::DevtoolsControlMsg>>, devtools_sender: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
@@ -938,14 +937,14 @@ fn create_constellation(
let system_font_service = Arc::new( let system_font_service = Arc::new(
SystemFontService::spawn( SystemFontService::spawn(
compositor_proxy.cross_process_compositor_api.clone(), paint_proxy.cross_process_paint_api.clone(),
mem_profiler_chan.clone(), mem_profiler_chan.clone(),
) )
.to_proxy(), .to_proxy(),
); );
let initial_state = InitialConstellationState { let initial_state = InitialConstellationState {
compositor_proxy, paint_proxy,
embedder_proxy, embedder_proxy,
devtools_sender, devtools_sender,
#[cfg(feature = "bluetooth")] #[cfg(feature = "bluetooth")]
@@ -958,13 +957,13 @@ fn create_constellation(
time_profiler_chan, time_profiler_chan,
mem_profiler_chan, mem_profiler_chan,
#[cfg(feature = "webxr")] #[cfg(feature = "webxr")]
webxr_registry: Some(compositor.webxr_main_thread_registry()), webxr_registry: Some(paint.webxr_main_thread_registry()),
#[cfg(not(feature = "webxr"))] #[cfg(not(feature = "webxr"))]
webxr_registry: None, webxr_registry: None,
webgl_threads: Some(compositor.webgl_threads()), webgl_threads: Some(paint.webgl_threads()),
webrender_external_image_id_manager: compositor.webrender_external_image_id_manager(), webrender_external_image_id_manager: paint.webrender_external_image_id_manager(),
#[cfg(feature = "webgpu")] #[cfg(feature = "webgpu")]
wgpu_image_map: compositor.webgpu_image_map(), wgpu_image_map: paint.webgpu_image_map(),
user_content_manager, user_content_manager,
async_runtime, async_runtime,
privileged_urls, privileged_urls,

View File

@@ -105,7 +105,7 @@ impl Drop for WebViewInner {
self.servo self.servo
.constellation_proxy() .constellation_proxy()
.send(EmbedderToConstellationMessage::CloseWebView(self.id)); .send(EmbedderToConstellationMessage::CloseWebView(self.id));
self.servo.compositor_mut().remove_webview(self.id); self.servo.paint_mut().remove_webview(self.id);
} }
} }
@@ -113,7 +113,7 @@ impl WebView {
pub(crate) fn new(builder: WebViewBuilder) -> Self { pub(crate) fn new(builder: WebViewBuilder) -> Self {
let servo = builder.servo; let servo = builder.servo;
let painter_id = servo let painter_id = servo
.compositor_mut() .paint_mut()
.register_rendering_context(builder.rendering_context.clone()); .register_rendering_context(builder.rendering_context.clone());
let id = WebViewId::new(painter_id); let id = WebViewId::new(painter_id);
@@ -136,7 +136,7 @@ impl WebView {
}))); })));
let viewport_details = webview.viewport_details(); let viewport_details = webview.viewport_details();
servo.compositor().add_webview( servo.paint().add_webview(
Box::new(ServoRendererWebView { Box::new(ServoRendererWebView {
weak_handle: webview.weak_handle(), weak_handle: webview.weak_handle(),
id, id,
@@ -339,7 +339,7 @@ impl WebView {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.resize_rendering_context(self.id(), new_size); .resize_rendering_context(self.id(), new_size);
} }
@@ -358,14 +358,14 @@ impl WebView {
self.inner_mut().hidpi_scale_factor = new_scale_factor; self.inner_mut().hidpi_scale_factor = new_scale_factor;
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.set_hidpi_scale_factor(self.id(), new_scale_factor); .set_hidpi_scale_factor(self.id(), new_scale_factor);
} }
pub fn show(&self) { pub fn show(&self) {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.show_webview(self.id()) .show_webview(self.id())
.expect("BUG: invalid WebView instance"); .expect("BUG: invalid WebView instance");
} }
@@ -373,7 +373,7 @@ impl WebView {
pub fn hide(&self) { pub fn hide(&self) {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.hide_webview(self.id()) .hide_webview(self.id())
.expect("BUG: invalid WebView instance"); .expect("BUG: invalid WebView instance");
} }
@@ -443,7 +443,7 @@ impl WebView {
pub fn notify_scroll_event(&self, scroll: Scroll, point: WebViewPoint) { pub fn notify_scroll_event(&self, scroll: Scroll, point: WebViewPoint) {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.notify_scroll_event(self.id(), scroll, point); .notify_scroll_event(self.id(), scroll, point);
} }
@@ -451,11 +451,11 @@ impl WebView {
let event: InputEventAndId = event.into(); let event: InputEventAndId = event.into();
let event_id = event.id; let event_id = event.id;
// Events with a `point` first go to the compositor for hit testing. // Events with a `point` first go to `Paint` for hit testing.
if event.event.point().is_some() { if event.event.point().is_some() {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.notify_input_event(self.id(), event); .notify_input_event(self.id(), event);
} else { } else {
self.inner().servo.constellation_proxy().send( self.inner().servo.constellation_proxy().send(
@@ -491,13 +491,13 @@ impl WebView {
pub fn set_page_zoom(&self, new_zoom: f32) { pub fn set_page_zoom(&self, new_zoom: f32) {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.set_page_zoom(self.id(), new_zoom); .set_page_zoom(self.id(), new_zoom);
} }
/// Get the page zoom of the [`WebView`]. /// Get the page zoom of the [`WebView`].
pub fn page_zoom(&self) -> f32 { pub fn page_zoom(&self) -> f32 {
self.inner().servo.compositor().page_zoom(self.id()) self.inner().servo.paint().page_zoom(self.id())
} }
/// Adjust the pinch zoom on this [`WebView`] multiplying the current pinch zoom /// Adjust the pinch zoom on this [`WebView`] multiplying the current pinch zoom
@@ -512,14 +512,14 @@ impl WebView {
pub fn pinch_zoom(&self, pinch_zoom_delta: f32, center: DevicePoint) { pub fn pinch_zoom(&self, pinch_zoom_delta: f32, center: DevicePoint) {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.pinch_zoom(self.id(), pinch_zoom_delta, center); .pinch_zoom(self.id(), pinch_zoom_delta, center);
} }
pub fn device_pixels_per_css_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> { pub fn device_pixels_per_css_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.device_pixels_per_page_pixel(self.id()) .device_pixels_per_page_pixel(self.id())
} }
@@ -537,14 +537,11 @@ impl WebView {
} }
pub fn toggle_webrender_debugging(&self, debugging: WebRenderDebugOption) { pub fn toggle_webrender_debugging(&self, debugging: WebRenderDebugOption) {
self.inner() self.inner().servo.paint().toggle_webrender_debug(debugging);
.servo
.compositor()
.toggle_webrender_debug(debugging);
} }
pub fn capture_webrender(&self) { pub fn capture_webrender(&self) {
self.inner().servo.compositor().capture_webrender(self.id()); self.inner().servo.paint().capture_webrender(self.id());
} }
pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) { pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) {
@@ -565,7 +562,7 @@ impl WebView {
/// Paint the contents of this [`WebView`] into its `RenderingContext`. /// Paint the contents of this [`WebView`] into its `RenderingContext`.
pub fn paint(&self) { pub fn paint(&self) {
self.inner().servo.compositor().render(self.id()); self.inner().servo.paint().render(self.id());
} }
/// Evaluate the specified string of JavaScript code. Once execution is complete or an error /// Evaluate the specified string of JavaScript code. Once execution is complete or an error
@@ -606,7 +603,7 @@ impl WebView {
) { ) {
self.inner() self.inner()
.servo .servo
.compositor() .paint()
.request_screenshot(self.id(), rect, Box::new(callback)); .request_screenshot(self.id(), rect, Box::new(callback));
} }

View File

@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Defines data structures which are consumed by the Compositor. //! Defines data structures which are consumed by `Paint`.
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashMap; use std::collections::HashMap;
@@ -419,12 +419,12 @@ impl ScrollTreeNode {
} }
/// A tree of spatial nodes, which mirrors the spatial nodes in the WebRender /// A tree of spatial nodes, which mirrors the spatial nodes in the WebRender
/// display list, except these are used to scrolling in the compositor so that /// display list, except these are used for scrolling in `Paint` so that
/// new offsets can be sent to WebRender. /// new offsets can be sent to WebRender.
#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)] #[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
pub struct ScrollTree { pub struct ScrollTree {
/// A list of compositor-side scroll nodes that describe the tree /// A list of `Paint`-side scroll nodes that describe the tree
/// of WebRender spatial nodes, used by the compositor to scroll the /// of WebRender spatial nodes, used by `Paint` to scroll the
/// contents of the display list. /// contents of the display list.
pub nodes: Vec<ScrollTreeNode>, pub nodes: Vec<ScrollTreeNode>,
} }
@@ -799,10 +799,10 @@ impl ScrollTree {
} }
} }
/// A data structure which stores compositor-side information about /// A data structure which stores `Paint`-side information about
/// display lists sent to the compositor. /// display lists sent to `Paint`.
#[derive(Debug, Deserialize, MallocSizeOf, Serialize)] #[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct CompositorDisplayListInfo { pub struct PaintDisplayListInfo {
/// The WebRender [PipelineId] of this display list. /// The WebRender [PipelineId] of this display list.
pub pipeline_id: PipelineId, pub pipeline_id: PipelineId,
@@ -816,7 +816,7 @@ pub struct CompositorDisplayListInfo {
/// The epoch of the display list. /// The epoch of the display list.
pub epoch: Epoch, pub epoch: Epoch,
/// A ScrollTree used by the compositor to scroll the contents of the /// A ScrollTree used by `Paint` to scroll the contents of the
/// display list. /// display list.
pub scroll_tree: ScrollTree, pub scroll_tree: ScrollTree,
@@ -838,8 +838,8 @@ pub struct CompositorDisplayListInfo {
pub first_reflow: bool, pub first_reflow: bool,
} }
impl CompositorDisplayListInfo { impl PaintDisplayListInfo {
/// Create a new CompositorDisplayListInfo with the root reference frame /// Create a new PaintDisplayListInfo with the root reference frame
/// and scroll frame already added to the scroll tree. /// and scroll frame already added to the scroll tree.
pub fn new( pub fn new(
viewport_details: ViewportDetails, viewport_details: ViewportDetails,
@@ -875,7 +875,7 @@ impl CompositorDisplayListInfo {
}), }),
); );
CompositorDisplayListInfo { PaintDisplayListInfo {
pipeline_id, pipeline_id,
viewport_details, viewport_details,
content_size, content_size,

View File

@@ -29,7 +29,7 @@ use std::sync::{Arc, Mutex};
use base::generic_channel::{self, GenericCallback, GenericSender}; use base::generic_channel::{self, GenericCallback, GenericSender};
use bitflags::bitflags; use bitflags::bitflags;
use display_list::CompositorDisplayListInfo; use display_list::PaintDisplayListInfo;
use embedder_traits::ScreenGeometry; use embedder_traits::ScreenGeometry;
use euclid::default::Size2D as UntypedSize2D; use euclid::default::Size2D as UntypedSize2D;
use ipc_channel::ipc::{self, IpcSharedMemory}; use ipc_channel::ipc::{self, IpcSharedMemory};
@@ -47,25 +47,25 @@ use webrender_api::{
use crate::largest_contentful_paint_candidate::LCPCandidate; use crate::largest_contentful_paint_candidate::LCPCandidate;
use crate::viewport_description::ViewportDescription; use crate::viewport_description::ViewportDescription;
/// Sends messages to the compositor. /// Sends messages to `Paint`.
#[derive(Clone)] #[derive(Clone)]
pub struct CompositorProxy { pub struct PaintProxy {
pub sender: Sender<Result<CompositorMsg, ipc_channel::Error>>, pub sender: Sender<Result<PaintMessage, ipc_channel::Error>>,
/// Access to [`Self::sender`] that is possible to send across an IPC /// Access to [`Self::sender`] that is possible to send across an IPC
/// channel. These messages are routed via the router thread to /// channel. These messages are routed via the router thread to
/// [`Self::sender`]. /// [`Self::sender`].
pub cross_process_compositor_api: CrossProcessCompositorApi, pub cross_process_paint_api: CrossProcessPaintApi,
pub event_loop_waker: Box<dyn EventLoopWaker>, pub event_loop_waker: Box<dyn EventLoopWaker>,
} }
impl OpaqueSender<CompositorMsg> for CompositorProxy { impl OpaqueSender<PaintMessage> for PaintProxy {
fn send(&self, message: CompositorMsg) { fn send(&self, message: PaintMessage) {
CompositorProxy::send(self, message) PaintProxy::send(self, message)
} }
} }
impl CompositorProxy { impl PaintProxy {
pub fn send(&self, msg: CompositorMsg) { pub fn send(&self, msg: PaintMessage) {
self.route_msg(Ok(msg)) self.route_msg(Ok(msg))
} }
@@ -73,7 +73,7 @@ impl CompositorProxy {
/// ///
/// This method is a temporary solution, and will be removed when migrating /// This method is a temporary solution, and will be removed when migrating
/// to `GenericChannel`. /// to `GenericChannel`.
pub fn route_msg(&self, msg: Result<CompositorMsg, ipc_channel::Error>) { pub fn route_msg(&self, msg: Result<PaintMessage, ipc_channel::Error>) {
if let Err(err) = self.sender.send(msg) { if let Err(err) = self.sender.send(msg) {
warn!("Failed to send response ({:?}).", err); warn!("Failed to send response ({:?}).", err);
} }
@@ -81,16 +81,16 @@ impl CompositorProxy {
} }
} }
/// Messages from (or via) the constellation thread to the compositor. /// Messages from (or via) the constellation thread to `Paint`.
#[derive(Deserialize, IntoStaticStr, Serialize)] #[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum CompositorMsg { pub enum PaintMessage {
/// Alerts the compositor that the given pipeline has changed whether it is running animations. /// Alerts `Paint` that the given pipeline has changed whether it is running animations.
ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState), ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
/// Updates the frame tree for the given webview. /// Updates the frame tree for the given webview.
SetFrameTreeForWebView(WebViewId, SendableFrameTree), SetFrameTreeForWebView(WebViewId, SendableFrameTree),
/// Set whether to use less resources by stopping animations. /// Set whether to use less resources by stopping animations.
SetThrottled(WebViewId, PipelineId, bool), SetThrottled(WebViewId, PipelineId, bool),
/// WebRender has produced a new frame. This message informs the compositor that /// WebRender has produced a new frame. This message informs `Paint` that
/// the frame is ready. It contains a bool to indicate if it needs to composite, the /// the frame is ready. It contains a bool to indicate if it needs to composite, the
/// `DocumentId` of the new frame and the `PainterId` of the associated painter. /// `DocumentId` of the new frame and the `PainterId` of the associated painter.
NewWebRenderFrameReady(PainterId, DocumentId, bool), NewWebRenderFrameReady(PainterId, DocumentId, bool),
@@ -172,19 +172,19 @@ pub enum CompositorMsg {
), ),
/// Remove the given font resources from our WebRender instance. /// Remove the given font resources from our WebRender instance.
RemoveFonts(PainterId, Vec<FontKey>, Vec<FontInstanceKey>), RemoveFonts(PainterId, Vec<FontKey>, Vec<FontInstanceKey>),
/// Measure the current memory usage associated with the compositor. /// Measure the current memory usage associated with `Paint`.
/// The report must be sent on the provided channel once it's complete. /// The report must be sent on the provided channel once it's complete.
CollectMemoryReport(ReportsChan), CollectMemoryReport(ReportsChan),
/// A top-level frame has parsed a viewport metatag and is sending the new constraints. /// A top-level frame has parsed a viewport metatag and is sending the new constraints.
Viewport(WebViewId, ViewportDescription), Viewport(WebViewId, ViewportDescription),
/// Let the compositor know that the given WebView is ready to have a screenshot taken /// Let `Paint` know that the given WebView is ready to have a screenshot taken
/// after the given pipeline's epochs have been rendered. /// after the given pipeline's epochs have been rendered.
ScreenshotReadinessReponse(WebViewId, FxHashMap<PipelineId, Epoch>), ScreenshotReadinessReponse(WebViewId, FxHashMap<PipelineId, Epoch>),
/// The candidate of largest-contentful-paint /// The candidate of largest-contentful-paint
SendLCPCandidate(LCPCandidate, WebViewId, PipelineId, Epoch), SendLCPCandidate(LCPCandidate, WebViewId, PipelineId, Epoch),
} }
impl Debug for CompositorMsg { impl Debug for PaintMessage {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> { fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
let string: &'static str = self.into(); let string: &'static str = self.into();
write!(formatter, "{string}") write!(formatter, "{string}")
@@ -206,29 +206,29 @@ pub struct CompositionPipeline {
/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance. /// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct CrossProcessCompositorApi(GenericCallback<CompositorMsg>); pub struct CrossProcessPaintApi(GenericCallback<PaintMessage>);
impl CrossProcessCompositorApi { impl CrossProcessPaintApi {
/// Create a new [`CrossProcessCompositorApi`] struct. /// Create a new [`CrossProcessPaintApi`] struct.
pub fn new(callback: GenericCallback<CompositorMsg>) -> Self { pub fn new(callback: GenericCallback<PaintMessage>) -> Self {
CrossProcessCompositorApi(callback) CrossProcessPaintApi(callback)
} }
/// Create a new [`CrossProcessCompositorApi`] struct that does not have a listener on the other /// Create a new [`CrossProcessPaintApi`] struct that does not have a listener on the other
/// end to use for unit testing. /// end to use for unit testing.
pub fn dummy() -> Self { pub fn dummy() -> Self {
Self::dummy_with_callback(None) Self::dummy_with_callback(None)
} }
/// Create a new [`CrossProcessCompositorApi`] struct for unit testing with an optional callback /// Create a new [`CrossProcessPaintApi`] struct for unit testing with an optional callback
/// that can respond to compositor messages. /// that can respond to `PaintMessage`s.
pub fn dummy_with_callback( pub fn dummy_with_callback(
callback: Option<Box<dyn Fn(CompositorMsg) + Send + 'static>>, callback: Option<Box<dyn Fn(PaintMessage) + Send + 'static>>,
) -> Self { ) -> Self {
let callback = GenericCallback::new(move |msg| { let callback = GenericCallback::new(move |msg| {
if let Some(ref handler) = callback { if let Some(ref handler) = callback {
if let Ok(compositor_msg) = msg { if let Ok(paint_message) = msg {
handler(compositor_msg); handler(paint_message);
} }
} }
}) })
@@ -240,7 +240,7 @@ impl CrossProcessCompositorApi {
pub fn send_initial_transaction(&self, webview_id: WebViewId, pipeline: WebRenderPipelineId) { pub fn send_initial_transaction(&self, webview_id: WebViewId, pipeline: WebRenderPipelineId) {
if let Err(e) = self if let Err(e) = self
.0 .0
.send(CompositorMsg::SendInitialTransaction(webview_id, pipeline)) .send(PaintMessage::SendInitialTransaction(webview_id, pipeline))
{ {
warn!("Error sending initial transaction: {}", e); warn!("Error sending initial transaction: {}", e);
} }
@@ -256,7 +256,7 @@ impl CrossProcessCompositorApi {
delta: LayoutVector2D, delta: LayoutVector2D,
scroll_id: ExternalScrollId, scroll_id: ExternalScrollId,
) { ) {
if let Err(error) = self.0.send(CompositorMsg::ScrollNodeByDelta( if let Err(error) = self.0.send(PaintMessage::ScrollNodeByDelta(
webview_id, webview_id,
pipeline_id, pipeline_id,
delta, delta,
@@ -275,7 +275,7 @@ impl CrossProcessCompositorApi {
pub fn scroll_viewport_by_delta(&self, webview_id: WebViewId, delta: LayoutVector2D) { pub fn scroll_viewport_by_delta(&self, webview_id: WebViewId, delta: LayoutVector2D) {
if let Err(error) = self if let Err(error) = self
.0 .0
.send(CompositorMsg::ScrollViewportByDelta(webview_id, delta)) .send(PaintMessage::ScrollViewportByDelta(webview_id, delta))
{ {
warn!("Error scroll viewport: {error}"); warn!("Error scroll viewport: {error}");
} }
@@ -288,7 +288,7 @@ impl CrossProcessCompositorApi {
canvas_epoch: Epoch, canvas_epoch: Epoch,
image_keys: Vec<ImageKey>, image_keys: Vec<ImageKey>,
) { ) {
if let Err(error) = self.0.send(CompositorMsg::DelayNewFrameForCanvas( if let Err(error) = self.0.send(PaintMessage::DelayNewFrameForCanvas(
webview_id, webview_id,
pipeline_id, pipeline_id,
canvas_epoch, canvas_epoch,
@@ -301,7 +301,7 @@ impl CrossProcessCompositorApi {
/// Inform the renderer that the rendering epoch has advanced. This typically happens after /// Inform the renderer that the rendering epoch has advanced. This typically happens after
/// a new display list is sent and/or canvas and animated images are updated. /// a new display list is sent and/or canvas and animated images are updated.
pub fn update_epoch(&self, webview_id: WebViewId, pipeline_id: PipelineId, epoch: Epoch) { pub fn update_epoch(&self, webview_id: WebViewId, pipeline_id: PipelineId, epoch: Epoch) {
if let Err(error) = self.0.send(CompositorMsg::UpdateEpoch { if let Err(error) = self.0.send(PaintMessage::UpdateEpoch {
webview_id, webview_id,
pipeline_id, pipeline_id,
epoch, epoch,
@@ -314,12 +314,12 @@ impl CrossProcessCompositorApi {
pub fn send_display_list( pub fn send_display_list(
&self, &self,
webview_id: WebViewId, webview_id: WebViewId,
display_list_info: &CompositorDisplayListInfo, display_list_info: &PaintDisplayListInfo,
list: BuiltDisplayList, list: BuiltDisplayList,
) { ) {
let (display_list_data, display_list_descriptor) = list.into_data(); let (display_list_data, display_list_descriptor) = list.into_data();
let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap(); let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
if let Err(e) = self.0.send(CompositorMsg::SendDisplayList { if let Err(e) = self.0.send(PaintMessage::SendDisplayList {
webview_id, webview_id,
display_list_descriptor, display_list_descriptor,
display_list_receiver, display_list_receiver,
@@ -344,7 +344,7 @@ impl CrossProcessCompositorApi {
} }
} }
/// Send the largest contentful paint candidate to the compositor. /// Send the largest contentful paint candidate to `Paint`.
pub fn send_lcp_candidate( pub fn send_lcp_candidate(
&self, &self,
lcp_candidate: LCPCandidate, lcp_candidate: LCPCandidate,
@@ -352,7 +352,7 @@ impl CrossProcessCompositorApi {
pipeline_id: PipelineId, pipeline_id: PipelineId,
epoch: Epoch, epoch: Epoch,
) { ) {
if let Err(error) = self.0.send(CompositorMsg::SendLCPCandidate( if let Err(error) = self.0.send(PaintMessage::SendLCPCandidate(
lcp_candidate, lcp_candidate,
webview_id, webview_id,
pipeline_id, pipeline_id,
@@ -364,7 +364,7 @@ impl CrossProcessCompositorApi {
/// Ask the Servo renderer to generate a new frame after having new display lists. /// Ask the Servo renderer to generate a new frame after having new display lists.
pub fn generate_frame(&self, painter_ids: Vec<PainterId>) { pub fn generate_frame(&self, painter_ids: Vec<PainterId>) {
if let Err(error) = self.0.send(CompositorMsg::GenerateFrame(painter_ids)) { if let Err(error) = self.0.send(PaintMessage::GenerateFrame(painter_ids)) {
warn!("Error generating frame: {error}"); warn!("Error generating frame: {error}");
} }
} }
@@ -373,20 +373,20 @@ impl CrossProcessCompositorApi {
pub fn generate_image_key_blocking(&self, webview_id: WebViewId) -> Option<ImageKey> { pub fn generate_image_key_blocking(&self, webview_id: WebViewId) -> Option<ImageKey> {
let (sender, receiver) = generic_channel::channel().unwrap(); let (sender, receiver) = generic_channel::channel().unwrap();
self.0 self.0
.send(CompositorMsg::GenerateImageKey(webview_id, sender)) .send(PaintMessage::GenerateImageKey(webview_id, sender))
.ok()?; .ok()?;
receiver.recv().ok() receiver.recv().ok()
} }
/// Sends a message to the compositor for creating new image keys. /// Sends a message to `Paint` for creating new image keys.
/// The compositor will then send a batch of keys over the constellation to the script_thread /// `Paint` will then send a batch of keys over the constellation to the script_thread
/// and the appropriate pipeline. /// and the appropriate pipeline.
pub fn generate_image_key_async(&self, webview_id: WebViewId, pipeline_id: PipelineId) { pub fn generate_image_key_async(&self, webview_id: WebViewId, pipeline_id: PipelineId) {
if let Err(e) = self.0.send(CompositorMsg::GenerateImageKeysForPipeline( if let Err(e) = self.0.send(PaintMessage::GenerateImageKeysForPipeline(
webview_id, webview_id,
pipeline_id, pipeline_id,
)) { )) {
warn!("Could not send image keys to Compositor {}", e); warn!("Could not send image keys to Paint {}", e);
} }
} }
@@ -421,10 +421,7 @@ impl CrossProcessCompositorApi {
/// Perform an image resource update operation. /// Perform an image resource update operation.
pub fn update_images(&self, painter_id: PainterId, updates: SmallVec<[ImageUpdate; 1]>) { pub fn update_images(&self, painter_id: PainterId, updates: SmallVec<[ImageUpdate; 1]>) {
if let Err(e) = self if let Err(e) = self.0.send(PaintMessage::UpdateImages(painter_id, updates)) {
.0
.send(CompositorMsg::UpdateImages(painter_id, updates))
{
warn!("error sending image updates: {}", e); warn!("error sending image updates: {}", e);
} }
} }
@@ -440,7 +437,7 @@ impl CrossProcessCompositorApi {
} }
let _ = self let _ = self
.0 .0
.send(CompositorMsg::RemoveFonts(painter_id, keys, instance_keys)); .send(PaintMessage::RemoveFonts(painter_id, keys, instance_keys));
} }
pub fn add_font_instance( pub fn add_font_instance(
@@ -451,7 +448,7 @@ impl CrossProcessCompositorApi {
flags: FontInstanceFlags, flags: FontInstanceFlags,
variations: Vec<FontVariation>, variations: Vec<FontVariation>,
) { ) {
let _x = self.0.send(CompositorMsg::AddFontInstance( let _x = self.0.send(PaintMessage::AddFontInstance(
font_key.into(), font_key.into(),
font_instance_key, font_instance_key,
font_key, font_key,
@@ -462,7 +459,7 @@ impl CrossProcessCompositorApi {
} }
pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) { pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
let _ = self.0.send(CompositorMsg::AddFont( let _ = self.0.send(PaintMessage::AddFont(
font_key.into(), font_key.into(),
font_key, font_key,
data, data,
@@ -471,7 +468,7 @@ impl CrossProcessCompositorApi {
} }
pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) { pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
let _ = self.0.send(CompositorMsg::AddSystemFont( let _ = self.0.send(PaintMessage::AddSystemFont(
font_key.into(), font_key.into(),
font_key, font_key,
handle, handle,
@@ -485,7 +482,7 @@ impl CrossProcessCompositorApi {
painter_id: PainterId, painter_id: PainterId,
) -> (Vec<FontKey>, Vec<FontInstanceKey>) { ) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
let (sender, receiver) = generic_channel::channel().expect("Could not create IPC channel"); let (sender, receiver) = generic_channel::channel().expect("Could not create IPC channel");
let _ = self.0.send(CompositorMsg::GenerateFontKeys( let _ = self.0.send(PaintMessage::GenerateFontKeys(
number_of_font_keys, number_of_font_keys,
number_of_font_instance_keys, number_of_font_instance_keys,
sender, sender,
@@ -495,9 +492,7 @@ impl CrossProcessCompositorApi {
} }
pub fn viewport(&self, webview_id: WebViewId, description: ViewportDescription) { pub fn viewport(&self, webview_id: WebViewId, description: ViewportDescription) {
let _ = self let _ = self.0.send(PaintMessage::Viewport(webview_id, description));
.0
.send(CompositorMsg::Viewport(webview_id, description));
} }
pub fn pipeline_exited( pub fn pipeline_exited(
@@ -506,7 +501,7 @@ impl CrossProcessCompositorApi {
pipeline_id: PipelineId, pipeline_id: PipelineId,
source: PipelineExitSource, source: PipelineExitSource,
) { ) {
let _ = self.0.send(CompositorMsg::PipelineExited( let _ = self.0.send(PaintMessage::PipelineExited(
webview_id, webview_id,
pipeline_id, pipeline_id,
source, source,

View File

@@ -14,7 +14,7 @@ use base::id::{
ServiceWorkerRegistrationId, WebViewId, ServiceWorkerRegistrationId, WebViewId,
}; };
use canvas_traits::canvas::{CanvasId, CanvasMsg}; use canvas_traits::canvas::{CanvasId, CanvasMsg};
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use content_security_policy::sandboxing_directive::SandboxingFlagSet; use content_security_policy::sandboxing_directive::SandboxingFlagSet;
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId}; use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
use embedder_traits::{ use embedder_traits::{
@@ -236,8 +236,8 @@ pub struct SWManagerSenders {
pub swmanager_sender: GenericSender<SWManagerMsg>, pub swmanager_sender: GenericSender<SWManagerMsg>,
/// [`ResourceThreads`] for initating fetches or using i/o. /// [`ResourceThreads`] for initating fetches or using i/o.
pub resource_threads: ResourceThreads, pub resource_threads: ResourceThreads,
/// [`CrossProcessCompositorApi`] for communicating with the compositor. /// [`CrossProcessPaintApi`] for communicating with `Paint`.
pub compositor_api: CrossProcessCompositorApi, pub paint_api: CrossProcessPaintApi,
/// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`. /// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
pub system_font_service_sender: SystemFontServiceProxySender, pub system_font_service_sender: SystemFontServiceProxySender,
/// Sender of messages to the manager. /// Sender of messages to the manager.

View File

@@ -19,8 +19,8 @@ use base::cross_process_instant::CrossProcessInstant;
use base::id::{MessagePortId, PipelineId, ScriptEventLoopId, WebViewId}; use base::id::{MessagePortId, PipelineId, ScriptEventLoopId, WebViewId};
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType; use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
use embedder_traits::{ use embedder_traits::{
CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, InputEventAndId, EmbedderControlId, EmbedderControlResponse, InputEventAndId, JavaScriptEvaluationId,
JavaScriptEvaluationId, MediaSessionActionType, Theme, TraversalId, ViewportDetails, MediaSessionActionType, PaintHitTestResult, Theme, TraversalId, ViewportDetails,
WebDriverCommandMsg, WebDriverCommandMsg,
}; };
pub use from_script_message::*; pub use from_script_message::*;
@@ -79,7 +79,7 @@ pub enum EmbedderToConstellationMessage {
/// Make none of the webviews focused. /// Make none of the webviews focused.
BlurWebView, BlurWebView,
/// Forward an input event to an appropriate ScriptTask. /// Forward an input event to an appropriate ScriptTask.
ForwardInputEvent(WebViewId, InputEventAndId, Option<CompositorHitTestResult>), ForwardInputEvent(WebViewId, InputEventAndId, Option<PaintHitTestResult>),
/// Request that the given pipeline refresh the cursor by doing a hit test at the most /// Request that the given pipeline refresh the cursor by doing a hit test at the most
/// recently hovered cursor position and resetting the cursor. This happens after a /// recently hovered cursor position and resetting the cursor. This happens after a
/// display list update is rendered. /// display list update is rendered.

View File

@@ -306,7 +306,7 @@ pub struct ViewportDetails {
pub size: Size2D<f32, CSSPixel>, pub size: Size2D<f32, CSSPixel>,
/// The scale factor to use to account for HiDPI scaling. This does not take into account /// The scale factor to use to account for HiDPI scaling. This does not take into account
/// any page or pinch zoom applied by the compositor to the contents. /// any page or pinch zoom applied by `Paint` to the contents.
pub hidpi_scale_factor: Scale<f32, CSSPixel, DevicePixel>, pub hidpi_scale_factor: Scale<f32, CSSPixel, DevicePixel>,
} }
@@ -877,9 +877,9 @@ impl UntrustedNodeAddress {
} }
} }
/// The result of a hit test in the compositor. /// The result of a hit test in `Paint`.
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct CompositorHitTestResult { pub struct PaintHitTestResult {
/// The pipeline id of the resulting item. /// The pipeline id of the resulting item.
pub pipeline_id: PipelineId, pub pipeline_id: PipelineId,

View File

@@ -24,7 +24,7 @@ use base::Epoch;
use base::generic_channel::GenericSender; use base::generic_channel::GenericSender;
use base::id::{BrowsingContextId, PipelineId, WebViewId}; use base::id::{BrowsingContextId, PipelineId, WebViewId};
use bitflags::bitflags; use bitflags::bitflags;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails}; use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails};
use euclid::Point2D; use euclid::Point2D;
use euclid::default::{Point2D as UntypedPoint2D, Rect}; use euclid::default::{Point2D as UntypedPoint2D, Rect};
@@ -209,7 +209,7 @@ pub struct LayoutConfig {
pub image_cache: Arc<dyn ImageCache>, pub image_cache: Arc<dyn ImageCache>,
pub font_context: Arc<FontContext>, pub font_context: Arc<FontContext>,
pub time_profiler_chan: time::ProfilerChan, pub time_profiler_chan: time::ProfilerChan,
pub compositor_api: CrossProcessCompositorApi, pub paint_api: CrossProcessPaintApi,
pub viewport_details: ViewportDetails, pub viewport_details: ViewportDetails,
pub theme: Theme, pub theme: Theme,
} }
@@ -297,7 +297,7 @@ pub trait Layout {
painter: Box<dyn Painter>, painter: Box<dyn Painter>,
); );
/// Set the scroll states of this layout after a compositor scroll. /// Set the scroll states of this layout after a `Paint` scroll.
fn set_scroll_offsets_from_renderer( fn set_scroll_offsets_from_renderer(
&mut self, &mut self,
scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>, scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>,

View File

@@ -5,7 +5,7 @@
use std::sync::Arc; use std::sync::Arc;
use base::id::{PipelineId, WebViewId}; use base::id::{PipelineId, WebViewId};
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use log::debug; use log::debug;
use malloc_size_of::MallocSizeOfOps; use malloc_size_of::MallocSizeOfOps;
use malloc_size_of_derive::MallocSizeOf; use malloc_size_of_derive::MallocSizeOf;
@@ -164,7 +164,7 @@ pub trait ImageCacheFactory: Sync + Send {
&self, &self,
webview_id: WebViewId, webview_id: WebViewId,
pipeline_id: PipelineId, pipeline_id: PipelineId,
compositor_api: &CrossProcessCompositorApi, paint_api: &CrossProcessPaintApi,
) -> Arc<dyn ImageCache>; ) -> Arc<dyn ImageCache>;
} }

View File

@@ -61,10 +61,10 @@ pub enum ProfilerMsg {
#[repr(u32)] #[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
pub enum ProfilerCategory { pub enum ProfilerCategory {
/// The compositor is rasterising or presenting. /// `Paint` is rasterising or presenting.
/// ///
/// Not associated with a specific URL. /// Not associated with a specific URL.
Compositing = 0x00, Painting = 0x00,
/// The script thread is doing layout work. /// The script thread is doing layout work.
Layout = 0x10, Layout = 0x10,
@@ -128,7 +128,7 @@ pub enum ProfilerCategory {
impl ProfilerCategory { impl ProfilerCategory {
pub const fn variant_name(&self) -> &'static str { pub const fn variant_name(&self) -> &'static str {
match self { match self {
ProfilerCategory::Compositing => "Compositing", ProfilerCategory::Painting => "Painting",
ProfilerCategory::Layout => "Layout", ProfilerCategory::Layout => "Layout",
ProfilerCategory::ImageSaving => "ImageSaving", ProfilerCategory::ImageSaving => "ImageSaving",
ProfilerCategory::ScriptSpawnPipeline => "ScriptSpawnPipeline", ProfilerCategory::ScriptSpawnPipeline => "ScriptSpawnPipeline",

View File

@@ -20,7 +20,7 @@ use base::id::{
#[cfg(feature = "bluetooth")] #[cfg(feature = "bluetooth")]
use bluetooth_traits::BluetoothRequest; use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline; use canvas_traits::webgl::WebGLPipeline;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessPaintApi;
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType; use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
use constellation_traits::{ use constellation_traits::{
KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationSender, KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationSender,
@@ -30,9 +30,9 @@ use crossbeam_channel::RecvTimeoutError;
use devtools_traits::ScriptToDevtoolsControlMsg; use devtools_traits::ScriptToDevtoolsControlMsg;
use embedder_traits::user_content_manager::UserContentManager; use embedder_traits::user_content_manager::UserContentManager;
use embedder_traits::{ use embedder_traits::{
CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber, EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber, InputEventAndId,
InputEventAndId, JavaScriptEvaluationId, MediaSessionActionType, ScriptToEmbedderChan, Theme, JavaScriptEvaluationId, MediaSessionActionType, PaintHitTestResult, ScriptToEmbedderChan,
ViewportDetails, WebDriverScriptCommand, Theme, ViewportDetails, WebDriverScriptCommand,
}; };
use euclid::{Scale, Size2D}; use euclid::{Scale, Size2D};
use fonts_traits::SystemFontServiceProxySender; use fonts_traits::SystemFontServiceProxySender;
@@ -142,7 +142,7 @@ pub enum UpdatePipelineIdReason {
Traversal, Traversal,
} }
/// Messages sent to the `ScriptThread` event loop from the `Constellation`, `Compositor`, and (for /// Messages sent to the `ScriptThread` event loop from the `Constellation`, `Paint`, and (for
/// now) `Layout`. /// now) `Layout`.
#[derive(Deserialize, IntoStaticStr, Serialize)] #[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum ScriptThreadMessage { pub enum ScriptThreadMessage {
@@ -273,7 +273,7 @@ pub enum ScriptThreadMessage {
/// Notifies script thread that WebGPU server has started /// Notifies script thread that WebGPU server has started
#[cfg(feature = "webgpu")] #[cfg(feature = "webgpu")]
SetWebGPUPort(IpcReceiver<WebGPUMsg>), SetWebGPUPort(IpcReceiver<WebGPUMsg>),
/// The compositor scrolled and is updating the scroll states of the nodes in the given /// `Paint` scrolled and is updating the scroll states of the nodes in the given
/// pipeline via the Constellation. /// pipeline via the Constellation.
SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>), SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>),
/// Evaluate the given JavaScript and return a result via a corresponding message /// Evaluate the given JavaScript and return a result via a corresponding message
@@ -317,7 +317,7 @@ pub enum DocumentState {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ConstellationInputEvent { pub struct ConstellationInputEvent {
/// The hit test result of this input event, if any. /// The hit test result of this input event, if any.
pub hit_test_result: Option<CompositorHitTestResult>, pub hit_test_result: Option<PaintHitTestResult>,
/// The pressed mouse button state of the constellation when this input /// The pressed mouse button state of the constellation when this input
/// event was triggered. /// event was triggered.
pub pressed_mouse_buttons: u16, pub pressed_mouse_buttons: u16,
@@ -368,8 +368,8 @@ pub struct InitialScriptState {
pub webgl_chan: Option<WebGLPipeline>, pub webgl_chan: Option<WebGLPipeline>,
/// The XR device registry /// The XR device registry
pub webxr_registry: Option<webxr_api::Registry>, pub webxr_registry: Option<webxr_api::Registry>,
/// Access to the compositor across a process boundary. /// Access to `Paint` across a process boundary.
pub cross_process_compositor_api: CrossProcessCompositorApi, pub cross_process_paint_api: CrossProcessPaintApi,
/// Application window's GL Context for Media player /// Application window's GL Context for Media player
pub player_context: WindowGLContext, pub player_context: WindowGLContext,
/// User content manager /// User content manager

View File

@@ -4,7 +4,7 @@
use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads, webgl_channel}; use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads, webgl_channel};
use compositing_traits::{ use compositing_traits::{
CrossProcessCompositorApi, PainterSurfmanDetailsMap, WebRenderExternalImageIdManager, CrossProcessPaintApi, PainterSurfmanDetailsMap, WebRenderExternalImageIdManager,
}; };
use log::debug; use log::debug;
use surfman::Device; use surfman::Device;
@@ -27,7 +27,7 @@ pub struct WebGLComm {
impl WebGLComm { impl WebGLComm {
/// Creates a new `WebGLComm` object. /// Creates a new `WebGLComm` object.
pub fn new( pub fn new(
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
external_image_id_manager: WebRenderExternalImageIdManager, external_image_id_manager: WebRenderExternalImageIdManager,
painter_surfman_details_map: PainterSurfmanDetailsMap, painter_surfman_details_map: PainterSurfmanDetailsMap,
) -> WebGLComm { ) -> WebGLComm {
@@ -43,7 +43,7 @@ impl WebGLComm {
// This implementation creates a single `WebGLThread` for all the pipelines. // This implementation creates a single `WebGLThread` for all the pipelines.
let init = WebGLThreadInit { let init = WebGLThreadInit {
compositor_api, paint_api,
external_image_id_manager, external_image_id_manager,
sender: sender.clone(), sender: sender.clone(),
receiver, receiver,

View File

@@ -28,7 +28,7 @@ use canvas_traits::webgl::{
WebGLVersion, WebGLVertexArrayId, YAxisTreatment, WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
}; };
use compositing_traits::{ use compositing_traits::{
CrossProcessCompositorApi, PainterSurfmanDetailsMap, SerializableImageData, CrossProcessPaintApi, PainterSurfmanDetailsMap, SerializableImageData,
WebRenderExternalImageIdManager, WebRenderImageHandlerType, WebRenderExternalImageIdManager, WebRenderImageHandlerType,
}; };
use euclid::default::Size2D; use euclid::default::Size2D;
@@ -220,7 +220,7 @@ pub(crate) struct WebGLThread {
/// The GPU device. /// The GPU device.
device_map: HashMap<PainterId, Rc<Device>>, device_map: HashMap<PainterId, Rc<Device>>,
/// Channel used to generate/update or delete `ImageKey`s. /// Channel used to generate/update or delete `ImageKey`s.
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
/// Map of live WebGLContexts. /// Map of live WebGLContexts.
contexts: FxHashMap<WebGLContextId, GLContextData>, contexts: FxHashMap<WebGLContextId, GLContextData>,
/// Cached information for WebGLContexts. /// Cached information for WebGLContexts.
@@ -249,7 +249,7 @@ pub(crate) struct WebGLThread {
/// The data required to initialize an instance of the WebGLThread type. /// The data required to initialize an instance of the WebGLThread type.
pub(crate) struct WebGLThreadInit { pub(crate) struct WebGLThreadInit {
pub compositor_api: CrossProcessCompositorApi, pub paint_api: CrossProcessPaintApi,
pub external_image_id_manager: WebRenderExternalImageIdManager, pub external_image_id_manager: WebRenderExternalImageIdManager,
pub sender: WebGLSender<WebGLMsg>, pub sender: WebGLSender<WebGLMsg>,
pub receiver: WebGLReceiver<WebGLMsg>, pub receiver: WebGLReceiver<WebGLMsg>,
@@ -267,7 +267,7 @@ impl WebGLThread {
/// Create a new instance of WebGLThread. /// Create a new instance of WebGLThread.
pub(crate) fn new( pub(crate) fn new(
WebGLThreadInit { WebGLThreadInit {
compositor_api, paint_api,
external_image_id_manager: external_images, external_image_id_manager: external_images,
sender, sender,
receiver, receiver,
@@ -280,7 +280,7 @@ impl WebGLThread {
) -> Self { ) -> Self {
WebGLThread { WebGLThread {
device_map: Default::default(), device_map: Default::default(),
compositor_api, paint_api,
contexts: Default::default(), contexts: Default::default(),
cached_context_info: Default::default(), cached_context_info: Default::default(),
bound_context_id: None, bound_context_id: None,
@@ -770,7 +770,7 @@ impl WebGLThread {
.remove(&context_id) .remove(&context_id)
.and_then(|info| info.image_key) .and_then(|info| info.image_key)
{ {
self.compositor_api.delete_image(image_key); self.paint_api.delete_image(image_key);
} }
if !self.contexts.contains_key(&context_id) { if !self.contexts.contains_key(&context_id) {
@@ -951,7 +951,7 @@ impl WebGLThread {
info.alpha = has_alpha; info.alpha = has_alpha;
if let Some(image_key) = info.image_key { if let Some(image_key) = info.image_key {
self.compositor_api.update_image( self.paint_api.update_image(
image_key, image_key,
info.image_descriptor(), info.image_descriptor(),
image_data, image_data,
@@ -998,16 +998,16 @@ impl WebGLThread {
fn handle_set_image_key(&mut self, context_id: WebGLContextId, image_key: ImageKey) { fn handle_set_image_key(&mut self, context_id: WebGLContextId, image_key: ImageKey) {
let external_image_data = self.external_image_data(context_id); let external_image_data = self.external_image_data(context_id);
let Some(info) = self.cached_context_info.get_mut(&context_id) else { let Some(info) = self.cached_context_info.get_mut(&context_id) else {
self.compositor_api.delete_image(image_key); self.paint_api.delete_image(image_key);
return; return;
}; };
if let Some(old_image_key) = info.image_key.replace(image_key) { if let Some(old_image_key) = info.image_key.replace(image_key) {
self.compositor_api.delete_image(old_image_key); self.paint_api.delete_image(old_image_key);
return; return;
} }
self.compositor_api self.paint_api
.add_image(image_key, info.image_descriptor(), external_image_data); .add_image(image_key, info.image_descriptor(), external_image_data);
} }
} }

View File

@@ -10,8 +10,7 @@ use std::sync::{Arc, Mutex};
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use base::Epoch; use base::Epoch;
use compositing_traits::{ use compositing_traits::{
CrossProcessCompositorApi, ExternalImageSource, SerializableImageData, CrossProcessPaintApi, ExternalImageSource, SerializableImageData, WebRenderExternalImageApi,
WebRenderExternalImageApi,
}; };
use euclid::default::Size2D; use euclid::default::Size2D;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
@@ -466,11 +465,7 @@ impl ContextData {
/// Destroy the context that this [`ContextData`] represents, /// Destroy the context that this [`ContextData`] represents,
/// freeing all of its buffers, and deleting the associated WebRender image. /// freeing all of its buffers, and deleting the associated WebRender image.
fn destroy( fn destroy(mut self, script_sender: &IpcSender<WebGPUMsg>, paint_api: &CrossProcessPaintApi) {
mut self,
script_sender: &IpcSender<WebGPUMsg>,
compositor_api: &CrossProcessCompositorApi,
) {
// This frees the id in the `ScriptThread`. // This frees the id in the `ScriptThread`.
for staging_buffer in self.inactive_staging_buffers { for staging_buffer in self.inactive_staging_buffers {
if let Err(error) = script_sender.send(WebGPUMsg::FreeBuffer(staging_buffer.buffer_id)) if let Err(error) = script_sender.send(WebGPUMsg::FreeBuffer(staging_buffer.buffer_id))
@@ -482,7 +477,7 @@ impl ContextData {
}; };
} }
if let Some(image_key) = self.image_key.take() { if let Some(image_key) = self.image_key.take() {
compositor_api.delete_image(image_key); paint_api.delete_image(image_key);
} }
} }
@@ -545,10 +540,10 @@ impl crate::WGPU {
let context_data = webgpu_contexts.get_mut(&context_id).unwrap(); let context_data = webgpu_contexts.get_mut(&context_id).unwrap();
if let Some(old_image_key) = context_data.image_key.replace(image_key) { if let Some(old_image_key) = context_data.image_key.replace(image_key) {
self.compositor_api.delete_image(old_image_key); self.paint_api.delete_image(old_image_key);
} }
self.compositor_api.add_image( self.paint_api.add_image(
image_key, image_key,
ImageDescriptor { ImageDescriptor {
format: ImageFormat::BGRA8, format: ImageFormat::BGRA8,
@@ -655,7 +650,7 @@ impl crate::WGPU {
}) = pending_texture }) = pending_texture
else { else {
context_data.clear_presentation(); context_data.clear_presentation();
self.compositor_api.update_image( self.paint_api.update_image(
image_key, image_key,
ImageDescriptor { ImageDescriptor {
format: ImageFormat::BGRA8, format: ImageFormat::BGRA8,
@@ -672,7 +667,7 @@ impl crate::WGPU {
let Some(staging_buffer) = context_data.get_or_make_available_buffer(&configuration) else { let Some(staging_buffer) = context_data.get_or_make_available_buffer(&configuration) else {
warn!("Failure obtaining available staging buffer"); warn!("Failure obtaining available staging buffer");
context_data.clear_presentation(); context_data.clear_presentation();
self.compositor_api.update_image( self.paint_api.update_image(
image_key, image_key,
configuration.into(), configuration.into(),
SerializableImageData::External(image_data(context_id)), SerializableImageData::External(image_data(context_id)),
@@ -682,7 +677,7 @@ impl crate::WGPU {
}; };
let epoch = context_data.next_epoch(); let epoch = context_data.next_epoch();
let wgpu_image_map = self.wgpu_image_map.clone(); let wgpu_image_map = self.wgpu_image_map.clone();
let compositor_api = self.compositor_api.clone(); let paint_api = self.paint_api.clone();
drop(webgpu_contexts); drop(webgpu_contexts);
self.texture_download( self.texture_download(
texture_id, texture_id,
@@ -702,7 +697,7 @@ impl crate::WGPU {
context_data.clear_presentation(); context_data.clear_presentation();
} }
// update image in WR // update image in WR
compositor_api.update_image( paint_api.update_image(
image_key, image_key,
configuration.into(), configuration.into(),
SerializableImageData::External(image_data(context_id)), SerializableImageData::External(image_data(context_id)),
@@ -798,6 +793,6 @@ impl crate::WGPU {
.unwrap() .unwrap()
.remove(&context_id) .remove(&context_id)
.unwrap() .unwrap()
.destroy(&self.script_sender, &self.compositor_api); .destroy(&self.script_sender, &self.paint_api);
} }
} }

View File

@@ -14,14 +14,14 @@ mod wgpu_thread;
use std::borrow::Cow; use std::borrow::Cow;
use compositing_traits::{CrossProcessCompositorApi, WebRenderExternalImageIdManager}; use compositing_traits::{CrossProcessPaintApi, WebRenderExternalImageIdManager};
use ipc_channel::ipc::{self, IpcReceiver}; use ipc_channel::ipc::{self, IpcReceiver};
use servo_config::pref; use servo_config::pref;
pub mod canvas_context; pub mod canvas_context;
pub fn start_webgpu_thread( pub fn start_webgpu_thread(
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
webrender_external_image_id_manager: WebRenderExternalImageIdManager, webrender_external_image_id_manager: WebRenderExternalImageIdManager,
wgpu_image_map: WebGpuExternalImageMap, wgpu_image_map: WebGpuExternalImageMap,
) -> Option<(WebGPU, IpcReceiver<WebGPUMsg>)> { ) -> Option<(WebGPU, IpcReceiver<WebGPUMsg>)> {
@@ -58,7 +58,7 @@ pub fn start_webgpu_thread(
receiver, receiver,
sender_clone, sender_clone,
script_sender, script_sender,
compositor_api, paint_api,
webrender_external_image_id_manager, webrender_external_image_id_manager,
wgpu_image_map, wgpu_image_map,
) )

View File

@@ -10,7 +10,7 @@ use std::sync::{Arc, Mutex};
use base::id::PipelineId; use base::id::PipelineId;
use compositing_traits::{ use compositing_traits::{
CrossProcessCompositorApi, WebRenderExternalImageIdManager, WebRenderImageHandlerType, CrossProcessPaintApi, WebRenderExternalImageIdManager, WebRenderImageHandlerType,
}; };
use ipc_channel::ipc::{IpcReceiver, IpcSender, IpcSharedMemory}; use ipc_channel::ipc::{IpcReceiver, IpcSender, IpcSharedMemory};
use log::{info, warn}; use log::{info, warn};
@@ -104,7 +104,7 @@ pub(crate) struct WGPU {
/// because wgpu does not invalidate command encoder object /// because wgpu does not invalidate command encoder object
/// (this is also reused for invalidation of command buffers) /// (this is also reused for invalidation of command buffers)
error_command_encoders: FxHashMap<id::CommandEncoderId, String>, error_command_encoders: FxHashMap<id::CommandEncoderId, String>,
pub(crate) compositor_api: CrossProcessCompositorApi, pub(crate) paint_api: CrossProcessPaintApi,
pub(crate) webrender_external_image_id_manager: WebRenderExternalImageIdManager, pub(crate) webrender_external_image_id_manager: WebRenderExternalImageIdManager,
pub(crate) wgpu_image_map: WebGpuExternalImageMap, pub(crate) wgpu_image_map: WebGpuExternalImageMap,
/// Provides access to poller thread /// Provides access to poller thread
@@ -120,7 +120,7 @@ impl WGPU {
receiver: IpcReceiver<WebGPURequest>, receiver: IpcReceiver<WebGPURequest>,
sender: IpcSender<WebGPURequest>, sender: IpcSender<WebGPURequest>,
script_sender: IpcSender<WebGPUMsg>, script_sender: IpcSender<WebGPUMsg>,
compositor_api: CrossProcessCompositorApi, paint_api: CrossProcessPaintApi,
webrender_external_image_id_manager: WebRenderExternalImageIdManager, webrender_external_image_id_manager: WebRenderExternalImageIdManager,
wgpu_image_map: WebGpuExternalImageMap, wgpu_image_map: WebGpuExternalImageMap,
) -> Self { ) -> Self {
@@ -149,7 +149,7 @@ impl WGPU {
global, global,
devices: Arc::new(Mutex::new(FxHashMap::default())), devices: Arc::new(Mutex::new(FxHashMap::default())),
error_command_encoders: FxHashMap::default(), error_command_encoders: FxHashMap::default(),
compositor_api, paint_api,
webrender_external_image_id_manager, webrender_external_image_id_manager,
wgpu_image_map, wgpu_image_map,
compute_passes: FxHashMap::default(), compute_passes: FxHashMap::default(),

View File

@@ -100,7 +100,7 @@ impl PlatformWindow for Window {
// Because we are managing the rendering surface ourselves, there will be no other // Because we are managing the rendering surface ourselves, there will be no other
// notification (such as from the display manager) that it has changed size, so we // notification (such as from the display manager) that it has changed size, so we
// must notify the compositor here. // must notify `Paint` here.
webview.resize(PhysicalSize::new( webview.resize(PhysicalSize::new(
new_size.width as u32, new_size.width as u32,
new_size.height as u32, new_size.height as u32,
@@ -150,7 +150,7 @@ impl PlatformWindow for Window {
self.inner_size.set(self.screen_size); self.inner_size.set(self.screen_size);
// Because we are managing the rendering surface ourselves, there will be no other // Because we are managing the rendering surface ourselves, there will be no other
// notification (such as from the display manager) that it has changed size, so we // notification (such as from the display manager) that it has changed size, so we
// must notify the compositor here. // must notify the `Paint` here.
webview.resize(PhysicalSize::new( webview.resize(PhysicalSize::new(
self.screen_size.width as u32, self.screen_size.width as u32,
self.screen_size.height as u32, self.screen_size.height as u32,

View File

@@ -123,7 +123,7 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_init<'local>(
"script::dom::bindings::error", "script::dom::bindings::error",
// Show GL errors by default. // Show GL errors by default.
"canvas::webgl_thread", "canvas::webgl_thread",
"compositing::compositor", "compositing::paint",
"constellation::constellation", "constellation::constellation",
]; ];
let mut filter_builder = FilterBuilder::new(); let mut filter_builder = FilterBuilder::new();
@@ -518,22 +518,19 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_click(
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub extern "C" fn Java_org_servo_servoview_JNIServo_pauseCompositor( pub extern "C" fn Java_org_servo_servoview_JNIServo_pausePainting(mut env: JNIEnv, _: JClass<'_>) {
mut env: JNIEnv, debug!("pausePainting");
_: JClass<'_>, call(&mut env, |s| s.pause_painting());
) {
debug!("pauseCompositor");
call(&mut env, |s| s.pause_compositor());
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
pub extern "C" fn Java_org_servo_servoview_JNIServo_resumeCompositor<'local>( pub extern "C" fn Java_org_servo_servoview_JNIServo_resumePainting<'local>(
mut env: JNIEnv<'local>, mut env: JNIEnv<'local>,
_: JClass<'local>, _: JClass<'local>,
surface: JObject<'local>, surface: JObject<'local>,
coordinates: JObject<'local>, coordinates: JObject<'local>,
) { ) {
debug!("resumeCompositor"); debug!("resumePainting");
let viewport_rect = match jni_coordinate_to_rust_viewport_rect(&mut env, &coordinates) { let viewport_rect = match jni_coordinate_to_rust_viewport_rect(&mut env, &coordinates) {
Ok(viewport_rect) => viewport_rect, Ok(viewport_rect) => viewport_rect,
Err(error) => return throw(&mut env, &error), Err(error) => return throw(&mut env, &error),
@@ -541,7 +538,7 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_resumeCompositor<'local>(
let (_, window_handle) = display_and_window_handle(&mut env, &surface); let (_, window_handle) = display_and_window_handle(&mut env, &surface);
call(&mut env, |app| { call(&mut env, |app| {
app.resume_compositor(window_handle, viewport_rect); app.resume_painting(window_handle, viewport_rect);
}); });
} }

View File

@@ -583,14 +583,14 @@ impl App {
self.spin_event_loop(); self.spin_event_loop();
} }
pub fn pause_compositor(&self) { pub fn pause_painting(&self) {
if let Err(e) = self.platform_window.rendering_context.take_window() { if let Err(e) = self.platform_window.rendering_context.take_window() {
warn!("Unbinding native surface from context failed ({:?})", e); warn!("Unbinding native surface from context failed ({:?})", e);
} }
self.spin_event_loop(); self.spin_event_loop();
} }
pub fn resume_compositor( pub fn resume_painting(
&self, &self,
window_handle: RawWindowHandle, window_handle: RawWindowHandle,
viewport_rect: Rect<i32, DevicePixel>, viewport_rect: Rect<i32, DevicePixel>,

View File

@@ -400,12 +400,12 @@ impl ServoAction {
.expect("Should always start with at least one WebView"); .expect("Should always start with at least one WebView");
if webview.id() != native_webview_components.id { if webview.id() != native_webview_components.id {
servo.activate_webview(native_webview_components.id); servo.activate_webview(native_webview_components.id);
servo.pause_compositor(); servo.pause_painting();
let (window_handle, viewport_rect) = get_raw_window_handle( let (window_handle, viewport_rect) = get_raw_window_handle(
native_webview_components.xcomponent.0, native_webview_components.xcomponent.0,
native_webview_components.window.0, native_webview_components.window.0,
); );
servo.resume_compositor(window_handle, viewport_rect); servo.resume_painting(window_handle, viewport_rect);
let url = webview let url = webview
.url() .url()
.map(|u| u.to_string()) .map(|u| u.to_string())
@@ -419,12 +419,12 @@ impl ServoAction {
} }
}, },
NewWebview(xcomponent, window) => { NewWebview(xcomponent, window) => {
servo.pause_compositor(); servo.pause_painting();
let webview = let webview =
servo.create_and_activate_toplevel_webview("about:blank".parse().unwrap()); servo.create_and_activate_toplevel_webview("about:blank".parse().unwrap());
let (window_handle, viewport_rect) = get_raw_window_handle(xcomponent.0, window.0); let (window_handle, viewport_rect) = get_raw_window_handle(xcomponent.0, window.0);
servo.resume_compositor(window_handle, viewport_rect); servo.resume_painting(window_handle, viewport_rect);
let id = webview.id(); let id = webview.id();
NATIVE_WEBVIEWS NATIVE_WEBVIEWS
.lock() .lock()
@@ -700,7 +700,7 @@ static LOGGER: LazyLock<hilog::Logger> = LazyLock::new(|| {
"script::dom::console", "script::dom::console",
// Show GL errors by default. // Show GL errors by default.
"canvas::webgl_thread", "canvas::webgl_thread",
"compositing::compositor", "compositing::paint",
"compositing::touch", "compositing::touch",
"constellation::constellation", "constellation::constellation",
"ohos_ime", "ohos_ime",

View File

@@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! The `servo` test application. //! The `servoshell` test application.
//! //!
//! Creates a `Servo` instance with a simple implementation of //! Creates a `Servo` instance with a example implementation of a working
//! the compositor's `WindowMethods` to create a working web browser. //! web browser.
//! //!
//! This browser's implementation of `WindowMethods` is built on top //! This browser's implementation of `WindowMethods` is built on top
//! of [winit], the cross-platform windowing library. //! of [winit], the cross-platform windowing library.

View File

@@ -309,7 +309,8 @@ impl RunningAppState {
/// Spins the internal application event loop. /// Spins the internal application event loop.
/// ///
/// - Notifies Servo about incoming gamepad events /// - Notifies Servo about incoming gamepad events
/// - Spin the Servo event loop, which will run the compositor and trigger delegate methods. /// - Spin the Servo event loop, which will update Servo's embedding layer and trigger
/// delegate methods.
/// ///
/// Returns true if the event loop should continue spinning and false if it should exit. /// Returns true if the event loop should continue spinning and false if it should exit.
pub(crate) fn spin_event_loop(self: &Rc<Self>) -> bool { pub(crate) fn spin_event_loop(self: &Rc<Self>) -> bool {

View File

@@ -186,7 +186,7 @@ impl ServoShellWindow {
self.platform_window self.platform_window
.update_user_interface_state(state, self); .update_user_interface_state(state, self);
// Delegate handlers may have asked us to present or update compositor contents. // Delegate handlers may have asked us to present or update painted WebView contents.
// Currently, egui-file-dialog dialogs need to be constantly redrawn or animations aren't fluid. // Currently, egui-file-dialog dialogs need to be constantly redrawn or animations aren't fluid.
let needs_repaint = self.needs_repaint.take(); let needs_repaint = self.needs_repaint.take();
if updated_user_interface || needs_repaint { if updated_user_interface || needs_repaint {