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 canvas_traits::canvas::*;
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
use pixels::Snapshot;
use webrender_api::ImageKey;
@@ -23,28 +23,28 @@ pub(crate) enum Filter {
pub(crate) struct CanvasData<DrawTarget: GenericDrawTarget> {
draw_target: DrawTarget,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
image_key: Option<ImageKey>,
}
impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
pub(crate) fn new(
size: Size2D<u64>,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
) -> CanvasData<DrawTarget> {
CanvasData {
draw_target: DrawTarget::new(size.max(MIN_WR_IMAGE_SIZE).cast()),
compositor_api,
paint_api,
image_key: None,
}
}
pub(crate) fn set_image_key(&mut self, image_key: ImageKey) {
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) {
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.compositor_api
self.paint_api
.update_image(image_key, descriptor, data, canvas_epoch);
}
@@ -440,7 +440,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
impl<D: GenericDrawTarget> Drop for CanvasData<D> {
fn drop(&mut self) {
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 canvas_traits::ConstellationCanvasMsg;
use canvas_traits::canvas::*;
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use crossbeam_channel::{Sender, select, unbounded};
use euclid::default::{Rect, Size2D, Transform2D};
use log::warn;
@@ -22,22 +22,22 @@ use crate::canvas_data::*;
pub struct CanvasPaintThread {
canvases: FxHashMap<CanvasId, Canvas>,
next_canvas_id: CanvasId,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
}
impl CanvasPaintThread {
fn new(compositor_api: CrossProcessCompositorApi) -> CanvasPaintThread {
fn new(paint_api: CrossProcessPaintApi) -> CanvasPaintThread {
CanvasPaintThread {
canvases: FxHashMap::default(),
next_canvas_id: CanvasId(0),
compositor_api: compositor_api.clone(),
paint_api: paint_api.clone(),
}
}
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
/// communicate with it.
pub fn start(
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
let (ipc_sender, ipc_receiver) = generic_channel::channel::<CanvasMsg>().unwrap();
let msg_receiver = ipc_receiver.route_preserving_errors();
@@ -46,7 +46,7 @@ impl CanvasPaintThread {
.name("Canvas".to_owned())
.spawn(move || {
let mut canvas_paint_thread = CanvasPaintThread::new(
compositor_api);
paint_api);
loop {
select! {
recv(msg_receiver) -> msg => {
@@ -97,7 +97,7 @@ impl CanvasPaintThread {
let canvas_id = self.next_canvas_id;
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);
Some(canvas_id)
@@ -298,17 +298,15 @@ enum 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)
.to_lowercase()
.as_str()
{
#[cfg(feature = "vello_cpu")]
"" | "auto" | "vello_cpu" => {
Some(Self::VelloCPU(CanvasData::new(size, compositor_api)))
},
"" | "auto" | "vello_cpu" => Some(Self::VelloCPU(CanvasData::new(size, paint_api))),
#[cfg(feature = "vello")]
"" | "auto" | "vello" => Some(Self::Vello(CanvasData::new(size, compositor_api))),
"" | "auto" | "vello" => Some(Self::Vello(CanvasData::new(size, paint_api))),
s => {
warn!("Unknown 2D canvas backend: `{s}`");
None

View File

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

View File

@@ -15,7 +15,7 @@ use bitflags::bitflags;
use canvas_traits::webgl::{WebGLContextId, WebGLThreads};
use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{
CompositorMsg, CompositorProxy, PainterSurfmanDetails, PainterSurfmanDetailsMap,
PaintMessage, PaintProxy, PainterSurfmanDetails, PainterSurfmanDetailsMap,
WebRenderExternalImageIdManager, WebViewTrait,
};
use constellation_traits::EmbedderToConstellationMessage;
@@ -47,7 +47,7 @@ use webrender::{CaptureBits, MemoryReport};
use webrender_api::units::{DevicePixel, DevicePoint};
use webrender_api::{FontInstanceKey, FontKey, ImageKey};
use crate::InitialCompositorState;
use crate::InitialPaintState;
use crate::painter::Painter;
use crate::webview_renderer::UnknownWebView;
@@ -59,26 +59,46 @@ pub enum WebRenderDebugOption {
RenderTargetDebug,
}
/// NB: Never block on the constellation, because sometimes the constellation blocks on us.
pub struct IOCompositor {
/// All of the [`Painters`] for this [`IOCompositor`]. Each [`Painter`] handles painting to
/// [`Paint`] is Servo's rendering subsystem. It has a few responsibilities:
///
/// 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`].
painters: Vec<Rc<RefCell<Painter>>>,
/// A [`CompositorProxy`] which can be used to allow other parts of Servo to communicate
/// with this [`IOCompositor`].
pub(crate) compositor_proxy: CompositorProxy,
/// A [`PaintProxy`] which can be used to allow other parts of Servo to communicate
/// with this [`Paint`].
pub(crate) paint_proxy: PaintProxy,
/// An [`EventLoopWaker`] used to wake up the main embedder event loop when the renderer needs
/// to run.
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
/// the compositor. This is shared with the `Servo` instance.
/// Tracks whether we are in the process of shutting down, or have shut down and
/// should shut down `Paint`. This is shared with the `Servo` instance.
shutdown_state: Rc<Cell<ShutdownState>>,
/// 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.
pub(crate) embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
@@ -136,12 +156,12 @@ bitflags! {
}
}
impl IOCompositor {
pub fn new(state: InitialCompositorState) -> Rc<RefCell<Self>> {
impl Paint {
pub fn new(state: InitialPaintState) -> Rc<RefCell<Self>> {
let registration = state.mem_profiler_chan.prepare_memory_reporting(
"compositor".into(),
state.compositor_proxy.clone(),
CompositorMsg::CollectMemoryReport,
"paint".into(),
state.paint_proxy.clone(),
PaintMessage::CollectMemoryReport,
);
let webrender_external_image_id_manager = WebRenderExternalImageIdManager::default();
@@ -153,7 +173,7 @@ impl IOCompositor {
#[cfg(feature = "webxr")]
webxr_layer_grand_manager,
} = WebGLComm::new(
state.compositor_proxy.cross_process_compositor_api.clone(),
state.paint_proxy.cross_process_paint_api.clone(),
webrender_external_image_id_manager.clone(),
painter_surfman_details_map.clone(),
);
@@ -174,12 +194,12 @@ impl IOCompositor {
webxr_main_thread
};
Rc::new(RefCell::new(IOCompositor {
Rc::new(RefCell::new(Paint {
painters: Default::default(),
compositor_proxy: state.compositor_proxy,
paint_proxy: state.paint_proxy,
event_loop_waker: state.event_loop_waker,
shutdown_state: state.shutdown_state,
compositor_receiver: state.receiver,
paint_receiver: state.receiver,
embedder_to_constellation_sender: state.embedder_to_constellation_sender.clone(),
webrender_external_image_id_manager,
webgl_threads,
@@ -308,9 +328,9 @@ impl IOCompositor {
}
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).
while self.compositor_receiver.try_recv().is_ok() {}
while self.paint_receiver.try_recv().is_ok() {}
let (webgl_exit_sender, webgl_exit_receiver) =
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:?}");
match self.shutdown_state() {
@@ -340,16 +360,16 @@ impl IOCompositor {
return;
},
ShutdownState::FinishedShuttingDown => {
// Messages to the compositor are ignored after shutdown is complete.
// Messages to Paint are ignored after shutdown is complete.
return;
},
}
match msg {
CompositorMsg::CollectMemoryReport(sender) => {
PaintMessage::CollectMemoryReport(sender) => {
self.collect_memory_report(sender);
},
CompositorMsg::ChangeRunningAnimationsState(
PaintMessage::ChangeRunningAnimationsState(
webview_id,
pipeline_id,
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()) {
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()) {
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()) {
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.");
},
CompositorMsg::SendInitialTransaction(webview_id, pipeline_id) => {
PaintMessage::SendInitialTransaction(webview_id, pipeline_id) => {
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
painter.send_initial_pipeline_transaction(webview_id, pipeline_id);
}
},
CompositorMsg::ScrollNodeByDelta(
PaintMessage::ScrollNodeByDelta(
webview_id,
pipeline_id,
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()) {
painter.scroll_viewport_by_delta(webview_id, delta);
}
},
CompositorMsg::UpdateEpoch {
PaintMessage::UpdateEpoch {
webview_id,
pipeline_id,
epoch,
@@ -414,7 +434,7 @@ impl IOCompositor {
painter.update_epoch(webview_id, pipeline_id, epoch);
}
},
CompositorMsg::SendDisplayList {
PaintMessage::SendDisplayList {
webview_id,
display_list_descriptor,
display_list_receiver,
@@ -427,25 +447,25 @@ impl IOCompositor {
);
}
},
CompositorMsg::GenerateFrame(painter_ids) => {
PaintMessage::GenerateFrame(painter_ids) => {
for painter_id in painter_ids {
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
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);
},
CompositorMsg::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
PaintMessage::GenerateImageKeysForPipeline(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) {
painter.update_images(updates);
}
},
CompositorMsg::DelayNewFrameForCanvas(
PaintMessage::DelayNewFrameForCanvas(
webview_id,
pipeline_id,
canvas_epoch,
@@ -455,21 +475,21 @@ impl IOCompositor {
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());
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
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());
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
painter.add_system_font(font_key, native_handle);
}
},
CompositorMsg::AddFontInstance(
PaintMessage::AddFontInstance(
painter_id,
font_instance_key,
font_key,
@@ -484,12 +504,12 @@ impl IOCompositor {
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) {
painter.remove_fonts(keys, instance_keys);
}
},
CompositorMsg::GenerateFontKeys(
PaintMessage::GenerateFontKeys(
number_of_font_keys,
number_of_font_instance_keys,
result_sender,
@@ -502,17 +522,17 @@ impl IOCompositor {
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()) {
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()) {
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()) {
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))
.sum();
reports.push(Report {
path: path!["compositor", "scroll-tree"],
path: path!["paint", "scroll-tree"],
kind: ReportKind::ExplicitJemallocHeapSize,
size: scroll_trees_memory_usage,
});
@@ -574,29 +594,29 @@ impl IOCompositor {
sender.send(ProcessReports::new(reports));
}
/// Handle messages sent to the compositor during the shutdown process. In general,
/// the things the compositor can do in this state are limited. It's very important to
/// Handle messages sent to `Paint` during the shutdown process. In general,
/// 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
/// results to finish their own shut down process. We try to do as little as possible
/// during this time.
///
/// 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
/// compositor no longer does any WebRender frame generation.
fn handle_browser_message_while_shutting_down(&self, msg: CompositorMsg) {
/// generate them, but assume they will never be used, since once shutting down
/// `Paint` no longer does any WebRender frame generation.
fn handle_browser_message_while_shutting_down(&self, msg: PaintMessage) {
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()) {
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);
},
CompositorMsg::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
PaintMessage::GenerateImageKeysForPipeline(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_instance_keys,
result_sender,
@@ -668,20 +688,20 @@ impl IOCompositor {
.render(&self.time_profiler_chan);
}
/// Get the message receiver for this [`IOCompositor`].
pub fn receiver(&self) -> &RoutedReceiver<CompositorMsg> {
&self.compositor_receiver
/// Get the message receiver for this [`Paint`].
pub fn receiver(&self) -> &RoutedReceiver<PaintMessage> {
&self.paint_receiver
}
#[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
// 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
// when calling `handle_new_webrender_frame_ready`.
let mut saw_webrender_frame_ready_for_painter = HashMap::new();
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) {
painter.decrement_pending_frames();
*saw_webrender_frame_ready_for_painter

View File

@@ -10,7 +10,7 @@ use std::sync::Arc;
use base::Epoch;
use base::cross_process_instant::CrossProcessInstant;
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::rendering_context::RenderingContext;
use compositing_traits::viewport_description::ViewportDescription;
@@ -22,7 +22,7 @@ use constellation_traits::{EmbedderToConstellationMessage, PaintMetricEvent};
use crossbeam_channel::Sender;
use dpi::PhysicalSize;
use embedder_traits::{
CompositorHitTestResult, InputEvent, InputEventAndId, InputEventId, InputEventResult,
InputEvent, InputEventAndId, InputEventId, InputEventResult, PaintHitTestResult,
ScreenshotCaptureError, Scroll, ViewportDetails, WebViewPoint, WebViewRect,
};
use euclid::{Point2D, Rect, Scale, Size2D};
@@ -54,9 +54,9 @@ use webrender_api::{
};
use wr_malloc_size_of::MallocSizeOfOps;
use crate::IOCompositor;
use crate::compositor::{RepaintReason, WebRenderDebugOption};
use crate::Paint;
use crate::largest_contentful_paint_calculator::LargestContentfulPaintCalculator;
use crate::paint::{RepaintReason, WebRenderDebugOption};
use crate::refresh_driver::{AnimationRefreshDriverObserver, BaseRefreshDriver};
use crate::render_notifier::RenderNotifier;
use crate::screenshot::ScreenshotTaker;
@@ -141,10 +141,7 @@ impl Drop for Painter {
}
impl Painter {
pub(crate) fn new(
rendering_context: Rc<dyn RenderingContext>,
compositor: &IOCompositor,
) -> Self {
pub(crate) fn new(rendering_context: Rc<dyn RenderingContext>, paint: &Paint) -> Self {
let webrender_gl = rendering_context.gleam_gl_api();
// 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,);
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));
// Set WebRender external image handler for WebGL textures.
let image_handler = Box::new(WebGLExternalImages::new(
compositor.webgl_threads(),
paint.webgl_threads(),
rendering_context.clone(),
compositor.swap_chains.clone(),
compositor.busy_webgl_contexts_map.clone(),
paint.swap_chains.clone(),
paint.busy_webgl_contexts_map.clone(),
));
external_image_handlers.set_handler(image_handler, WebRenderImageHandlerType::WebGl);
#[cfg(feature = "webgpu")]
external_image_handlers.set_handler(
Box::new(webgpu::WebGpuExternalImages::new(
compositor.webgpu_image_map(),
)),
Box::new(webgpu::WebGpuExternalImages::new(paint.webgpu_image_map())),
WebRenderImageHandlerType::WebGpu,
);
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(
compositor.event_loop_waker.clone_box(),
paint.event_loop_waker.clone_box(),
rendering_context.refresh_driver(),
));
let animation_refresh_driver_observer = Rc::new(AnimationRefreshDriverObserver::new(
@@ -215,10 +210,7 @@ impl Painter {
let painter_id = PainterId::next();
let (mut webrender, webrender_api_sender) = webrender::create_webrender_instance(
webrender_gl.clone(),
Box::new(RenderNotifier::new(
painter_id,
compositor.compositor_proxy.clone(),
)),
Box::new(RenderNotifier::new(painter_id, paint.paint_proxy.clone())),
webrender::WebRenderOptions {
// We force the use of optimized shaders here because rendering is broken
// on Android emulators with unoptimized shaders. This is due to a known
@@ -391,7 +383,7 @@ impl Painter {
self.rendering_context.prepare_for_rendering();
time_profile!(
ProfilerCategory::Compositing,
ProfilerCategory::Painting,
None,
time_profiler_channel.clone(),
|| {
@@ -454,7 +446,7 @@ impl Painter {
match pipeline.first_paint_metric.get() {
// 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
// the first "real" display list.
PaintMetricState::Seen(epoch, first_reflow) if epoch <= current_epoch => {
@@ -545,7 +537,7 @@ impl Painter {
webrender_api: &RenderApi,
webrender_document: DocumentId,
point: DevicePoint,
) -> Vec<CompositorHitTestResult> {
) -> Vec<PaintHitTestResult> {
// DevicePoint and WorldPoint are the same for us.
let world_point = WorldPoint::from_untyped(point.to_untyped());
let results = webrender_api.hit_test(webrender_document, world_point);
@@ -556,7 +548,7 @@ impl Painter {
.map(|item| {
let pipeline_id = item.pipeline.into();
let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline);
CompositorHitTestResult {
PaintHitTestResult {
pipeline_id,
point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()),
external_scroll_id,
@@ -819,7 +811,7 @@ impl Painter {
pipeline_id: PipelineId,
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) {
webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source);
}
@@ -932,13 +924,13 @@ impl Painter {
return warn!("Could not receive display list info: {error}");
},
};
let display_list_info: CompositorDisplayListInfo =
match bincode::deserialize(&display_list_info) {
Ok(display_list_info) => display_list_info,
Err(error) => {
return warn!("Could not deserialize display list info: {error}");
},
};
let display_list_info: PaintDisplayListInfo = match bincode::deserialize(&display_list_info)
{
Ok(display_list_info) => display_list_info,
Err(error) => {
return warn!("Could not deserialize display list info: {error}");
},
};
let items_data = match display_list_receiver.recv() {
Ok(display_list_data) => display_list_data,
Err(error) => {
@@ -965,8 +957,7 @@ impl Painter {
},
display_list_descriptor,
);
let _span =
profile_traits::trace_span!("ScriptToCompositorMsg::BuiltDisplayList",).entered();
let _span = profile_traits::trace_span!("PaintMessage::SendDisplayList",).entered();
let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) else {
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.
pub throttled: bool,
/// The compositor-side [ScrollTree]. This is used to allow finding and scrolling
/// nodes in the compositor before forwarding new offsets to WebRender.
/// The `Paint`-side [ScrollTree]. This is used to allow finding and scrolling
/// nodes in `Paint` before forwarding new offsets to WebRender.
pub scroll_tree: ScrollTree,
/// The paint metric status of the first paint.

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,7 @@ use std::cell::{Cell, RefCell};
use std::rc::Rc;
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 log::{debug, error, warn};
use rustc_hash::FxHashMap;
@@ -14,7 +14,7 @@ use style_traits::CSSPixel;
use webrender_api::units::{DevicePixel, DevicePoint, DeviceVector2D};
use self::TouchSequenceState::*;
use crate::compositor::RepaintReason;
use crate::paint::RepaintReason;
use crate::painter::Painter;
use crate::refresh_driver::{BaseRefreshDriver, RefreshDriverObserver};
use crate::webview_renderer::{ScrollEvent, ScrollZoomEvent, WebViewRenderer};
@@ -76,11 +76,11 @@ pub enum TouchMoveAllowed {
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
/// while during panning and flinging actions.
struct HitTestResultCache {
value: CompositorHitTestResult,
value: PaintHitTestResult,
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)?;
if sequence.state == Finished {
return None;
@@ -640,7 +640,7 @@ impl TouchHandler {
pub(crate) fn set_hit_test_result_cache_value(
&mut self,
value: CompositorHitTestResult,
value: PaintHitTestResult,
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
) {
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/. */
/// Log an event from constellation at trace level.
/// - To disable tracing: RUST_LOG='compositor<constellation@=off'
/// - To enable tracing: RUST_LOG='compositor<constellation@'
/// - To disable tracing: RUST_LOG='paint<constellation@=off'
/// - To enable tracing: RUST_LOG='paint<constellation@'
macro_rules! trace_msg_from_constellation {
// This macro only exists to put the docs in the same file as the target prefix,
// so the macro definition is always the same.
@@ -23,11 +23,11 @@ mod from_constellation {
macro_rules! target {
($($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 {
match self {
Self::ChangeRunningAnimationsState(..) => target!("ChangeRunningAnimationsState"),

View File

@@ -15,8 +15,8 @@ use compositing_traits::{PipelineExitSource, SendableFrameTree, WebViewTrait};
use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType};
use crossbeam_channel::Sender;
use embedder_traits::{
AnimationState, CompositorHitTestResult, InputEvent, InputEventAndId, InputEventId,
InputEventResult, MouseButton, MouseButtonAction, MouseButtonEvent, MouseMoveEvent, Scroll,
AnimationState, InputEvent, InputEventAndId, InputEventId, InputEventResult, MouseButton,
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, PaintHitTestResult, Scroll,
ScrollEvent as EmbedderScrollEvent, TouchEvent, TouchEventType, ViewportDetails, WebViewPoint,
WheelEvent,
};
@@ -30,7 +30,7 @@ use webrender::RenderApi;
use webrender_api::units::{DevicePixel, DevicePoint, DeviceRect, DeviceVector2D, LayoutVector2D};
use webrender_api::{DocumentId, ExternalScrollId, ScrollLocation};
use crate::compositor::RepaintReason;
use crate::paint::RepaintReason;
use crate::painter::Painter;
use crate::pinch_zoom::PinchZoom;
use crate::pipeline_details::PipelineDetails;
@@ -59,7 +59,7 @@ pub(crate) enum ScrollZoomEvent {
#[derive(Clone, Debug)]
pub(crate) struct ScrollResult {
pub hit_test_result: CompositorHitTestResult,
pub hit_test_result: PaintHitTestResult,
/// The [`ExternalScrollId`] of the node that was actually scrolled.
///
/// 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>,
/// The rectangle of the [`WebView`] in device pixels, which is the viewport.
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>,
/// Pending scroll/zoom events.
pending_scroll_zoom_events: Vec<ScrollZoomEvent>,
@@ -154,11 +154,7 @@ impl WebViewRenderer {
}
}
fn hit_test(
&self,
webrender_api: &RenderApi,
point: DevicePoint,
) -> Vec<CompositorHitTestResult> {
fn hit_test(&self, webrender_api: &RenderApi, point: DevicePoint) -> Vec<PaintHitTestResult> {
Painter::hit_test_at_point_with_api_and_document(
webrender_api,
self.webrender_document,
@@ -893,7 +889,7 @@ impl WebViewRenderer {
return (pinch_zoom_result, vec![]);
};
let hit_test_result = CompositorHitTestResult {
let hit_test_result = PaintHitTestResult {
pipeline_id: root_pipeline_id,
// It's difficult to get a good value for this as it needs to be piped
// all the way through script and back here.
@@ -915,7 +911,7 @@ impl WebViewRenderer {
fn dispatch_scroll_event(
&self,
external_id: ExternalScrollId,
hit_test_result: CompositorHitTestResult,
hit_test_result: PaintHitTestResult,
) {
let event = InputEvent::Scroll(EmbedderScrollEvent { external_id }).into();
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 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
//! and cache shared fonts, images, or other resources.
//! * The service worker manager.
@@ -66,7 +66,7 @@
//! sender to send some data. Servo tries to achieve deadlock-freedom by using the following
//! can-block-on relation:
//!
//! * Constellation can block on compositor
//! * Constellation can block on `Paint`
//! * Constellation can block on embedder
//! * 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)
@@ -113,7 +113,7 @@ use canvas_traits::ConstellationCanvasMsg;
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use canvas_traits::webgl::WebGLThreads;
use compositing_traits::{
CompositorMsg, CompositorProxy, PipelineExitSource, SendableFrameTree,
PaintMessage, PaintProxy, PipelineExitSource, SendableFrameTree,
WebRenderExternalImageIdManager,
};
use constellation_traits::{
@@ -133,11 +133,12 @@ use devtools_traits::{
use embedder_traits::resources::{self, Resource};
use embedder_traits::user_content_manager::UserContentManager;
use embedder_traits::{
AnimationState, CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse,
EmbedderMsg, EmbedderProxy, FocusSequenceNumber, InputEvent, InputEventAndId, JSValue,
JavaScriptEvaluationError, JavaScriptEvaluationId, KeyboardEvent, MediaSessionActionType,
MediaSessionEvent, MediaSessionPlaybackState, MouseButton, MouseButtonAction, MouseButtonEvent,
Theme, ViewportDetails, WebDriverCommandMsg, WebDriverLoadStatus, WebDriverScriptCommand,
AnimationState, EmbedderControlId, EmbedderControlResponse, EmbedderMsg, EmbedderProxy,
FocusSequenceNumber, InputEvent, InputEventAndId, JSValue, JavaScriptEvaluationError,
JavaScriptEvaluationId, KeyboardEvent, MediaSessionActionType, MediaSessionEvent,
MediaSessionPlaybackState, MouseButton, MouseButtonAction, MouseButtonEvent,
PaintHitTestResult, Theme, ViewportDetails, WebDriverCommandMsg, WebDriverLoadStatus,
WebDriverScriptCommand,
};
use euclid::Size2D;
use euclid::default::Size2D as UntypedSize2D;
@@ -323,8 +324,8 @@ pub struct Constellation<STF, SWF> {
pub(crate) embedder_proxy: EmbedderProxy,
/// A channel (the implementation of which is port-specific) for the
/// constellation to send messages to the compositor thread.
pub(crate) compositor_proxy: CompositorProxy,
/// constellation to send messages to `Paint`.
pub(crate) paint_proxy: PaintProxy,
/// Bookkeeping data for all webviews in the constellation.
webviews: FxHashMap<WebViewId, ConstellationWebView>,
@@ -514,8 +515,8 @@ pub struct InitialConstellationState {
/// A channel through which messages can be sent to the embedder.
pub embedder_proxy: EmbedderProxy,
/// A channel through which messages can be sent to the compositor in-process.
pub compositor_proxy: CompositorProxy,
/// A channel through which messages can be sent to `Paint` in-process.
pub paint_proxy: PaintProxy,
/// A channel to the developer tools, if applicable.
pub devtools_sender: Option<Sender<DevtoolsControlMsg>>,
@@ -567,10 +568,10 @@ pub struct InitialConstellationState {
pub async_runtime: Box<dyn AsyncRuntime>,
}
/// When we are exiting a pipeline, we can either force exiting or not.
/// A normal exit waits for the compositor to update its state before
/// exiting, and delegates layout exit to script. A forced exit does
/// not notify the compositor, and exits layout without involving script.
/// When we are exiting a pipeline, we can either force exiting or not. A normal exit
/// waits for `Paint` to update its state before exiting, and delegates layout exit to
/// script. A forced exit does not notify `Paint`, and exits layout without involving
/// script.
#[derive(Clone, Copy, Debug)]
enum ExitPipelineMode {
Normal,
@@ -685,7 +686,7 @@ where
embedder_to_constellation_receiver,
layout_factory,
embedder_proxy: state.embedder_proxy,
compositor_proxy: state.compositor_proxy,
paint_proxy: state.paint_proxy,
webviews: Default::default(),
devtools_sender: state.devtools_sender,
script_to_devtools_callback: Default::default(),
@@ -1220,7 +1221,7 @@ where
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)]
fn handle_request(&mut self) {
#[expect(clippy::large_enum_variant)]
@@ -1229,12 +1230,12 @@ where
PipelineNamespace(PipelineNamespaceRequest),
Script((WebViewId, PipelineId, ScriptToConstellationMessage)),
BackgroundHangMonitor(HangMonitorAlert),
Compositor(EmbedderToConstellationMessage),
Embedder(EmbedderToConstellationMessage),
FromSWManager(SWManagerMsg),
RemoveProcess(usize),
}
// 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
// fails, it is because the matching sender has been
// reclaimed, but this can't happen in normal execution
@@ -1271,9 +1272,9 @@ where
.recv(&self.background_hang_monitor_receiver)
.expect("Unexpected BHM channel panic in constellation")
.map(Request::BackgroundHangMonitor),
3 => Ok(Request::Compositor(
3 => Ok(Request::Embedder(
oper.recv(&self.embedder_to_constellation_receiver)
.expect("Unexpected compositor channel panic in constellation"),
.expect("Unexpected embedder channel panic in constellation"),
)),
4 => oper
.recv(&self.swmanager_receiver)
@@ -1297,7 +1298,7 @@ where
Request::PipelineNamespace(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) => {
self.handle_request_from_script(message);
},
@@ -1341,8 +1342,8 @@ where
}
#[servo_tracing::instrument(skip_all)]
fn handle_request_from_compositor(&mut self, message: EmbedderToConstellationMessage) {
trace_msg_from_compositor!(message, "{message:?}");
fn handle_request_from_embedder(&mut self, message: EmbedderToConstellationMessage) {
trace_msg_from_embedder!(message, "{message:?}");
match message {
EmbedderToConstellationMessage::Exit => {
self.handle_exit();
@@ -2024,7 +2025,7 @@ where
};
let webgpu_chan = match browsing_context_group.webgpus.entry(host) {
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
.webrender_external_image_id_manager
.clone(),
@@ -2446,7 +2447,7 @@ where
resource_threads: self.public_resource_threads.clone(),
own_sender: own_sender.clone(),
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(),
};
@@ -2737,9 +2738,9 @@ where
};
// 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.
self.compositor_proxy.send(CompositorMsg::PipelineExited(
self.paint_proxy.send(PaintMessage::PipelineExited(
pipeline.webview_id,
pipeline.id,
PipelineExitSource::Constellation,
@@ -2962,7 +2963,7 @@ where
&mut self,
webview_id: WebViewId,
event: InputEventAndId,
hit_test_result: Option<CompositorHitTestResult>,
hit_test_result: Option<PaintHitTestResult>,
) {
if let InputEvent::MouseButton(event) = &event.event {
self.update_pressed_mouse_buttons(event);
@@ -3303,7 +3304,7 @@ where
webview_id,
None,
script_sender,
self.compositor_proxy.clone(),
self.paint_proxy.clone(),
is_parent_throttled,
load_info.load_data,
);
@@ -3380,7 +3381,7 @@ where
new_webview_id,
Some(opener_browsing_context_id),
script_sender,
self.compositor_proxy.clone(),
self.paint_proxy.clone(),
is_opener_throttled,
load_data,
);
@@ -3446,8 +3447,8 @@ where
if let Some(pipeline) = self.pipelines.get_mut(&pipeline_id) {
if pipeline.animation_state != animation_state {
pipeline.animation_state = animation_state;
self.compositor_proxy
.send(CompositorMsg::ChangeRunningAnimationsState(
self.paint_proxy
.send(PaintMessage::ChangeRunningAnimationsState(
pipeline.webview_id,
pipeline_id,
animation_state,
@@ -5042,8 +5043,8 @@ where
)
})
.collect();
self.compositor_proxy
.send(CompositorMsg::ScreenshotReadinessReponse(
self.paint_proxy
.send(PaintMessage::ScreenshotReadinessReponse(
screenshot_request.webview_id,
pipelines_and_epochs,
));
@@ -5393,7 +5394,7 @@ where
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);
self.send_screenshot_readiness_requests_to_pipelines();
@@ -5451,7 +5452,7 @@ where
.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)]
fn browsing_context_to_sendable(
&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)]
fn set_frame_tree_for_webview(&mut self, webview_id: WebViewId) {
// 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);
if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) {
debug!("{}: Sending frame tree", browsing_context_id);
self.compositor_proxy
.send(CompositorMsg::SetFrameTreeForWebView(
webview_id, frame_tree,
));
self.paint_proxy
.send(PaintMessage::SetFrameTreeForWebView(webview_id, frame_tree));
}
}
@@ -5567,7 +5566,7 @@ where
fn create_canvas_paint_thread(
&self,
) -> (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(

View File

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

View File

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

View File

@@ -6,7 +6,7 @@ use std::collections::HashSet;
use std::rc::Rc;
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 embedder_traits::{AnimationState, FocusSequenceNumber};
use ipc_channel::Error;
@@ -37,8 +37,8 @@ pub struct Pipeline {
/// The event loop handling this pipeline.
pub event_loop: Rc<EventLoop>,
/// A channel to the compositor.
pub compositor_proxy: CompositorProxy,
/// A channel to `Paint`.
pub paint_proxy: PaintProxy,
/// The most recently loaded URL in this pipeline.
/// 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.opener,
event_loop,
constellation.compositor_proxy.clone(),
constellation.paint_proxy.clone(),
throttled,
new_pipeline_info.load_data,
))
@@ -105,7 +105,7 @@ impl Pipeline {
webview_id: WebViewId,
opener: Option<BrowsingContextId>,
event_loop: Rc<EventLoop>,
compositor_proxy: CompositorProxy,
paint_proxy: PaintProxy,
throttled: bool,
load_data: LoadData,
) -> Self {
@@ -115,7 +115,7 @@ impl Pipeline {
webview_id,
opener,
event_loop,
compositor_proxy,
paint_proxy,
url: load_data.url.clone(),
children: vec![],
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 {
CompositionPipeline {
id: self.id,
@@ -191,11 +191,11 @@ impl Pipeline {
/// running timers at a heavily limited rate.
pub fn set_throttled(&self, throttled: bool) {
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);
if let Err(e) = err {
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
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
/// Log an event from compositor at trace level.
/// - To disable tracing: RUST_LOG='constellation<compositor@=off'
/// - To enable tracing: RUST_LOG='constellation<compositor@'
/// Log an event from embedder at trace level.
/// - To disable tracing: RUST_LOG='constellation<embedder@=off'
/// - To enable tracing: RUST_LOG='constellation<embedder@'
/// - Recommended filters when tracing is enabled:
/// - constellation<compositor@ForwardEvent(MouseMoveEvent)=off
/// - constellation<compositor@LogEntry=off
/// - constellation<compositor@ReadyToPresent=off
macro_rules! trace_msg_from_compositor {
/// - constellation<embedder@ForwardEvent(MouseMoveEvent)=off
/// - constellation<embedder@LogEntry=off
/// - constellation<embedder@ReadyToPresent=off
macro_rules! trace_msg_from_embedder {
// This macro only exists to put the docs in the same file as the target prefix,
// so the macro definition is always the same.
($event:expr, $($rest:tt)+) => {
@@ -35,14 +35,14 @@ pub(crate) trait LogTarget {
fn log_target(&self) -> &'static str;
}
mod from_compositor {
mod from_embedder {
use embedder_traits::{InputEvent, InputEventAndId};
use super::LogTarget;
macro_rules! target {
($($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 base::id::{PainterId, WebViewId};
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use content_security_policy::Violation;
use fonts_traits::{
CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
@@ -81,8 +81,8 @@ pub struct FontContext {
resource_threads: Mutex<CoreResourceThread>,
/// A sender that can send messages and receive replies from the compositor.
compositor_api: Mutex<CrossProcessCompositorApi>,
/// A sender that can send messages and receive replies from `Paint`.
paint_api: Mutex<CrossProcessPaintApi>,
/// 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.
@@ -143,14 +143,14 @@ impl Clone for WebFontDocumentContext {
impl FontContext {
pub fn new(
system_font_service_proxy: Arc<SystemFontServiceProxy>,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
resource_threads: ResourceThreads,
) -> Self {
#[allow(clippy::default_constructed_unit_structs)]
Self {
system_font_service_proxy,
resource_threads: Mutex::new(resource_threads.core_thread),
compositor_api: Mutex::new(compositor_api),
paint_api: Mutex::new(paint_api),
fonts: Default::default(),
resolved_font_groups: Default::default(),
web_fonts: Default::default(),
@@ -361,7 +361,7 @@ impl FontContext {
.entry(identifier.clone())
.or_insert_with(|| {
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_data.as_ipc_shared_memory(),
identifier.index(),
@@ -383,7 +383,7 @@ impl FontContext {
let font_instance_key = self
.system_font_service_proxy
.generate_font_instance_key(painter_id);
self.compositor_api.lock().add_font_instance(
self.paint_api.lock().add_font_instance(
font_instance_key,
font_key,
pt_size.to_f32_px(),

View File

@@ -9,7 +9,7 @@ use std::thread;
use app_units::Au;
use base::id::PainterId;
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use fonts_traits::{
FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, LowercaseFontFamilyName,
SystemFontServiceMessage, SystemFontServiceProxySender,
@@ -58,21 +58,21 @@ struct FontInstancesMapKey {
pub struct SystemFontService {
port: IpcReceiver<SystemFontServiceMessage>,
local_families: FontStore,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
// keys already have the IdNamespace for webrender
webrender_fonts: HashMap<(FontIdentifier, PainterId), FontKey>,
font_instances: HashMap<FontInstancesMapKey, FontInstanceKey>,
generic_fonts: ResolvedGenericFontFamilies,
/// 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
/// [`SystemFontService`] will fetch a new batch.
/// TODO: We currently do not delete the free keys if a `WebView` is removed.
free_font_keys: FxHashMap<PainterId, Vec<FontKey>>,
/// 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
/// [`SystemFontService`] will fetch a new batch.
free_font_instance_keys: FxHashMap<PainterId, Vec<FontInstanceKey>>,
@@ -80,7 +80,7 @@ pub struct SystemFontService {
impl SystemFontService {
pub fn spawn(
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
memory_profiler_sender: ProfilerChan,
) -> SystemFontServiceProxySender {
let (sender, receiver) = ipc::channel().unwrap();
@@ -93,7 +93,7 @@ impl SystemFontService {
let mut cache = SystemFontService {
port: receiver,
local_families: Default::default(),
compositor_api,
paint_api,
webrender_fonts: HashMap::new(),
font_instances: HashMap::new(),
generic_fonts: Default::default(),
@@ -204,7 +204,7 @@ impl SystemFontService {
const FREE_FONT_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_INSTANCE_KEYS_BATCH_SIZE - self.free_font_instance_keys.len(),
painter_id,
@@ -278,7 +278,7 @@ impl SystemFontService {
) -> FontInstanceKey {
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 font_key = *webrender_fonts
@@ -293,8 +293,7 @@ impl SystemFontService {
let FontIdentifier::Local(local_font_identifier) = identifier else {
unreachable!("Should never have a web font in the system font service");
};
compositor_api
.add_system_font(font_key, local_font_identifier.native_font_handle());
paint_api.add_system_font(font_key, local_font_identifier.native_font_handle());
font_key
});
@@ -312,7 +311,7 @@ impl SystemFontService {
.expect("We just filled the keys")
.pop()
.unwrap();
compositor_api.add_font_instance(
paint_api.add_font_instance(
font_instance_key,
font_key,
pt_size.to_f32_px(),

View File

@@ -14,7 +14,7 @@ mod font_context {
use std::thread;
use app_units::Au;
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use fonts::platform::font::PlatformFont;
use fonts::{
FallbackFontSelectionOptions, FontContext, FontDescriptor, FontFamilyDescriptor,
@@ -50,14 +50,14 @@ mod font_context {
let (system_font_service, system_font_service_proxy) = MockSystemFontService::spawn();
let (core_sender, _) = ipc::channel().unwrap();
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());
INIT.call_once(|| {
start_fetch_thread();
});
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_proxy,
}

View File

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

View File

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

View File

@@ -17,7 +17,7 @@ pub(crate) struct LargestContentfulPaintCandidateCollector {
/// The rect of viewport.
pub viewport_rect: LayoutRect,
/// 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,
}

View File

@@ -8,7 +8,7 @@ use std::sync::Arc;
use app_units::{AU_PER_PX, Au};
use base::id::ScrollTreeNodeId;
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::{
LCPCandidateID, LargestContentfulPaintType,
};
@@ -99,8 +99,8 @@ pub(crate) struct DisplayListBuilder<'a> {
/// The [`wr::DisplayListBuilder`] for this Servo [`DisplayListBuilder`].
pub webrender_display_list_builder: &'a mut wr::DisplayListBuilder,
/// The [`CompositorDisplayListInfo`] used to collect display list items and metadata.
pub compositor_info: &'a mut CompositorDisplayListInfo,
/// The [`PaintDisplayListInfo`] used to collect display list items and metadata.
pub paint_info: &'a mut PaintDisplayListInfo,
/// Data about the fragments that are highlighted by the inspector, if any.
///
@@ -176,8 +176,8 @@ impl DisplayListBuilder<'_> {
lcp_candidate_collector: Option<&mut LargestContentfulPaintCandidateCollector>,
) -> BuiltDisplayList {
// Build the rest of the display list which inclues all of the WebRender primitives.
let compositor_info = &mut stacking_context_tree.compositor_info;
let pipeline_id = compositor_info.pipeline_id;
let paint_info = &mut stacking_context_tree.paint_info;
let pipeline_id = paint_info.pipeline_id;
let mut webrender_display_list_builder =
webrender_api::DisplayListBuilder::new(pipeline_id);
webrender_display_list_builder.begin();
@@ -192,11 +192,11 @@ impl DisplayListBuilder<'_> {
let _span = profile_traits::trace_span!("DisplayListBuilder::build").entered();
let mut builder = DisplayListBuilder {
current_scroll_node_id: compositor_info.root_reference_frame_id,
current_reference_frame_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: paint_info.root_reference_frame_id,
current_clip_id: ClipId::INVALID,
webrender_display_list_builder: &mut webrender_display_list_builder,
compositor_info,
paint_info,
inspector_highlight: highlighted_dom_node.map(InspectorHighlight::for_node),
paint_body_background: true,
clip_map: Default::default(),
@@ -213,8 +213,8 @@ impl DisplayListBuilder<'_> {
// Add a single hit test that covers the entire viewport, so that WebRender knows
// which pipeline it hits when doing hit testing.
let pipeline_id = builder.compositor_info.pipeline_id;
let viewport_size = builder.compositor_info.viewport_details.size;
let pipeline_id = builder.paint_info.pipeline_id;
let viewport_size = builder.paint_info.viewport_details.size;
let viewport_rect = LayoutRect::from_size(viewport_size.cast_unit());
builder.wr().push_hit_test(
viewport_rect,
@@ -241,15 +241,15 @@ impl DisplayListBuilder<'_> {
}
fn pipeline_id(&mut self) -> wr::PipelineId {
self.compositor_info.pipeline_id
self.paint_info.pipeline_id
}
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 {
self.compositor_info.scroll_tree.webrender_id(id)
self.paint_info.scroll_tree.webrender_id(id)
}
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
// produced for every SpatialTree node is unique.
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());
mapping.push(SpatialId::root_reference_frame(self.pipeline_id()));
@@ -330,7 +330,7 @@ impl DisplayListBuilder<'_> {
}
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
@@ -532,7 +532,7 @@ impl DisplayListBuilder<'_> {
) {
if let Some(lcp_collector) = &mut self.lcp_candidate_collector {
let transform = self
.compositor_info
.paint_info
.scroll_tree
.cumulative_node_to_root_transform(self.current_scroll_node_id);
lcp_collector.add_or_update_candidate(
@@ -1137,7 +1137,7 @@ impl<'a> BuilderForBoxFragment<'a> {
fn build_hit_test(&self, builder: &mut DisplayListBuilder, rect: LayoutRect) {
let external_scroll_node_id = builder
.compositor_info
.paint_info
.external_scroll_id_for_scroll_tree_node(builder.current_scroll_node_id);
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::print_tree::PrintTree;
use compositing_traits::display_list::{
AxesScrollSensitivity, CompositorDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo,
AxesScrollSensitivity, PaintDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo,
SpatialTreeNodeInfo, StickyNodeInfo,
};
use embedder_traits::ViewportDetails;
@@ -106,11 +106,11 @@ pub(crate) struct StackingContextTree {
/// The root stacking context of this [`StackingContextTree`].
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
/// 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.
pub compositor_info: CompositorDisplayListInfo,
pub paint_info: PaintDisplayListInfo,
/// All of the clips collected for this [`StackingContextTree`]. These are added
/// 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 compositor_info = CompositorDisplayListInfo::new(
let paint_info = PaintDisplayListInfo::new(
viewport_details,
scrollable_overflow,
pipeline_id,
@@ -145,7 +145,7 @@ impl StackingContextTree {
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(
fragment_tree.initial_containing_block,
root_scroll_node_id,
@@ -154,7 +154,7 @@ impl StackingContextTree {
);
let cb_for_fixed_descendants = ContainingBlock::new(
fragment_tree.initial_containing_block,
compositor_info.root_reference_frame_id,
paint_info.root_reference_frame_id,
None,
ClipId::INVALID,
);
@@ -174,7 +174,7 @@ impl StackingContextTree {
let mut stacking_context_tree = Self {
// 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),
compositor_info,
paint_info,
clip_store: Default::default(),
};
@@ -209,7 +209,7 @@ impl StackingContextTree {
transform: LayoutTransform,
kind: wr::ReferenceFrameKind,
) -> ScrollTreeNodeId {
self.compositor_info.scroll_tree.add_scroll_tree_node(
self.paint_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id),
SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo {
origin,
@@ -229,7 +229,7 @@ impl StackingContextTree {
clip_rect: LayoutRect,
scroll_sensitivity: AxesScrollSensitivity,
) -> ScrollTreeNodeId {
self.compositor_info.scroll_tree.add_scroll_tree_node(
self.paint_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id),
SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo {
external_id,
@@ -250,7 +250,7 @@ impl StackingContextTree {
vertical_offset_bounds: StickyOffsetBounds,
horizontal_offset_bounds: StickyOffsetBounds,
) -> ScrollTreeNodeId {
self.compositor_info.scroll_tree.add_scroll_tree_node(
self.paint_info.scroll_tree.add_scroll_tree_node(
Some(parent_scroll_node_id),
SpatialTreeNodeInfo::Sticky(StickyNodeInfo {
frame_rect,
@@ -1505,7 +1505,7 @@ impl BoxFragment {
let tag = self.base.tag?;
let external_scroll_id = wr::ExternalScrollId(
tag.to_display_list_fragment_id(),
stacking_context_tree.compositor_info.pipeline_id,
stacking_context_tree.paint_info.pipeline_id,
);
let sensitivity = AxesScrollSensitivity {
@@ -1546,7 +1546,7 @@ impl BoxFragment {
None => {
// This is a direct descendant of a reference frame.
&stacking_context_tree
.compositor_info
.paint_info
.viewport_details
.layout_size()
},

View File

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

View File

@@ -116,7 +116,7 @@ pub(crate) fn process_box_area_request(
}
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 {
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());
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 {
return box_areas
.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::threadpool::ThreadPool;
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
use compositing_traits::{CrossProcessPaintApi, ImageUpdate, SerializableImageData};
use imsz::imsz_from_reader;
use log::{debug, warn};
use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps};
@@ -121,7 +121,7 @@ fn decode_bytes_sync(
}
fn set_webrender_image_key(
compositor_api: &CrossProcessCompositorApi,
paint_api: &CrossProcessPaintApi,
image: &mut RasterImage,
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 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);
}
@@ -461,9 +461,9 @@ struct ImageCacheStore {
#[conditional_malloc_size_of]
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"]
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
/// The [`WebView`] of the `Webview` associated with this [`ImageCache`].
webview_id: WebViewId,
@@ -481,11 +481,11 @@ impl ImageCacheStore {
fn set_key_and_finish_load(&mut self, pending_image: PendingKey, image_key: WebRenderImageKey) {
match pending_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));
},
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);
},
}
@@ -512,7 +512,7 @@ impl ImageCacheStore {
fn fetch_more_image_keys(&mut self) {
self.key_cache.cache = KeyCacheState::PendingBatch;
self.compositor_api
self.paint_api
.generate_image_key_async(self.webview_id, self.pipeline_id);
}
@@ -533,7 +533,7 @@ impl ImageCacheStore {
self.load_image_with_keycache(key);
}
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);
self.key_cache.cache = KeyCacheState::PendingBatch
}
@@ -689,7 +689,7 @@ impl ImageCacheFactory for ImageCacheFactoryImpl {
&self,
webview_id: WebViewId,
pipeline_id: PipelineId,
compositor_api: &CrossProcessCompositorApi,
paint_api: &CrossProcessPaintApi,
) -> Arc<dyn ImageCache> {
Arc::new(ImageCacheImpl {
store: Arc::new(Mutex::new(ImageCacheStore {
@@ -698,7 +698,7 @@ impl ImageCacheFactory for ImageCacheFactoryImpl {
vector_images: FxHashMap::default(),
rasterized_vector_images: FxHashMap::default(),
broken_image_icon_image: OnceCell::new(),
compositor_api: compositor_api.clone(),
paint_api: paint_api.clone(),
pipeline_id,
webview_id,
key_cache: KeyCache::new(),
@@ -744,7 +744,7 @@ impl ImageCache for ImageCacheImpl {
}
store
.compositor_api
.paint_api
.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)
.or_else(|| load_from_memory(FALLBACK_RIPPY, CorsStatus::Unsafe))?;
let image_key = store
.compositor_api
.paint_api
.generate_image_key_blocking(store.webview_id)
.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))
})
.clone()
@@ -1100,7 +1100,7 @@ impl Drop for ImageCacheStore {
.filter_map(|task| task.result.as_ref()?.id.map(ImageUpdate::DeleteImage)),
)
.collect();
self.compositor_api
self.paint_api
.update_images(self.webview_id.into(), image_updates);
}
}

View File

@@ -6,7 +6,7 @@ use std::sync::Arc;
use std::time::Duration;
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 net::image_cache::ImageCacheFactoryImpl;
use net_traits::image_cache::{
@@ -26,17 +26,15 @@ use crate::mock_origin;
fn create_test_image_cache() -> (Arc<dyn ImageCache>, Receiver<PipelineId>) {
let (sender, receiver) = unbounded();
let compositor_api =
CrossProcessCompositorApi::dummy_with_callback(Some(Box::new(move |msg| {
if let compositing_traits::CompositorMsg::GenerateImageKeysForPipeline(_, pipeline_id) =
msg
{
let _ = sender.send(pipeline_id);
}
})));
let paint_api = CrossProcessPaintApi::dummy_with_callback(Some(Box::new(move |msg| {
if let compositing_traits::PaintMessage::GenerateImageKeysForPipeline(_, pipeline_id) = msg
{
let _ = sender.send(pipeline_id);
}
})));
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)
}

View File

@@ -375,7 +375,7 @@ pub(crate) struct Document {
/// Whether we're in the process of running animation callbacks.
///
/// 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>,
/// Tracks all outstanding loads related to this document.
loader: DomRefCell<DocumentLoader>,
@@ -2801,7 +2801,7 @@ impl Document {
if !image_keys.is_empty() {
results.insert(ReflowPhasesRun::UpdatedImageData);
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.window().pipeline_id(),
current_rendering_epoch,
@@ -2811,7 +2811,7 @@ impl Document {
let results = results.union(self.window().reflow(ReflowGoal::UpdateTheRendering));
self.window().compositor_api().update_epoch(
self.window().paint_api().update_epoch(
self.webview_id(),
pipeline_id,
current_rendering_epoch,

View File

@@ -70,9 +70,9 @@ pub(crate) struct DocumentEventHandler {
window: Dom<Window>,
/// Pending input events, to be handled at the next rendering opportunity.
#[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>>,
/// 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>>,
/// <https://w3c.github.io/uievents/#event-type-dblclick>
#[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) {
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(..)) {
// First try to replace any existing mouse move event.
if let Some(mouse_move_event) = self
.mouse_move_event_index
.borrow()
.and_then(|index| pending_compositor_events.get_mut(index))
.and_then(|index| pending_input_events.get_mut(index))
{
*mouse_move_event = event;
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
@@ -466,8 +466,8 @@ impl DocumentEventHandler {
);
}
// Send mousemove event to topmost target, unless it's an iframe, in which case the
// compositor should have also sent an event to the inner document.
// Send mousemove event to topmost target, unless it's an iframe, in which case
// `Paint` should have also sent an event to the inner document.
MouseEvent::new_simple(
&self.window,
FireMouseEventType::Move,
@@ -1605,7 +1605,7 @@ impl DocumentEventHandler {
if scrolling_box.is_viewport() && parent_pipeline.is_none() {
let (_, delta) = calculate_current_scroll_offset_and_delta();
self.window
.compositor_api()
.paint_api()
.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 base::id::WebViewId;
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
use compositing_traits::{CrossProcessPaintApi, ImageUpdate, SerializableImageData};
use content_security_policy::sandboxing_directive::SandboxingFlagSet;
use dom_struct::dom_struct;
use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState};
@@ -171,7 +171,7 @@ pub(crate) struct MediaFrameRenderer {
webview_id: WebViewId,
player_id: Option<usize>,
glplayer_id: Option<u64>,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
#[ignore_malloc_size_of = "Defined in other crates"]
player_context: WindowGLContext,
current_frame: Option<MediaFrame>,
@@ -185,14 +185,14 @@ pub(crate) struct MediaFrameRenderer {
impl MediaFrameRenderer {
fn new(
webview_id: WebViewId,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
player_context: WindowGLContext,
) -> Self {
Self {
webview_id,
player_id: None,
glplayer_id: None,
compositor_api,
paint_api,
player_context,
current_frame: None,
old_frame: None,
@@ -295,7 +295,7 @@ impl MediaFrameRenderer {
}
if !updates.is_empty() {
self.compositor_api
self.paint_api
.update_images(self.webview_id.into(), updates);
}
}
@@ -361,9 +361,8 @@ impl VideoFrameRenderer for MediaFrameRenderer {
Some(current_frame) => {
self.old_frame = Some(current_frame.image_key);
let Some(new_image_key) = self
.compositor_api
.generate_image_key_blocking(self.webview_id)
let Some(new_image_key) =
self.paint_api.generate_image_key_blocking(self.webview_id)
else {
return;
};
@@ -397,9 +396,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data));
},
None => {
let Some(image_key) = self
.compositor_api
.generate_image_key_blocking(self.webview_id)
let Some(image_key) = self.paint_api.generate_image_key_blocking(self.webview_id)
else {
return;
};
@@ -432,7 +429,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data));
},
}
self.compositor_api
self.paint_api
.update_images(self.webview_id.into(), updates);
}
}
@@ -649,7 +646,7 @@ impl HTMLMediaElement {
player: Default::default(),
video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
document.webview_id(),
document.window().compositor_api().clone(),
document.window().paint_api().clone(),
document.window().get_player_context(),
))),
audio_renderer: Default::default(),

View File

@@ -144,7 +144,7 @@ impl HTMLMetaElement {
if let Ok(viewport) = ViewportDescription::from_str(&content.value()) {
self.owner_window()
.compositor_api()
.paint_api()
.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
/// `CompositorHitTestResult` against our current layout.
/// `PaintHitTestResult` against our current layout.
pub(crate) struct HitTestResult {
pub node: DomRoot<Node>,
pub cursor: Cursor,

View File

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

View File

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

View File

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

View File

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

View File

@@ -17,9 +17,9 @@ use base::id::{PipelineNamespace, PipelineNamespaceId};
use bluetooth::BluetoothThreadFactory;
#[cfg(feature = "bluetooth")]
use bluetooth_traits::BluetoothRequest;
use compositing::{IOCompositor, InitialCompositorState};
use compositing::{InitialPaintState, Paint};
pub use compositing_traits::rendering_context::RenderingContext;
use compositing_traits::{CompositorMsg, CompositorProxy, CrossProcessCompositorApi};
use compositing_traits::{CrossProcessPaintApi, PaintMessage, PaintProxy};
#[cfg(all(
not(target_os = "windows"),
not(target_os = "ios"),
@@ -135,7 +135,7 @@ mod media_platform {
struct ServoInner {
delegate: RefCell<Rc<dyn ServoDelegate>>,
compositor: Rc<RefCell<IOCompositor>>,
paint: Rc<RefCell<Paint>>,
constellation_proxy: ConstellationProxy,
embedder_receiver: Receiver<EmbedderMsg>,
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();
while let Ok(message) = compositor.receiver().try_recv() {
while let Ok(message) = paint.receiver().try_recv() {
match message {
Ok(message) => messages.push(message),
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() {
self.handle_embedder_message(message);
@@ -200,7 +200,7 @@ impl ServoInner {
.notify_error(ServoError::LostConnectionWithBackend);
}
self.compositor.borrow_mut().perform_updates();
self.paint.borrow_mut().perform_updates();
self.send_new_frame_ready_messages();
self.handle_delegate_errors();
self.clean_up_destroyed_webview_handles();
@@ -213,7 +213,7 @@ impl ServoInner {
}
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
.iter()
@@ -242,7 +242,7 @@ impl ServoInner {
fn finish_shutting_down(&self) {
debug!("Servo received message that Constellation shutdown is complete");
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) {
@@ -364,7 +364,7 @@ impl ServoInner {
.finish_evaluation(evaluation_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,
input_event_id,
result,
@@ -682,12 +682,11 @@ impl Servo {
PipelineNamespace::install(PipelineNamespaceId(0));
// 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
// to deliver the message.
let event_loop_waker = builder.event_loop_waker;
let (compositor_proxy, compositor_receiver) =
create_compositor_channel(event_loop_waker.clone());
let (paint_proxy, paint_receiver) = create_paint_channel(event_loop_waker.clone());
let (constellation_proxy, embedder_to_constellation_receiver) = ConstellationProxy::new();
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
let time_profiler_chan = profile_time::Profiler::create(
@@ -718,12 +717,12 @@ impl Servo {
let mut protocols = ProtocolRegistry::with_internal_protocols();
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.
let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown));
let compositor = IOCompositor::new(InitialCompositorState {
compositor_proxy: compositor_proxy.clone(),
receiver: compositor_receiver,
let paint = Paint::new(InitialPaintState {
paint_proxy: paint_proxy.clone(),
receiver: paint_receiver,
embedder_to_constellation_sender: constellation_proxy.sender().clone(),
time_profiler_chan: time_profiler_chan.clone(),
mem_profiler_chan: mem_profiler_chan.clone(),
@@ -748,10 +747,10 @@ impl Servo {
create_constellation(
embedder_to_constellation_receiver,
&compositor.borrow(),
&paint.borrow(),
opts.config_dir.clone(),
embedder_proxy,
compositor_proxy.clone(),
paint_proxy.clone(),
time_profiler_chan,
mem_profiler_chan,
devtools_sender,
@@ -768,7 +767,7 @@ impl Servo {
Servo(Rc::new(ServoInner {
delegate: RefCell::new(Rc::new(DefaultServoDelegate)),
compositor,
paint,
javascript_evaluator: Rc::new(RefCell::new(JavaScriptEvaluator::new(
constellation_proxy.clone(),
))),
@@ -799,9 +798,9 @@ impl Servo {
/// 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
/// - 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) {
self.0.spin_event_loop();
}
@@ -846,12 +845,12 @@ impl Servo {
self.0.private_resource_threads.clear_cookies();
}
pub(crate) fn compositor<'a>(&'a self) -> Ref<'a, IOCompositor> {
self.0.compositor.borrow()
pub(crate) fn paint<'a>(&'a self) -> Ref<'a, Paint> {
self.0.paint.borrow()
}
pub(crate) fn compositor_mut<'a>(&'a self) -> RefMut<'a, IOCompositor> {
self.0.compositor.borrow_mut()
pub(crate) fn paint_mut<'a>(&'a self) -> RefMut<'a, Paint> {
self.0.paint.borrow_mut()
}
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>,
) -> (CompositorProxy, RoutedReceiver<CompositorMsg>) {
) -> (PaintProxy, RoutedReceiver<PaintMessage>) {
let (sender, receiver) = unbounded();
let sender_clone = sender.clone();
let event_loop_waker_clone = event_loop_waker.clone();
// This callback is equivalent to `CompositorProxy::send`
let result_callback = move |msg: Result<CompositorMsg, ipc_channel::Error>| {
// This callback is equivalent to `PaintProxy::send`
let result_callback = move |msg: Result<PaintMessage, ipc_channel::Error>| {
if let Err(err) = sender_clone.send(msg) {
warn!("Failed to send response ({:?}).", err);
}
@@ -898,23 +897,23 @@ fn create_compositor_channel(
let generic_callback =
GenericCallback::new(result_callback).expect("Failed to create callback");
let cross_process_compositor_api = CrossProcessCompositorApi::new(generic_callback);
let compositor_proxy = CompositorProxy {
let cross_process_paint_api = CrossProcessPaintApi::new(generic_callback);
let paint_proxy = PaintProxy {
sender,
cross_process_compositor_api,
cross_process_paint_api,
event_loop_waker,
};
(compositor_proxy, receiver)
(paint_proxy, receiver)
}
#[allow(clippy::too_many_arguments)]
fn create_constellation(
embedder_to_constellation_receiver: Receiver<EmbedderToConstellationMessage>,
compositor: &IOCompositor,
paint: &Paint,
config_dir: Option<PathBuf>,
embedder_proxy: EmbedderProxy,
compositor_proxy: CompositorProxy,
paint_proxy: PaintProxy,
time_profiler_chan: time::ProfilerChan,
mem_profiler_chan: mem::ProfilerChan,
devtools_sender: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
@@ -938,14 +937,14 @@ fn create_constellation(
let system_font_service = Arc::new(
SystemFontService::spawn(
compositor_proxy.cross_process_compositor_api.clone(),
paint_proxy.cross_process_paint_api.clone(),
mem_profiler_chan.clone(),
)
.to_proxy(),
);
let initial_state = InitialConstellationState {
compositor_proxy,
paint_proxy,
embedder_proxy,
devtools_sender,
#[cfg(feature = "bluetooth")]
@@ -958,13 +957,13 @@ fn create_constellation(
time_profiler_chan,
mem_profiler_chan,
#[cfg(feature = "webxr")]
webxr_registry: Some(compositor.webxr_main_thread_registry()),
webxr_registry: Some(paint.webxr_main_thread_registry()),
#[cfg(not(feature = "webxr"))]
webxr_registry: None,
webgl_threads: Some(compositor.webgl_threads()),
webrender_external_image_id_manager: compositor.webrender_external_image_id_manager(),
webgl_threads: Some(paint.webgl_threads()),
webrender_external_image_id_manager: paint.webrender_external_image_id_manager(),
#[cfg(feature = "webgpu")]
wgpu_image_map: compositor.webgpu_image_map(),
wgpu_image_map: paint.webgpu_image_map(),
user_content_manager,
async_runtime,
privileged_urls,

View File

@@ -105,7 +105,7 @@ impl Drop for WebViewInner {
self.servo
.constellation_proxy()
.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 {
let servo = builder.servo;
let painter_id = servo
.compositor_mut()
.paint_mut()
.register_rendering_context(builder.rendering_context.clone());
let id = WebViewId::new(painter_id);
@@ -136,7 +136,7 @@ impl WebView {
})));
let viewport_details = webview.viewport_details();
servo.compositor().add_webview(
servo.paint().add_webview(
Box::new(ServoRendererWebView {
weak_handle: webview.weak_handle(),
id,
@@ -339,7 +339,7 @@ impl WebView {
self.inner()
.servo
.compositor()
.paint()
.resize_rendering_context(self.id(), new_size);
}
@@ -358,14 +358,14 @@ impl WebView {
self.inner_mut().hidpi_scale_factor = new_scale_factor;
self.inner()
.servo
.compositor()
.paint()
.set_hidpi_scale_factor(self.id(), new_scale_factor);
}
pub fn show(&self) {
self.inner()
.servo
.compositor()
.paint()
.show_webview(self.id())
.expect("BUG: invalid WebView instance");
}
@@ -373,7 +373,7 @@ impl WebView {
pub fn hide(&self) {
self.inner()
.servo
.compositor()
.paint()
.hide_webview(self.id())
.expect("BUG: invalid WebView instance");
}
@@ -443,7 +443,7 @@ impl WebView {
pub fn notify_scroll_event(&self, scroll: Scroll, point: WebViewPoint) {
self.inner()
.servo
.compositor()
.paint()
.notify_scroll_event(self.id(), scroll, point);
}
@@ -451,11 +451,11 @@ impl WebView {
let event: InputEventAndId = event.into();
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() {
self.inner()
.servo
.compositor()
.paint()
.notify_input_event(self.id(), event);
} else {
self.inner().servo.constellation_proxy().send(
@@ -491,13 +491,13 @@ impl WebView {
pub fn set_page_zoom(&self, new_zoom: f32) {
self.inner()
.servo
.compositor()
.paint()
.set_page_zoom(self.id(), new_zoom);
}
/// Get the page zoom of the [`WebView`].
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
@@ -512,14 +512,14 @@ impl WebView {
pub fn pinch_zoom(&self, pinch_zoom_delta: f32, center: DevicePoint) {
self.inner()
.servo
.compositor()
.paint()
.pinch_zoom(self.id(), pinch_zoom_delta, center);
}
pub fn device_pixels_per_css_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
self.inner()
.servo
.compositor()
.paint()
.device_pixels_per_page_pixel(self.id())
}
@@ -537,14 +537,11 @@ impl WebView {
}
pub fn toggle_webrender_debugging(&self, debugging: WebRenderDebugOption) {
self.inner()
.servo
.compositor()
.toggle_webrender_debug(debugging);
self.inner().servo.paint().toggle_webrender_debug(debugging);
}
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) {
@@ -565,7 +562,7 @@ impl WebView {
/// Paint the contents of this [`WebView`] into its `RenderingContext`.
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
@@ -606,7 +603,7 @@ impl WebView {
) {
self.inner()
.servo
.compositor()
.paint()
.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
* 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::collections::HashMap;
@@ -419,12 +419,12 @@ impl ScrollTreeNode {
}
/// 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.
#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
pub struct ScrollTree {
/// A list of compositor-side scroll nodes that describe the tree
/// of WebRender spatial nodes, used by the compositor to scroll the
/// A list of `Paint`-side scroll nodes that describe the tree
/// of WebRender spatial nodes, used by `Paint` to scroll the
/// contents of the display list.
pub nodes: Vec<ScrollTreeNode>,
}
@@ -799,10 +799,10 @@ impl ScrollTree {
}
}
/// A data structure which stores compositor-side information about
/// display lists sent to the compositor.
/// A data structure which stores `Paint`-side information about
/// display lists sent to `Paint`.
#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct CompositorDisplayListInfo {
pub struct PaintDisplayListInfo {
/// The WebRender [PipelineId] of this display list.
pub pipeline_id: PipelineId,
@@ -816,7 +816,7 @@ pub struct CompositorDisplayListInfo {
/// The epoch of the display list.
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.
pub scroll_tree: ScrollTree,
@@ -838,8 +838,8 @@ pub struct CompositorDisplayListInfo {
pub first_reflow: bool,
}
impl CompositorDisplayListInfo {
/// Create a new CompositorDisplayListInfo with the root reference frame
impl PaintDisplayListInfo {
/// Create a new PaintDisplayListInfo with the root reference frame
/// and scroll frame already added to the scroll tree.
pub fn new(
viewport_details: ViewportDetails,
@@ -875,7 +875,7 @@ impl CompositorDisplayListInfo {
}),
);
CompositorDisplayListInfo {
PaintDisplayListInfo {
pipeline_id,
viewport_details,
content_size,

View File

@@ -29,7 +29,7 @@ use std::sync::{Arc, Mutex};
use base::generic_channel::{self, GenericCallback, GenericSender};
use bitflags::bitflags;
use display_list::CompositorDisplayListInfo;
use display_list::PaintDisplayListInfo;
use embedder_traits::ScreenGeometry;
use euclid::default::Size2D as UntypedSize2D;
use ipc_channel::ipc::{self, IpcSharedMemory};
@@ -47,25 +47,25 @@ use webrender_api::{
use crate::largest_contentful_paint_candidate::LCPCandidate;
use crate::viewport_description::ViewportDescription;
/// Sends messages to the compositor.
/// Sends messages to `Paint`.
#[derive(Clone)]
pub struct CompositorProxy {
pub sender: Sender<Result<CompositorMsg, ipc_channel::Error>>,
pub struct PaintProxy {
pub sender: Sender<Result<PaintMessage, ipc_channel::Error>>,
/// Access to [`Self::sender`] that is possible to send across an IPC
/// channel. These messages are routed via the router thread to
/// [`Self::sender`].
pub cross_process_compositor_api: CrossProcessCompositorApi,
pub cross_process_paint_api: CrossProcessPaintApi,
pub event_loop_waker: Box<dyn EventLoopWaker>,
}
impl OpaqueSender<CompositorMsg> for CompositorProxy {
fn send(&self, message: CompositorMsg) {
CompositorProxy::send(self, message)
impl OpaqueSender<PaintMessage> for PaintProxy {
fn send(&self, message: PaintMessage) {
PaintProxy::send(self, message)
}
}
impl CompositorProxy {
pub fn send(&self, msg: CompositorMsg) {
impl PaintProxy {
pub fn send(&self, msg: PaintMessage) {
self.route_msg(Ok(msg))
}
@@ -73,7 +73,7 @@ impl CompositorProxy {
///
/// This method is a temporary solution, and will be removed when migrating
/// 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) {
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)]
pub enum CompositorMsg {
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
pub enum PaintMessage {
/// Alerts `Paint` that the given pipeline has changed whether it is running animations.
ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
/// Updates the frame tree for the given webview.
SetFrameTreeForWebView(WebViewId, SendableFrameTree),
/// Set whether to use less resources by stopping animations.
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
/// `DocumentId` of the new frame and the `PainterId` of the associated painter.
NewWebRenderFrameReady(PainterId, DocumentId, bool),
@@ -172,19 +172,19 @@ pub enum CompositorMsg {
),
/// Remove the given font resources from our WebRender instance.
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.
CollectMemoryReport(ReportsChan),
/// A top-level frame has parsed a viewport metatag and is sending the new constraints.
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.
ScreenshotReadinessReponse(WebViewId, FxHashMap<PipelineId, Epoch>),
/// The candidate of largest-contentful-paint
SendLCPCandidate(LCPCandidate, WebViewId, PipelineId, Epoch),
}
impl Debug for CompositorMsg {
impl Debug for PaintMessage {
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
let string: &'static str = self.into();
write!(formatter, "{string}")
@@ -206,29 +206,29 @@ pub struct CompositionPipeline {
/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
pub struct CrossProcessCompositorApi(GenericCallback<CompositorMsg>);
pub struct CrossProcessPaintApi(GenericCallback<PaintMessage>);
impl CrossProcessCompositorApi {
/// Create a new [`CrossProcessCompositorApi`] struct.
pub fn new(callback: GenericCallback<CompositorMsg>) -> Self {
CrossProcessCompositorApi(callback)
impl CrossProcessPaintApi {
/// Create a new [`CrossProcessPaintApi`] struct.
pub fn new(callback: GenericCallback<PaintMessage>) -> Self {
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.
pub fn dummy() -> Self {
Self::dummy_with_callback(None)
}
/// Create a new [`CrossProcessCompositorApi`] struct for unit testing with an optional callback
/// that can respond to compositor messages.
/// Create a new [`CrossProcessPaintApi`] struct for unit testing with an optional callback
/// that can respond to `PaintMessage`s.
pub fn dummy_with_callback(
callback: Option<Box<dyn Fn(CompositorMsg) + Send + 'static>>,
callback: Option<Box<dyn Fn(PaintMessage) + Send + 'static>>,
) -> Self {
let callback = GenericCallback::new(move |msg| {
if let Some(ref handler) = callback {
if let Ok(compositor_msg) = msg {
handler(compositor_msg);
if let Ok(paint_message) = msg {
handler(paint_message);
}
}
})
@@ -240,7 +240,7 @@ impl CrossProcessCompositorApi {
pub fn send_initial_transaction(&self, webview_id: WebViewId, pipeline: WebRenderPipelineId) {
if let Err(e) = self
.0
.send(CompositorMsg::SendInitialTransaction(webview_id, pipeline))
.send(PaintMessage::SendInitialTransaction(webview_id, pipeline))
{
warn!("Error sending initial transaction: {}", e);
}
@@ -256,7 +256,7 @@ impl CrossProcessCompositorApi {
delta: LayoutVector2D,
scroll_id: ExternalScrollId,
) {
if let Err(error) = self.0.send(CompositorMsg::ScrollNodeByDelta(
if let Err(error) = self.0.send(PaintMessage::ScrollNodeByDelta(
webview_id,
pipeline_id,
delta,
@@ -275,7 +275,7 @@ impl CrossProcessCompositorApi {
pub fn scroll_viewport_by_delta(&self, webview_id: WebViewId, delta: LayoutVector2D) {
if let Err(error) = self
.0
.send(CompositorMsg::ScrollViewportByDelta(webview_id, delta))
.send(PaintMessage::ScrollViewportByDelta(webview_id, delta))
{
warn!("Error scroll viewport: {error}");
}
@@ -288,7 +288,7 @@ impl CrossProcessCompositorApi {
canvas_epoch: Epoch,
image_keys: Vec<ImageKey>,
) {
if let Err(error) = self.0.send(CompositorMsg::DelayNewFrameForCanvas(
if let Err(error) = self.0.send(PaintMessage::DelayNewFrameForCanvas(
webview_id,
pipeline_id,
canvas_epoch,
@@ -301,7 +301,7 @@ impl CrossProcessCompositorApi {
/// 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.
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,
pipeline_id,
epoch,
@@ -314,12 +314,12 @@ impl CrossProcessCompositorApi {
pub fn send_display_list(
&self,
webview_id: WebViewId,
display_list_info: &CompositorDisplayListInfo,
display_list_info: &PaintDisplayListInfo,
list: BuiltDisplayList,
) {
let (display_list_data, display_list_descriptor) = list.into_data();
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,
display_list_descriptor,
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(
&self,
lcp_candidate: LCPCandidate,
@@ -352,7 +352,7 @@ impl CrossProcessCompositorApi {
pipeline_id: PipelineId,
epoch: Epoch,
) {
if let Err(error) = self.0.send(CompositorMsg::SendLCPCandidate(
if let Err(error) = self.0.send(PaintMessage::SendLCPCandidate(
lcp_candidate,
webview_id,
pipeline_id,
@@ -364,7 +364,7 @@ impl CrossProcessCompositorApi {
/// Ask the Servo renderer to generate a new frame after having new display lists.
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}");
}
}
@@ -373,20 +373,20 @@ impl CrossProcessCompositorApi {
pub fn generate_image_key_blocking(&self, webview_id: WebViewId) -> Option<ImageKey> {
let (sender, receiver) = generic_channel::channel().unwrap();
self.0
.send(CompositorMsg::GenerateImageKey(webview_id, sender))
.send(PaintMessage::GenerateImageKey(webview_id, sender))
.ok()?;
receiver.recv().ok()
}
/// Sends a message to the compositor for creating new image keys.
/// The compositor will then send a batch of keys over the constellation to the script_thread
/// Sends a message to `Paint` for creating new image keys.
/// `Paint` will then send a batch of keys over the constellation to the script_thread
/// and the appropriate pipeline.
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,
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.
pub fn update_images(&self, painter_id: PainterId, updates: SmallVec<[ImageUpdate; 1]>) {
if let Err(e) = self
.0
.send(CompositorMsg::UpdateImages(painter_id, updates))
{
if let Err(e) = self.0.send(PaintMessage::UpdateImages(painter_id, updates)) {
warn!("error sending image updates: {}", e);
}
}
@@ -440,7 +437,7 @@ impl CrossProcessCompositorApi {
}
let _ = self
.0
.send(CompositorMsg::RemoveFonts(painter_id, keys, instance_keys));
.send(PaintMessage::RemoveFonts(painter_id, keys, instance_keys));
}
pub fn add_font_instance(
@@ -451,7 +448,7 @@ impl CrossProcessCompositorApi {
flags: FontInstanceFlags,
variations: Vec<FontVariation>,
) {
let _x = self.0.send(CompositorMsg::AddFontInstance(
let _x = self.0.send(PaintMessage::AddFontInstance(
font_key.into(),
font_instance_key,
font_key,
@@ -462,7 +459,7 @@ impl CrossProcessCompositorApi {
}
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,
data,
@@ -471,7 +468,7 @@ impl CrossProcessCompositorApi {
}
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,
handle,
@@ -485,7 +482,7 @@ impl CrossProcessCompositorApi {
painter_id: PainterId,
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
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_instance_keys,
sender,
@@ -495,9 +492,7 @@ impl CrossProcessCompositorApi {
}
pub fn viewport(&self, webview_id: WebViewId, description: ViewportDescription) {
let _ = self
.0
.send(CompositorMsg::Viewport(webview_id, description));
let _ = self.0.send(PaintMessage::Viewport(webview_id, description));
}
pub fn pipeline_exited(
@@ -506,7 +501,7 @@ impl CrossProcessCompositorApi {
pipeline_id: PipelineId,
source: PipelineExitSource,
) {
let _ = self.0.send(CompositorMsg::PipelineExited(
let _ = self.0.send(PaintMessage::PipelineExited(
webview_id,
pipeline_id,
source,

View File

@@ -14,7 +14,7 @@ use base::id::{
ServiceWorkerRegistrationId, WebViewId,
};
use canvas_traits::canvas::{CanvasId, CanvasMsg};
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use content_security_policy::sandboxing_directive::SandboxingFlagSet;
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
use embedder_traits::{
@@ -236,8 +236,8 @@ pub struct SWManagerSenders {
pub swmanager_sender: GenericSender<SWManagerMsg>,
/// [`ResourceThreads`] for initating fetches or using i/o.
pub resource_threads: ResourceThreads,
/// [`CrossProcessCompositorApi`] for communicating with the compositor.
pub compositor_api: CrossProcessCompositorApi,
/// [`CrossProcessPaintApi`] for communicating with `Paint`.
pub paint_api: CrossProcessPaintApi,
/// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
pub system_font_service_sender: SystemFontServiceProxySender,
/// 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 compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
use embedder_traits::{
CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, InputEventAndId,
JavaScriptEvaluationId, MediaSessionActionType, Theme, TraversalId, ViewportDetails,
EmbedderControlId, EmbedderControlResponse, InputEventAndId, JavaScriptEvaluationId,
MediaSessionActionType, PaintHitTestResult, Theme, TraversalId, ViewportDetails,
WebDriverCommandMsg,
};
pub use from_script_message::*;
@@ -79,7 +79,7 @@ pub enum EmbedderToConstellationMessage {
/// Make none of the webviews focused.
BlurWebView,
/// 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
/// recently hovered cursor position and resetting the cursor. This happens after a
/// display list update is rendered.

View File

@@ -306,7 +306,7 @@ pub struct ViewportDetails {
pub size: Size2D<f32, CSSPixel>,
/// 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>,
}
@@ -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)]
pub struct CompositorHitTestResult {
pub struct PaintHitTestResult {
/// The pipeline id of the resulting item.
pub pipeline_id: PipelineId,

View File

@@ -24,7 +24,7 @@ use base::Epoch;
use base::generic_channel::GenericSender;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
use bitflags::bitflags;
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails};
use euclid::Point2D;
use euclid::default::{Point2D as UntypedPoint2D, Rect};
@@ -209,7 +209,7 @@ pub struct LayoutConfig {
pub image_cache: Arc<dyn ImageCache>,
pub font_context: Arc<FontContext>,
pub time_profiler_chan: time::ProfilerChan,
pub compositor_api: CrossProcessCompositorApi,
pub paint_api: CrossProcessPaintApi,
pub viewport_details: ViewportDetails,
pub theme: Theme,
}
@@ -297,7 +297,7 @@ pub trait Layout {
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(
&mut self,
scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>,

View File

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

View File

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

View File

@@ -20,7 +20,7 @@ use base::id::{
#[cfg(feature = "bluetooth")]
use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline;
use compositing_traits::CrossProcessCompositorApi;
use compositing_traits::CrossProcessPaintApi;
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
use constellation_traits::{
KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationSender,
@@ -30,9 +30,9 @@ use crossbeam_channel::RecvTimeoutError;
use devtools_traits::ScriptToDevtoolsControlMsg;
use embedder_traits::user_content_manager::UserContentManager;
use embedder_traits::{
CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber,
InputEventAndId, JavaScriptEvaluationId, MediaSessionActionType, ScriptToEmbedderChan, Theme,
ViewportDetails, WebDriverScriptCommand,
EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber, InputEventAndId,
JavaScriptEvaluationId, MediaSessionActionType, PaintHitTestResult, ScriptToEmbedderChan,
Theme, ViewportDetails, WebDriverScriptCommand,
};
use euclid::{Scale, Size2D};
use fonts_traits::SystemFontServiceProxySender;
@@ -142,7 +142,7 @@ pub enum UpdatePipelineIdReason {
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`.
#[derive(Deserialize, IntoStaticStr, Serialize)]
pub enum ScriptThreadMessage {
@@ -273,7 +273,7 @@ pub enum ScriptThreadMessage {
/// Notifies script thread that WebGPU server has started
#[cfg(feature = "webgpu")]
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.
SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>),
/// Evaluate the given JavaScript and return a result via a corresponding message
@@ -317,7 +317,7 @@ pub enum DocumentState {
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ConstellationInputEvent {
/// 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
/// event was triggered.
pub pressed_mouse_buttons: u16,
@@ -368,8 +368,8 @@ pub struct InitialScriptState {
pub webgl_chan: Option<WebGLPipeline>,
/// The XR device registry
pub webxr_registry: Option<webxr_api::Registry>,
/// Access to the compositor across a process boundary.
pub cross_process_compositor_api: CrossProcessCompositorApi,
/// Access to `Paint` across a process boundary.
pub cross_process_paint_api: CrossProcessPaintApi,
/// Application window's GL Context for Media player
pub player_context: WindowGLContext,
/// User content manager

View File

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

View File

@@ -28,7 +28,7 @@ use canvas_traits::webgl::{
WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
};
use compositing_traits::{
CrossProcessCompositorApi, PainterSurfmanDetailsMap, SerializableImageData,
CrossProcessPaintApi, PainterSurfmanDetailsMap, SerializableImageData,
WebRenderExternalImageIdManager, WebRenderImageHandlerType,
};
use euclid::default::Size2D;
@@ -220,7 +220,7 @@ pub(crate) struct WebGLThread {
/// The GPU device.
device_map: HashMap<PainterId, Rc<Device>>,
/// Channel used to generate/update or delete `ImageKey`s.
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
/// Map of live WebGLContexts.
contexts: FxHashMap<WebGLContextId, GLContextData>,
/// Cached information for WebGLContexts.
@@ -249,7 +249,7 @@ pub(crate) struct WebGLThread {
/// The data required to initialize an instance of the WebGLThread type.
pub(crate) struct WebGLThreadInit {
pub compositor_api: CrossProcessCompositorApi,
pub paint_api: CrossProcessPaintApi,
pub external_image_id_manager: WebRenderExternalImageIdManager,
pub sender: WebGLSender<WebGLMsg>,
pub receiver: WebGLReceiver<WebGLMsg>,
@@ -267,7 +267,7 @@ impl WebGLThread {
/// Create a new instance of WebGLThread.
pub(crate) fn new(
WebGLThreadInit {
compositor_api,
paint_api,
external_image_id_manager: external_images,
sender,
receiver,
@@ -280,7 +280,7 @@ impl WebGLThread {
) -> Self {
WebGLThread {
device_map: Default::default(),
compositor_api,
paint_api,
contexts: Default::default(),
cached_context_info: Default::default(),
bound_context_id: None,
@@ -770,7 +770,7 @@ impl WebGLThread {
.remove(&context_id)
.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) {
@@ -951,7 +951,7 @@ impl WebGLThread {
info.alpha = has_alpha;
if let Some(image_key) = info.image_key {
self.compositor_api.update_image(
self.paint_api.update_image(
image_key,
info.image_descriptor(),
image_data,
@@ -998,16 +998,16 @@ impl WebGLThread {
fn handle_set_image_key(&mut self, context_id: WebGLContextId, image_key: ImageKey) {
let external_image_data = self.external_image_data(context_id);
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;
};
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;
}
self.compositor_api
self.paint_api
.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 base::Epoch;
use compositing_traits::{
CrossProcessCompositorApi, ExternalImageSource, SerializableImageData,
WebRenderExternalImageApi,
CrossProcessPaintApi, ExternalImageSource, SerializableImageData, WebRenderExternalImageApi,
};
use euclid::default::Size2D;
use ipc_channel::ipc::IpcSender;
@@ -466,11 +465,7 @@ impl ContextData {
/// Destroy the context that this [`ContextData`] represents,
/// freeing all of its buffers, and deleting the associated WebRender image.
fn destroy(
mut self,
script_sender: &IpcSender<WebGPUMsg>,
compositor_api: &CrossProcessCompositorApi,
) {
fn destroy(mut self, script_sender: &IpcSender<WebGPUMsg>, paint_api: &CrossProcessPaintApi) {
// This frees the id in the `ScriptThread`.
for staging_buffer in self.inactive_staging_buffers {
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() {
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();
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,
ImageDescriptor {
format: ImageFormat::BGRA8,
@@ -655,7 +650,7 @@ impl crate::WGPU {
}) = pending_texture
else {
context_data.clear_presentation();
self.compositor_api.update_image(
self.paint_api.update_image(
image_key,
ImageDescriptor {
format: ImageFormat::BGRA8,
@@ -672,7 +667,7 @@ impl crate::WGPU {
let Some(staging_buffer) = context_data.get_or_make_available_buffer(&configuration) else {
warn!("Failure obtaining available staging buffer");
context_data.clear_presentation();
self.compositor_api.update_image(
self.paint_api.update_image(
image_key,
configuration.into(),
SerializableImageData::External(image_data(context_id)),
@@ -682,7 +677,7 @@ impl crate::WGPU {
};
let epoch = context_data.next_epoch();
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);
self.texture_download(
texture_id,
@@ -702,7 +697,7 @@ impl crate::WGPU {
context_data.clear_presentation();
}
// update image in WR
compositor_api.update_image(
paint_api.update_image(
image_key,
configuration.into(),
SerializableImageData::External(image_data(context_id)),
@@ -798,6 +793,6 @@ impl crate::WGPU {
.unwrap()
.remove(&context_id)
.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 compositing_traits::{CrossProcessCompositorApi, WebRenderExternalImageIdManager};
use compositing_traits::{CrossProcessPaintApi, WebRenderExternalImageIdManager};
use ipc_channel::ipc::{self, IpcReceiver};
use servo_config::pref;
pub mod canvas_context;
pub fn start_webgpu_thread(
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
webrender_external_image_id_manager: WebRenderExternalImageIdManager,
wgpu_image_map: WebGpuExternalImageMap,
) -> Option<(WebGPU, IpcReceiver<WebGPUMsg>)> {
@@ -58,7 +58,7 @@ pub fn start_webgpu_thread(
receiver,
sender_clone,
script_sender,
compositor_api,
paint_api,
webrender_external_image_id_manager,
wgpu_image_map,
)

View File

@@ -10,7 +10,7 @@ use std::sync::{Arc, Mutex};
use base::id::PipelineId;
use compositing_traits::{
CrossProcessCompositorApi, WebRenderExternalImageIdManager, WebRenderImageHandlerType,
CrossProcessPaintApi, WebRenderExternalImageIdManager, WebRenderImageHandlerType,
};
use ipc_channel::ipc::{IpcReceiver, IpcSender, IpcSharedMemory};
use log::{info, warn};
@@ -104,7 +104,7 @@ pub(crate) struct WGPU {
/// because wgpu does not invalidate command encoder object
/// (this is also reused for invalidation of command buffers)
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) wgpu_image_map: WebGpuExternalImageMap,
/// Provides access to poller thread
@@ -120,7 +120,7 @@ impl WGPU {
receiver: IpcReceiver<WebGPURequest>,
sender: IpcSender<WebGPURequest>,
script_sender: IpcSender<WebGPUMsg>,
compositor_api: CrossProcessCompositorApi,
paint_api: CrossProcessPaintApi,
webrender_external_image_id_manager: WebRenderExternalImageIdManager,
wgpu_image_map: WebGpuExternalImageMap,
) -> Self {
@@ -149,7 +149,7 @@ impl WGPU {
global,
devices: Arc::new(Mutex::new(FxHashMap::default())),
error_command_encoders: FxHashMap::default(),
compositor_api,
paint_api,
webrender_external_image_id_manager,
wgpu_image_map,
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
// 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(
new_size.width as u32,
new_size.height as u32,
@@ -150,7 +150,7 @@ impl PlatformWindow for Window {
self.inner_size.set(self.screen_size);
// 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
// must notify the compositor here.
// must notify the `Paint` here.
webview.resize(PhysicalSize::new(
self.screen_size.width 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",
// Show GL errors by default.
"canvas::webgl_thread",
"compositing::compositor",
"compositing::paint",
"constellation::constellation",
];
let mut filter_builder = FilterBuilder::new();
@@ -518,22 +518,19 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_click(
}
#[unsafe(no_mangle)]
pub extern "C" fn Java_org_servo_servoview_JNIServo_pauseCompositor(
mut env: JNIEnv,
_: JClass<'_>,
) {
debug!("pauseCompositor");
call(&mut env, |s| s.pause_compositor());
pub extern "C" fn Java_org_servo_servoview_JNIServo_pausePainting(mut env: JNIEnv, _: JClass<'_>) {
debug!("pausePainting");
call(&mut env, |s| s.pause_painting());
}
#[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>,
_: JClass<'local>,
surface: JObject<'local>,
coordinates: JObject<'local>,
) {
debug!("resumeCompositor");
debug!("resumePainting");
let viewport_rect = match jni_coordinate_to_rust_viewport_rect(&mut env, &coordinates) {
Ok(viewport_rect) => viewport_rect,
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);
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();
}
pub fn pause_compositor(&self) {
pub fn pause_painting(&self) {
if let Err(e) = self.platform_window.rendering_context.take_window() {
warn!("Unbinding native surface from context failed ({:?})", e);
}
self.spin_event_loop();
}
pub fn resume_compositor(
pub fn resume_painting(
&self,
window_handle: RawWindowHandle,
viewport_rect: Rect<i32, DevicePixel>,

View File

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

View File

@@ -2,10 +2,10 @@
* 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/. */
//! The `servo` test application.
//! The `servoshell` test application.
//!
//! Creates a `Servo` instance with a simple implementation of
//! the compositor's `WindowMethods` to create a working web browser.
//! Creates a `Servo` instance with a example implementation of a working
//! web browser.
//!
//! This browser's implementation of `WindowMethods` is built on top
//! of [winit], the cross-platform windowing library.

View File

@@ -309,7 +309,8 @@ impl RunningAppState {
/// Spins the internal application event loop.
///
/// - 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.
pub(crate) fn spin_event_loop(self: &Rc<Self>) -> bool {

View File

@@ -186,7 +186,7 @@ impl ServoShellWindow {
self.platform_window
.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.
let needs_repaint = self.needs_repaint.take();
if updated_user_interface || needs_repaint {