mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
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:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use base::Epoch;
|
use base::Epoch;
|
||||||
use canvas_traits::canvas::*;
|
use canvas_traits::canvas::*;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
|
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
|
||||||
use pixels::Snapshot;
|
use pixels::Snapshot;
|
||||||
use webrender_api::ImageKey;
|
use webrender_api::ImageKey;
|
||||||
@@ -23,28 +23,28 @@ pub(crate) enum Filter {
|
|||||||
|
|
||||||
pub(crate) struct CanvasData<DrawTarget: GenericDrawTarget> {
|
pub(crate) struct CanvasData<DrawTarget: GenericDrawTarget> {
|
||||||
draw_target: DrawTarget,
|
draw_target: DrawTarget,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
image_key: Option<ImageKey>,
|
image_key: Option<ImageKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
size: Size2D<u64>,
|
size: Size2D<u64>,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
) -> CanvasData<DrawTarget> {
|
) -> CanvasData<DrawTarget> {
|
||||||
CanvasData {
|
CanvasData {
|
||||||
draw_target: DrawTarget::new(size.max(MIN_WR_IMAGE_SIZE).cast()),
|
draw_target: DrawTarget::new(size.max(MIN_WR_IMAGE_SIZE).cast()),
|
||||||
compositor_api,
|
paint_api,
|
||||||
image_key: None,
|
image_key: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_image_key(&mut self, image_key: ImageKey) {
|
pub(crate) fn set_image_key(&mut self, image_key: ImageKey) {
|
||||||
let (descriptor, data) = self.draw_target.image_descriptor_and_serializable_data();
|
let (descriptor, data) = self.draw_target.image_descriptor_and_serializable_data();
|
||||||
self.compositor_api.add_image(image_key, descriptor, data);
|
self.paint_api.add_image(image_key, descriptor, data);
|
||||||
|
|
||||||
if let Some(old_image_key) = self.image_key.replace(image_key) {
|
if let Some(old_image_key) = self.image_key.replace(image_key) {
|
||||||
self.compositor_api.delete_image(old_image_key);
|
self.paint_api.delete_image(old_image_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,7 +322,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
|||||||
self.draw_target.image_descriptor_and_serializable_data()
|
self.draw_target.image_descriptor_and_serializable_data()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.update_image(image_key, descriptor, data, canvas_epoch);
|
.update_image(image_key, descriptor, data, canvas_epoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +440,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
|||||||
impl<D: GenericDrawTarget> Drop for CanvasData<D> {
|
impl<D: GenericDrawTarget> Drop for CanvasData<D> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(image_key) = self.image_key {
|
if let Some(image_key) = self.image_key {
|
||||||
self.compositor_api.delete_image(image_key);
|
self.paint_api.delete_image(image_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use base::generic_channel::GenericSender;
|
|||||||
use base::{Epoch, generic_channel};
|
use base::{Epoch, generic_channel};
|
||||||
use canvas_traits::ConstellationCanvasMsg;
|
use canvas_traits::ConstellationCanvasMsg;
|
||||||
use canvas_traits::canvas::*;
|
use canvas_traits::canvas::*;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use crossbeam_channel::{Sender, select, unbounded};
|
use crossbeam_channel::{Sender, select, unbounded};
|
||||||
use euclid::default::{Rect, Size2D, Transform2D};
|
use euclid::default::{Rect, Size2D, Transform2D};
|
||||||
use log::warn;
|
use log::warn;
|
||||||
@@ -22,22 +22,22 @@ use crate::canvas_data::*;
|
|||||||
pub struct CanvasPaintThread {
|
pub struct CanvasPaintThread {
|
||||||
canvases: FxHashMap<CanvasId, Canvas>,
|
canvases: FxHashMap<CanvasId, Canvas>,
|
||||||
next_canvas_id: CanvasId,
|
next_canvas_id: CanvasId,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CanvasPaintThread {
|
impl CanvasPaintThread {
|
||||||
fn new(compositor_api: CrossProcessCompositorApi) -> CanvasPaintThread {
|
fn new(paint_api: CrossProcessPaintApi) -> CanvasPaintThread {
|
||||||
CanvasPaintThread {
|
CanvasPaintThread {
|
||||||
canvases: FxHashMap::default(),
|
canvases: FxHashMap::default(),
|
||||||
next_canvas_id: CanvasId(0),
|
next_canvas_id: CanvasId(0),
|
||||||
compositor_api: compositor_api.clone(),
|
paint_api: paint_api.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
|
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
|
||||||
/// communicate with it.
|
/// communicate with it.
|
||||||
pub fn start(
|
pub fn start(
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
|
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
|
||||||
let (ipc_sender, ipc_receiver) = generic_channel::channel::<CanvasMsg>().unwrap();
|
let (ipc_sender, ipc_receiver) = generic_channel::channel::<CanvasMsg>().unwrap();
|
||||||
let msg_receiver = ipc_receiver.route_preserving_errors();
|
let msg_receiver = ipc_receiver.route_preserving_errors();
|
||||||
@@ -46,7 +46,7 @@ impl CanvasPaintThread {
|
|||||||
.name("Canvas".to_owned())
|
.name("Canvas".to_owned())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let mut canvas_paint_thread = CanvasPaintThread::new(
|
let mut canvas_paint_thread = CanvasPaintThread::new(
|
||||||
compositor_api);
|
paint_api);
|
||||||
loop {
|
loop {
|
||||||
select! {
|
select! {
|
||||||
recv(msg_receiver) -> msg => {
|
recv(msg_receiver) -> msg => {
|
||||||
@@ -97,7 +97,7 @@ impl CanvasPaintThread {
|
|||||||
let canvas_id = self.next_canvas_id;
|
let canvas_id = self.next_canvas_id;
|
||||||
self.next_canvas_id.0 += 1;
|
self.next_canvas_id.0 += 1;
|
||||||
|
|
||||||
let canvas = Canvas::new(size, self.compositor_api.clone())?;
|
let canvas = Canvas::new(size, self.paint_api.clone())?;
|
||||||
self.canvases.insert(canvas_id, canvas);
|
self.canvases.insert(canvas_id, canvas);
|
||||||
|
|
||||||
Some(canvas_id)
|
Some(canvas_id)
|
||||||
@@ -298,17 +298,15 @@ enum Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Canvas {
|
impl Canvas {
|
||||||
fn new(size: Size2D<u64>, compositor_api: CrossProcessCompositorApi) -> Option<Self> {
|
fn new(size: Size2D<u64>, paint_api: CrossProcessPaintApi) -> Option<Self> {
|
||||||
match servo_config::pref!(dom_canvas_backend)
|
match servo_config::pref!(dom_canvas_backend)
|
||||||
.to_lowercase()
|
.to_lowercase()
|
||||||
.as_str()
|
.as_str()
|
||||||
{
|
{
|
||||||
#[cfg(feature = "vello_cpu")]
|
#[cfg(feature = "vello_cpu")]
|
||||||
"" | "auto" | "vello_cpu" => {
|
"" | "auto" | "vello_cpu" => Some(Self::VelloCPU(CanvasData::new(size, paint_api))),
|
||||||
Some(Self::VelloCPU(CanvasData::new(size, compositor_api)))
|
|
||||||
},
|
|
||||||
#[cfg(feature = "vello")]
|
#[cfg(feature = "vello")]
|
||||||
"" | "auto" | "vello" => Some(Self::Vello(CanvasData::new(size, compositor_api))),
|
"" | "auto" | "vello" => Some(Self::Vello(CanvasData::new(size, paint_api))),
|
||||||
s => {
|
s => {
|
||||||
warn!("Unknown 2D canvas backend: `{s}`");
|
warn!("Unknown 2D canvas backend: `{s}`");
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::cell::Cell;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use base::generic_channel::RoutedReceiver;
|
use base::generic_channel::RoutedReceiver;
|
||||||
use compositing_traits::{CompositorMsg, CompositorProxy};
|
use compositing_traits::{PaintMessage, PaintProxy};
|
||||||
use constellation_traits::EmbedderToConstellationMessage;
|
use constellation_traits::EmbedderToConstellationMessage;
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use embedder_traits::{EventLoopWaker, ShutdownState};
|
use embedder_traits::{EventLoopWaker, ShutdownState};
|
||||||
@@ -16,13 +16,13 @@ use profile_traits::{mem, time};
|
|||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
use webxr::WebXrRegistry;
|
use webxr::WebXrRegistry;
|
||||||
|
|
||||||
pub use crate::compositor::{IOCompositor, WebRenderDebugOption};
|
pub use crate::paint::{Paint, WebRenderDebugOption};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod tracing;
|
mod tracing;
|
||||||
|
|
||||||
mod compositor;
|
|
||||||
mod largest_contentful_paint_calculator;
|
mod largest_contentful_paint_calculator;
|
||||||
|
mod paint;
|
||||||
mod painter;
|
mod painter;
|
||||||
mod pinch_zoom;
|
mod pinch_zoom;
|
||||||
mod pipeline_details;
|
mod pipeline_details;
|
||||||
@@ -33,12 +33,12 @@ mod touch;
|
|||||||
mod webrender_external_images;
|
mod webrender_external_images;
|
||||||
mod webview_renderer;
|
mod webview_renderer;
|
||||||
|
|
||||||
/// Data used to construct a compositor.
|
/// Data used to initialize the `Paint` subsystem.
|
||||||
pub struct InitialCompositorState {
|
pub struct InitialPaintState {
|
||||||
/// A channel to the compositor.
|
/// A channel to `Paint`.
|
||||||
pub compositor_proxy: CompositorProxy,
|
pub paint_proxy: PaintProxy,
|
||||||
/// A port on which messages inbound to the compositor can be received.
|
/// A port on which messages inbound to `Paint` can be received.
|
||||||
pub receiver: RoutedReceiver<CompositorMsg>,
|
pub receiver: RoutedReceiver<PaintMessage>,
|
||||||
/// A channel to the constellation.
|
/// A channel to the constellation.
|
||||||
pub embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
|
pub embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
|
||||||
/// A channel to the time profiler thread.
|
/// A channel to the time profiler thread.
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use bitflags::bitflags;
|
|||||||
use canvas_traits::webgl::{WebGLContextId, WebGLThreads};
|
use canvas_traits::webgl::{WebGLContextId, WebGLThreads};
|
||||||
use compositing_traits::rendering_context::RenderingContext;
|
use compositing_traits::rendering_context::RenderingContext;
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CompositorMsg, CompositorProxy, PainterSurfmanDetails, PainterSurfmanDetailsMap,
|
PaintMessage, PaintProxy, PainterSurfmanDetails, PainterSurfmanDetailsMap,
|
||||||
WebRenderExternalImageIdManager, WebViewTrait,
|
WebRenderExternalImageIdManager, WebViewTrait,
|
||||||
};
|
};
|
||||||
use constellation_traits::EmbedderToConstellationMessage;
|
use constellation_traits::EmbedderToConstellationMessage;
|
||||||
@@ -47,7 +47,7 @@ use webrender::{CaptureBits, MemoryReport};
|
|||||||
use webrender_api::units::{DevicePixel, DevicePoint};
|
use webrender_api::units::{DevicePixel, DevicePoint};
|
||||||
use webrender_api::{FontInstanceKey, FontKey, ImageKey};
|
use webrender_api::{FontInstanceKey, FontKey, ImageKey};
|
||||||
|
|
||||||
use crate::InitialCompositorState;
|
use crate::InitialPaintState;
|
||||||
use crate::painter::Painter;
|
use crate::painter::Painter;
|
||||||
use crate::webview_renderer::UnknownWebView;
|
use crate::webview_renderer::UnknownWebView;
|
||||||
|
|
||||||
@@ -59,26 +59,46 @@ pub enum WebRenderDebugOption {
|
|||||||
RenderTargetDebug,
|
RenderTargetDebug,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NB: Never block on the constellation, because sometimes the constellation blocks on us.
|
/// [`Paint`] is Servo's rendering subsystem. It has a few responsibilities:
|
||||||
pub struct IOCompositor {
|
///
|
||||||
/// All of the [`Painters`] for this [`IOCompositor`]. Each [`Painter`] handles painting to
|
/// 1. Maintain a WebRender instance for each [`RenderingContext`] that Servo knows about.
|
||||||
|
/// [`RenderingContext`]s are per-`WebView`, but more than one `WebView` can use the same
|
||||||
|
/// [`RenderingContext`]. This allows multiple `WebView`s to share the same WebRender
|
||||||
|
/// instance which is more efficient. This is useful for tabbed web browsers.
|
||||||
|
/// 2. Receive display lists from the layout of all of the currently active `Pipeline`s
|
||||||
|
/// (frames). These display lists are sent to WebRender, and new frames are generated.
|
||||||
|
/// Once the frame is ready the [`Painter`] for the WebRender instance will ask libservo
|
||||||
|
/// to inform the embedder that a new frame is ready so that it can trigger a paint.
|
||||||
|
/// 3. Drive animation and animation callback updates. Animation updates should ideally be
|
||||||
|
/// coordinated with the system vsync signal, so the `RefreshDriver` is exposed in the
|
||||||
|
/// API to allow the embedder to do this. The [`Painter`] then asks its `WebView`s to
|
||||||
|
/// update their rendering, which triggers layouts.
|
||||||
|
/// 4. Eagerly handle scrolling and touch events. In order to avoid latency when handling
|
||||||
|
/// these kind of actions, each [`Painter`] will eagerly process touch events and
|
||||||
|
/// perform panning and zooming operations on their WebRender contents -- informing the
|
||||||
|
/// WebView contents asynchronously.
|
||||||
|
///
|
||||||
|
/// `Paint` and all of its contained structs should **never** block on the Constellation,
|
||||||
|
/// because sometimes the Constellation blocks on us.
|
||||||
|
pub struct Paint {
|
||||||
|
/// All of the [`Painters`] for this [`Paint`]. Each [`Painter`] handles painting to
|
||||||
/// a single [`RenderingContext`].
|
/// a single [`RenderingContext`].
|
||||||
painters: Vec<Rc<RefCell<Painter>>>,
|
painters: Vec<Rc<RefCell<Painter>>>,
|
||||||
|
|
||||||
/// A [`CompositorProxy`] which can be used to allow other parts of Servo to communicate
|
/// A [`PaintProxy`] which can be used to allow other parts of Servo to communicate
|
||||||
/// with this [`IOCompositor`].
|
/// with this [`Paint`].
|
||||||
pub(crate) compositor_proxy: CompositorProxy,
|
pub(crate) paint_proxy: PaintProxy,
|
||||||
|
|
||||||
/// An [`EventLoopWaker`] used to wake up the main embedder event loop when the renderer needs
|
/// An [`EventLoopWaker`] used to wake up the main embedder event loop when the renderer needs
|
||||||
/// to run.
|
/// to run.
|
||||||
pub(crate) event_loop_waker: Box<dyn EventLoopWaker>,
|
pub(crate) event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
|
|
||||||
/// Tracks whether we are in the process of shutting down, or have shut down and should close
|
/// Tracks whether we are in the process of shutting down, or have shut down and
|
||||||
/// the compositor. This is shared with the `Servo` instance.
|
/// should shut down `Paint`. This is shared with the `Servo` instance.
|
||||||
shutdown_state: Rc<Cell<ShutdownState>>,
|
shutdown_state: Rc<Cell<ShutdownState>>,
|
||||||
|
|
||||||
/// The port on which we receive messages.
|
/// The port on which we receive messages.
|
||||||
compositor_receiver: RoutedReceiver<CompositorMsg>,
|
paint_receiver: RoutedReceiver<PaintMessage>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the constellation.
|
/// The channel on which messages can be sent to the constellation.
|
||||||
pub(crate) embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
|
pub(crate) embedder_to_constellation_sender: Sender<EmbedderToConstellationMessage>,
|
||||||
@@ -136,12 +156,12 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IOCompositor {
|
impl Paint {
|
||||||
pub fn new(state: InitialCompositorState) -> Rc<RefCell<Self>> {
|
pub fn new(state: InitialPaintState) -> Rc<RefCell<Self>> {
|
||||||
let registration = state.mem_profiler_chan.prepare_memory_reporting(
|
let registration = state.mem_profiler_chan.prepare_memory_reporting(
|
||||||
"compositor".into(),
|
"paint".into(),
|
||||||
state.compositor_proxy.clone(),
|
state.paint_proxy.clone(),
|
||||||
CompositorMsg::CollectMemoryReport,
|
PaintMessage::CollectMemoryReport,
|
||||||
);
|
);
|
||||||
|
|
||||||
let webrender_external_image_id_manager = WebRenderExternalImageIdManager::default();
|
let webrender_external_image_id_manager = WebRenderExternalImageIdManager::default();
|
||||||
@@ -153,7 +173,7 @@ impl IOCompositor {
|
|||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
webxr_layer_grand_manager,
|
webxr_layer_grand_manager,
|
||||||
} = WebGLComm::new(
|
} = WebGLComm::new(
|
||||||
state.compositor_proxy.cross_process_compositor_api.clone(),
|
state.paint_proxy.cross_process_paint_api.clone(),
|
||||||
webrender_external_image_id_manager.clone(),
|
webrender_external_image_id_manager.clone(),
|
||||||
painter_surfman_details_map.clone(),
|
painter_surfman_details_map.clone(),
|
||||||
);
|
);
|
||||||
@@ -174,12 +194,12 @@ impl IOCompositor {
|
|||||||
webxr_main_thread
|
webxr_main_thread
|
||||||
};
|
};
|
||||||
|
|
||||||
Rc::new(RefCell::new(IOCompositor {
|
Rc::new(RefCell::new(Paint {
|
||||||
painters: Default::default(),
|
painters: Default::default(),
|
||||||
compositor_proxy: state.compositor_proxy,
|
paint_proxy: state.paint_proxy,
|
||||||
event_loop_waker: state.event_loop_waker,
|
event_loop_waker: state.event_loop_waker,
|
||||||
shutdown_state: state.shutdown_state,
|
shutdown_state: state.shutdown_state,
|
||||||
compositor_receiver: state.receiver,
|
paint_receiver: state.receiver,
|
||||||
embedder_to_constellation_sender: state.embedder_to_constellation_sender.clone(),
|
embedder_to_constellation_sender: state.embedder_to_constellation_sender.clone(),
|
||||||
webrender_external_image_id_manager,
|
webrender_external_image_id_manager,
|
||||||
webgl_threads,
|
webgl_threads,
|
||||||
@@ -308,9 +328,9 @@ impl IOCompositor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish_shutting_down(&self) {
|
pub fn finish_shutting_down(&self) {
|
||||||
// Drain compositor port, sometimes messages contain channels that are blocking
|
// Drain paint port, sometimes messages contain channels that are blocking
|
||||||
// another thread from finishing (i.e. SetFrameTree).
|
// another thread from finishing (i.e. SetFrameTree).
|
||||||
while self.compositor_receiver.try_recv().is_ok() {}
|
while self.paint_receiver.try_recv().is_ok() {}
|
||||||
|
|
||||||
let (webgl_exit_sender, webgl_exit_receiver) =
|
let (webgl_exit_sender, webgl_exit_receiver) =
|
||||||
ipc::channel().expect("Failed to create IPC channel!");
|
ipc::channel().expect("Failed to create IPC channel!");
|
||||||
@@ -330,7 +350,7 @@ impl IOCompositor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_browser_message(&self, msg: CompositorMsg) {
|
fn handle_browser_message(&self, msg: PaintMessage) {
|
||||||
trace_msg_from_constellation!(msg, "{msg:?}");
|
trace_msg_from_constellation!(msg, "{msg:?}");
|
||||||
|
|
||||||
match self.shutdown_state() {
|
match self.shutdown_state() {
|
||||||
@@ -340,16 +360,16 @@ impl IOCompositor {
|
|||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
ShutdownState::FinishedShuttingDown => {
|
ShutdownState::FinishedShuttingDown => {
|
||||||
// Messages to the compositor are ignored after shutdown is complete.
|
// Messages to Paint are ignored after shutdown is complete.
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
CompositorMsg::CollectMemoryReport(sender) => {
|
PaintMessage::CollectMemoryReport(sender) => {
|
||||||
self.collect_memory_report(sender);
|
self.collect_memory_report(sender);
|
||||||
},
|
},
|
||||||
CompositorMsg::ChangeRunningAnimationsState(
|
PaintMessage::ChangeRunningAnimationsState(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
animation_state,
|
animation_state,
|
||||||
@@ -362,30 +382,30 @@ impl IOCompositor {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::SetFrameTreeForWebView(webview_id, frame_tree) => {
|
PaintMessage::SetFrameTreeForWebView(webview_id, frame_tree) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.set_frame_tree_for_webview(&frame_tree);
|
painter.set_frame_tree_for_webview(&frame_tree);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::SetThrottled(webview_id, pipeline_id, throttled) => {
|
PaintMessage::SetThrottled(webview_id, pipeline_id, throttled) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.set_throttled(webview_id, pipeline_id, throttled);
|
painter.set_throttled(webview_id, pipeline_id, throttled);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
|
PaintMessage::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source);
|
painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::NewWebRenderFrameReady(..) => {
|
PaintMessage::NewWebRenderFrameReady(..) => {
|
||||||
unreachable!("New WebRender frames should be handled in the caller.");
|
unreachable!("New WebRender frames should be handled in the caller.");
|
||||||
},
|
},
|
||||||
CompositorMsg::SendInitialTransaction(webview_id, pipeline_id) => {
|
PaintMessage::SendInitialTransaction(webview_id, pipeline_id) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.send_initial_pipeline_transaction(webview_id, pipeline_id);
|
painter.send_initial_pipeline_transaction(webview_id, pipeline_id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::ScrollNodeByDelta(
|
PaintMessage::ScrollNodeByDelta(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
offset,
|
offset,
|
||||||
@@ -400,12 +420,12 @@ impl IOCompositor {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::ScrollViewportByDelta(webview_id, delta) => {
|
PaintMessage::ScrollViewportByDelta(webview_id, delta) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.scroll_viewport_by_delta(webview_id, delta);
|
painter.scroll_viewport_by_delta(webview_id, delta);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::UpdateEpoch {
|
PaintMessage::UpdateEpoch {
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
epoch,
|
epoch,
|
||||||
@@ -414,7 +434,7 @@ impl IOCompositor {
|
|||||||
painter.update_epoch(webview_id, pipeline_id, epoch);
|
painter.update_epoch(webview_id, pipeline_id, epoch);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::SendDisplayList {
|
PaintMessage::SendDisplayList {
|
||||||
webview_id,
|
webview_id,
|
||||||
display_list_descriptor,
|
display_list_descriptor,
|
||||||
display_list_receiver,
|
display_list_receiver,
|
||||||
@@ -427,25 +447,25 @@ impl IOCompositor {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateFrame(painter_ids) => {
|
PaintMessage::GenerateFrame(painter_ids) => {
|
||||||
for painter_id in painter_ids {
|
for painter_id in painter_ids {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
||||||
painter.generate_frame_for_script();
|
painter.generate_frame_for_script();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateImageKey(webview_id, result_sender) => {
|
PaintMessage::GenerateImageKey(webview_id, result_sender) => {
|
||||||
self.handle_generate_image_key(webview_id, result_sender);
|
self.handle_generate_image_key(webview_id, result_sender);
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
|
PaintMessage::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
|
||||||
self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id);
|
self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id);
|
||||||
},
|
},
|
||||||
CompositorMsg::UpdateImages(painter_id, updates) => {
|
PaintMessage::UpdateImages(painter_id, updates) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
||||||
painter.update_images(updates);
|
painter.update_images(updates);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::DelayNewFrameForCanvas(
|
PaintMessage::DelayNewFrameForCanvas(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
canvas_epoch,
|
canvas_epoch,
|
||||||
@@ -455,21 +475,21 @@ impl IOCompositor {
|
|||||||
painter.delay_new_frames_for_canvas(pipeline_id, canvas_epoch, image_keys);
|
painter.delay_new_frames_for_canvas(pipeline_id, canvas_epoch, image_keys);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::AddFont(painter_id, font_key, data, index) => {
|
PaintMessage::AddFont(painter_id, font_key, data, index) => {
|
||||||
debug_assert!(painter_id == font_key.into());
|
debug_assert!(painter_id == font_key.into());
|
||||||
|
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
||||||
painter.add_font(font_key, data, index);
|
painter.add_font(font_key, data, index);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::AddSystemFont(painter_id, font_key, native_handle) => {
|
PaintMessage::AddSystemFont(painter_id, font_key, native_handle) => {
|
||||||
debug_assert!(painter_id == font_key.into());
|
debug_assert!(painter_id == font_key.into());
|
||||||
|
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
||||||
painter.add_system_font(font_key, native_handle);
|
painter.add_system_font(font_key, native_handle);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::AddFontInstance(
|
PaintMessage::AddFontInstance(
|
||||||
painter_id,
|
painter_id,
|
||||||
font_instance_key,
|
font_instance_key,
|
||||||
font_key,
|
font_key,
|
||||||
@@ -484,12 +504,12 @@ impl IOCompositor {
|
|||||||
painter.add_font_instance(font_instance_key, font_key, size, flags, variations);
|
painter.add_font_instance(font_instance_key, font_key, size, flags, variations);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::RemoveFonts(painter_id, keys, instance_keys) => {
|
PaintMessage::RemoveFonts(painter_id, keys, instance_keys) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
if let Some(mut painter) = self.maybe_painter_mut(painter_id) {
|
||||||
painter.remove_fonts(keys, instance_keys);
|
painter.remove_fonts(keys, instance_keys);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateFontKeys(
|
PaintMessage::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
result_sender,
|
result_sender,
|
||||||
@@ -502,17 +522,17 @@ impl IOCompositor {
|
|||||||
painter_id,
|
painter_id,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
CompositorMsg::Viewport(webview_id, viewport_description) => {
|
PaintMessage::Viewport(webview_id, viewport_description) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.set_viewport_description(webview_id, viewport_description);
|
painter.set_viewport_description(webview_id, viewport_description);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::ScreenshotReadinessReponse(webview_id, pipelines_and_epochs) => {
|
PaintMessage::ScreenshotReadinessReponse(webview_id, pipelines_and_epochs) => {
|
||||||
if let Some(painter) = self.maybe_painter(webview_id.into()) {
|
if let Some(painter) = self.maybe_painter(webview_id.into()) {
|
||||||
painter.handle_screenshot_readiness_reply(webview_id, pipelines_and_epochs);
|
painter.handle_screenshot_readiness_reply(webview_id, pipelines_and_epochs);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::SendLCPCandidate(lcp_candidate, webview_id, pipeline_id, epoch) => {
|
PaintMessage::SendLCPCandidate(lcp_candidate, webview_id, pipeline_id, epoch) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.append_lcp_candidate(lcp_candidate, webview_id, pipeline_id, epoch);
|
painter.append_lcp_candidate(lcp_candidate, webview_id, pipeline_id, epoch);
|
||||||
}
|
}
|
||||||
@@ -565,7 +585,7 @@ impl IOCompositor {
|
|||||||
.map(|painter| painter.borrow().scroll_trees_memory_usage(ops))
|
.map(|painter| painter.borrow().scroll_trees_memory_usage(ops))
|
||||||
.sum();
|
.sum();
|
||||||
reports.push(Report {
|
reports.push(Report {
|
||||||
path: path!["compositor", "scroll-tree"],
|
path: path!["paint", "scroll-tree"],
|
||||||
kind: ReportKind::ExplicitJemallocHeapSize,
|
kind: ReportKind::ExplicitJemallocHeapSize,
|
||||||
size: scroll_trees_memory_usage,
|
size: scroll_trees_memory_usage,
|
||||||
});
|
});
|
||||||
@@ -574,29 +594,29 @@ impl IOCompositor {
|
|||||||
sender.send(ProcessReports::new(reports));
|
sender.send(ProcessReports::new(reports));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle messages sent to the compositor during the shutdown process. In general,
|
/// Handle messages sent to `Paint` during the shutdown process. In general,
|
||||||
/// the things the compositor can do in this state are limited. It's very important to
|
/// the things `Paint` can do in this state are limited. It's very important to
|
||||||
/// answer any synchronous messages though as other threads might be waiting on the
|
/// answer any synchronous messages though as other threads might be waiting on the
|
||||||
/// results to finish their own shut down process. We try to do as little as possible
|
/// results to finish their own shut down process. We try to do as little as possible
|
||||||
/// during this time.
|
/// during this time.
|
||||||
///
|
///
|
||||||
/// When that involves generating WebRender ids, our approach here is to simply
|
/// When that involves generating WebRender ids, our approach here is to simply
|
||||||
/// generate them, but assume they will never be used, since once shutting down the
|
/// generate them, but assume they will never be used, since once shutting down
|
||||||
/// compositor no longer does any WebRender frame generation.
|
/// `Paint` no longer does any WebRender frame generation.
|
||||||
fn handle_browser_message_while_shutting_down(&self, msg: CompositorMsg) {
|
fn handle_browser_message_while_shutting_down(&self, msg: PaintMessage) {
|
||||||
match msg {
|
match msg {
|
||||||
CompositorMsg::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
|
PaintMessage::PipelineExited(webview_id, pipeline_id, pipeline_exit_source) => {
|
||||||
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
if let Some(mut painter) = self.maybe_painter_mut(webview_id.into()) {
|
||||||
painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source);
|
painter.notify_pipeline_exited(webview_id, pipeline_id, pipeline_exit_source);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateImageKey(webview_id, result_sender) => {
|
PaintMessage::GenerateImageKey(webview_id, result_sender) => {
|
||||||
self.handle_generate_image_key(webview_id, result_sender);
|
self.handle_generate_image_key(webview_id, result_sender);
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
|
PaintMessage::GenerateImageKeysForPipeline(webview_id, pipeline_id) => {
|
||||||
self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id);
|
self.handle_generate_image_keys_for_pipeline(webview_id, pipeline_id);
|
||||||
},
|
},
|
||||||
CompositorMsg::GenerateFontKeys(
|
PaintMessage::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
result_sender,
|
result_sender,
|
||||||
@@ -668,20 +688,20 @@ impl IOCompositor {
|
|||||||
.render(&self.time_profiler_chan);
|
.render(&self.time_profiler_chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the message receiver for this [`IOCompositor`].
|
/// Get the message receiver for this [`Paint`].
|
||||||
pub fn receiver(&self) -> &RoutedReceiver<CompositorMsg> {
|
pub fn receiver(&self) -> &RoutedReceiver<PaintMessage> {
|
||||||
&self.compositor_receiver
|
&self.paint_receiver
|
||||||
}
|
}
|
||||||
|
|
||||||
#[servo_tracing::instrument(skip_all)]
|
#[servo_tracing::instrument(skip_all)]
|
||||||
pub fn handle_messages(&self, mut messages: Vec<CompositorMsg>) {
|
pub fn handle_messages(&self, mut messages: Vec<PaintMessage>) {
|
||||||
// Pull out the `NewWebRenderFrameReady` messages from the list of messages and handle them
|
// Pull out the `NewWebRenderFrameReady` messages from the list of messages and handle them
|
||||||
// at the end of this function. This prevents overdraw when more than a single message of
|
// at the end of this function. This prevents overdraw when more than a single message of
|
||||||
// this type of received. In addition, if any of these frames need a repaint, that reflected
|
// this type of received. In addition, if any of these frames need a repaint, that reflected
|
||||||
// when calling `handle_new_webrender_frame_ready`.
|
// when calling `handle_new_webrender_frame_ready`.
|
||||||
let mut saw_webrender_frame_ready_for_painter = HashMap::new();
|
let mut saw_webrender_frame_ready_for_painter = HashMap::new();
|
||||||
messages.retain(|message| match message {
|
messages.retain(|message| match message {
|
||||||
CompositorMsg::NewWebRenderFrameReady(painter_id, _document_id, need_repaint) => {
|
PaintMessage::NewWebRenderFrameReady(painter_id, _document_id, need_repaint) => {
|
||||||
if let Some(painter) = self.maybe_painter(*painter_id) {
|
if let Some(painter) = self.maybe_painter(*painter_id) {
|
||||||
painter.decrement_pending_frames();
|
painter.decrement_pending_frames();
|
||||||
*saw_webrender_frame_ready_for_painter
|
*saw_webrender_frame_ready_for_painter
|
||||||
@@ -10,7 +10,7 @@ use std::sync::Arc;
|
|||||||
use base::Epoch;
|
use base::Epoch;
|
||||||
use base::cross_process_instant::CrossProcessInstant;
|
use base::cross_process_instant::CrossProcessInstant;
|
||||||
use base::id::{PainterId, PipelineId, WebViewId};
|
use base::id::{PainterId, PipelineId, WebViewId};
|
||||||
use compositing_traits::display_list::{CompositorDisplayListInfo, ScrollType};
|
use compositing_traits::display_list::{PaintDisplayListInfo, ScrollType};
|
||||||
use compositing_traits::largest_contentful_paint_candidate::LCPCandidate;
|
use compositing_traits::largest_contentful_paint_candidate::LCPCandidate;
|
||||||
use compositing_traits::rendering_context::RenderingContext;
|
use compositing_traits::rendering_context::RenderingContext;
|
||||||
use compositing_traits::viewport_description::ViewportDescription;
|
use compositing_traits::viewport_description::ViewportDescription;
|
||||||
@@ -22,7 +22,7 @@ use constellation_traits::{EmbedderToConstellationMessage, PaintMetricEvent};
|
|||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use dpi::PhysicalSize;
|
use dpi::PhysicalSize;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
CompositorHitTestResult, InputEvent, InputEventAndId, InputEventId, InputEventResult,
|
InputEvent, InputEventAndId, InputEventId, InputEventResult, PaintHitTestResult,
|
||||||
ScreenshotCaptureError, Scroll, ViewportDetails, WebViewPoint, WebViewRect,
|
ScreenshotCaptureError, Scroll, ViewportDetails, WebViewPoint, WebViewRect,
|
||||||
};
|
};
|
||||||
use euclid::{Point2D, Rect, Scale, Size2D};
|
use euclid::{Point2D, Rect, Scale, Size2D};
|
||||||
@@ -54,9 +54,9 @@ use webrender_api::{
|
|||||||
};
|
};
|
||||||
use wr_malloc_size_of::MallocSizeOfOps;
|
use wr_malloc_size_of::MallocSizeOfOps;
|
||||||
|
|
||||||
use crate::IOCompositor;
|
use crate::Paint;
|
||||||
use crate::compositor::{RepaintReason, WebRenderDebugOption};
|
|
||||||
use crate::largest_contentful_paint_calculator::LargestContentfulPaintCalculator;
|
use crate::largest_contentful_paint_calculator::LargestContentfulPaintCalculator;
|
||||||
|
use crate::paint::{RepaintReason, WebRenderDebugOption};
|
||||||
use crate::refresh_driver::{AnimationRefreshDriverObserver, BaseRefreshDriver};
|
use crate::refresh_driver::{AnimationRefreshDriverObserver, BaseRefreshDriver};
|
||||||
use crate::render_notifier::RenderNotifier;
|
use crate::render_notifier::RenderNotifier;
|
||||||
use crate::screenshot::ScreenshotTaker;
|
use crate::screenshot::ScreenshotTaker;
|
||||||
@@ -141,10 +141,7 @@ impl Drop for Painter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Painter {
|
impl Painter {
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(rendering_context: Rc<dyn RenderingContext>, paint: &Paint) -> Self {
|
||||||
rendering_context: Rc<dyn RenderingContext>,
|
|
||||||
compositor: &IOCompositor,
|
|
||||||
) -> Self {
|
|
||||||
let webrender_gl = rendering_context.gleam_gl_api();
|
let webrender_gl = rendering_context.gleam_gl_api();
|
||||||
|
|
||||||
// Make sure the gl context is made current.
|
// Make sure the gl context is made current.
|
||||||
@@ -153,31 +150,29 @@ impl Painter {
|
|||||||
}
|
}
|
||||||
debug_assert_eq!(webrender_gl.get_error(), gleam::gl::NO_ERROR,);
|
debug_assert_eq!(webrender_gl.get_error(), gleam::gl::NO_ERROR,);
|
||||||
|
|
||||||
let id_manager = compositor.webrender_external_image_id_manager();
|
let id_manager = paint.webrender_external_image_id_manager();
|
||||||
let mut external_image_handlers = Box::new(WebRenderExternalImageHandlers::new(id_manager));
|
let mut external_image_handlers = Box::new(WebRenderExternalImageHandlers::new(id_manager));
|
||||||
|
|
||||||
// Set WebRender external image handler for WebGL textures.
|
// Set WebRender external image handler for WebGL textures.
|
||||||
let image_handler = Box::new(WebGLExternalImages::new(
|
let image_handler = Box::new(WebGLExternalImages::new(
|
||||||
compositor.webgl_threads(),
|
paint.webgl_threads(),
|
||||||
rendering_context.clone(),
|
rendering_context.clone(),
|
||||||
compositor.swap_chains.clone(),
|
paint.swap_chains.clone(),
|
||||||
compositor.busy_webgl_contexts_map.clone(),
|
paint.busy_webgl_contexts_map.clone(),
|
||||||
));
|
));
|
||||||
external_image_handlers.set_handler(image_handler, WebRenderImageHandlerType::WebGl);
|
external_image_handlers.set_handler(image_handler, WebRenderImageHandlerType::WebGl);
|
||||||
|
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
external_image_handlers.set_handler(
|
external_image_handlers.set_handler(
|
||||||
Box::new(webgpu::WebGpuExternalImages::new(
|
Box::new(webgpu::WebGpuExternalImages::new(paint.webgpu_image_map())),
|
||||||
compositor.webgpu_image_map(),
|
|
||||||
)),
|
|
||||||
WebRenderImageHandlerType::WebGpu,
|
WebRenderImageHandlerType::WebGpu,
|
||||||
);
|
);
|
||||||
|
|
||||||
WindowGLContext::initialize_image_handler(&mut external_image_handlers);
|
WindowGLContext::initialize_image_handler(&mut external_image_handlers);
|
||||||
|
|
||||||
let embedder_to_constellation_sender = compositor.embedder_to_constellation_sender.clone();
|
let embedder_to_constellation_sender = paint.embedder_to_constellation_sender.clone();
|
||||||
let refresh_driver = Rc::new(BaseRefreshDriver::new(
|
let refresh_driver = Rc::new(BaseRefreshDriver::new(
|
||||||
compositor.event_loop_waker.clone_box(),
|
paint.event_loop_waker.clone_box(),
|
||||||
rendering_context.refresh_driver(),
|
rendering_context.refresh_driver(),
|
||||||
));
|
));
|
||||||
let animation_refresh_driver_observer = Rc::new(AnimationRefreshDriverObserver::new(
|
let animation_refresh_driver_observer = Rc::new(AnimationRefreshDriverObserver::new(
|
||||||
@@ -215,10 +210,7 @@ impl Painter {
|
|||||||
let painter_id = PainterId::next();
|
let painter_id = PainterId::next();
|
||||||
let (mut webrender, webrender_api_sender) = webrender::create_webrender_instance(
|
let (mut webrender, webrender_api_sender) = webrender::create_webrender_instance(
|
||||||
webrender_gl.clone(),
|
webrender_gl.clone(),
|
||||||
Box::new(RenderNotifier::new(
|
Box::new(RenderNotifier::new(painter_id, paint.paint_proxy.clone())),
|
||||||
painter_id,
|
|
||||||
compositor.compositor_proxy.clone(),
|
|
||||||
)),
|
|
||||||
webrender::WebRenderOptions {
|
webrender::WebRenderOptions {
|
||||||
// We force the use of optimized shaders here because rendering is broken
|
// We force the use of optimized shaders here because rendering is broken
|
||||||
// on Android emulators with unoptimized shaders. This is due to a known
|
// on Android emulators with unoptimized shaders. This is due to a known
|
||||||
@@ -391,7 +383,7 @@ impl Painter {
|
|||||||
self.rendering_context.prepare_for_rendering();
|
self.rendering_context.prepare_for_rendering();
|
||||||
|
|
||||||
time_profile!(
|
time_profile!(
|
||||||
ProfilerCategory::Compositing,
|
ProfilerCategory::Painting,
|
||||||
None,
|
None,
|
||||||
time_profiler_channel.clone(),
|
time_profiler_channel.clone(),
|
||||||
|| {
|
|| {
|
||||||
@@ -454,7 +446,7 @@ impl Painter {
|
|||||||
|
|
||||||
match pipeline.first_paint_metric.get() {
|
match pipeline.first_paint_metric.get() {
|
||||||
// We need to check whether the current epoch is later, because
|
// We need to check whether the current epoch is later, because
|
||||||
// CrossProcessCompositorMessage::SendInitialTransaction sends an
|
// CrossProcessPaintMessage::SendInitialTransaction sends an
|
||||||
// empty display list to WebRender which can happen before we receive
|
// empty display list to WebRender which can happen before we receive
|
||||||
// the first "real" display list.
|
// the first "real" display list.
|
||||||
PaintMetricState::Seen(epoch, first_reflow) if epoch <= current_epoch => {
|
PaintMetricState::Seen(epoch, first_reflow) if epoch <= current_epoch => {
|
||||||
@@ -545,7 +537,7 @@ impl Painter {
|
|||||||
webrender_api: &RenderApi,
|
webrender_api: &RenderApi,
|
||||||
webrender_document: DocumentId,
|
webrender_document: DocumentId,
|
||||||
point: DevicePoint,
|
point: DevicePoint,
|
||||||
) -> Vec<CompositorHitTestResult> {
|
) -> Vec<PaintHitTestResult> {
|
||||||
// DevicePoint and WorldPoint are the same for us.
|
// DevicePoint and WorldPoint are the same for us.
|
||||||
let world_point = WorldPoint::from_untyped(point.to_untyped());
|
let world_point = WorldPoint::from_untyped(point.to_untyped());
|
||||||
let results = webrender_api.hit_test(webrender_document, world_point);
|
let results = webrender_api.hit_test(webrender_document, world_point);
|
||||||
@@ -556,7 +548,7 @@ impl Painter {
|
|||||||
.map(|item| {
|
.map(|item| {
|
||||||
let pipeline_id = item.pipeline.into();
|
let pipeline_id = item.pipeline.into();
|
||||||
let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline);
|
let external_scroll_id = ExternalScrollId(item.tag.0, item.pipeline);
|
||||||
CompositorHitTestResult {
|
PaintHitTestResult {
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()),
|
point_in_viewport: Point2D::from_untyped(item.point_in_viewport.to_untyped()),
|
||||||
external_scroll_id,
|
external_scroll_id,
|
||||||
@@ -819,7 +811,7 @@ impl Painter {
|
|||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
pipeline_exit_source: PipelineExitSource,
|
pipeline_exit_source: PipelineExitSource,
|
||||||
) {
|
) {
|
||||||
debug!("Compositor got pipeline exited: {webview_id:?} {pipeline_id:?}",);
|
debug!("Paint got pipeline exited: {webview_id:?} {pipeline_id:?}",);
|
||||||
if let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) {
|
if let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) {
|
||||||
webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source);
|
webview_renderer.pipeline_exited(pipeline_id, pipeline_exit_source);
|
||||||
}
|
}
|
||||||
@@ -932,13 +924,13 @@ impl Painter {
|
|||||||
return warn!("Could not receive display list info: {error}");
|
return warn!("Could not receive display list info: {error}");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let display_list_info: CompositorDisplayListInfo =
|
let display_list_info: PaintDisplayListInfo = match bincode::deserialize(&display_list_info)
|
||||||
match bincode::deserialize(&display_list_info) {
|
{
|
||||||
Ok(display_list_info) => display_list_info,
|
Ok(display_list_info) => display_list_info,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return warn!("Could not deserialize display list info: {error}");
|
return warn!("Could not deserialize display list info: {error}");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let items_data = match display_list_receiver.recv() {
|
let items_data = match display_list_receiver.recv() {
|
||||||
Ok(display_list_data) => display_list_data,
|
Ok(display_list_data) => display_list_data,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
@@ -965,8 +957,7 @@ impl Painter {
|
|||||||
},
|
},
|
||||||
display_list_descriptor,
|
display_list_descriptor,
|
||||||
);
|
);
|
||||||
let _span =
|
let _span = profile_traits::trace_span!("PaintMessage::SendDisplayList",).entered();
|
||||||
profile_traits::trace_span!("ScriptToCompositorMsg::BuiltDisplayList",).entered();
|
|
||||||
let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) else {
|
let Some(webview_renderer) = self.webview_renderers.get_mut(&webview_id) else {
|
||||||
return warn!("Could not find WebView for incoming display list");
|
return warn!("Could not find WebView for incoming display list");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ pub(crate) struct PipelineDetails {
|
|||||||
/// Whether to use less resources by stopping animations.
|
/// Whether to use less resources by stopping animations.
|
||||||
pub throttled: bool,
|
pub throttled: bool,
|
||||||
|
|
||||||
/// The compositor-side [ScrollTree]. This is used to allow finding and scrolling
|
/// The `Paint`-side [ScrollTree]. This is used to allow finding and scrolling
|
||||||
/// nodes in the compositor before forwarding new offsets to WebRender.
|
/// nodes in `Paint` before forwarding new offsets to WebRender.
|
||||||
pub scroll_tree: ScrollTree,
|
pub scroll_tree: ScrollTree,
|
||||||
|
|
||||||
/// The paint metric status of the first paint.
|
/// The paint metric status of the first paint.
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ impl Default for TimerRefreshDriver {
|
|||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let (sender, receiver) = crossbeam_channel::unbounded::<TimerThreadMessage>();
|
let (sender, receiver) = crossbeam_channel::unbounded::<TimerThreadMessage>();
|
||||||
let join_handle = thread::Builder::new()
|
let join_handle = thread::Builder::new()
|
||||||
.name(String::from("CompositorTimerThread"))
|
.name(String::from("PaintTimerThread"))
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
let mut scheduler = TimerScheduler::default();
|
let mut scheduler = TimerScheduler::default();
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,20 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use base::id::PainterId;
|
use base::id::PainterId;
|
||||||
use compositing_traits::{CompositorMsg, CompositorProxy};
|
use compositing_traits::{PaintMessage, PaintProxy};
|
||||||
use webrender_api::{DocumentId, FramePublishId, FrameReadyParams};
|
use webrender_api::{DocumentId, FramePublishId, FrameReadyParams};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct RenderNotifier {
|
pub(crate) struct RenderNotifier {
|
||||||
painter_id: PainterId,
|
painter_id: PainterId,
|
||||||
compositor_proxy: CompositorProxy,
|
paint_proxy: PaintProxy,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderNotifier {
|
impl RenderNotifier {
|
||||||
pub(crate) fn new(painter_id: PainterId, compositor_proxy: CompositorProxy) -> RenderNotifier {
|
pub(crate) fn new(painter_id: PainterId, paint_proxy: PaintProxy) -> RenderNotifier {
|
||||||
RenderNotifier {
|
RenderNotifier {
|
||||||
painter_id,
|
painter_id,
|
||||||
compositor_proxy,
|
paint_proxy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ impl webrender_api::RenderNotifier for RenderNotifier {
|
|||||||
fn clone(&self) -> Box<dyn webrender_api::RenderNotifier> {
|
fn clone(&self) -> Box<dyn webrender_api::RenderNotifier> {
|
||||||
Box::new(RenderNotifier::new(
|
Box::new(RenderNotifier::new(
|
||||||
self.painter_id,
|
self.painter_id,
|
||||||
self.compositor_proxy.clone(),
|
self.paint_proxy.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,11 +37,10 @@ impl webrender_api::RenderNotifier for RenderNotifier {
|
|||||||
_: FramePublishId,
|
_: FramePublishId,
|
||||||
frame_ready_params: &FrameReadyParams,
|
frame_ready_params: &FrameReadyParams,
|
||||||
) {
|
) {
|
||||||
self.compositor_proxy
|
self.paint_proxy.send(PaintMessage::NewWebRenderFrameReady(
|
||||||
.send(CompositorMsg::NewWebRenderFrameReady(
|
self.painter_id,
|
||||||
self.painter_id,
|
document_id,
|
||||||
document_id,
|
frame_ready_params.render,
|
||||||
frame_ready_params.render,
|
));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use image::RgbaImage;
|
|||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use webrender_api::units::{DeviceIntRect, DeviceRect};
|
use webrender_api::units::{DeviceIntRect, DeviceRect};
|
||||||
|
|
||||||
use crate::compositor::RepaintReason;
|
use crate::paint::RepaintReason;
|
||||||
use crate::painter::Painter;
|
use crate::painter::Painter;
|
||||||
|
|
||||||
pub(crate) struct ScreenshotRequest {
|
pub(crate) struct ScreenshotRequest {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::cell::{Cell, RefCell};
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use base::id::WebViewId;
|
use base::id::WebViewId;
|
||||||
use embedder_traits::{CompositorHitTestResult, InputEventId, Scroll, TouchEventType, TouchId};
|
use embedder_traits::{InputEventId, PaintHitTestResult, Scroll, TouchEventType, TouchId};
|
||||||
use euclid::{Point2D, Scale, Vector2D};
|
use euclid::{Point2D, Scale, Vector2D};
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
@@ -14,7 +14,7 @@ use style_traits::CSSPixel;
|
|||||||
use webrender_api::units::{DevicePixel, DevicePoint, DeviceVector2D};
|
use webrender_api::units::{DevicePixel, DevicePoint, DeviceVector2D};
|
||||||
|
|
||||||
use self::TouchSequenceState::*;
|
use self::TouchSequenceState::*;
|
||||||
use crate::compositor::RepaintReason;
|
use crate::paint::RepaintReason;
|
||||||
use crate::painter::Painter;
|
use crate::painter::Painter;
|
||||||
use crate::refresh_driver::{BaseRefreshDriver, RefreshDriverObserver};
|
use crate::refresh_driver::{BaseRefreshDriver, RefreshDriverObserver};
|
||||||
use crate::webview_renderer::{ScrollEvent, ScrollZoomEvent, WebViewRenderer};
|
use crate::webview_renderer::{ScrollEvent, ScrollZoomEvent, WebViewRenderer};
|
||||||
@@ -76,11 +76,11 @@ pub enum TouchMoveAllowed {
|
|||||||
Pending,
|
Pending,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A cached [`CompositorHitTestResult`] to use during a touch sequence. This
|
/// A cached [`PaintHitTestResult`] to use during a touch sequence. This
|
||||||
/// is kept so that the renderer doesn't have to constantly keep making hit tests
|
/// is kept so that the renderer doesn't have to constantly keep making hit tests
|
||||||
/// while during panning and flinging actions.
|
/// while during panning and flinging actions.
|
||||||
struct HitTestResultCache {
|
struct HitTestResultCache {
|
||||||
value: CompositorHitTestResult,
|
value: PaintHitTestResult,
|
||||||
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
|
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,7 +627,7 @@ impl TouchHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_hit_test_result_cache_value(&self) -> Option<CompositorHitTestResult> {
|
pub(crate) fn get_hit_test_result_cache_value(&self) -> Option<PaintHitTestResult> {
|
||||||
let sequence = self.touch_sequence_map.get(&self.current_sequence_id)?;
|
let sequence = self.touch_sequence_map.get(&self.current_sequence_id)?;
|
||||||
if sequence.state == Finished {
|
if sequence.state == Finished {
|
||||||
return None;
|
return None;
|
||||||
@@ -640,7 +640,7 @@ impl TouchHandler {
|
|||||||
|
|
||||||
pub(crate) fn set_hit_test_result_cache_value(
|
pub(crate) fn set_hit_test_result_cache_value(
|
||||||
&mut self,
|
&mut self,
|
||||||
value: CompositorHitTestResult,
|
value: PaintHitTestResult,
|
||||||
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
|
device_pixels_per_page: Scale<f32, CSSPixel, DevicePixel>,
|
||||||
) {
|
) {
|
||||||
if let Some(sequence) = self.touch_sequence_map.get_mut(&self.current_sequence_id) {
|
if let Some(sequence) = self.touch_sequence_map.get_mut(&self.current_sequence_id) {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/// Log an event from constellation at trace level.
|
/// Log an event from constellation at trace level.
|
||||||
/// - To disable tracing: RUST_LOG='compositor<constellation@=off'
|
/// - To disable tracing: RUST_LOG='paint<constellation@=off'
|
||||||
/// - To enable tracing: RUST_LOG='compositor<constellation@'
|
/// - To enable tracing: RUST_LOG='paint<constellation@'
|
||||||
macro_rules! trace_msg_from_constellation {
|
macro_rules! trace_msg_from_constellation {
|
||||||
// This macro only exists to put the docs in the same file as the target prefix,
|
// This macro only exists to put the docs in the same file as the target prefix,
|
||||||
// so the macro definition is always the same.
|
// so the macro definition is always the same.
|
||||||
@@ -23,11 +23,11 @@ mod from_constellation {
|
|||||||
|
|
||||||
macro_rules! target {
|
macro_rules! target {
|
||||||
($($name:literal)+) => {
|
($($name:literal)+) => {
|
||||||
concat!("compositor<constellation@", $($name),+)
|
concat!("paint<constellation@", $($name),+)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LogTarget for compositing_traits::CompositorMsg {
|
impl LogTarget for compositing_traits::PaintMessage {
|
||||||
fn log_target(&self) -> &'static str {
|
fn log_target(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::ChangeRunningAnimationsState(..) => target!("ChangeRunningAnimationsState"),
|
Self::ChangeRunningAnimationsState(..) => target!("ChangeRunningAnimationsState"),
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ use compositing_traits::{PipelineExitSource, SendableFrameTree, WebViewTrait};
|
|||||||
use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType};
|
use constellation_traits::{EmbedderToConstellationMessage, WindowSizeType};
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
AnimationState, CompositorHitTestResult, InputEvent, InputEventAndId, InputEventId,
|
AnimationState, InputEvent, InputEventAndId, InputEventId, InputEventResult, MouseButton,
|
||||||
InputEventResult, MouseButton, MouseButtonAction, MouseButtonEvent, MouseMoveEvent, Scroll,
|
MouseButtonAction, MouseButtonEvent, MouseMoveEvent, PaintHitTestResult, Scroll,
|
||||||
ScrollEvent as EmbedderScrollEvent, TouchEvent, TouchEventType, ViewportDetails, WebViewPoint,
|
ScrollEvent as EmbedderScrollEvent, TouchEvent, TouchEventType, ViewportDetails, WebViewPoint,
|
||||||
WheelEvent,
|
WheelEvent,
|
||||||
};
|
};
|
||||||
@@ -30,7 +30,7 @@ use webrender::RenderApi;
|
|||||||
use webrender_api::units::{DevicePixel, DevicePoint, DeviceRect, DeviceVector2D, LayoutVector2D};
|
use webrender_api::units::{DevicePixel, DevicePoint, DeviceRect, DeviceVector2D, LayoutVector2D};
|
||||||
use webrender_api::{DocumentId, ExternalScrollId, ScrollLocation};
|
use webrender_api::{DocumentId, ExternalScrollId, ScrollLocation};
|
||||||
|
|
||||||
use crate::compositor::RepaintReason;
|
use crate::paint::RepaintReason;
|
||||||
use crate::painter::Painter;
|
use crate::painter::Painter;
|
||||||
use crate::pinch_zoom::PinchZoom;
|
use crate::pinch_zoom::PinchZoom;
|
||||||
use crate::pipeline_details::PipelineDetails;
|
use crate::pipeline_details::PipelineDetails;
|
||||||
@@ -59,7 +59,7 @@ pub(crate) enum ScrollZoomEvent {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub(crate) struct ScrollResult {
|
pub(crate) struct ScrollResult {
|
||||||
pub hit_test_result: CompositorHitTestResult,
|
pub hit_test_result: PaintHitTestResult,
|
||||||
/// The [`ExternalScrollId`] of the node that was actually scrolled.
|
/// The [`ExternalScrollId`] of the node that was actually scrolled.
|
||||||
///
|
///
|
||||||
/// Note that this is an inclusive ancestor of `external_scroll_id` in
|
/// Note that this is an inclusive ancestor of `external_scroll_id` in
|
||||||
@@ -88,7 +88,7 @@ pub(crate) struct WebViewRenderer {
|
|||||||
pub root_pipeline_id: Option<PipelineId>,
|
pub root_pipeline_id: Option<PipelineId>,
|
||||||
/// The rectangle of the [`WebView`] in device pixels, which is the viewport.
|
/// The rectangle of the [`WebView`] in device pixels, which is the viewport.
|
||||||
pub rect: DeviceRect,
|
pub rect: DeviceRect,
|
||||||
/// Tracks details about each active pipeline that the compositor knows about.
|
/// Tracks details about each active pipeline that `Paint` knows about.
|
||||||
pub pipelines: FxHashMap<PipelineId, PipelineDetails>,
|
pub pipelines: FxHashMap<PipelineId, PipelineDetails>,
|
||||||
/// Pending scroll/zoom events.
|
/// Pending scroll/zoom events.
|
||||||
pending_scroll_zoom_events: Vec<ScrollZoomEvent>,
|
pending_scroll_zoom_events: Vec<ScrollZoomEvent>,
|
||||||
@@ -154,11 +154,7 @@ impl WebViewRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hit_test(
|
fn hit_test(&self, webrender_api: &RenderApi, point: DevicePoint) -> Vec<PaintHitTestResult> {
|
||||||
&self,
|
|
||||||
webrender_api: &RenderApi,
|
|
||||||
point: DevicePoint,
|
|
||||||
) -> Vec<CompositorHitTestResult> {
|
|
||||||
Painter::hit_test_at_point_with_api_and_document(
|
Painter::hit_test_at_point_with_api_and_document(
|
||||||
webrender_api,
|
webrender_api,
|
||||||
self.webrender_document,
|
self.webrender_document,
|
||||||
@@ -893,7 +889,7 @@ impl WebViewRenderer {
|
|||||||
return (pinch_zoom_result, vec![]);
|
return (pinch_zoom_result, vec![]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let hit_test_result = CompositorHitTestResult {
|
let hit_test_result = PaintHitTestResult {
|
||||||
pipeline_id: root_pipeline_id,
|
pipeline_id: root_pipeline_id,
|
||||||
// It's difficult to get a good value for this as it needs to be piped
|
// It's difficult to get a good value for this as it needs to be piped
|
||||||
// all the way through script and back here.
|
// all the way through script and back here.
|
||||||
@@ -915,7 +911,7 @@ impl WebViewRenderer {
|
|||||||
fn dispatch_scroll_event(
|
fn dispatch_scroll_event(
|
||||||
&self,
|
&self,
|
||||||
external_id: ExternalScrollId,
|
external_id: ExternalScrollId,
|
||||||
hit_test_result: CompositorHitTestResult,
|
hit_test_result: PaintHitTestResult,
|
||||||
) {
|
) {
|
||||||
let event = InputEvent::Scroll(EmbedderScrollEvent { external_id }).into();
|
let event = InputEvent::Scroll(EmbedderScrollEvent { external_id }).into();
|
||||||
let msg = EmbedderToConstellationMessage::ForwardInputEvent(
|
let msg = EmbedderToConstellationMessage::ForwardInputEvent(
|
||||||
|
|||||||
@@ -42,10 +42,10 @@
|
|||||||
//! +------------+ +------------+
|
//! +------------+ +------------+
|
||||||
//! ```
|
//! ```
|
||||||
//
|
//
|
||||||
//! The constellation also maintains channels to threads, including:
|
//! The constellation also maintains channels to other parts of Servo, including:
|
||||||
//!
|
//!
|
||||||
//! * The script thread.
|
//! * The script thread.
|
||||||
//! * The graphics compositor.
|
//! * The `Paint` subsystem, which runs in the same thread as the `Servo` instance.
|
||||||
//! * The font cache, image cache, and resource manager, which load
|
//! * The font cache, image cache, and resource manager, which load
|
||||||
//! and cache shared fonts, images, or other resources.
|
//! and cache shared fonts, images, or other resources.
|
||||||
//! * The service worker manager.
|
//! * The service worker manager.
|
||||||
@@ -66,7 +66,7 @@
|
|||||||
//! sender to send some data. Servo tries to achieve deadlock-freedom by using the following
|
//! sender to send some data. Servo tries to achieve deadlock-freedom by using the following
|
||||||
//! can-block-on relation:
|
//! can-block-on relation:
|
||||||
//!
|
//!
|
||||||
//! * Constellation can block on compositor
|
//! * Constellation can block on `Paint`
|
||||||
//! * Constellation can block on embedder
|
//! * Constellation can block on embedder
|
||||||
//! * Script can block on anything (other than script)
|
//! * Script can block on anything (other than script)
|
||||||
//! * Blocking is transitive (if T1 can block on T2 and T2 can block on T3 then T1 can block on T3)
|
//! * Blocking is transitive (if T1 can block on T2 and T2 can block on T3 then T1 can block on T3)
|
||||||
@@ -113,7 +113,7 @@ use canvas_traits::ConstellationCanvasMsg;
|
|||||||
use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
||||||
use canvas_traits::webgl::WebGLThreads;
|
use canvas_traits::webgl::WebGLThreads;
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CompositorMsg, CompositorProxy, PipelineExitSource, SendableFrameTree,
|
PaintMessage, PaintProxy, PipelineExitSource, SendableFrameTree,
|
||||||
WebRenderExternalImageIdManager,
|
WebRenderExternalImageIdManager,
|
||||||
};
|
};
|
||||||
use constellation_traits::{
|
use constellation_traits::{
|
||||||
@@ -133,11 +133,12 @@ use devtools_traits::{
|
|||||||
use embedder_traits::resources::{self, Resource};
|
use embedder_traits::resources::{self, Resource};
|
||||||
use embedder_traits::user_content_manager::UserContentManager;
|
use embedder_traits::user_content_manager::UserContentManager;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
AnimationState, CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse,
|
AnimationState, EmbedderControlId, EmbedderControlResponse, EmbedderMsg, EmbedderProxy,
|
||||||
EmbedderMsg, EmbedderProxy, FocusSequenceNumber, InputEvent, InputEventAndId, JSValue,
|
FocusSequenceNumber, InputEvent, InputEventAndId, JSValue, JavaScriptEvaluationError,
|
||||||
JavaScriptEvaluationError, JavaScriptEvaluationId, KeyboardEvent, MediaSessionActionType,
|
JavaScriptEvaluationId, KeyboardEvent, MediaSessionActionType, MediaSessionEvent,
|
||||||
MediaSessionEvent, MediaSessionPlaybackState, MouseButton, MouseButtonAction, MouseButtonEvent,
|
MediaSessionPlaybackState, MouseButton, MouseButtonAction, MouseButtonEvent,
|
||||||
Theme, ViewportDetails, WebDriverCommandMsg, WebDriverLoadStatus, WebDriverScriptCommand,
|
PaintHitTestResult, Theme, ViewportDetails, WebDriverCommandMsg, WebDriverLoadStatus,
|
||||||
|
WebDriverScriptCommand,
|
||||||
};
|
};
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use euclid::default::Size2D as UntypedSize2D;
|
use euclid::default::Size2D as UntypedSize2D;
|
||||||
@@ -323,8 +324,8 @@ pub struct Constellation<STF, SWF> {
|
|||||||
pub(crate) embedder_proxy: EmbedderProxy,
|
pub(crate) embedder_proxy: EmbedderProxy,
|
||||||
|
|
||||||
/// A channel (the implementation of which is port-specific) for the
|
/// A channel (the implementation of which is port-specific) for the
|
||||||
/// constellation to send messages to the compositor thread.
|
/// constellation to send messages to `Paint`.
|
||||||
pub(crate) compositor_proxy: CompositorProxy,
|
pub(crate) paint_proxy: PaintProxy,
|
||||||
|
|
||||||
/// Bookkeeping data for all webviews in the constellation.
|
/// Bookkeeping data for all webviews in the constellation.
|
||||||
webviews: FxHashMap<WebViewId, ConstellationWebView>,
|
webviews: FxHashMap<WebViewId, ConstellationWebView>,
|
||||||
@@ -514,8 +515,8 @@ pub struct InitialConstellationState {
|
|||||||
/// A channel through which messages can be sent to the embedder.
|
/// A channel through which messages can be sent to the embedder.
|
||||||
pub embedder_proxy: EmbedderProxy,
|
pub embedder_proxy: EmbedderProxy,
|
||||||
|
|
||||||
/// A channel through which messages can be sent to the compositor in-process.
|
/// A channel through which messages can be sent to `Paint` in-process.
|
||||||
pub compositor_proxy: CompositorProxy,
|
pub paint_proxy: PaintProxy,
|
||||||
|
|
||||||
/// A channel to the developer tools, if applicable.
|
/// A channel to the developer tools, if applicable.
|
||||||
pub devtools_sender: Option<Sender<DevtoolsControlMsg>>,
|
pub devtools_sender: Option<Sender<DevtoolsControlMsg>>,
|
||||||
@@ -567,10 +568,10 @@ pub struct InitialConstellationState {
|
|||||||
pub async_runtime: Box<dyn AsyncRuntime>,
|
pub async_runtime: Box<dyn AsyncRuntime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When we are exiting a pipeline, we can either force exiting or not.
|
/// When we are exiting a pipeline, we can either force exiting or not. A normal exit
|
||||||
/// A normal exit waits for the compositor to update its state before
|
/// waits for `Paint` to update its state before exiting, and delegates layout exit to
|
||||||
/// exiting, and delegates layout exit to script. A forced exit does
|
/// script. A forced exit does not notify `Paint`, and exits layout without involving
|
||||||
/// not notify the compositor, and exits layout without involving script.
|
/// script.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
enum ExitPipelineMode {
|
enum ExitPipelineMode {
|
||||||
Normal,
|
Normal,
|
||||||
@@ -685,7 +686,7 @@ where
|
|||||||
embedder_to_constellation_receiver,
|
embedder_to_constellation_receiver,
|
||||||
layout_factory,
|
layout_factory,
|
||||||
embedder_proxy: state.embedder_proxy,
|
embedder_proxy: state.embedder_proxy,
|
||||||
compositor_proxy: state.compositor_proxy,
|
paint_proxy: state.paint_proxy,
|
||||||
webviews: Default::default(),
|
webviews: Default::default(),
|
||||||
devtools_sender: state.devtools_sender,
|
devtools_sender: state.devtools_sender,
|
||||||
script_to_devtools_callback: Default::default(),
|
script_to_devtools_callback: Default::default(),
|
||||||
@@ -1220,7 +1221,7 @@ where
|
|||||||
self.pending_changes.push(change);
|
self.pending_changes.push(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles loading pages, navigation, and granting access to the compositor
|
/// Handles loading pages, navigation, and granting access to `Paint`.
|
||||||
#[servo_tracing::instrument(skip_all)]
|
#[servo_tracing::instrument(skip_all)]
|
||||||
fn handle_request(&mut self) {
|
fn handle_request(&mut self) {
|
||||||
#[expect(clippy::large_enum_variant)]
|
#[expect(clippy::large_enum_variant)]
|
||||||
@@ -1229,12 +1230,12 @@ where
|
|||||||
PipelineNamespace(PipelineNamespaceRequest),
|
PipelineNamespace(PipelineNamespaceRequest),
|
||||||
Script((WebViewId, PipelineId, ScriptToConstellationMessage)),
|
Script((WebViewId, PipelineId, ScriptToConstellationMessage)),
|
||||||
BackgroundHangMonitor(HangMonitorAlert),
|
BackgroundHangMonitor(HangMonitorAlert),
|
||||||
Compositor(EmbedderToConstellationMessage),
|
Embedder(EmbedderToConstellationMessage),
|
||||||
FromSWManager(SWManagerMsg),
|
FromSWManager(SWManagerMsg),
|
||||||
RemoveProcess(usize),
|
RemoveProcess(usize),
|
||||||
}
|
}
|
||||||
// Get one incoming request.
|
// Get one incoming request.
|
||||||
// This is one of the few places where the compositor is
|
// This is one of the few places where `Paint` is
|
||||||
// allowed to panic. If one of the receiver.recv() calls
|
// allowed to panic. If one of the receiver.recv() calls
|
||||||
// fails, it is because the matching sender has been
|
// fails, it is because the matching sender has been
|
||||||
// reclaimed, but this can't happen in normal execution
|
// reclaimed, but this can't happen in normal execution
|
||||||
@@ -1271,9 +1272,9 @@ where
|
|||||||
.recv(&self.background_hang_monitor_receiver)
|
.recv(&self.background_hang_monitor_receiver)
|
||||||
.expect("Unexpected BHM channel panic in constellation")
|
.expect("Unexpected BHM channel panic in constellation")
|
||||||
.map(Request::BackgroundHangMonitor),
|
.map(Request::BackgroundHangMonitor),
|
||||||
3 => Ok(Request::Compositor(
|
3 => Ok(Request::Embedder(
|
||||||
oper.recv(&self.embedder_to_constellation_receiver)
|
oper.recv(&self.embedder_to_constellation_receiver)
|
||||||
.expect("Unexpected compositor channel panic in constellation"),
|
.expect("Unexpected embedder channel panic in constellation"),
|
||||||
)),
|
)),
|
||||||
4 => oper
|
4 => oper
|
||||||
.recv(&self.swmanager_receiver)
|
.recv(&self.swmanager_receiver)
|
||||||
@@ -1297,7 +1298,7 @@ where
|
|||||||
Request::PipelineNamespace(message) => {
|
Request::PipelineNamespace(message) => {
|
||||||
self.handle_request_for_pipeline_namespace(message)
|
self.handle_request_for_pipeline_namespace(message)
|
||||||
},
|
},
|
||||||
Request::Compositor(message) => self.handle_request_from_compositor(message),
|
Request::Embedder(message) => self.handle_request_from_embedder(message),
|
||||||
Request::Script(message) => {
|
Request::Script(message) => {
|
||||||
self.handle_request_from_script(message);
|
self.handle_request_from_script(message);
|
||||||
},
|
},
|
||||||
@@ -1341,8 +1342,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[servo_tracing::instrument(skip_all)]
|
#[servo_tracing::instrument(skip_all)]
|
||||||
fn handle_request_from_compositor(&mut self, message: EmbedderToConstellationMessage) {
|
fn handle_request_from_embedder(&mut self, message: EmbedderToConstellationMessage) {
|
||||||
trace_msg_from_compositor!(message, "{message:?}");
|
trace_msg_from_embedder!(message, "{message:?}");
|
||||||
match message {
|
match message {
|
||||||
EmbedderToConstellationMessage::Exit => {
|
EmbedderToConstellationMessage::Exit => {
|
||||||
self.handle_exit();
|
self.handle_exit();
|
||||||
@@ -2024,7 +2025,7 @@ where
|
|||||||
};
|
};
|
||||||
let webgpu_chan = match browsing_context_group.webgpus.entry(host) {
|
let webgpu_chan = match browsing_context_group.webgpus.entry(host) {
|
||||||
Entry::Vacant(v) => start_webgpu_thread(
|
Entry::Vacant(v) => start_webgpu_thread(
|
||||||
self.compositor_proxy.cross_process_compositor_api.clone(),
|
self.paint_proxy.cross_process_paint_api.clone(),
|
||||||
self.webrender_wgpu
|
self.webrender_wgpu
|
||||||
.webrender_external_image_id_manager
|
.webrender_external_image_id_manager
|
||||||
.clone(),
|
.clone(),
|
||||||
@@ -2446,7 +2447,7 @@ where
|
|||||||
resource_threads: self.public_resource_threads.clone(),
|
resource_threads: self.public_resource_threads.clone(),
|
||||||
own_sender: own_sender.clone(),
|
own_sender: own_sender.clone(),
|
||||||
receiver,
|
receiver,
|
||||||
compositor_api: self.compositor_proxy.cross_process_compositor_api.clone(),
|
paint_api: self.paint_proxy.cross_process_paint_api.clone(),
|
||||||
system_font_service_sender: self.system_font_service.to_sender(),
|
system_font_service_sender: self.system_font_service.to_sender(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2737,9 +2738,9 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Now that the Script and Constellation parts of Servo no longer have a reference to
|
// Now that the Script and Constellation parts of Servo no longer have a reference to
|
||||||
// this pipeline, tell the compositor that it has shut down. This is delayed until the
|
// this pipeline, tell `Paint` that it has shut down. This is delayed until the
|
||||||
// last moment.
|
// last moment.
|
||||||
self.compositor_proxy.send(CompositorMsg::PipelineExited(
|
self.paint_proxy.send(PaintMessage::PipelineExited(
|
||||||
pipeline.webview_id,
|
pipeline.webview_id,
|
||||||
pipeline.id,
|
pipeline.id,
|
||||||
PipelineExitSource::Constellation,
|
PipelineExitSource::Constellation,
|
||||||
@@ -2962,7 +2963,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
event: InputEventAndId,
|
event: InputEventAndId,
|
||||||
hit_test_result: Option<CompositorHitTestResult>,
|
hit_test_result: Option<PaintHitTestResult>,
|
||||||
) {
|
) {
|
||||||
if let InputEvent::MouseButton(event) = &event.event {
|
if let InputEvent::MouseButton(event) = &event.event {
|
||||||
self.update_pressed_mouse_buttons(event);
|
self.update_pressed_mouse_buttons(event);
|
||||||
@@ -3303,7 +3304,7 @@ where
|
|||||||
webview_id,
|
webview_id,
|
||||||
None,
|
None,
|
||||||
script_sender,
|
script_sender,
|
||||||
self.compositor_proxy.clone(),
|
self.paint_proxy.clone(),
|
||||||
is_parent_throttled,
|
is_parent_throttled,
|
||||||
load_info.load_data,
|
load_info.load_data,
|
||||||
);
|
);
|
||||||
@@ -3380,7 +3381,7 @@ where
|
|||||||
new_webview_id,
|
new_webview_id,
|
||||||
Some(opener_browsing_context_id),
|
Some(opener_browsing_context_id),
|
||||||
script_sender,
|
script_sender,
|
||||||
self.compositor_proxy.clone(),
|
self.paint_proxy.clone(),
|
||||||
is_opener_throttled,
|
is_opener_throttled,
|
||||||
load_data,
|
load_data,
|
||||||
);
|
);
|
||||||
@@ -3446,8 +3447,8 @@ where
|
|||||||
if let Some(pipeline) = self.pipelines.get_mut(&pipeline_id) {
|
if let Some(pipeline) = self.pipelines.get_mut(&pipeline_id) {
|
||||||
if pipeline.animation_state != animation_state {
|
if pipeline.animation_state != animation_state {
|
||||||
pipeline.animation_state = animation_state;
|
pipeline.animation_state = animation_state;
|
||||||
self.compositor_proxy
|
self.paint_proxy
|
||||||
.send(CompositorMsg::ChangeRunningAnimationsState(
|
.send(PaintMessage::ChangeRunningAnimationsState(
|
||||||
pipeline.webview_id,
|
pipeline.webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
animation_state,
|
animation_state,
|
||||||
@@ -5042,8 +5043,8 @@ where
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
self.compositor_proxy
|
self.paint_proxy
|
||||||
.send(CompositorMsg::ScreenshotReadinessReponse(
|
.send(PaintMessage::ScreenshotReadinessReponse(
|
||||||
screenshot_request.webview_id,
|
screenshot_request.webview_id,
|
||||||
pipelines_and_epochs,
|
pipelines_and_epochs,
|
||||||
));
|
));
|
||||||
@@ -5393,7 +5394,7 @@ where
|
|||||||
self.pending_changes.remove(pending_index);
|
self.pending_changes.remove(pending_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform script, compositor that this pipeline has exited.
|
// Inform script and paint that this pipeline has exited.
|
||||||
pipeline.send_exit_message_to_script(dbc);
|
pipeline.send_exit_message_to_script(dbc);
|
||||||
|
|
||||||
self.send_screenshot_readiness_requests_to_pipelines();
|
self.send_screenshot_readiness_requests_to_pipelines();
|
||||||
@@ -5451,7 +5452,7 @@ where
|
|||||||
.expect("Unknown top-level browsing context")
|
.expect("Unknown top-level browsing context")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a browsing context to a sendable form to pass to the compositor
|
// Convert a browsing context to a sendable form to pass to `Paint`
|
||||||
#[servo_tracing::instrument(skip_all)]
|
#[servo_tracing::instrument(skip_all)]
|
||||||
fn browsing_context_to_sendable(
|
fn browsing_context_to_sendable(
|
||||||
&self,
|
&self,
|
||||||
@@ -5481,7 +5482,7 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the frame tree for the given webview to the compositor.
|
/// Send the frame tree for the given webview to `Paint`.
|
||||||
#[servo_tracing::instrument(skip_all)]
|
#[servo_tracing::instrument(skip_all)]
|
||||||
fn set_frame_tree_for_webview(&mut self, webview_id: WebViewId) {
|
fn set_frame_tree_for_webview(&mut self, webview_id: WebViewId) {
|
||||||
// Note that this function can panic, due to ipc-channel creation failure.
|
// Note that this function can panic, due to ipc-channel creation failure.
|
||||||
@@ -5490,10 +5491,8 @@ where
|
|||||||
let browsing_context_id = BrowsingContextId::from(webview_id);
|
let browsing_context_id = BrowsingContextId::from(webview_id);
|
||||||
if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) {
|
if let Some(frame_tree) = self.browsing_context_to_sendable(browsing_context_id) {
|
||||||
debug!("{}: Sending frame tree", browsing_context_id);
|
debug!("{}: Sending frame tree", browsing_context_id);
|
||||||
self.compositor_proxy
|
self.paint_proxy
|
||||||
.send(CompositorMsg::SetFrameTreeForWebView(
|
.send(PaintMessage::SetFrameTreeForWebView(webview_id, frame_tree));
|
||||||
webview_id, frame_tree,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5567,7 +5566,7 @@ where
|
|||||||
fn create_canvas_paint_thread(
|
fn create_canvas_paint_thread(
|
||||||
&self,
|
&self,
|
||||||
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
|
) -> (Sender<ConstellationCanvasMsg>, GenericSender<CanvasMsg>) {
|
||||||
CanvasPaintThread::start(self.compositor_proxy.cross_process_compositor_api.clone())
|
CanvasPaintThread::start(self.paint_proxy.cross_process_paint_api.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_embedder_control_response(
|
fn handle_embedder_control_response(
|
||||||
|
|||||||
@@ -104,10 +104,7 @@ impl EventLoop {
|
|||||||
constellation_to_script_sender: script_chan,
|
constellation_to_script_sender: script_chan,
|
||||||
constellation_to_script_receiver: script_port,
|
constellation_to_script_receiver: script_port,
|
||||||
pipeline_namespace_id: constellation.next_pipeline_namespace_id(),
|
pipeline_namespace_id: constellation.next_pipeline_namespace_id(),
|
||||||
cross_process_compositor_api: constellation
|
cross_process_paint_api: constellation.paint_proxy.cross_process_paint_api.clone(),
|
||||||
.compositor_proxy
|
|
||||||
.cross_process_compositor_api
|
|
||||||
.clone(),
|
|
||||||
webgl_chan: constellation
|
webgl_chan: constellation
|
||||||
.webgl_threads
|
.webgl_threads
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ impl Log for FromScriptLogger {
|
|||||||
fn flush(&self) {}
|
fn flush(&self) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A logger directed at the constellation from the compositor
|
/// A logger directed at the constellation from `Paint`.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FromEmbedderLogger {
|
pub struct FromEmbedderLogger {
|
||||||
/// A channel to the constellation
|
/// A channel to the constellation
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::collections::HashSet;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use base::id::{BrowsingContextId, HistoryStateId, PipelineId, WebViewId};
|
use base::id::{BrowsingContextId, HistoryStateId, PipelineId, WebViewId};
|
||||||
use compositing_traits::{CompositionPipeline, CompositorMsg, CompositorProxy};
|
use compositing_traits::{CompositionPipeline, PaintMessage, PaintProxy};
|
||||||
use constellation_traits::{LoadData, ServiceWorkerManagerFactory};
|
use constellation_traits::{LoadData, ServiceWorkerManagerFactory};
|
||||||
use embedder_traits::{AnimationState, FocusSequenceNumber};
|
use embedder_traits::{AnimationState, FocusSequenceNumber};
|
||||||
use ipc_channel::Error;
|
use ipc_channel::Error;
|
||||||
@@ -37,8 +37,8 @@ pub struct Pipeline {
|
|||||||
/// The event loop handling this pipeline.
|
/// The event loop handling this pipeline.
|
||||||
pub event_loop: Rc<EventLoop>,
|
pub event_loop: Rc<EventLoop>,
|
||||||
|
|
||||||
/// A channel to the compositor.
|
/// A channel to `Paint`.
|
||||||
pub compositor_proxy: CompositorProxy,
|
pub paint_proxy: PaintProxy,
|
||||||
|
|
||||||
/// The most recently loaded URL in this pipeline.
|
/// The most recently loaded URL in this pipeline.
|
||||||
/// Note that this URL can change, for example if the page navigates
|
/// Note that this URL can change, for example if the page navigates
|
||||||
@@ -91,7 +91,7 @@ impl Pipeline {
|
|||||||
new_pipeline_info.webview_id,
|
new_pipeline_info.webview_id,
|
||||||
new_pipeline_info.opener,
|
new_pipeline_info.opener,
|
||||||
event_loop,
|
event_loop,
|
||||||
constellation.compositor_proxy.clone(),
|
constellation.paint_proxy.clone(),
|
||||||
throttled,
|
throttled,
|
||||||
new_pipeline_info.load_data,
|
new_pipeline_info.load_data,
|
||||||
))
|
))
|
||||||
@@ -105,7 +105,7 @@ impl Pipeline {
|
|||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
opener: Option<BrowsingContextId>,
|
opener: Option<BrowsingContextId>,
|
||||||
event_loop: Rc<EventLoop>,
|
event_loop: Rc<EventLoop>,
|
||||||
compositor_proxy: CompositorProxy,
|
paint_proxy: PaintProxy,
|
||||||
throttled: bool,
|
throttled: bool,
|
||||||
load_data: LoadData,
|
load_data: LoadData,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -115,7 +115,7 @@ impl Pipeline {
|
|||||||
webview_id,
|
webview_id,
|
||||||
opener,
|
opener,
|
||||||
event_loop,
|
event_loop,
|
||||||
compositor_proxy,
|
paint_proxy,
|
||||||
url: load_data.url.clone(),
|
url: load_data.url.clone(),
|
||||||
children: vec![],
|
children: vec![],
|
||||||
animation_state: AnimationState::NoAnimationsPresent,
|
animation_state: AnimationState::NoAnimationsPresent,
|
||||||
@@ -155,7 +155,7 @@ impl Pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The compositor's view of a pipeline.
|
/// `Paint`'s view of a pipeline.
|
||||||
pub fn to_sendable(&self) -> CompositionPipeline {
|
pub fn to_sendable(&self) -> CompositionPipeline {
|
||||||
CompositionPipeline {
|
CompositionPipeline {
|
||||||
id: self.id,
|
id: self.id,
|
||||||
@@ -191,11 +191,11 @@ impl Pipeline {
|
|||||||
/// running timers at a heavily limited rate.
|
/// running timers at a heavily limited rate.
|
||||||
pub fn set_throttled(&self, throttled: bool) {
|
pub fn set_throttled(&self, throttled: bool) {
|
||||||
let script_msg = ScriptThreadMessage::SetThrottled(self.webview_id, self.id, throttled);
|
let script_msg = ScriptThreadMessage::SetThrottled(self.webview_id, self.id, throttled);
|
||||||
let compositor_msg = CompositorMsg::SetThrottled(self.webview_id, self.id, throttled);
|
let paint_message = PaintMessage::SetThrottled(self.webview_id, self.id, throttled);
|
||||||
let err = self.event_loop.send(script_msg);
|
let err = self.event_loop.send(script_msg);
|
||||||
if let Err(e) = err {
|
if let Err(e) = err {
|
||||||
warn!("Sending SetThrottled to script failed ({}).", e);
|
warn!("Sending SetThrottled to script failed ({}).", e);
|
||||||
}
|
}
|
||||||
self.compositor_proxy.send(compositor_msg);
|
self.paint_proxy.send(paint_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,14 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
/// Log an event from compositor at trace level.
|
/// Log an event from embedder at trace level.
|
||||||
/// - To disable tracing: RUST_LOG='constellation<compositor@=off'
|
/// - To disable tracing: RUST_LOG='constellation<embedder@=off'
|
||||||
/// - To enable tracing: RUST_LOG='constellation<compositor@'
|
/// - To enable tracing: RUST_LOG='constellation<embedder@'
|
||||||
/// - Recommended filters when tracing is enabled:
|
/// - Recommended filters when tracing is enabled:
|
||||||
/// - constellation<compositor@ForwardEvent(MouseMoveEvent)=off
|
/// - constellation<embedder@ForwardEvent(MouseMoveEvent)=off
|
||||||
/// - constellation<compositor@LogEntry=off
|
/// - constellation<embedder@LogEntry=off
|
||||||
/// - constellation<compositor@ReadyToPresent=off
|
/// - constellation<embedder@ReadyToPresent=off
|
||||||
macro_rules! trace_msg_from_compositor {
|
macro_rules! trace_msg_from_embedder {
|
||||||
// This macro only exists to put the docs in the same file as the target prefix,
|
// This macro only exists to put the docs in the same file as the target prefix,
|
||||||
// so the macro definition is always the same.
|
// so the macro definition is always the same.
|
||||||
($event:expr, $($rest:tt)+) => {
|
($event:expr, $($rest:tt)+) => {
|
||||||
@@ -35,14 +35,14 @@ pub(crate) trait LogTarget {
|
|||||||
fn log_target(&self) -> &'static str;
|
fn log_target(&self) -> &'static str;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod from_compositor {
|
mod from_embedder {
|
||||||
use embedder_traits::{InputEvent, InputEventAndId};
|
use embedder_traits::{InputEvent, InputEventAndId};
|
||||||
|
|
||||||
use super::LogTarget;
|
use super::LogTarget;
|
||||||
|
|
||||||
macro_rules! target {
|
macro_rules! target {
|
||||||
($($name:literal)+) => {
|
($($name:literal)+) => {
|
||||||
concat!("constellation<compositor@", $($name),+)
|
concat!("constellation<embedder@", $($name),+)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use base::id::{PainterId, WebViewId};
|
use base::id::{PainterId, WebViewId};
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use content_security_policy::Violation;
|
use content_security_policy::Violation;
|
||||||
use fonts_traits::{
|
use fonts_traits::{
|
||||||
CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
|
CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
|
||||||
@@ -81,8 +81,8 @@ pub struct FontContext {
|
|||||||
|
|
||||||
resource_threads: Mutex<CoreResourceThread>,
|
resource_threads: Mutex<CoreResourceThread>,
|
||||||
|
|
||||||
/// A sender that can send messages and receive replies from the compositor.
|
/// A sender that can send messages and receive replies from `Paint`.
|
||||||
compositor_api: Mutex<CrossProcessCompositorApi>,
|
paint_api: Mutex<CrossProcessPaintApi>,
|
||||||
|
|
||||||
/// The actual instances of fonts ie a [`FontTemplate`] combined with a size and
|
/// The actual instances of fonts ie a [`FontTemplate`] combined with a size and
|
||||||
/// other font properties, along with the font data and a platform font instance.
|
/// other font properties, along with the font data and a platform font instance.
|
||||||
@@ -143,14 +143,14 @@ impl Clone for WebFontDocumentContext {
|
|||||||
impl FontContext {
|
impl FontContext {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
system_font_service_proxy: Arc<SystemFontServiceProxy>,
|
system_font_service_proxy: Arc<SystemFontServiceProxy>,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
resource_threads: ResourceThreads,
|
resource_threads: ResourceThreads,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
#[allow(clippy::default_constructed_unit_structs)]
|
#[allow(clippy::default_constructed_unit_structs)]
|
||||||
Self {
|
Self {
|
||||||
system_font_service_proxy,
|
system_font_service_proxy,
|
||||||
resource_threads: Mutex::new(resource_threads.core_thread),
|
resource_threads: Mutex::new(resource_threads.core_thread),
|
||||||
compositor_api: Mutex::new(compositor_api),
|
paint_api: Mutex::new(paint_api),
|
||||||
fonts: Default::default(),
|
fonts: Default::default(),
|
||||||
resolved_font_groups: Default::default(),
|
resolved_font_groups: Default::default(),
|
||||||
web_fonts: Default::default(),
|
web_fonts: Default::default(),
|
||||||
@@ -361,7 +361,7 @@ impl FontContext {
|
|||||||
.entry(identifier.clone())
|
.entry(identifier.clone())
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let font_key = self.system_font_service_proxy.generate_font_key(painter_id);
|
let font_key = self.system_font_service_proxy.generate_font_key(painter_id);
|
||||||
self.compositor_api.lock().add_font(
|
self.paint_api.lock().add_font(
|
||||||
font_key,
|
font_key,
|
||||||
font_data.as_ipc_shared_memory(),
|
font_data.as_ipc_shared_memory(),
|
||||||
identifier.index(),
|
identifier.index(),
|
||||||
@@ -383,7 +383,7 @@ impl FontContext {
|
|||||||
let font_instance_key = self
|
let font_instance_key = self
|
||||||
.system_font_service_proxy
|
.system_font_service_proxy
|
||||||
.generate_font_instance_key(painter_id);
|
.generate_font_instance_key(painter_id);
|
||||||
self.compositor_api.lock().add_font_instance(
|
self.paint_api.lock().add_font_instance(
|
||||||
font_instance_key,
|
font_instance_key,
|
||||||
font_key,
|
font_key,
|
||||||
pt_size.to_f32_px(),
|
pt_size.to_f32_px(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::thread;
|
|||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use base::id::PainterId;
|
use base::id::PainterId;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use fonts_traits::{
|
use fonts_traits::{
|
||||||
FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, LowercaseFontFamilyName,
|
FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, LowercaseFontFamilyName,
|
||||||
SystemFontServiceMessage, SystemFontServiceProxySender,
|
SystemFontServiceMessage, SystemFontServiceProxySender,
|
||||||
@@ -58,21 +58,21 @@ struct FontInstancesMapKey {
|
|||||||
pub struct SystemFontService {
|
pub struct SystemFontService {
|
||||||
port: IpcReceiver<SystemFontServiceMessage>,
|
port: IpcReceiver<SystemFontServiceMessage>,
|
||||||
local_families: FontStore,
|
local_families: FontStore,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
// keys already have the IdNamespace for webrender
|
// keys already have the IdNamespace for webrender
|
||||||
webrender_fonts: HashMap<(FontIdentifier, PainterId), FontKey>,
|
webrender_fonts: HashMap<(FontIdentifier, PainterId), FontKey>,
|
||||||
font_instances: HashMap<FontInstancesMapKey, FontInstanceKey>,
|
font_instances: HashMap<FontInstancesMapKey, FontInstanceKey>,
|
||||||
generic_fonts: ResolvedGenericFontFamilies,
|
generic_fonts: ResolvedGenericFontFamilies,
|
||||||
|
|
||||||
/// This is an optimization that allows the [`SystemFontService`] to send font data to
|
/// This is an optimization that allows the [`SystemFontService`] to send font data to
|
||||||
/// the compositor asynchronously for creating WebRender fonts, while immediately
|
/// `Paint` asynchronously for creating WebRender fonts, while immediately
|
||||||
/// returning a font key for that data. Once the free keys are exhausted, the
|
/// returning a font key for that data. Once the free keys are exhausted, the
|
||||||
/// [`SystemFontService`] will fetch a new batch.
|
/// [`SystemFontService`] will fetch a new batch.
|
||||||
/// TODO: We currently do not delete the free keys if a `WebView` is removed.
|
/// TODO: We currently do not delete the free keys if a `WebView` is removed.
|
||||||
free_font_keys: FxHashMap<PainterId, Vec<FontKey>>,
|
free_font_keys: FxHashMap<PainterId, Vec<FontKey>>,
|
||||||
|
|
||||||
/// This is an optimization that allows the [`SystemFontService`] to create WebRender font
|
/// This is an optimization that allows the [`SystemFontService`] to create WebRender font
|
||||||
/// instances in the compositor asynchronously, while immediately returning a font
|
/// instances in `Paint` asynchronously, while immediately returning a font
|
||||||
/// instance key for the instance. Once the free keys are exhausted, the
|
/// instance key for the instance. Once the free keys are exhausted, the
|
||||||
/// [`SystemFontService`] will fetch a new batch.
|
/// [`SystemFontService`] will fetch a new batch.
|
||||||
free_font_instance_keys: FxHashMap<PainterId, Vec<FontInstanceKey>>,
|
free_font_instance_keys: FxHashMap<PainterId, Vec<FontInstanceKey>>,
|
||||||
@@ -80,7 +80,7 @@ pub struct SystemFontService {
|
|||||||
|
|
||||||
impl SystemFontService {
|
impl SystemFontService {
|
||||||
pub fn spawn(
|
pub fn spawn(
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
memory_profiler_sender: ProfilerChan,
|
memory_profiler_sender: ProfilerChan,
|
||||||
) -> SystemFontServiceProxySender {
|
) -> SystemFontServiceProxySender {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
@@ -93,7 +93,7 @@ impl SystemFontService {
|
|||||||
let mut cache = SystemFontService {
|
let mut cache = SystemFontService {
|
||||||
port: receiver,
|
port: receiver,
|
||||||
local_families: Default::default(),
|
local_families: Default::default(),
|
||||||
compositor_api,
|
paint_api,
|
||||||
webrender_fonts: HashMap::new(),
|
webrender_fonts: HashMap::new(),
|
||||||
font_instances: HashMap::new(),
|
font_instances: HashMap::new(),
|
||||||
generic_fonts: Default::default(),
|
generic_fonts: Default::default(),
|
||||||
@@ -204,7 +204,7 @@ impl SystemFontService {
|
|||||||
|
|
||||||
const FREE_FONT_KEYS_BATCH_SIZE: usize = 40;
|
const FREE_FONT_KEYS_BATCH_SIZE: usize = 40;
|
||||||
const FREE_FONT_INSTANCE_KEYS_BATCH_SIZE: usize = 40;
|
const FREE_FONT_INSTANCE_KEYS_BATCH_SIZE: usize = 40;
|
||||||
let (mut new_font_keys, mut new_font_instance_keys) = self.compositor_api.fetch_font_keys(
|
let (mut new_font_keys, mut new_font_instance_keys) = self.paint_api.fetch_font_keys(
|
||||||
FREE_FONT_KEYS_BATCH_SIZE - self.free_font_keys.len(),
|
FREE_FONT_KEYS_BATCH_SIZE - self.free_font_keys.len(),
|
||||||
FREE_FONT_INSTANCE_KEYS_BATCH_SIZE - self.free_font_instance_keys.len(),
|
FREE_FONT_INSTANCE_KEYS_BATCH_SIZE - self.free_font_instance_keys.len(),
|
||||||
painter_id,
|
painter_id,
|
||||||
@@ -278,7 +278,7 @@ impl SystemFontService {
|
|||||||
) -> FontInstanceKey {
|
) -> FontInstanceKey {
|
||||||
self.fetch_font_keys_if_needed(painter_id);
|
self.fetch_font_keys_if_needed(painter_id);
|
||||||
|
|
||||||
let compositor_api = &self.compositor_api;
|
let paint_api = &self.paint_api;
|
||||||
let webrender_fonts = &mut self.webrender_fonts;
|
let webrender_fonts = &mut self.webrender_fonts;
|
||||||
|
|
||||||
let font_key = *webrender_fonts
|
let font_key = *webrender_fonts
|
||||||
@@ -293,8 +293,7 @@ impl SystemFontService {
|
|||||||
let FontIdentifier::Local(local_font_identifier) = identifier else {
|
let FontIdentifier::Local(local_font_identifier) = identifier else {
|
||||||
unreachable!("Should never have a web font in the system font service");
|
unreachable!("Should never have a web font in the system font service");
|
||||||
};
|
};
|
||||||
compositor_api
|
paint_api.add_system_font(font_key, local_font_identifier.native_font_handle());
|
||||||
.add_system_font(font_key, local_font_identifier.native_font_handle());
|
|
||||||
font_key
|
font_key
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -312,7 +311,7 @@ impl SystemFontService {
|
|||||||
.expect("We just filled the keys")
|
.expect("We just filled the keys")
|
||||||
.pop()
|
.pop()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
compositor_api.add_font_instance(
|
paint_api.add_font_instance(
|
||||||
font_instance_key,
|
font_instance_key,
|
||||||
font_key,
|
font_key,
|
||||||
pt_size.to_f32_px(),
|
pt_size.to_f32_px(),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ mod font_context {
|
|||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use fonts::platform::font::PlatformFont;
|
use fonts::platform::font::PlatformFont;
|
||||||
use fonts::{
|
use fonts::{
|
||||||
FallbackFontSelectionOptions, FontContext, FontDescriptor, FontFamilyDescriptor,
|
FallbackFontSelectionOptions, FontContext, FontDescriptor, FontFamilyDescriptor,
|
||||||
@@ -50,14 +50,14 @@ mod font_context {
|
|||||||
let (system_font_service, system_font_service_proxy) = MockSystemFontService::spawn();
|
let (system_font_service, system_font_service_proxy) = MockSystemFontService::spawn();
|
||||||
let (core_sender, _) = ipc::channel().unwrap();
|
let (core_sender, _) = ipc::channel().unwrap();
|
||||||
let mock_resource_threads = ResourceThreads::new(core_sender);
|
let mock_resource_threads = ResourceThreads::new(core_sender);
|
||||||
let mock_compositor_api = CrossProcessCompositorApi::dummy();
|
let mock_paint_api = CrossProcessPaintApi::dummy();
|
||||||
|
|
||||||
let proxy_clone = Arc::new(system_font_service_proxy.to_sender().to_proxy());
|
let proxy_clone = Arc::new(system_font_service_proxy.to_sender().to_proxy());
|
||||||
INIT.call_once(|| {
|
INIT.call_once(|| {
|
||||||
start_fetch_thread();
|
start_fetch_thread();
|
||||||
});
|
});
|
||||||
Self {
|
Self {
|
||||||
context: FontContext::new(proxy_clone, mock_compositor_api, mock_resource_threads),
|
context: FontContext::new(proxy_clone, mock_paint_api, mock_resource_threads),
|
||||||
system_font_service,
|
system_font_service,
|
||||||
system_font_service_proxy,
|
system_font_service_proxy,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,11 +65,7 @@ impl<'a> BackgroundPainter<'a> {
|
|||||||
if &BackgroundAttachment::Fixed ==
|
if &BackgroundAttachment::Fixed ==
|
||||||
get_cyclic(&background.background_attachment.0, layer_index)
|
get_cyclic(&background.background_attachment.0, layer_index)
|
||||||
{
|
{
|
||||||
return builder
|
return builder.paint_info.viewport_details.layout_size().into();
|
||||||
.compositor_info
|
|
||||||
.viewport_details
|
|
||||||
.layout_size()
|
|
||||||
.into();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match get_cyclic(&background.background_clip.0, layer_index) {
|
match get_cyclic(&background.background_clip.0, layer_index) {
|
||||||
@@ -153,11 +149,7 @@ impl<'a> BackgroundPainter<'a> {
|
|||||||
Origin::PaddingBox => *fragment_builder.padding_rect(),
|
Origin::PaddingBox => *fragment_builder.padding_rect(),
|
||||||
Origin::BorderBox => fragment_builder.border_rect,
|
Origin::BorderBox => fragment_builder.border_rect,
|
||||||
},
|
},
|
||||||
BackgroundAttachment::Fixed => builder
|
BackgroundAttachment::Fixed => builder.paint_info.viewport_details.layout_size().into(),
|
||||||
.compositor_info
|
|
||||||
.viewport_details
|
|
||||||
.layout_size()
|
|
||||||
.into(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ impl<'a> HitTest<'a> {
|
|||||||
|
|
||||||
let transform = self
|
let transform = self
|
||||||
.stacking_context_tree
|
.stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.scroll_tree
|
.scroll_tree
|
||||||
.cumulative_root_to_node_transform(scroll_tree_node_id)?;
|
.cumulative_root_to_node_transform(scroll_tree_node_id)?;
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ impl Fragment {
|
|||||||
if is_root_element {
|
if is_root_element {
|
||||||
let viewport_size = hit_test
|
let viewport_size = hit_test
|
||||||
.stacking_context_tree
|
.stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.viewport_details
|
.viewport_details
|
||||||
.size;
|
.size;
|
||||||
let viewport_rect = LayoutRect::from_origin_and_size(
|
let viewport_rect = LayoutRect::from_origin_and_size(
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ pub(crate) struct LargestContentfulPaintCandidateCollector {
|
|||||||
/// The rect of viewport.
|
/// The rect of viewport.
|
||||||
pub viewport_rect: LayoutRect,
|
pub viewport_rect: LayoutRect,
|
||||||
/// Flag to indicate if there is an update to LCP candidate.
|
/// Flag to indicate if there is an update to LCP candidate.
|
||||||
/// This is used to avoid sending duplicate LCP candidates to the compositor.
|
/// This is used to avoid sending duplicate LCP candidates to `Paint`.
|
||||||
pub did_lcp_candidate_update: bool,
|
pub did_lcp_candidate_update: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use std::sync::Arc;
|
|||||||
use app_units::{AU_PER_PX, Au};
|
use app_units::{AU_PER_PX, Au};
|
||||||
use base::id::ScrollTreeNodeId;
|
use base::id::ScrollTreeNodeId;
|
||||||
use clip::{Clip, ClipId};
|
use clip::{Clip, ClipId};
|
||||||
use compositing_traits::display_list::{CompositorDisplayListInfo, SpatialTreeNodeInfo};
|
use compositing_traits::display_list::{PaintDisplayListInfo, SpatialTreeNodeInfo};
|
||||||
use compositing_traits::largest_contentful_paint_candidate::{
|
use compositing_traits::largest_contentful_paint_candidate::{
|
||||||
LCPCandidateID, LargestContentfulPaintType,
|
LCPCandidateID, LargestContentfulPaintType,
|
||||||
};
|
};
|
||||||
@@ -99,8 +99,8 @@ pub(crate) struct DisplayListBuilder<'a> {
|
|||||||
/// The [`wr::DisplayListBuilder`] for this Servo [`DisplayListBuilder`].
|
/// The [`wr::DisplayListBuilder`] for this Servo [`DisplayListBuilder`].
|
||||||
pub webrender_display_list_builder: &'a mut wr::DisplayListBuilder,
|
pub webrender_display_list_builder: &'a mut wr::DisplayListBuilder,
|
||||||
|
|
||||||
/// The [`CompositorDisplayListInfo`] used to collect display list items and metadata.
|
/// The [`PaintDisplayListInfo`] used to collect display list items and metadata.
|
||||||
pub compositor_info: &'a mut CompositorDisplayListInfo,
|
pub paint_info: &'a mut PaintDisplayListInfo,
|
||||||
|
|
||||||
/// Data about the fragments that are highlighted by the inspector, if any.
|
/// Data about the fragments that are highlighted by the inspector, if any.
|
||||||
///
|
///
|
||||||
@@ -176,8 +176,8 @@ impl DisplayListBuilder<'_> {
|
|||||||
lcp_candidate_collector: Option<&mut LargestContentfulPaintCandidateCollector>,
|
lcp_candidate_collector: Option<&mut LargestContentfulPaintCandidateCollector>,
|
||||||
) -> BuiltDisplayList {
|
) -> BuiltDisplayList {
|
||||||
// Build the rest of the display list which inclues all of the WebRender primitives.
|
// Build the rest of the display list which inclues all of the WebRender primitives.
|
||||||
let compositor_info = &mut stacking_context_tree.compositor_info;
|
let paint_info = &mut stacking_context_tree.paint_info;
|
||||||
let pipeline_id = compositor_info.pipeline_id;
|
let pipeline_id = paint_info.pipeline_id;
|
||||||
let mut webrender_display_list_builder =
|
let mut webrender_display_list_builder =
|
||||||
webrender_api::DisplayListBuilder::new(pipeline_id);
|
webrender_api::DisplayListBuilder::new(pipeline_id);
|
||||||
webrender_display_list_builder.begin();
|
webrender_display_list_builder.begin();
|
||||||
@@ -192,11 +192,11 @@ impl DisplayListBuilder<'_> {
|
|||||||
|
|
||||||
let _span = profile_traits::trace_span!("DisplayListBuilder::build").entered();
|
let _span = profile_traits::trace_span!("DisplayListBuilder::build").entered();
|
||||||
let mut builder = DisplayListBuilder {
|
let mut builder = DisplayListBuilder {
|
||||||
current_scroll_node_id: compositor_info.root_reference_frame_id,
|
current_scroll_node_id: paint_info.root_reference_frame_id,
|
||||||
current_reference_frame_scroll_node_id: compositor_info.root_reference_frame_id,
|
current_reference_frame_scroll_node_id: paint_info.root_reference_frame_id,
|
||||||
current_clip_id: ClipId::INVALID,
|
current_clip_id: ClipId::INVALID,
|
||||||
webrender_display_list_builder: &mut webrender_display_list_builder,
|
webrender_display_list_builder: &mut webrender_display_list_builder,
|
||||||
compositor_info,
|
paint_info,
|
||||||
inspector_highlight: highlighted_dom_node.map(InspectorHighlight::for_node),
|
inspector_highlight: highlighted_dom_node.map(InspectorHighlight::for_node),
|
||||||
paint_body_background: true,
|
paint_body_background: true,
|
||||||
clip_map: Default::default(),
|
clip_map: Default::default(),
|
||||||
@@ -213,8 +213,8 @@ impl DisplayListBuilder<'_> {
|
|||||||
|
|
||||||
// Add a single hit test that covers the entire viewport, so that WebRender knows
|
// Add a single hit test that covers the entire viewport, so that WebRender knows
|
||||||
// which pipeline it hits when doing hit testing.
|
// which pipeline it hits when doing hit testing.
|
||||||
let pipeline_id = builder.compositor_info.pipeline_id;
|
let pipeline_id = builder.paint_info.pipeline_id;
|
||||||
let viewport_size = builder.compositor_info.viewport_details.size;
|
let viewport_size = builder.paint_info.viewport_details.size;
|
||||||
let viewport_rect = LayoutRect::from_size(viewport_size.cast_unit());
|
let viewport_rect = LayoutRect::from_size(viewport_size.cast_unit());
|
||||||
builder.wr().push_hit_test(
|
builder.wr().push_hit_test(
|
||||||
viewport_rect,
|
viewport_rect,
|
||||||
@@ -241,15 +241,15 @@ impl DisplayListBuilder<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn pipeline_id(&mut self) -> wr::PipelineId {
|
fn pipeline_id(&mut self) -> wr::PipelineId {
|
||||||
self.compositor_info.pipeline_id
|
self.paint_info.pipeline_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_is_contentful(&mut self) {
|
fn mark_is_contentful(&mut self) {
|
||||||
self.compositor_info.is_contentful = true;
|
self.paint_info.is_contentful = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spatial_id(&self, id: ScrollTreeNodeId) -> SpatialId {
|
fn spatial_id(&self, id: ScrollTreeNodeId) -> SpatialId {
|
||||||
self.compositor_info.scroll_tree.webrender_id(id)
|
self.paint_info.scroll_tree.webrender_id(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clip_chain_id(&self, id: ClipId) -> ClipChainId {
|
fn clip_chain_id(&self, id: ClipId) -> ClipChainId {
|
||||||
@@ -267,7 +267,7 @@ impl DisplayListBuilder<'_> {
|
|||||||
// list. This is merely to ensure that the currently-unused SpatialTreeItemKey
|
// list. This is merely to ensure that the currently-unused SpatialTreeItemKey
|
||||||
// produced for every SpatialTree node is unique.
|
// produced for every SpatialTree node is unique.
|
||||||
let mut spatial_tree_count = 0;
|
let mut spatial_tree_count = 0;
|
||||||
let mut scroll_tree = std::mem::take(&mut self.compositor_info.scroll_tree);
|
let mut scroll_tree = std::mem::take(&mut self.paint_info.scroll_tree);
|
||||||
let mut mapping = Vec::with_capacity(scroll_tree.nodes.len());
|
let mut mapping = Vec::with_capacity(scroll_tree.nodes.len());
|
||||||
|
|
||||||
mapping.push(SpatialId::root_reference_frame(self.pipeline_id()));
|
mapping.push(SpatialId::root_reference_frame(self.pipeline_id()));
|
||||||
@@ -330,7 +330,7 @@ impl DisplayListBuilder<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scroll_tree.update_mapping(mapping);
|
scroll_tree.update_mapping(mapping);
|
||||||
self.compositor_info.scroll_tree = scroll_tree;
|
self.paint_info.scroll_tree = scroll_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the given [`Clip`] to the WebRender display list and create a mapping from
|
/// Add the given [`Clip`] to the WebRender display list and create a mapping from
|
||||||
@@ -532,7 +532,7 @@ impl DisplayListBuilder<'_> {
|
|||||||
) {
|
) {
|
||||||
if let Some(lcp_collector) = &mut self.lcp_candidate_collector {
|
if let Some(lcp_collector) = &mut self.lcp_candidate_collector {
|
||||||
let transform = self
|
let transform = self
|
||||||
.compositor_info
|
.paint_info
|
||||||
.scroll_tree
|
.scroll_tree
|
||||||
.cumulative_node_to_root_transform(self.current_scroll_node_id);
|
.cumulative_node_to_root_transform(self.current_scroll_node_id);
|
||||||
lcp_collector.add_or_update_candidate(
|
lcp_collector.add_or_update_candidate(
|
||||||
@@ -1137,7 +1137,7 @@ impl<'a> BuilderForBoxFragment<'a> {
|
|||||||
|
|
||||||
fn build_hit_test(&self, builder: &mut DisplayListBuilder, rect: LayoutRect) {
|
fn build_hit_test(&self, builder: &mut DisplayListBuilder, rect: LayoutRect) {
|
||||||
let external_scroll_node_id = builder
|
let external_scroll_node_id = builder
|
||||||
.compositor_info
|
.paint_info
|
||||||
.external_scroll_id_for_scroll_tree_node(builder.current_scroll_node_id);
|
.external_scroll_id_for_scroll_tree_node(builder.current_scroll_node_id);
|
||||||
|
|
||||||
let mut common = builder.common_properties(rect, &self.fragment.style);
|
let mut common = builder.common_properties(rect, &self.fragment.style);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use app_units::Au;
|
|||||||
use base::id::ScrollTreeNodeId;
|
use base::id::ScrollTreeNodeId;
|
||||||
use base::print_tree::PrintTree;
|
use base::print_tree::PrintTree;
|
||||||
use compositing_traits::display_list::{
|
use compositing_traits::display_list::{
|
||||||
AxesScrollSensitivity, CompositorDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo,
|
AxesScrollSensitivity, PaintDisplayListInfo, ReferenceFrameNodeInfo, ScrollableNodeInfo,
|
||||||
SpatialTreeNodeInfo, StickyNodeInfo,
|
SpatialTreeNodeInfo, StickyNodeInfo,
|
||||||
};
|
};
|
||||||
use embedder_traits::ViewportDetails;
|
use embedder_traits::ViewportDetails;
|
||||||
@@ -106,11 +106,11 @@ pub(crate) struct StackingContextTree {
|
|||||||
/// The root stacking context of this [`StackingContextTree`].
|
/// The root stacking context of this [`StackingContextTree`].
|
||||||
pub root_stacking_context: StackingContext,
|
pub root_stacking_context: StackingContext,
|
||||||
|
|
||||||
/// The information about the WebRender display list that the compositor
|
/// The information about the WebRender display list that `Paint`
|
||||||
/// consumes. This curerntly contains the out-of-band hit testing information
|
/// consumes. This curerntly contains the out-of-band hit testing information
|
||||||
/// data structure that the compositor uses to map hit tests to information
|
/// data structure that `Paint` uses to map hit tests to information
|
||||||
/// about the item hit.
|
/// about the item hit.
|
||||||
pub compositor_info: CompositorDisplayListInfo,
|
pub paint_info: PaintDisplayListInfo,
|
||||||
|
|
||||||
/// All of the clips collected for this [`StackingContextTree`]. These are added
|
/// All of the clips collected for this [`StackingContextTree`]. These are added
|
||||||
/// for things like `overflow`. More clips may be created later during WebRender
|
/// for things like `overflow`. More clips may be created later during WebRender
|
||||||
@@ -135,7 +135,7 @@ impl StackingContextTree {
|
|||||||
));
|
));
|
||||||
|
|
||||||
let viewport_size = viewport_details.layout_size();
|
let viewport_size = viewport_details.layout_size();
|
||||||
let compositor_info = CompositorDisplayListInfo::new(
|
let paint_info = PaintDisplayListInfo::new(
|
||||||
viewport_details,
|
viewport_details,
|
||||||
scrollable_overflow,
|
scrollable_overflow,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
@@ -145,7 +145,7 @@ impl StackingContextTree {
|
|||||||
first_reflow,
|
first_reflow,
|
||||||
);
|
);
|
||||||
|
|
||||||
let root_scroll_node_id = compositor_info.root_scroll_node_id;
|
let root_scroll_node_id = paint_info.root_scroll_node_id;
|
||||||
let cb_for_non_fixed_descendants = ContainingBlock::new(
|
let cb_for_non_fixed_descendants = ContainingBlock::new(
|
||||||
fragment_tree.initial_containing_block,
|
fragment_tree.initial_containing_block,
|
||||||
root_scroll_node_id,
|
root_scroll_node_id,
|
||||||
@@ -154,7 +154,7 @@ impl StackingContextTree {
|
|||||||
);
|
);
|
||||||
let cb_for_fixed_descendants = ContainingBlock::new(
|
let cb_for_fixed_descendants = ContainingBlock::new(
|
||||||
fragment_tree.initial_containing_block,
|
fragment_tree.initial_containing_block,
|
||||||
compositor_info.root_reference_frame_id,
|
paint_info.root_reference_frame_id,
|
||||||
None,
|
None,
|
||||||
ClipId::INVALID,
|
ClipId::INVALID,
|
||||||
);
|
);
|
||||||
@@ -174,7 +174,7 @@ impl StackingContextTree {
|
|||||||
let mut stacking_context_tree = Self {
|
let mut stacking_context_tree = Self {
|
||||||
// This is just a temporary value that will be replaced once we have finished building the tree.
|
// This is just a temporary value that will be replaced once we have finished building the tree.
|
||||||
root_stacking_context: StackingContext::create_root(root_scroll_node_id, debug),
|
root_stacking_context: StackingContext::create_root(root_scroll_node_id, debug),
|
||||||
compositor_info,
|
paint_info,
|
||||||
clip_store: Default::default(),
|
clip_store: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ impl StackingContextTree {
|
|||||||
transform: LayoutTransform,
|
transform: LayoutTransform,
|
||||||
kind: wr::ReferenceFrameKind,
|
kind: wr::ReferenceFrameKind,
|
||||||
) -> ScrollTreeNodeId {
|
) -> ScrollTreeNodeId {
|
||||||
self.compositor_info.scroll_tree.add_scroll_tree_node(
|
self.paint_info.scroll_tree.add_scroll_tree_node(
|
||||||
Some(parent_scroll_node_id),
|
Some(parent_scroll_node_id),
|
||||||
SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo {
|
SpatialTreeNodeInfo::ReferenceFrame(ReferenceFrameNodeInfo {
|
||||||
origin,
|
origin,
|
||||||
@@ -229,7 +229,7 @@ impl StackingContextTree {
|
|||||||
clip_rect: LayoutRect,
|
clip_rect: LayoutRect,
|
||||||
scroll_sensitivity: AxesScrollSensitivity,
|
scroll_sensitivity: AxesScrollSensitivity,
|
||||||
) -> ScrollTreeNodeId {
|
) -> ScrollTreeNodeId {
|
||||||
self.compositor_info.scroll_tree.add_scroll_tree_node(
|
self.paint_info.scroll_tree.add_scroll_tree_node(
|
||||||
Some(parent_scroll_node_id),
|
Some(parent_scroll_node_id),
|
||||||
SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo {
|
SpatialTreeNodeInfo::Scroll(ScrollableNodeInfo {
|
||||||
external_id,
|
external_id,
|
||||||
@@ -250,7 +250,7 @@ impl StackingContextTree {
|
|||||||
vertical_offset_bounds: StickyOffsetBounds,
|
vertical_offset_bounds: StickyOffsetBounds,
|
||||||
horizontal_offset_bounds: StickyOffsetBounds,
|
horizontal_offset_bounds: StickyOffsetBounds,
|
||||||
) -> ScrollTreeNodeId {
|
) -> ScrollTreeNodeId {
|
||||||
self.compositor_info.scroll_tree.add_scroll_tree_node(
|
self.paint_info.scroll_tree.add_scroll_tree_node(
|
||||||
Some(parent_scroll_node_id),
|
Some(parent_scroll_node_id),
|
||||||
SpatialTreeNodeInfo::Sticky(StickyNodeInfo {
|
SpatialTreeNodeInfo::Sticky(StickyNodeInfo {
|
||||||
frame_rect,
|
frame_rect,
|
||||||
@@ -1505,7 +1505,7 @@ impl BoxFragment {
|
|||||||
let tag = self.base.tag?;
|
let tag = self.base.tag?;
|
||||||
let external_scroll_id = wr::ExternalScrollId(
|
let external_scroll_id = wr::ExternalScrollId(
|
||||||
tag.to_display_list_fragment_id(),
|
tag.to_display_list_fragment_id(),
|
||||||
stacking_context_tree.compositor_info.pipeline_id,
|
stacking_context_tree.paint_info.pipeline_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
let sensitivity = AxesScrollSensitivity {
|
let sensitivity = AxesScrollSensitivity {
|
||||||
@@ -1546,7 +1546,7 @@ impl BoxFragment {
|
|||||||
None => {
|
None => {
|
||||||
// This is a direct descendant of a reference frame.
|
// This is a direct descendant of a reference frame.
|
||||||
&stacking_context_tree
|
&stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.viewport_details
|
.viewport_details
|
||||||
.layout_size()
|
.layout_size()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use app_units::Au;
|
|||||||
use base::generic_channel::GenericSender;
|
use base::generic_channel::GenericSender;
|
||||||
use base::id::{PipelineId, WebViewId};
|
use base::id::{PipelineId, WebViewId};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use compositing_traits::display_list::ScrollType;
|
use compositing_traits::display_list::ScrollType;
|
||||||
use cssparser::ParserInput;
|
use cssparser::ParserInput;
|
||||||
use embedder_traits::{Theme, ViewportDetails};
|
use embedder_traits::{Theme, ViewportDetails};
|
||||||
@@ -192,8 +192,8 @@ pub struct LayoutThread {
|
|||||||
/// The executors for paint worklets.
|
/// The executors for paint worklets.
|
||||||
registered_painters: RegisteredPaintersImpl,
|
registered_painters: RegisteredPaintersImpl,
|
||||||
|
|
||||||
/// Cross-process access to the Compositor API.
|
/// Cross-process access to the `Paint` API.
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
|
|
||||||
/// Debug options, copied from configuration to this `LayoutThread` in order
|
/// Debug options, copied from configuration to this `LayoutThread` in order
|
||||||
/// to avoid having to constantly access the thread-safe global options.
|
/// to avoid having to constantly access the thread-safe global options.
|
||||||
@@ -221,11 +221,8 @@ impl Drop for LayoutThread {
|
|||||||
let (keys, instance_keys) = self
|
let (keys, instance_keys) = self
|
||||||
.font_context
|
.font_context
|
||||||
.collect_unused_webrender_resources(true /* all */);
|
.collect_unused_webrender_resources(true /* all */);
|
||||||
self.compositor_api.remove_unused_font_resources(
|
self.paint_api
|
||||||
self.webview_id.into(),
|
.remove_unused_font_resources(self.webview_id.into(), keys, instance_keys)
|
||||||
keys,
|
|
||||||
instance_keys,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +389,7 @@ impl Layout for LayoutThread {
|
|||||||
let stacking_context_tree = stacking_context_tree
|
let stacking_context_tree = stacking_context_tree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("Should always have a StackingContextTree for offset parent queries");
|
.expect("Should always have a StackingContextTree for offset parent queries");
|
||||||
process_offset_parent_query(&stacking_context_tree.compositor_info.scroll_tree, node)
|
process_offset_parent_query(&stacking_context_tree.paint_info.scroll_tree, node)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,7 +597,7 @@ impl Layout for LayoutThread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
stacking_context_tree
|
stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.scroll_tree
|
.scroll_tree
|
||||||
.set_all_scroll_offsets(scroll_states);
|
.set_all_scroll_offsets(scroll_states);
|
||||||
}
|
}
|
||||||
@@ -609,7 +606,7 @@ impl Layout for LayoutThread {
|
|||||||
self.stacking_context_tree
|
self.stacking_context_tree
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.and_then(|tree| tree.compositor_info.scroll_tree.scroll_offset(id))
|
.and_then(|tree| tree.paint_info.scroll_tree.scroll_offset(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn needs_new_display_list(&self) -> bool {
|
fn needs_new_display_list(&self) -> bool {
|
||||||
@@ -711,7 +708,7 @@ impl LayoutThread {
|
|||||||
fn new(config: LayoutConfig) -> LayoutThread {
|
fn new(config: LayoutConfig) -> LayoutThread {
|
||||||
// Let webrender know about this pipeline by sending an empty display list.
|
// Let webrender know about this pipeline by sending an empty display list.
|
||||||
config
|
config
|
||||||
.compositor_api
|
.paint_api
|
||||||
.send_initial_transaction(config.webview_id, config.id.into());
|
.send_initial_transaction(config.webview_id, config.id.into());
|
||||||
|
|
||||||
let mut font = Font::initial_values();
|
let mut font = Font::initial_values();
|
||||||
@@ -753,7 +750,7 @@ impl LayoutThread {
|
|||||||
box_tree: Default::default(),
|
box_tree: Default::default(),
|
||||||
fragment_tree: Default::default(),
|
fragment_tree: Default::default(),
|
||||||
stacking_context_tree: Default::default(),
|
stacking_context_tree: Default::default(),
|
||||||
compositor_api: config.compositor_api,
|
paint_api: config.paint_api,
|
||||||
stylist: Stylist::new(device, QuirksMode::NoQuirks),
|
stylist: Stylist::new(device, QuirksMode::NoQuirks),
|
||||||
resolved_images_cache: Default::default(),
|
resolved_images_cache: Default::default(),
|
||||||
debug: opts::get().debug.clone(),
|
debug: opts::get().debug.clone(),
|
||||||
@@ -1222,7 +1219,7 @@ impl LayoutThread {
|
|||||||
let mut stacking_context_tree = self.stacking_context_tree.borrow_mut();
|
let mut stacking_context_tree = self.stacking_context_tree.borrow_mut();
|
||||||
let old_scroll_offsets = stacking_context_tree
|
let old_scroll_offsets = stacking_context_tree
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|tree| tree.compositor_info.scroll_tree.scroll_offsets());
|
.map(|tree| tree.paint_info.scroll_tree.scroll_offsets());
|
||||||
|
|
||||||
// Build the StackingContextTree. This turns the `FragmentTree` into a
|
// Build the StackingContextTree. This turns the `FragmentTree` into a
|
||||||
// tree of fragments in CSS painting order and also creates all
|
// tree of fragments in CSS painting order and also creates all
|
||||||
@@ -1240,14 +1237,14 @@ impl LayoutThread {
|
|||||||
// adjusted by any new scroll constraints.
|
// adjusted by any new scroll constraints.
|
||||||
if let Some(old_scroll_offsets) = old_scroll_offsets {
|
if let Some(old_scroll_offsets) = old_scroll_offsets {
|
||||||
new_stacking_context_tree
|
new_stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.scroll_tree
|
.scroll_tree
|
||||||
.set_all_scroll_offsets(&old_scroll_offsets);
|
.set_all_scroll_offsets(&old_scroll_offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.debug.scroll_tree {
|
if self.debug.scroll_tree {
|
||||||
new_stacking_context_tree
|
new_stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.scroll_tree
|
.scroll_tree
|
||||||
.debug_print();
|
.debug_print();
|
||||||
}
|
}
|
||||||
@@ -1289,9 +1286,9 @@ impl LayoutThread {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Eventually this should be set when `compositor_info` is created, but that requires
|
// TODO: Eventually this should be set when `paint_info` is created, but that requires
|
||||||
// ensuring that the Epoch is passed to any method that can creates `StackingContextTree`.
|
// ensuring that the Epoch is passed to any method that can creates `StackingContextTree`.
|
||||||
stacking_context_tree.compositor_info.epoch = reflow_request.epoch;
|
stacking_context_tree.paint_info.epoch = reflow_request.epoch;
|
||||||
|
|
||||||
let mut lcp_candidate_collector = self.lcp_candidate_collector.borrow_mut();
|
let mut lcp_candidate_collector = self.lcp_candidate_collector.borrow_mut();
|
||||||
if pref!(largest_contentful_paint_enabled) {
|
if pref!(largest_contentful_paint_enabled) {
|
||||||
@@ -1299,7 +1296,7 @@ impl LayoutThread {
|
|||||||
if lcp_candidate_collector.is_none() {
|
if lcp_candidate_collector.is_none() {
|
||||||
*lcp_candidate_collector = Some(LargestContentfulPaintCandidateCollector::new(
|
*lcp_candidate_collector = Some(LargestContentfulPaintCandidateCollector::new(
|
||||||
stacking_context_tree
|
stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.viewport_details
|
.viewport_details
|
||||||
.layout_size(),
|
.layout_size(),
|
||||||
));
|
));
|
||||||
@@ -1317,19 +1314,19 @@ impl LayoutThread {
|
|||||||
&self.debug,
|
&self.debug,
|
||||||
lcp_candidate_collector.as_mut(),
|
lcp_candidate_collector.as_mut(),
|
||||||
);
|
);
|
||||||
self.compositor_api.send_display_list(
|
self.paint_api.send_display_list(
|
||||||
self.webview_id,
|
self.webview_id,
|
||||||
&stacking_context_tree.compositor_info,
|
&stacking_context_tree.paint_info,
|
||||||
built_display_list,
|
built_display_list,
|
||||||
);
|
);
|
||||||
if let Some(lcp_candidate_collector) = lcp_candidate_collector.as_mut() {
|
if let Some(lcp_candidate_collector) = lcp_candidate_collector.as_mut() {
|
||||||
if lcp_candidate_collector.did_lcp_candidate_update {
|
if lcp_candidate_collector.did_lcp_candidate_update {
|
||||||
if let Some(lcp_candidate) = lcp_candidate_collector.largest_contentful_paint() {
|
if let Some(lcp_candidate) = lcp_candidate_collector.largest_contentful_paint() {
|
||||||
self.compositor_api.send_lcp_candidate(
|
self.paint_api.send_lcp_candidate(
|
||||||
lcp_candidate,
|
lcp_candidate,
|
||||||
self.webview_id,
|
self.webview_id,
|
||||||
self.id,
|
self.id,
|
||||||
stacking_context_tree.compositor_info.epoch,
|
stacking_context_tree.paint_info.epoch,
|
||||||
);
|
);
|
||||||
lcp_candidate_collector.did_lcp_candidate_update = false;
|
lcp_candidate_collector.did_lcp_candidate_update = false;
|
||||||
}
|
}
|
||||||
@@ -1339,11 +1336,8 @@ impl LayoutThread {
|
|||||||
let (keys, instance_keys) = self
|
let (keys, instance_keys) = self
|
||||||
.font_context
|
.font_context
|
||||||
.collect_unused_webrender_resources(false /* all */);
|
.collect_unused_webrender_resources(false /* all */);
|
||||||
self.compositor_api.remove_unused_font_resources(
|
self.paint_api
|
||||||
self.webview_id.into(),
|
.remove_unused_font_resources(self.webview_id.into(), keys, instance_keys);
|
||||||
keys,
|
|
||||||
instance_keys,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.have_ever_generated_display_list.set(true);
|
self.have_ever_generated_display_list.set(true);
|
||||||
self.need_new_display_list.set(false);
|
self.need_new_display_list.set(false);
|
||||||
@@ -1363,7 +1357,7 @@ impl LayoutThread {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(offset) = stacking_context_tree
|
if let Some(offset) = stacking_context_tree
|
||||||
.compositor_info
|
.paint_info
|
||||||
.scroll_tree
|
.scroll_tree
|
||||||
.set_scroll_offset_for_node_with_external_scroll_id(
|
.set_scroll_offset_for_node_with_external_scroll_id(
|
||||||
external_scroll_id,
|
external_scroll_id,
|
||||||
@@ -1371,7 +1365,7 @@ impl LayoutThread {
|
|||||||
ScrollType::Script,
|
ScrollType::Script,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
self.compositor_api.scroll_node_by_delta(
|
self.paint_api.scroll_node_by_delta(
|
||||||
self.webview_id,
|
self.webview_id,
|
||||||
self.id.into(),
|
self.id.into(),
|
||||||
offset,
|
offset,
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ pub(crate) fn process_box_area_request(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let Some(transform) =
|
let Some(transform) =
|
||||||
root_transform_for_layout_node(&stacking_context_tree.compositor_info.scroll_tree, node)
|
root_transform_for_layout_node(&stacking_context_tree.paint_info.scroll_tree, node)
|
||||||
else {
|
else {
|
||||||
return Some(Rect::new(rect_union.origin, Size2D::zero()));
|
return Some(Rect::new(rect_union.origin, Size2D::zero()));
|
||||||
};
|
};
|
||||||
@@ -136,7 +136,7 @@ pub(crate) fn process_box_areas_request(
|
|||||||
.map(|rect| rect.to_untyped());
|
.map(|rect| rect.to_untyped());
|
||||||
|
|
||||||
let Some(transform) =
|
let Some(transform) =
|
||||||
root_transform_for_layout_node(&stacking_context_tree.compositor_info.scroll_tree, node)
|
root_transform_for_layout_node(&stacking_context_tree.paint_info.scroll_tree, node)
|
||||||
else {
|
else {
|
||||||
return box_areas
|
return box_areas
|
||||||
.map(|rect| Rect::new(rect.origin, Size2D::zero()))
|
.map(|rect| Rect::new(rect.origin, Size2D::zero()))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use std::{mem, thread};
|
|||||||
|
|
||||||
use base::id::{PipelineId, WebViewId};
|
use base::id::{PipelineId, WebViewId};
|
||||||
use base::threadpool::ThreadPool;
|
use base::threadpool::ThreadPool;
|
||||||
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
|
use compositing_traits::{CrossProcessPaintApi, ImageUpdate, SerializableImageData};
|
||||||
use imsz::imsz_from_reader;
|
use imsz::imsz_from_reader;
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf as MallocSizeOfTrait, MallocSizeOfOps};
|
||||||
@@ -121,7 +121,7 @@ fn decode_bytes_sync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_webrender_image_key(
|
fn set_webrender_image_key(
|
||||||
compositor_api: &CrossProcessCompositorApi,
|
paint_api: &CrossProcessPaintApi,
|
||||||
image: &mut RasterImage,
|
image: &mut RasterImage,
|
||||||
image_key: WebRenderImageKey,
|
image_key: WebRenderImageKey,
|
||||||
) {
|
) {
|
||||||
@@ -132,7 +132,7 @@ fn set_webrender_image_key(
|
|||||||
let (descriptor, ipc_shared_memory) = image.webrender_image_descriptor_and_data_for_frame(0);
|
let (descriptor, ipc_shared_memory) = image.webrender_image_descriptor_and_data_for_frame(0);
|
||||||
let data = SerializableImageData::Raw(ipc_shared_memory);
|
let data = SerializableImageData::Raw(ipc_shared_memory);
|
||||||
|
|
||||||
compositor_api.add_image(image_key, descriptor, data);
|
paint_api.add_image(image_key, descriptor, data);
|
||||||
image.id = Some(image_key);
|
image.id = Some(image_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,9 +461,9 @@ struct ImageCacheStore {
|
|||||||
#[conditional_malloc_size_of]
|
#[conditional_malloc_size_of]
|
||||||
broken_image_icon_image: OnceCell<Option<Arc<RasterImage>>>,
|
broken_image_icon_image: OnceCell<Option<Arc<RasterImage>>>,
|
||||||
|
|
||||||
/// Cross-process compositor API instance.
|
/// Cross-process `Paint` API instance.
|
||||||
#[ignore_malloc_size_of = "Channel from another crate"]
|
#[ignore_malloc_size_of = "Channel from another crate"]
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
|
|
||||||
/// The [`WebView`] of the `Webview` associated with this [`ImageCache`].
|
/// The [`WebView`] of the `Webview` associated with this [`ImageCache`].
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
@@ -481,11 +481,11 @@ impl ImageCacheStore {
|
|||||||
fn set_key_and_finish_load(&mut self, pending_image: PendingKey, image_key: WebRenderImageKey) {
|
fn set_key_and_finish_load(&mut self, pending_image: PendingKey, image_key: WebRenderImageKey) {
|
||||||
match pending_image {
|
match pending_image {
|
||||||
PendingKey::RasterImage((pending_id, mut raster_image)) => {
|
PendingKey::RasterImage((pending_id, mut raster_image)) => {
|
||||||
set_webrender_image_key(&self.compositor_api, &mut raster_image, image_key);
|
set_webrender_image_key(&self.paint_api, &mut raster_image, image_key);
|
||||||
self.complete_load(pending_id, LoadResult::LoadedRasterImage(raster_image));
|
self.complete_load(pending_id, LoadResult::LoadedRasterImage(raster_image));
|
||||||
},
|
},
|
||||||
PendingKey::Svg((pending_id, mut raster_image, requested_size)) => {
|
PendingKey::Svg((pending_id, mut raster_image, requested_size)) => {
|
||||||
set_webrender_image_key(&self.compositor_api, &mut raster_image, image_key);
|
set_webrender_image_key(&self.paint_api, &mut raster_image, image_key);
|
||||||
self.complete_load_svg(raster_image, pending_id, requested_size);
|
self.complete_load_svg(raster_image, pending_id, requested_size);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -512,7 +512,7 @@ impl ImageCacheStore {
|
|||||||
|
|
||||||
fn fetch_more_image_keys(&mut self) {
|
fn fetch_more_image_keys(&mut self) {
|
||||||
self.key_cache.cache = KeyCacheState::PendingBatch;
|
self.key_cache.cache = KeyCacheState::PendingBatch;
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.generate_image_key_async(self.webview_id, self.pipeline_id);
|
.generate_image_key_async(self.webview_id, self.pipeline_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,7 +533,7 @@ impl ImageCacheStore {
|
|||||||
self.load_image_with_keycache(key);
|
self.load_image_with_keycache(key);
|
||||||
}
|
}
|
||||||
if !self.key_cache.images_pending_keys.is_empty() {
|
if !self.key_cache.images_pending_keys.is_empty() {
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.generate_image_key_async(self.webview_id, self.pipeline_id);
|
.generate_image_key_async(self.webview_id, self.pipeline_id);
|
||||||
self.key_cache.cache = KeyCacheState::PendingBatch
|
self.key_cache.cache = KeyCacheState::PendingBatch
|
||||||
}
|
}
|
||||||
@@ -689,7 +689,7 @@ impl ImageCacheFactory for ImageCacheFactoryImpl {
|
|||||||
&self,
|
&self,
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
compositor_api: &CrossProcessCompositorApi,
|
paint_api: &CrossProcessPaintApi,
|
||||||
) -> Arc<dyn ImageCache> {
|
) -> Arc<dyn ImageCache> {
|
||||||
Arc::new(ImageCacheImpl {
|
Arc::new(ImageCacheImpl {
|
||||||
store: Arc::new(Mutex::new(ImageCacheStore {
|
store: Arc::new(Mutex::new(ImageCacheStore {
|
||||||
@@ -698,7 +698,7 @@ impl ImageCacheFactory for ImageCacheFactoryImpl {
|
|||||||
vector_images: FxHashMap::default(),
|
vector_images: FxHashMap::default(),
|
||||||
rasterized_vector_images: FxHashMap::default(),
|
rasterized_vector_images: FxHashMap::default(),
|
||||||
broken_image_icon_image: OnceCell::new(),
|
broken_image_icon_image: OnceCell::new(),
|
||||||
compositor_api: compositor_api.clone(),
|
paint_api: paint_api.clone(),
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
webview_id,
|
webview_id,
|
||||||
key_cache: KeyCache::new(),
|
key_cache: KeyCache::new(),
|
||||||
@@ -744,7 +744,7 @@ impl ImageCache for ImageCacheImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
store
|
store
|
||||||
.compositor_api
|
.paint_api
|
||||||
.generate_image_key_blocking(store.webview_id)
|
.generate_image_key_blocking(store.webview_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1073,10 +1073,10 @@ impl ImageCache for ImageCacheImpl {
|
|||||||
let mut image = load_from_memory(&self.broken_image_icon_data, CorsStatus::Unsafe)
|
let mut image = load_from_memory(&self.broken_image_icon_data, CorsStatus::Unsafe)
|
||||||
.or_else(|| load_from_memory(FALLBACK_RIPPY, CorsStatus::Unsafe))?;
|
.or_else(|| load_from_memory(FALLBACK_RIPPY, CorsStatus::Unsafe))?;
|
||||||
let image_key = store
|
let image_key = store
|
||||||
.compositor_api
|
.paint_api
|
||||||
.generate_image_key_blocking(store.webview_id)
|
.generate_image_key_blocking(store.webview_id)
|
||||||
.expect("Could not generate image key for broken image icon");
|
.expect("Could not generate image key for broken image icon");
|
||||||
set_webrender_image_key(&store.compositor_api, &mut image, image_key);
|
set_webrender_image_key(&store.paint_api, &mut image, image_key);
|
||||||
Some(Arc::new(image))
|
Some(Arc::new(image))
|
||||||
})
|
})
|
||||||
.clone()
|
.clone()
|
||||||
@@ -1100,7 +1100,7 @@ impl Drop for ImageCacheStore {
|
|||||||
.filter_map(|task| task.result.as_ref()?.id.map(ImageUpdate::DeleteImage)),
|
.filter_map(|task| task.result.as_ref()?.id.map(ImageUpdate::DeleteImage)),
|
||||||
)
|
)
|
||||||
.collect();
|
.collect();
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.update_images(self.webview_id.into(), image_updates);
|
.update_images(self.webview_id.into(), image_updates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::sync::Arc;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use base::id::{PipelineId, TEST_PIPELINE_ID, TEST_WEBVIEW_ID};
|
use base::id::{PipelineId, TEST_PIPELINE_ID, TEST_WEBVIEW_ID};
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use crossbeam_channel::{Receiver, Sender, unbounded};
|
use crossbeam_channel::{Receiver, Sender, unbounded};
|
||||||
use net::image_cache::ImageCacheFactoryImpl;
|
use net::image_cache::ImageCacheFactoryImpl;
|
||||||
use net_traits::image_cache::{
|
use net_traits::image_cache::{
|
||||||
@@ -26,17 +26,15 @@ use crate::mock_origin;
|
|||||||
|
|
||||||
fn create_test_image_cache() -> (Arc<dyn ImageCache>, Receiver<PipelineId>) {
|
fn create_test_image_cache() -> (Arc<dyn ImageCache>, Receiver<PipelineId>) {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
let compositor_api =
|
let paint_api = CrossProcessPaintApi::dummy_with_callback(Some(Box::new(move |msg| {
|
||||||
CrossProcessCompositorApi::dummy_with_callback(Some(Box::new(move |msg| {
|
if let compositing_traits::PaintMessage::GenerateImageKeysForPipeline(_, pipeline_id) = msg
|
||||||
if let compositing_traits::CompositorMsg::GenerateImageKeysForPipeline(_, pipeline_id) =
|
{
|
||||||
msg
|
let _ = sender.send(pipeline_id);
|
||||||
{
|
}
|
||||||
let _ = sender.send(pipeline_id);
|
})));
|
||||||
}
|
|
||||||
})));
|
|
||||||
|
|
||||||
let factory = ImageCacheFactoryImpl::new(vec![]);
|
let factory = ImageCacheFactoryImpl::new(vec![]);
|
||||||
let cache = factory.create(TEST_WEBVIEW_ID, TEST_PIPELINE_ID, &compositor_api);
|
let cache = factory.create(TEST_WEBVIEW_ID, TEST_PIPELINE_ID, &paint_api);
|
||||||
(cache, receiver)
|
(cache, receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ pub(crate) struct Document {
|
|||||||
/// Whether we're in the process of running animation callbacks.
|
/// Whether we're in the process of running animation callbacks.
|
||||||
///
|
///
|
||||||
/// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid
|
/// Tracking this is not necessary for correctness. Instead, it is an optimization to avoid
|
||||||
/// sending needless `ChangeRunningAnimationsState` messages to the compositor.
|
/// sending needless `ChangeRunningAnimationsState` messages to `Paint`.
|
||||||
running_animation_callbacks: Cell<bool>,
|
running_animation_callbacks: Cell<bool>,
|
||||||
/// Tracks all outstanding loads related to this document.
|
/// Tracks all outstanding loads related to this document.
|
||||||
loader: DomRefCell<DocumentLoader>,
|
loader: DomRefCell<DocumentLoader>,
|
||||||
@@ -2801,7 +2801,7 @@ impl Document {
|
|||||||
if !image_keys.is_empty() {
|
if !image_keys.is_empty() {
|
||||||
results.insert(ReflowPhasesRun::UpdatedImageData);
|
results.insert(ReflowPhasesRun::UpdatedImageData);
|
||||||
self.waiting_on_canvas_image_updates.set(true);
|
self.waiting_on_canvas_image_updates.set(true);
|
||||||
self.window().compositor_api().delay_new_frame_for_canvas(
|
self.window().paint_api().delay_new_frame_for_canvas(
|
||||||
self.webview_id(),
|
self.webview_id(),
|
||||||
self.window().pipeline_id(),
|
self.window().pipeline_id(),
|
||||||
current_rendering_epoch,
|
current_rendering_epoch,
|
||||||
@@ -2811,7 +2811,7 @@ impl Document {
|
|||||||
|
|
||||||
let results = results.union(self.window().reflow(ReflowGoal::UpdateTheRendering));
|
let results = results.union(self.window().reflow(ReflowGoal::UpdateTheRendering));
|
||||||
|
|
||||||
self.window().compositor_api().update_epoch(
|
self.window().paint_api().update_epoch(
|
||||||
self.webview_id(),
|
self.webview_id(),
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
current_rendering_epoch,
|
current_rendering_epoch,
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ pub(crate) struct DocumentEventHandler {
|
|||||||
window: Dom<Window>,
|
window: Dom<Window>,
|
||||||
/// Pending input events, to be handled at the next rendering opportunity.
|
/// Pending input events, to be handled at the next rendering opportunity.
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
#[ignore_malloc_size_of = "CompositorEvent contains data from outside crates"]
|
#[ignore_malloc_size_of = "InputEvent contains data from outside crates"]
|
||||||
pending_input_events: DomRefCell<Vec<ConstellationInputEvent>>,
|
pending_input_events: DomRefCell<Vec<ConstellationInputEvent>>,
|
||||||
/// The index of the last mouse move event in the pending compositor events queue.
|
/// The index of the last mouse move event in the pending input events queue.
|
||||||
mouse_move_event_index: DomRefCell<Option<usize>>,
|
mouse_move_event_index: DomRefCell<Option<usize>>,
|
||||||
/// <https://w3c.github.io/uievents/#event-type-dblclick>
|
/// <https://w3c.github.io/uievents/#event-type-dblclick>
|
||||||
#[ignore_malloc_size_of = "Defined in std"]
|
#[ignore_malloc_size_of = "Defined in std"]
|
||||||
@@ -115,24 +115,24 @@ impl DocumentEventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note a pending compositor event, to be processed at the next `update_the_rendering` task.
|
/// Note a pending input event, to be processed at the next `update_the_rendering` task.
|
||||||
pub(crate) fn note_pending_input_event(&self, event: ConstellationInputEvent) {
|
pub(crate) fn note_pending_input_event(&self, event: ConstellationInputEvent) {
|
||||||
let mut pending_compositor_events = self.pending_input_events.borrow_mut();
|
let mut pending_input_events = self.pending_input_events.borrow_mut();
|
||||||
if matches!(event.event.event, InputEvent::MouseMove(..)) {
|
if matches!(event.event.event, InputEvent::MouseMove(..)) {
|
||||||
// First try to replace any existing mouse move event.
|
// First try to replace any existing mouse move event.
|
||||||
if let Some(mouse_move_event) = self
|
if let Some(mouse_move_event) = self
|
||||||
.mouse_move_event_index
|
.mouse_move_event_index
|
||||||
.borrow()
|
.borrow()
|
||||||
.and_then(|index| pending_compositor_events.get_mut(index))
|
.and_then(|index| pending_input_events.get_mut(index))
|
||||||
{
|
{
|
||||||
*mouse_move_event = event;
|
*mouse_move_event = event;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
*self.mouse_move_event_index.borrow_mut() = Some(pending_compositor_events.len());
|
*self.mouse_move_event_index.borrow_mut() = Some(pending_input_events.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
pending_compositor_events.push(event);
|
pending_input_events.push(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether or not this [`Document`] has any pending input events to be processed during
|
/// Whether or not this [`Document`] has any pending input events to be processed during
|
||||||
@@ -466,8 +466,8 @@ impl DocumentEventHandler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send mousemove event to topmost target, unless it's an iframe, in which case the
|
// Send mousemove event to topmost target, unless it's an iframe, in which case
|
||||||
// compositor should have also sent an event to the inner document.
|
// `Paint` should have also sent an event to the inner document.
|
||||||
MouseEvent::new_simple(
|
MouseEvent::new_simple(
|
||||||
&self.window,
|
&self.window,
|
||||||
FireMouseEventType::Move,
|
FireMouseEventType::Move,
|
||||||
@@ -1605,7 +1605,7 @@ impl DocumentEventHandler {
|
|||||||
if scrolling_box.is_viewport() && parent_pipeline.is_none() {
|
if scrolling_box.is_viewport() && parent_pipeline.is_none() {
|
||||||
let (_, delta) = calculate_current_scroll_offset_and_delta();
|
let (_, delta) = calculate_current_scroll_offset_and_delta();
|
||||||
self.window
|
self.window
|
||||||
.compositor_api()
|
.paint_api()
|
||||||
.scroll_viewport_by_delta(self.window.webview_id(), delta);
|
.scroll_viewport_by_delta(self.window.webview_id(), delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::time::{Duration, Instant};
|
|||||||
use std::{f64, mem};
|
use std::{f64, mem};
|
||||||
|
|
||||||
use base::id::WebViewId;
|
use base::id::WebViewId;
|
||||||
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
|
use compositing_traits::{CrossProcessPaintApi, ImageUpdate, SerializableImageData};
|
||||||
use content_security_policy::sandboxing_directive::SandboxingFlagSet;
|
use content_security_policy::sandboxing_directive::SandboxingFlagSet;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState};
|
use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState};
|
||||||
@@ -171,7 +171,7 @@ pub(crate) struct MediaFrameRenderer {
|
|||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
player_id: Option<usize>,
|
player_id: Option<usize>,
|
||||||
glplayer_id: Option<u64>,
|
glplayer_id: Option<u64>,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
#[ignore_malloc_size_of = "Defined in other crates"]
|
#[ignore_malloc_size_of = "Defined in other crates"]
|
||||||
player_context: WindowGLContext,
|
player_context: WindowGLContext,
|
||||||
current_frame: Option<MediaFrame>,
|
current_frame: Option<MediaFrame>,
|
||||||
@@ -185,14 +185,14 @@ pub(crate) struct MediaFrameRenderer {
|
|||||||
impl MediaFrameRenderer {
|
impl MediaFrameRenderer {
|
||||||
fn new(
|
fn new(
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
player_context: WindowGLContext,
|
player_context: WindowGLContext,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
webview_id,
|
webview_id,
|
||||||
player_id: None,
|
player_id: None,
|
||||||
glplayer_id: None,
|
glplayer_id: None,
|
||||||
compositor_api,
|
paint_api,
|
||||||
player_context,
|
player_context,
|
||||||
current_frame: None,
|
current_frame: None,
|
||||||
old_frame: None,
|
old_frame: None,
|
||||||
@@ -295,7 +295,7 @@ impl MediaFrameRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !updates.is_empty() {
|
if !updates.is_empty() {
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.update_images(self.webview_id.into(), updates);
|
.update_images(self.webview_id.into(), updates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -361,9 +361,8 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||||||
Some(current_frame) => {
|
Some(current_frame) => {
|
||||||
self.old_frame = Some(current_frame.image_key);
|
self.old_frame = Some(current_frame.image_key);
|
||||||
|
|
||||||
let Some(new_image_key) = self
|
let Some(new_image_key) =
|
||||||
.compositor_api
|
self.paint_api.generate_image_key_blocking(self.webview_id)
|
||||||
.generate_image_key_blocking(self.webview_id)
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -397,9 +396,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||||||
updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data));
|
updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data));
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
let Some(image_key) = self
|
let Some(image_key) = self.paint_api.generate_image_key_blocking(self.webview_id)
|
||||||
.compositor_api
|
|
||||||
.generate_image_key_blocking(self.webview_id)
|
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -432,7 +429,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||||||
updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data));
|
updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.update_images(self.webview_id.into(), updates);
|
.update_images(self.webview_id.into(), updates);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -649,7 +646,7 @@ impl HTMLMediaElement {
|
|||||||
player: Default::default(),
|
player: Default::default(),
|
||||||
video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
|
video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
|
||||||
document.webview_id(),
|
document.webview_id(),
|
||||||
document.window().compositor_api().clone(),
|
document.window().paint_api().clone(),
|
||||||
document.window().get_player_context(),
|
document.window().get_player_context(),
|
||||||
))),
|
))),
|
||||||
audio_renderer: Default::default(),
|
audio_renderer: Default::default(),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ impl HTMLMetaElement {
|
|||||||
|
|
||||||
if let Ok(viewport) = ViewportDescription::from_str(&content.value()) {
|
if let Ok(viewport) = ViewportDescription::from_str(&content.value()) {
|
||||||
self.owner_window()
|
self.owner_window()
|
||||||
.compositor_api()
|
.paint_api()
|
||||||
.viewport(self.owner_window().webview_id(), viewport);
|
.viewport(self.owner_window().webview_id(), viewport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ impl InputEventMethods<crate::DomTypeHolder> for InputEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`HitTestResult`] that is the result of doing a hit test based on a less-fine-grained
|
/// A [`HitTestResult`] that is the result of doing a hit test based on a less-fine-grained
|
||||||
/// `CompositorHitTestResult` against our current layout.
|
/// `PaintHitTestResult` against our current layout.
|
||||||
pub(crate) struct HitTestResult {
|
pub(crate) struct HitTestResult {
|
||||||
pub node: DomRoot<Node>,
|
pub node: DomRoot<Node>,
|
||||||
pub cursor: Cursor,
|
pub cursor: Cursor,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ use base64::Engine;
|
|||||||
#[cfg(feature = "bluetooth")]
|
#[cfg(feature = "bluetooth")]
|
||||||
use bluetooth_traits::BluetoothRequest;
|
use bluetooth_traits::BluetoothRequest;
|
||||||
use canvas_traits::webgl::WebGLChan;
|
use canvas_traits::webgl::WebGLChan;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use constellation_traits::{
|
use constellation_traits::{
|
||||||
LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
|
LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
|
||||||
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
|
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
|
||||||
@@ -407,10 +407,10 @@ pub(crate) struct Window {
|
|||||||
/// Flag to identify whether mutation observers are present(true)/absent(false)
|
/// Flag to identify whether mutation observers are present(true)/absent(false)
|
||||||
exists_mut_observer: Cell<bool>,
|
exists_mut_observer: Cell<bool>,
|
||||||
|
|
||||||
/// Cross-process access to the compositor.
|
/// Cross-process access to `Paint`.
|
||||||
#[ignore_malloc_size_of = "Wraps an IpcSender"]
|
#[ignore_malloc_size_of = "Wraps an IpcSender"]
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
|
|
||||||
/// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete.
|
/// Indicate whether a SetDocumentStatus message has been sent after a reflow is complete.
|
||||||
/// It is used to avoid sending idle message more than once, which is unnecessary.
|
/// It is used to avoid sending idle message more than once, which is unnecessary.
|
||||||
@@ -744,8 +744,8 @@ impl Window {
|
|||||||
let _ = std::mem::replace(&mut *self.pending_image_callbacks.borrow_mut(), images);
|
let _ = std::mem::replace(&mut *self.pending_image_callbacks.borrow_mut(), images);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compositor_api(&self) -> &CrossProcessCompositorApi {
|
pub(crate) fn paint_api(&self) -> &CrossProcessPaintApi {
|
||||||
&self.compositor_api
|
&self.paint_api
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn userscripts(&self) -> &[UserScript] {
|
pub(crate) fn userscripts(&self) -> &[UserScript] {
|
||||||
@@ -2399,7 +2399,7 @@ impl Window {
|
|||||||
let reflow_phases_run =
|
let reflow_phases_run =
|
||||||
self.reflow(ReflowGoal::UpdateScrollNode(scroll_id, Vector2D::new(x, y)));
|
self.reflow(ReflowGoal::UpdateScrollNode(scroll_id, Vector2D::new(x, y)));
|
||||||
if reflow_phases_run.needs_frame() {
|
if reflow_phases_run.needs_frame() {
|
||||||
self.compositor_api()
|
self.paint_api()
|
||||||
.generate_frame(vec![self.webview_id().into()]);
|
.generate_frame(vec![self.webview_id().into()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2657,7 +2657,7 @@ impl Window {
|
|||||||
//
|
//
|
||||||
// See <https://github.com/servo/servo/issues/14719>
|
// See <https://github.com/servo/servo/issues/14719>
|
||||||
if self.Document().update_the_rendering().needs_frame() {
|
if self.Document().update_the_rendering().needs_frame() {
|
||||||
self.compositor_api()
|
self.paint_api()
|
||||||
.generate_frame(vec![self.webview_id().into()]);
|
.generate_frame(vec![self.webview_id().into()]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3155,7 +3155,7 @@ impl Window {
|
|||||||
// Set the window proxy to be this object.
|
// Set the window proxy to be this object.
|
||||||
self.window_proxy().set_currently_active(self, can_gc);
|
self.window_proxy().set_currently_active(self, can_gc);
|
||||||
|
|
||||||
// Push the document title to the compositor since we are
|
// Push the document title to `Paint` since we are
|
||||||
// activating this document due to a navigation.
|
// activating this document due to a navigation.
|
||||||
self.Document().title_changed();
|
self.Document().title_changed();
|
||||||
}
|
}
|
||||||
@@ -3440,7 +3440,7 @@ impl Window {
|
|||||||
navigation_start: CrossProcessInstant,
|
navigation_start: CrossProcessInstant,
|
||||||
webgl_chan: Option<WebGLChan>,
|
webgl_chan: Option<WebGLChan>,
|
||||||
#[cfg(feature = "webxr")] webxr_registry: Option<webxr_api::Registry>,
|
#[cfg(feature = "webxr")] webxr_registry: Option<webxr_api::Registry>,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
unminify_js: bool,
|
unminify_js: bool,
|
||||||
unminify_css: bool,
|
unminify_css: bool,
|
||||||
local_script_source: Option<String>,
|
local_script_source: Option<String>,
|
||||||
@@ -3523,7 +3523,7 @@ impl Window {
|
|||||||
test_worklet: Default::default(),
|
test_worklet: Default::default(),
|
||||||
paint_worklet: Default::default(),
|
paint_worklet: Default::default(),
|
||||||
exists_mut_observer: Cell::new(false),
|
exists_mut_observer: Cell::new(false),
|
||||||
compositor_api,
|
paint_api,
|
||||||
has_sent_idle_message: Cell::new(false),
|
has_sent_idle_message: Cell::new(false),
|
||||||
unminify_css,
|
unminify_css,
|
||||||
user_content_manager,
|
user_content_manager,
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ impl ImageAnimationManager {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
window
|
window
|
||||||
.compositor_api()
|
.paint_api()
|
||||||
.update_images(window.webview_id().into(), updates);
|
.update_images(window.webview_id().into(), updates);
|
||||||
|
|
||||||
self.maybe_schedule_update(window, now);
|
self.maybe_schedule_update(window, now);
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ use base::id::{
|
|||||||
};
|
};
|
||||||
use canvas_traits::webgl::WebGLPipeline;
|
use canvas_traits::webgl::WebGLPipeline;
|
||||||
use chrono::{DateTime, Local};
|
use chrono::{DateTime, Local};
|
||||||
use compositing_traits::{CrossProcessCompositorApi, PipelineExitSource};
|
use compositing_traits::{CrossProcessPaintApi, PipelineExitSource};
|
||||||
use constellation_traits::{
|
use constellation_traits::{
|
||||||
JsEvalResult, LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
|
JsEvalResult, LoadData, LoadOrigin, NavigationHistoryBehavior, ScreenshotReadinessResponse,
|
||||||
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
|
ScriptToConstellationChan, ScriptToConstellationMessage, StructuredSerializedData,
|
||||||
@@ -306,9 +306,9 @@ pub struct ScriptThread {
|
|||||||
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
|
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
|
||||||
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
|
|
||||||
/// Cross-process access to the compositor's API.
|
/// Cross-process access to `Paint`'s API.
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
|
|
||||||
/// Periodically print out on which events script threads spend their processing time.
|
/// Periodically print out on which events script threads spend their processing time.
|
||||||
profile_script_events: bool,
|
profile_script_events: bool,
|
||||||
@@ -963,7 +963,7 @@ impl ScriptThread {
|
|||||||
worklet_thread_pool: Default::default(),
|
worklet_thread_pool: Default::default(),
|
||||||
docs_with_no_blocking_loads: Default::default(),
|
docs_with_no_blocking_loads: Default::default(),
|
||||||
custom_element_reaction_stack: Rc::new(CustomElementReactionStack::new()),
|
custom_element_reaction_stack: Rc::new(CustomElementReactionStack::new()),
|
||||||
compositor_api: state.cross_process_compositor_api,
|
paint_api: state.cross_process_paint_api,
|
||||||
profile_script_events: opts.debug.profile_script_events,
|
profile_script_events: opts.debug.profile_script_events,
|
||||||
print_pwm: opts.print_pwm,
|
print_pwm: opts.print_pwm,
|
||||||
unminify_js: opts.unminify_js,
|
unminify_js: opts.unminify_js,
|
||||||
@@ -1018,15 +1018,15 @@ impl ScriptThread {
|
|||||||
debug!("Stopped script thread.");
|
debug!("Stopped script thread.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process compositor events as part of a "update the rendering task".
|
/// Process input events as part of a "update the rendering task".
|
||||||
fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) {
|
fn process_pending_input_events(&self, pipeline_id: PipelineId, can_gc: CanGc) {
|
||||||
let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
|
let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
|
||||||
warn!("Processing pending compositor events for closed pipeline {pipeline_id}.");
|
warn!("Processing pending input events for closed pipeline {pipeline_id}.");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// Do not handle events if the BC has been, or is being, discarded
|
// Do not handle events if the BC has been, or is being, discarded
|
||||||
if document.window().Closed() {
|
if document.window().Closed() {
|
||||||
warn!("Compositor event sent to a pipeline with a closed window {pipeline_id}.");
|
warn!("Input event sent to a pipeline with a closed window {pipeline_id}.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1122,7 +1122,7 @@ impl ScriptThread {
|
|||||||
|
|
||||||
// TODO(#31581): The steps in the "Revealing the document" section need to be implemented
|
// TODO(#31581): The steps in the "Revealing the document" section need to be implemented
|
||||||
// `process_pending_input_events` handles the focusing steps as well as other events
|
// `process_pending_input_events` handles the focusing steps as well as other events
|
||||||
// from the compositor.
|
// from `Paint`.
|
||||||
|
|
||||||
// TODO: Should this be broken and to match the specification more closely? For instance see
|
// TODO: Should this be broken and to match the specification more closely? For instance see
|
||||||
// https://html.spec.whatwg.org/multipage/#flush-autofocus-candidates.
|
// https://html.spec.whatwg.org/multipage/#flush-autofocus-candidates.
|
||||||
@@ -1205,7 +1205,7 @@ impl ScriptThread {
|
|||||||
|
|
||||||
let should_generate_frame = !painters_generating_frames.is_empty();
|
let should_generate_frame = !painters_generating_frames.is_empty();
|
||||||
if should_generate_frame {
|
if should_generate_frame {
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.generate_frame(painters_generating_frames.into_iter().collect());
|
.generate_frame(painters_generating_frames.into_iter().collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2960,7 +2960,7 @@ impl ScriptThread {
|
|||||||
))
|
))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.pipeline_exited(webview_id, pipeline_id, PipelineExitSource::Script);
|
.pipeline_exited(webview_id, pipeline_id, PipelineExitSource::Script);
|
||||||
|
|
||||||
debug!("{pipeline_id}: Finished pipeline exit");
|
debug!("{pipeline_id}: Finished pipeline exit");
|
||||||
@@ -3128,14 +3128,14 @@ impl ScriptThread {
|
|||||||
|
|
||||||
let font_context = Arc::new(FontContext::new(
|
let font_context = Arc::new(FontContext::new(
|
||||||
self.system_font_service.clone(),
|
self.system_font_service.clone(),
|
||||||
self.compositor_api.clone(),
|
self.paint_api.clone(),
|
||||||
self.resource_threads.clone(),
|
self.resource_threads.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let image_cache = self.image_cache_factory.create(
|
let image_cache = self.image_cache_factory.create(
|
||||||
incomplete.webview_id,
|
incomplete.webview_id,
|
||||||
incomplete.pipeline_id,
|
incomplete.pipeline_id,
|
||||||
&self.compositor_api,
|
&self.paint_api,
|
||||||
);
|
);
|
||||||
|
|
||||||
let layout_config = LayoutConfig {
|
let layout_config = LayoutConfig {
|
||||||
@@ -3147,7 +3147,7 @@ impl ScriptThread {
|
|||||||
image_cache: image_cache.clone(),
|
image_cache: image_cache.clone(),
|
||||||
font_context: font_context.clone(),
|
font_context: font_context.clone(),
|
||||||
time_profiler_chan: self.senders.time_profiler_sender.clone(),
|
time_profiler_chan: self.senders.time_profiler_sender.clone(),
|
||||||
compositor_api: self.compositor_api.clone(),
|
paint_api: self.paint_api.clone(),
|
||||||
viewport_details: incomplete.viewport_details,
|
viewport_details: incomplete.viewport_details,
|
||||||
theme: incomplete.theme,
|
theme: incomplete.theme,
|
||||||
};
|
};
|
||||||
@@ -3185,7 +3185,7 @@ impl ScriptThread {
|
|||||||
self.webgl_chan.as_ref().map(|chan| chan.channel()),
|
self.webgl_chan.as_ref().map(|chan| chan.channel()),
|
||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
self.webxr_registry.clone(),
|
self.webxr_registry.clone(),
|
||||||
self.compositor_api.clone(),
|
self.paint_api.clone(),
|
||||||
self.unminify_js,
|
self.unminify_js,
|
||||||
self.unminify_css,
|
self.unminify_css,
|
||||||
self.local_script_source.clone(),
|
self.local_script_source.clone(),
|
||||||
@@ -3400,8 +3400,7 @@ impl ScriptThread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Queue compositor events for later dispatching as part of a
|
/// Queue input events for later dispatching as part of a `update_the_rendering` task.
|
||||||
/// `update_the_rendering` task.
|
|
||||||
fn handle_input_event(
|
fn handle_input_event(
|
||||||
&self,
|
&self,
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
@@ -3409,7 +3408,7 @@ impl ScriptThread {
|
|||||||
event: ConstellationInputEvent,
|
event: ConstellationInputEvent,
|
||||||
) {
|
) {
|
||||||
let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
|
let Some(document) = self.documents.borrow().find_document(pipeline_id) else {
|
||||||
warn!("Compositor event sent to closed pipeline {pipeline_id}.");
|
warn!("Input event sent to closed pipeline {pipeline_id}.");
|
||||||
let _ = self
|
let _ = self
|
||||||
.senders
|
.senders
|
||||||
.pipeline_to_embedder_sender
|
.pipeline_to_embedder_sender
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ impl ServiceWorkerManagerFactory for ServiceWorkerManager {
|
|||||||
receiver,
|
receiver,
|
||||||
swmanager_sender: constellation_sender,
|
swmanager_sender: constellation_sender,
|
||||||
system_font_service_sender,
|
system_font_service_sender,
|
||||||
compositor_api,
|
paint_api,
|
||||||
} = sw_senders;
|
} = sw_senders;
|
||||||
|
|
||||||
let from_constellation = receiver.route_preserving_errors();
|
let from_constellation = receiver.route_preserving_errors();
|
||||||
@@ -519,7 +519,7 @@ impl ServiceWorkerManagerFactory for ServiceWorkerManager {
|
|||||||
|
|
||||||
let font_context = Arc::new(FontContext::new(
|
let font_context = Arc::new(FontContext::new(
|
||||||
Arc::new(system_font_service_sender.to_proxy()),
|
Arc::new(system_font_service_sender.to_proxy()),
|
||||||
compositor_api,
|
paint_api,
|
||||||
resource_threads,
|
resource_threads,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ use base::id::{PipelineNamespace, PipelineNamespaceId};
|
|||||||
use bluetooth::BluetoothThreadFactory;
|
use bluetooth::BluetoothThreadFactory;
|
||||||
#[cfg(feature = "bluetooth")]
|
#[cfg(feature = "bluetooth")]
|
||||||
use bluetooth_traits::BluetoothRequest;
|
use bluetooth_traits::BluetoothRequest;
|
||||||
use compositing::{IOCompositor, InitialCompositorState};
|
use compositing::{InitialPaintState, Paint};
|
||||||
pub use compositing_traits::rendering_context::RenderingContext;
|
pub use compositing_traits::rendering_context::RenderingContext;
|
||||||
use compositing_traits::{CompositorMsg, CompositorProxy, CrossProcessCompositorApi};
|
use compositing_traits::{CrossProcessPaintApi, PaintMessage, PaintProxy};
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(target_os = "windows"),
|
not(target_os = "windows"),
|
||||||
not(target_os = "ios"),
|
not(target_os = "ios"),
|
||||||
@@ -135,7 +135,7 @@ mod media_platform {
|
|||||||
|
|
||||||
struct ServoInner {
|
struct ServoInner {
|
||||||
delegate: RefCell<Rc<dyn ServoDelegate>>,
|
delegate: RefCell<Rc<dyn ServoDelegate>>,
|
||||||
compositor: Rc<RefCell<IOCompositor>>,
|
paint: Rc<RefCell<Paint>>,
|
||||||
constellation_proxy: ConstellationProxy,
|
constellation_proxy: ConstellationProxy,
|
||||||
embedder_receiver: Receiver<EmbedderMsg>,
|
embedder_receiver: Receiver<EmbedderMsg>,
|
||||||
public_resource_threads: ResourceThreads,
|
public_resource_threads: ResourceThreads,
|
||||||
@@ -172,20 +172,20 @@ impl ServoInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let compositor = self.compositor.borrow();
|
let paint = self.paint.borrow();
|
||||||
let mut messages = Vec::new();
|
let mut messages = Vec::new();
|
||||||
while let Ok(message) = compositor.receiver().try_recv() {
|
while let Ok(message) = paint.receiver().try_recv() {
|
||||||
match message {
|
match message {
|
||||||
Ok(message) => messages.push(message),
|
Ok(message) => messages.push(message),
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
warn!("Router deserialization error: {error}. Ignoring this CompositorMsg.")
|
warn!("Router deserialization error: {error}. Ignoring this PaintMessage.")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compositor.handle_messages(messages);
|
paint.handle_messages(messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only handle incoming embedder messages if the compositor hasn't already started shutting down.
|
// Only handle incoming embedder messages if `Paint` hasn't already started shutting down.
|
||||||
while let Ok(message) = self.embedder_receiver.try_recv() {
|
while let Ok(message) = self.embedder_receiver.try_recv() {
|
||||||
self.handle_embedder_message(message);
|
self.handle_embedder_message(message);
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ impl ServoInner {
|
|||||||
.notify_error(ServoError::LostConnectionWithBackend);
|
.notify_error(ServoError::LostConnectionWithBackend);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compositor.borrow_mut().perform_updates();
|
self.paint.borrow_mut().perform_updates();
|
||||||
self.send_new_frame_ready_messages();
|
self.send_new_frame_ready_messages();
|
||||||
self.handle_delegate_errors();
|
self.handle_delegate_errors();
|
||||||
self.clean_up_destroyed_webview_handles();
|
self.clean_up_destroyed_webview_handles();
|
||||||
@@ -213,7 +213,7 @@ impl ServoInner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send_new_frame_ready_messages(&self) {
|
fn send_new_frame_ready_messages(&self) {
|
||||||
let webviews_needing_repaint = self.compositor.borrow().webviews_needing_repaint();
|
let webviews_needing_repaint = self.paint.borrow().webviews_needing_repaint();
|
||||||
|
|
||||||
for webview in webviews_needing_repaint
|
for webview in webviews_needing_repaint
|
||||||
.iter()
|
.iter()
|
||||||
@@ -242,7 +242,7 @@ impl ServoInner {
|
|||||||
fn finish_shutting_down(&self) {
|
fn finish_shutting_down(&self) {
|
||||||
debug!("Servo received message that Constellation shutdown is complete");
|
debug!("Servo received message that Constellation shutdown is complete");
|
||||||
self.shutdown_state.set(ShutdownState::FinishedShuttingDown);
|
self.shutdown_state.set(ShutdownState::FinishedShuttingDown);
|
||||||
self.compositor.borrow_mut().finish_shutting_down();
|
self.paint.borrow_mut().finish_shutting_down();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_embedder_message(&self, message: EmbedderMsg) {
|
fn handle_embedder_message(&self, message: EmbedderMsg) {
|
||||||
@@ -364,7 +364,7 @@ impl ServoInner {
|
|||||||
.finish_evaluation(evaluation_id, result);
|
.finish_evaluation(evaluation_id, result);
|
||||||
},
|
},
|
||||||
EmbedderMsg::InputEventHandled(webview_id, input_event_id, result) => {
|
EmbedderMsg::InputEventHandled(webview_id, input_event_id, result) => {
|
||||||
self.compositor.borrow_mut().notify_input_event_handled(
|
self.paint.borrow_mut().notify_input_event_handled(
|
||||||
webview_id,
|
webview_id,
|
||||||
input_event_id,
|
input_event_id,
|
||||||
result,
|
result,
|
||||||
@@ -682,12 +682,11 @@ impl Servo {
|
|||||||
PipelineNamespace::install(PipelineNamespaceId(0));
|
PipelineNamespace::install(PipelineNamespaceId(0));
|
||||||
|
|
||||||
// Get both endpoints of a special channel for communication between
|
// Get both endpoints of a special channel for communication between
|
||||||
// the client window and the compositor. This channel is unique because
|
// the client window and `Paint`. This channel is unique because
|
||||||
// messages to client may need to pump a platform-specific event loop
|
// messages to client may need to pump a platform-specific event loop
|
||||||
// to deliver the message.
|
// to deliver the message.
|
||||||
let event_loop_waker = builder.event_loop_waker;
|
let event_loop_waker = builder.event_loop_waker;
|
||||||
let (compositor_proxy, compositor_receiver) =
|
let (paint_proxy, paint_receiver) = create_paint_channel(event_loop_waker.clone());
|
||||||
create_compositor_channel(event_loop_waker.clone());
|
|
||||||
let (constellation_proxy, embedder_to_constellation_receiver) = ConstellationProxy::new();
|
let (constellation_proxy, embedder_to_constellation_receiver) = ConstellationProxy::new();
|
||||||
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
|
let (embedder_proxy, embedder_receiver) = create_embedder_channel(event_loop_waker.clone());
|
||||||
let time_profiler_chan = profile_time::Profiler::create(
|
let time_profiler_chan = profile_time::Profiler::create(
|
||||||
@@ -718,12 +717,12 @@ impl Servo {
|
|||||||
let mut protocols = ProtocolRegistry::with_internal_protocols();
|
let mut protocols = ProtocolRegistry::with_internal_protocols();
|
||||||
protocols.merge(builder.protocol_registry);
|
protocols.merge(builder.protocol_registry);
|
||||||
|
|
||||||
// The compositor coordinates with the client window to create the final
|
// The `Paint` coordinates with the client window to create the final
|
||||||
// rendered page and display it somewhere.
|
// rendered page and display it somewhere.
|
||||||
let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown));
|
let shutdown_state = Rc::new(Cell::new(ShutdownState::NotShuttingDown));
|
||||||
let compositor = IOCompositor::new(InitialCompositorState {
|
let paint = Paint::new(InitialPaintState {
|
||||||
compositor_proxy: compositor_proxy.clone(),
|
paint_proxy: paint_proxy.clone(),
|
||||||
receiver: compositor_receiver,
|
receiver: paint_receiver,
|
||||||
embedder_to_constellation_sender: constellation_proxy.sender().clone(),
|
embedder_to_constellation_sender: constellation_proxy.sender().clone(),
|
||||||
time_profiler_chan: time_profiler_chan.clone(),
|
time_profiler_chan: time_profiler_chan.clone(),
|
||||||
mem_profiler_chan: mem_profiler_chan.clone(),
|
mem_profiler_chan: mem_profiler_chan.clone(),
|
||||||
@@ -748,10 +747,10 @@ impl Servo {
|
|||||||
|
|
||||||
create_constellation(
|
create_constellation(
|
||||||
embedder_to_constellation_receiver,
|
embedder_to_constellation_receiver,
|
||||||
&compositor.borrow(),
|
&paint.borrow(),
|
||||||
opts.config_dir.clone(),
|
opts.config_dir.clone(),
|
||||||
embedder_proxy,
|
embedder_proxy,
|
||||||
compositor_proxy.clone(),
|
paint_proxy.clone(),
|
||||||
time_profiler_chan,
|
time_profiler_chan,
|
||||||
mem_profiler_chan,
|
mem_profiler_chan,
|
||||||
devtools_sender,
|
devtools_sender,
|
||||||
@@ -768,7 +767,7 @@ impl Servo {
|
|||||||
|
|
||||||
Servo(Rc::new(ServoInner {
|
Servo(Rc::new(ServoInner {
|
||||||
delegate: RefCell::new(Rc::new(DefaultServoDelegate)),
|
delegate: RefCell::new(Rc::new(DefaultServoDelegate)),
|
||||||
compositor,
|
paint,
|
||||||
javascript_evaluator: Rc::new(RefCell::new(JavaScriptEvaluator::new(
|
javascript_evaluator: Rc::new(RefCell::new(JavaScriptEvaluator::new(
|
||||||
constellation_proxy.clone(),
|
constellation_proxy.clone(),
|
||||||
))),
|
))),
|
||||||
@@ -799,9 +798,9 @@ impl Servo {
|
|||||||
|
|
||||||
/// Spin the Servo event loop, which:
|
/// Spin the Servo event loop, which:
|
||||||
///
|
///
|
||||||
/// - Performs updates in the compositor, such as queued pinch zoom events
|
/// - Performs updates in `Paint`, such as queued pinch zoom events
|
||||||
/// - Runs delebgate methods on all `WebView`s and `Servo` itself
|
/// - Runs delebgate methods on all `WebView`s and `Servo` itself
|
||||||
/// - Maybe update the rendered compositor output, but *without* swapping buffers.
|
/// - Maybe update the rendered `Paint` output, but *without* swapping buffers.
|
||||||
pub fn spin_event_loop(&self) {
|
pub fn spin_event_loop(&self) {
|
||||||
self.0.spin_event_loop();
|
self.0.spin_event_loop();
|
||||||
}
|
}
|
||||||
@@ -846,12 +845,12 @@ impl Servo {
|
|||||||
self.0.private_resource_threads.clear_cookies();
|
self.0.private_resource_threads.clear_cookies();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compositor<'a>(&'a self) -> Ref<'a, IOCompositor> {
|
pub(crate) fn paint<'a>(&'a self) -> Ref<'a, Paint> {
|
||||||
self.0.compositor.borrow()
|
self.0.paint.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn compositor_mut<'a>(&'a self) -> RefMut<'a, IOCompositor> {
|
pub(crate) fn paint_mut<'a>(&'a self) -> RefMut<'a, Paint> {
|
||||||
self.0.compositor.borrow_mut()
|
self.0.paint.borrow_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn webviews_mut<'a>(
|
pub(crate) fn webviews_mut<'a>(
|
||||||
@@ -882,14 +881,14 @@ fn create_embedder_channel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_compositor_channel(
|
fn create_paint_channel(
|
||||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
) -> (CompositorProxy, RoutedReceiver<CompositorMsg>) {
|
) -> (PaintProxy, RoutedReceiver<PaintMessage>) {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
let sender_clone = sender.clone();
|
let sender_clone = sender.clone();
|
||||||
let event_loop_waker_clone = event_loop_waker.clone();
|
let event_loop_waker_clone = event_loop_waker.clone();
|
||||||
// This callback is equivalent to `CompositorProxy::send`
|
// This callback is equivalent to `PaintProxy::send`
|
||||||
let result_callback = move |msg: Result<CompositorMsg, ipc_channel::Error>| {
|
let result_callback = move |msg: Result<PaintMessage, ipc_channel::Error>| {
|
||||||
if let Err(err) = sender_clone.send(msg) {
|
if let Err(err) = sender_clone.send(msg) {
|
||||||
warn!("Failed to send response ({:?}).", err);
|
warn!("Failed to send response ({:?}).", err);
|
||||||
}
|
}
|
||||||
@@ -898,23 +897,23 @@ fn create_compositor_channel(
|
|||||||
|
|
||||||
let generic_callback =
|
let generic_callback =
|
||||||
GenericCallback::new(result_callback).expect("Failed to create callback");
|
GenericCallback::new(result_callback).expect("Failed to create callback");
|
||||||
let cross_process_compositor_api = CrossProcessCompositorApi::new(generic_callback);
|
let cross_process_paint_api = CrossProcessPaintApi::new(generic_callback);
|
||||||
let compositor_proxy = CompositorProxy {
|
let paint_proxy = PaintProxy {
|
||||||
sender,
|
sender,
|
||||||
cross_process_compositor_api,
|
cross_process_paint_api,
|
||||||
event_loop_waker,
|
event_loop_waker,
|
||||||
};
|
};
|
||||||
|
|
||||||
(compositor_proxy, receiver)
|
(paint_proxy, receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn create_constellation(
|
fn create_constellation(
|
||||||
embedder_to_constellation_receiver: Receiver<EmbedderToConstellationMessage>,
|
embedder_to_constellation_receiver: Receiver<EmbedderToConstellationMessage>,
|
||||||
compositor: &IOCompositor,
|
paint: &Paint,
|
||||||
config_dir: Option<PathBuf>,
|
config_dir: Option<PathBuf>,
|
||||||
embedder_proxy: EmbedderProxy,
|
embedder_proxy: EmbedderProxy,
|
||||||
compositor_proxy: CompositorProxy,
|
paint_proxy: PaintProxy,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
mem_profiler_chan: mem::ProfilerChan,
|
mem_profiler_chan: mem::ProfilerChan,
|
||||||
devtools_sender: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
|
devtools_sender: Option<Sender<devtools_traits::DevtoolsControlMsg>>,
|
||||||
@@ -938,14 +937,14 @@ fn create_constellation(
|
|||||||
|
|
||||||
let system_font_service = Arc::new(
|
let system_font_service = Arc::new(
|
||||||
SystemFontService::spawn(
|
SystemFontService::spawn(
|
||||||
compositor_proxy.cross_process_compositor_api.clone(),
|
paint_proxy.cross_process_paint_api.clone(),
|
||||||
mem_profiler_chan.clone(),
|
mem_profiler_chan.clone(),
|
||||||
)
|
)
|
||||||
.to_proxy(),
|
.to_proxy(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let initial_state = InitialConstellationState {
|
let initial_state = InitialConstellationState {
|
||||||
compositor_proxy,
|
paint_proxy,
|
||||||
embedder_proxy,
|
embedder_proxy,
|
||||||
devtools_sender,
|
devtools_sender,
|
||||||
#[cfg(feature = "bluetooth")]
|
#[cfg(feature = "bluetooth")]
|
||||||
@@ -958,13 +957,13 @@ fn create_constellation(
|
|||||||
time_profiler_chan,
|
time_profiler_chan,
|
||||||
mem_profiler_chan,
|
mem_profiler_chan,
|
||||||
#[cfg(feature = "webxr")]
|
#[cfg(feature = "webxr")]
|
||||||
webxr_registry: Some(compositor.webxr_main_thread_registry()),
|
webxr_registry: Some(paint.webxr_main_thread_registry()),
|
||||||
#[cfg(not(feature = "webxr"))]
|
#[cfg(not(feature = "webxr"))]
|
||||||
webxr_registry: None,
|
webxr_registry: None,
|
||||||
webgl_threads: Some(compositor.webgl_threads()),
|
webgl_threads: Some(paint.webgl_threads()),
|
||||||
webrender_external_image_id_manager: compositor.webrender_external_image_id_manager(),
|
webrender_external_image_id_manager: paint.webrender_external_image_id_manager(),
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
wgpu_image_map: compositor.webgpu_image_map(),
|
wgpu_image_map: paint.webgpu_image_map(),
|
||||||
user_content_manager,
|
user_content_manager,
|
||||||
async_runtime,
|
async_runtime,
|
||||||
privileged_urls,
|
privileged_urls,
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ impl Drop for WebViewInner {
|
|||||||
self.servo
|
self.servo
|
||||||
.constellation_proxy()
|
.constellation_proxy()
|
||||||
.send(EmbedderToConstellationMessage::CloseWebView(self.id));
|
.send(EmbedderToConstellationMessage::CloseWebView(self.id));
|
||||||
self.servo.compositor_mut().remove_webview(self.id);
|
self.servo.paint_mut().remove_webview(self.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ impl WebView {
|
|||||||
pub(crate) fn new(builder: WebViewBuilder) -> Self {
|
pub(crate) fn new(builder: WebViewBuilder) -> Self {
|
||||||
let servo = builder.servo;
|
let servo = builder.servo;
|
||||||
let painter_id = servo
|
let painter_id = servo
|
||||||
.compositor_mut()
|
.paint_mut()
|
||||||
.register_rendering_context(builder.rendering_context.clone());
|
.register_rendering_context(builder.rendering_context.clone());
|
||||||
|
|
||||||
let id = WebViewId::new(painter_id);
|
let id = WebViewId::new(painter_id);
|
||||||
@@ -136,7 +136,7 @@ impl WebView {
|
|||||||
})));
|
})));
|
||||||
|
|
||||||
let viewport_details = webview.viewport_details();
|
let viewport_details = webview.viewport_details();
|
||||||
servo.compositor().add_webview(
|
servo.paint().add_webview(
|
||||||
Box::new(ServoRendererWebView {
|
Box::new(ServoRendererWebView {
|
||||||
weak_handle: webview.weak_handle(),
|
weak_handle: webview.weak_handle(),
|
||||||
id,
|
id,
|
||||||
@@ -339,7 +339,7 @@ impl WebView {
|
|||||||
|
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.resize_rendering_context(self.id(), new_size);
|
.resize_rendering_context(self.id(), new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,14 +358,14 @@ impl WebView {
|
|||||||
self.inner_mut().hidpi_scale_factor = new_scale_factor;
|
self.inner_mut().hidpi_scale_factor = new_scale_factor;
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.set_hidpi_scale_factor(self.id(), new_scale_factor);
|
.set_hidpi_scale_factor(self.id(), new_scale_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn show(&self) {
|
pub fn show(&self) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.show_webview(self.id())
|
.show_webview(self.id())
|
||||||
.expect("BUG: invalid WebView instance");
|
.expect("BUG: invalid WebView instance");
|
||||||
}
|
}
|
||||||
@@ -373,7 +373,7 @@ impl WebView {
|
|||||||
pub fn hide(&self) {
|
pub fn hide(&self) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.hide_webview(self.id())
|
.hide_webview(self.id())
|
||||||
.expect("BUG: invalid WebView instance");
|
.expect("BUG: invalid WebView instance");
|
||||||
}
|
}
|
||||||
@@ -443,7 +443,7 @@ impl WebView {
|
|||||||
pub fn notify_scroll_event(&self, scroll: Scroll, point: WebViewPoint) {
|
pub fn notify_scroll_event(&self, scroll: Scroll, point: WebViewPoint) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.notify_scroll_event(self.id(), scroll, point);
|
.notify_scroll_event(self.id(), scroll, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -451,11 +451,11 @@ impl WebView {
|
|||||||
let event: InputEventAndId = event.into();
|
let event: InputEventAndId = event.into();
|
||||||
let event_id = event.id;
|
let event_id = event.id;
|
||||||
|
|
||||||
// Events with a `point` first go to the compositor for hit testing.
|
// Events with a `point` first go to `Paint` for hit testing.
|
||||||
if event.event.point().is_some() {
|
if event.event.point().is_some() {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.notify_input_event(self.id(), event);
|
.notify_input_event(self.id(), event);
|
||||||
} else {
|
} else {
|
||||||
self.inner().servo.constellation_proxy().send(
|
self.inner().servo.constellation_proxy().send(
|
||||||
@@ -491,13 +491,13 @@ impl WebView {
|
|||||||
pub fn set_page_zoom(&self, new_zoom: f32) {
|
pub fn set_page_zoom(&self, new_zoom: f32) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.set_page_zoom(self.id(), new_zoom);
|
.set_page_zoom(self.id(), new_zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the page zoom of the [`WebView`].
|
/// Get the page zoom of the [`WebView`].
|
||||||
pub fn page_zoom(&self) -> f32 {
|
pub fn page_zoom(&self) -> f32 {
|
||||||
self.inner().servo.compositor().page_zoom(self.id())
|
self.inner().servo.paint().page_zoom(self.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adjust the pinch zoom on this [`WebView`] multiplying the current pinch zoom
|
/// Adjust the pinch zoom on this [`WebView`] multiplying the current pinch zoom
|
||||||
@@ -512,14 +512,14 @@ impl WebView {
|
|||||||
pub fn pinch_zoom(&self, pinch_zoom_delta: f32, center: DevicePoint) {
|
pub fn pinch_zoom(&self, pinch_zoom_delta: f32, center: DevicePoint) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.pinch_zoom(self.id(), pinch_zoom_delta, center);
|
.pinch_zoom(self.id(), pinch_zoom_delta, center);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn device_pixels_per_css_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
pub fn device_pixels_per_css_pixel(&self) -> Scale<f32, CSSPixel, DevicePixel> {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.device_pixels_per_page_pixel(self.id())
|
.device_pixels_per_page_pixel(self.id())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -537,14 +537,11 @@ impl WebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_webrender_debugging(&self, debugging: WebRenderDebugOption) {
|
pub fn toggle_webrender_debugging(&self, debugging: WebRenderDebugOption) {
|
||||||
self.inner()
|
self.inner().servo.paint().toggle_webrender_debug(debugging);
|
||||||
.servo
|
|
||||||
.compositor()
|
|
||||||
.toggle_webrender_debug(debugging);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn capture_webrender(&self) {
|
pub fn capture_webrender(&self) {
|
||||||
self.inner().servo.compositor().capture_webrender(self.id());
|
self.inner().servo.paint().capture_webrender(self.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) {
|
pub fn toggle_sampling_profiler(&self, rate: Duration, max_duration: Duration) {
|
||||||
@@ -565,7 +562,7 @@ impl WebView {
|
|||||||
|
|
||||||
/// Paint the contents of this [`WebView`] into its `RenderingContext`.
|
/// Paint the contents of this [`WebView`] into its `RenderingContext`.
|
||||||
pub fn paint(&self) {
|
pub fn paint(&self) {
|
||||||
self.inner().servo.compositor().render(self.id());
|
self.inner().servo.paint().render(self.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate the specified string of JavaScript code. Once execution is complete or an error
|
/// Evaluate the specified string of JavaScript code. Once execution is complete or an error
|
||||||
@@ -606,7 +603,7 @@ impl WebView {
|
|||||||
) {
|
) {
|
||||||
self.inner()
|
self.inner()
|
||||||
.servo
|
.servo
|
||||||
.compositor()
|
.paint()
|
||||||
.request_screenshot(self.id(), rect, Box::new(callback));
|
.request_screenshot(self.id(), rect, Box::new(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! Defines data structures which are consumed by the Compositor.
|
//! Defines data structures which are consumed by `Paint`.
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
@@ -419,12 +419,12 @@ impl ScrollTreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A tree of spatial nodes, which mirrors the spatial nodes in the WebRender
|
/// A tree of spatial nodes, which mirrors the spatial nodes in the WebRender
|
||||||
/// display list, except these are used to scrolling in the compositor so that
|
/// display list, except these are used for scrolling in `Paint` so that
|
||||||
/// new offsets can be sent to WebRender.
|
/// new offsets can be sent to WebRender.
|
||||||
#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Debug, Default, Deserialize, MallocSizeOf, Serialize)]
|
||||||
pub struct ScrollTree {
|
pub struct ScrollTree {
|
||||||
/// A list of compositor-side scroll nodes that describe the tree
|
/// A list of `Paint`-side scroll nodes that describe the tree
|
||||||
/// of WebRender spatial nodes, used by the compositor to scroll the
|
/// of WebRender spatial nodes, used by `Paint` to scroll the
|
||||||
/// contents of the display list.
|
/// contents of the display list.
|
||||||
pub nodes: Vec<ScrollTreeNode>,
|
pub nodes: Vec<ScrollTreeNode>,
|
||||||
}
|
}
|
||||||
@@ -799,10 +799,10 @@ impl ScrollTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A data structure which stores compositor-side information about
|
/// A data structure which stores `Paint`-side information about
|
||||||
/// display lists sent to the compositor.
|
/// display lists sent to `Paint`.
|
||||||
#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Debug, Deserialize, MallocSizeOf, Serialize)]
|
||||||
pub struct CompositorDisplayListInfo {
|
pub struct PaintDisplayListInfo {
|
||||||
/// The WebRender [PipelineId] of this display list.
|
/// The WebRender [PipelineId] of this display list.
|
||||||
pub pipeline_id: PipelineId,
|
pub pipeline_id: PipelineId,
|
||||||
|
|
||||||
@@ -816,7 +816,7 @@ pub struct CompositorDisplayListInfo {
|
|||||||
/// The epoch of the display list.
|
/// The epoch of the display list.
|
||||||
pub epoch: Epoch,
|
pub epoch: Epoch,
|
||||||
|
|
||||||
/// A ScrollTree used by the compositor to scroll the contents of the
|
/// A ScrollTree used by `Paint` to scroll the contents of the
|
||||||
/// display list.
|
/// display list.
|
||||||
pub scroll_tree: ScrollTree,
|
pub scroll_tree: ScrollTree,
|
||||||
|
|
||||||
@@ -838,8 +838,8 @@ pub struct CompositorDisplayListInfo {
|
|||||||
pub first_reflow: bool,
|
pub first_reflow: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompositorDisplayListInfo {
|
impl PaintDisplayListInfo {
|
||||||
/// Create a new CompositorDisplayListInfo with the root reference frame
|
/// Create a new PaintDisplayListInfo with the root reference frame
|
||||||
/// and scroll frame already added to the scroll tree.
|
/// and scroll frame already added to the scroll tree.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
viewport_details: ViewportDetails,
|
viewport_details: ViewportDetails,
|
||||||
@@ -875,7 +875,7 @@ impl CompositorDisplayListInfo {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
CompositorDisplayListInfo {
|
PaintDisplayListInfo {
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
viewport_details,
|
viewport_details,
|
||||||
content_size,
|
content_size,
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use base::generic_channel::{self, GenericCallback, GenericSender};
|
use base::generic_channel::{self, GenericCallback, GenericSender};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use display_list::CompositorDisplayListInfo;
|
use display_list::PaintDisplayListInfo;
|
||||||
use embedder_traits::ScreenGeometry;
|
use embedder_traits::ScreenGeometry;
|
||||||
use euclid::default::Size2D as UntypedSize2D;
|
use euclid::default::Size2D as UntypedSize2D;
|
||||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||||
@@ -47,25 +47,25 @@ use webrender_api::{
|
|||||||
use crate::largest_contentful_paint_candidate::LCPCandidate;
|
use crate::largest_contentful_paint_candidate::LCPCandidate;
|
||||||
use crate::viewport_description::ViewportDescription;
|
use crate::viewport_description::ViewportDescription;
|
||||||
|
|
||||||
/// Sends messages to the compositor.
|
/// Sends messages to `Paint`.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CompositorProxy {
|
pub struct PaintProxy {
|
||||||
pub sender: Sender<Result<CompositorMsg, ipc_channel::Error>>,
|
pub sender: Sender<Result<PaintMessage, ipc_channel::Error>>,
|
||||||
/// Access to [`Self::sender`] that is possible to send across an IPC
|
/// Access to [`Self::sender`] that is possible to send across an IPC
|
||||||
/// channel. These messages are routed via the router thread to
|
/// channel. These messages are routed via the router thread to
|
||||||
/// [`Self::sender`].
|
/// [`Self::sender`].
|
||||||
pub cross_process_compositor_api: CrossProcessCompositorApi,
|
pub cross_process_paint_api: CrossProcessPaintApi,
|
||||||
pub event_loop_waker: Box<dyn EventLoopWaker>,
|
pub event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OpaqueSender<CompositorMsg> for CompositorProxy {
|
impl OpaqueSender<PaintMessage> for PaintProxy {
|
||||||
fn send(&self, message: CompositorMsg) {
|
fn send(&self, message: PaintMessage) {
|
||||||
CompositorProxy::send(self, message)
|
PaintProxy::send(self, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CompositorProxy {
|
impl PaintProxy {
|
||||||
pub fn send(&self, msg: CompositorMsg) {
|
pub fn send(&self, msg: PaintMessage) {
|
||||||
self.route_msg(Ok(msg))
|
self.route_msg(Ok(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ impl CompositorProxy {
|
|||||||
///
|
///
|
||||||
/// This method is a temporary solution, and will be removed when migrating
|
/// This method is a temporary solution, and will be removed when migrating
|
||||||
/// to `GenericChannel`.
|
/// to `GenericChannel`.
|
||||||
pub fn route_msg(&self, msg: Result<CompositorMsg, ipc_channel::Error>) {
|
pub fn route_msg(&self, msg: Result<PaintMessage, ipc_channel::Error>) {
|
||||||
if let Err(err) = self.sender.send(msg) {
|
if let Err(err) = self.sender.send(msg) {
|
||||||
warn!("Failed to send response ({:?}).", err);
|
warn!("Failed to send response ({:?}).", err);
|
||||||
}
|
}
|
||||||
@@ -81,16 +81,16 @@ impl CompositorProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Messages from (or via) the constellation thread to the compositor.
|
/// Messages from (or via) the constellation thread to `Paint`.
|
||||||
#[derive(Deserialize, IntoStaticStr, Serialize)]
|
#[derive(Deserialize, IntoStaticStr, Serialize)]
|
||||||
pub enum CompositorMsg {
|
pub enum PaintMessage {
|
||||||
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
|
/// Alerts `Paint` that the given pipeline has changed whether it is running animations.
|
||||||
ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
|
ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
|
||||||
/// Updates the frame tree for the given webview.
|
/// Updates the frame tree for the given webview.
|
||||||
SetFrameTreeForWebView(WebViewId, SendableFrameTree),
|
SetFrameTreeForWebView(WebViewId, SendableFrameTree),
|
||||||
/// Set whether to use less resources by stopping animations.
|
/// Set whether to use less resources by stopping animations.
|
||||||
SetThrottled(WebViewId, PipelineId, bool),
|
SetThrottled(WebViewId, PipelineId, bool),
|
||||||
/// WebRender has produced a new frame. This message informs the compositor that
|
/// WebRender has produced a new frame. This message informs `Paint` that
|
||||||
/// the frame is ready. It contains a bool to indicate if it needs to composite, the
|
/// the frame is ready. It contains a bool to indicate if it needs to composite, the
|
||||||
/// `DocumentId` of the new frame and the `PainterId` of the associated painter.
|
/// `DocumentId` of the new frame and the `PainterId` of the associated painter.
|
||||||
NewWebRenderFrameReady(PainterId, DocumentId, bool),
|
NewWebRenderFrameReady(PainterId, DocumentId, bool),
|
||||||
@@ -172,19 +172,19 @@ pub enum CompositorMsg {
|
|||||||
),
|
),
|
||||||
/// Remove the given font resources from our WebRender instance.
|
/// Remove the given font resources from our WebRender instance.
|
||||||
RemoveFonts(PainterId, Vec<FontKey>, Vec<FontInstanceKey>),
|
RemoveFonts(PainterId, Vec<FontKey>, Vec<FontInstanceKey>),
|
||||||
/// Measure the current memory usage associated with the compositor.
|
/// Measure the current memory usage associated with `Paint`.
|
||||||
/// The report must be sent on the provided channel once it's complete.
|
/// The report must be sent on the provided channel once it's complete.
|
||||||
CollectMemoryReport(ReportsChan),
|
CollectMemoryReport(ReportsChan),
|
||||||
/// A top-level frame has parsed a viewport metatag and is sending the new constraints.
|
/// A top-level frame has parsed a viewport metatag and is sending the new constraints.
|
||||||
Viewport(WebViewId, ViewportDescription),
|
Viewport(WebViewId, ViewportDescription),
|
||||||
/// Let the compositor know that the given WebView is ready to have a screenshot taken
|
/// Let `Paint` know that the given WebView is ready to have a screenshot taken
|
||||||
/// after the given pipeline's epochs have been rendered.
|
/// after the given pipeline's epochs have been rendered.
|
||||||
ScreenshotReadinessReponse(WebViewId, FxHashMap<PipelineId, Epoch>),
|
ScreenshotReadinessReponse(WebViewId, FxHashMap<PipelineId, Epoch>),
|
||||||
/// The candidate of largest-contentful-paint
|
/// The candidate of largest-contentful-paint
|
||||||
SendLCPCandidate(LCPCandidate, WebViewId, PipelineId, Epoch),
|
SendLCPCandidate(LCPCandidate, WebViewId, PipelineId, Epoch),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for CompositorMsg {
|
impl Debug for PaintMessage {
|
||||||
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
||||||
let string: &'static str = self.into();
|
let string: &'static str = self.into();
|
||||||
write!(formatter, "{string}")
|
write!(formatter, "{string}")
|
||||||
@@ -206,29 +206,29 @@ pub struct CompositionPipeline {
|
|||||||
|
|
||||||
/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
|
/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
|
||||||
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
|
||||||
pub struct CrossProcessCompositorApi(GenericCallback<CompositorMsg>);
|
pub struct CrossProcessPaintApi(GenericCallback<PaintMessage>);
|
||||||
|
|
||||||
impl CrossProcessCompositorApi {
|
impl CrossProcessPaintApi {
|
||||||
/// Create a new [`CrossProcessCompositorApi`] struct.
|
/// Create a new [`CrossProcessPaintApi`] struct.
|
||||||
pub fn new(callback: GenericCallback<CompositorMsg>) -> Self {
|
pub fn new(callback: GenericCallback<PaintMessage>) -> Self {
|
||||||
CrossProcessCompositorApi(callback)
|
CrossProcessPaintApi(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`CrossProcessCompositorApi`] struct that does not have a listener on the other
|
/// Create a new [`CrossProcessPaintApi`] struct that does not have a listener on the other
|
||||||
/// end to use for unit testing.
|
/// end to use for unit testing.
|
||||||
pub fn dummy() -> Self {
|
pub fn dummy() -> Self {
|
||||||
Self::dummy_with_callback(None)
|
Self::dummy_with_callback(None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new [`CrossProcessCompositorApi`] struct for unit testing with an optional callback
|
/// Create a new [`CrossProcessPaintApi`] struct for unit testing with an optional callback
|
||||||
/// that can respond to compositor messages.
|
/// that can respond to `PaintMessage`s.
|
||||||
pub fn dummy_with_callback(
|
pub fn dummy_with_callback(
|
||||||
callback: Option<Box<dyn Fn(CompositorMsg) + Send + 'static>>,
|
callback: Option<Box<dyn Fn(PaintMessage) + Send + 'static>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let callback = GenericCallback::new(move |msg| {
|
let callback = GenericCallback::new(move |msg| {
|
||||||
if let Some(ref handler) = callback {
|
if let Some(ref handler) = callback {
|
||||||
if let Ok(compositor_msg) = msg {
|
if let Ok(paint_message) = msg {
|
||||||
handler(compositor_msg);
|
handler(paint_message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -240,7 +240,7 @@ impl CrossProcessCompositorApi {
|
|||||||
pub fn send_initial_transaction(&self, webview_id: WebViewId, pipeline: WebRenderPipelineId) {
|
pub fn send_initial_transaction(&self, webview_id: WebViewId, pipeline: WebRenderPipelineId) {
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.0
|
.0
|
||||||
.send(CompositorMsg::SendInitialTransaction(webview_id, pipeline))
|
.send(PaintMessage::SendInitialTransaction(webview_id, pipeline))
|
||||||
{
|
{
|
||||||
warn!("Error sending initial transaction: {}", e);
|
warn!("Error sending initial transaction: {}", e);
|
||||||
}
|
}
|
||||||
@@ -256,7 +256,7 @@ impl CrossProcessCompositorApi {
|
|||||||
delta: LayoutVector2D,
|
delta: LayoutVector2D,
|
||||||
scroll_id: ExternalScrollId,
|
scroll_id: ExternalScrollId,
|
||||||
) {
|
) {
|
||||||
if let Err(error) = self.0.send(CompositorMsg::ScrollNodeByDelta(
|
if let Err(error) = self.0.send(PaintMessage::ScrollNodeByDelta(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
delta,
|
delta,
|
||||||
@@ -275,7 +275,7 @@ impl CrossProcessCompositorApi {
|
|||||||
pub fn scroll_viewport_by_delta(&self, webview_id: WebViewId, delta: LayoutVector2D) {
|
pub fn scroll_viewport_by_delta(&self, webview_id: WebViewId, delta: LayoutVector2D) {
|
||||||
if let Err(error) = self
|
if let Err(error) = self
|
||||||
.0
|
.0
|
||||||
.send(CompositorMsg::ScrollViewportByDelta(webview_id, delta))
|
.send(PaintMessage::ScrollViewportByDelta(webview_id, delta))
|
||||||
{
|
{
|
||||||
warn!("Error scroll viewport: {error}");
|
warn!("Error scroll viewport: {error}");
|
||||||
}
|
}
|
||||||
@@ -288,7 +288,7 @@ impl CrossProcessCompositorApi {
|
|||||||
canvas_epoch: Epoch,
|
canvas_epoch: Epoch,
|
||||||
image_keys: Vec<ImageKey>,
|
image_keys: Vec<ImageKey>,
|
||||||
) {
|
) {
|
||||||
if let Err(error) = self.0.send(CompositorMsg::DelayNewFrameForCanvas(
|
if let Err(error) = self.0.send(PaintMessage::DelayNewFrameForCanvas(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
canvas_epoch,
|
canvas_epoch,
|
||||||
@@ -301,7 +301,7 @@ impl CrossProcessCompositorApi {
|
|||||||
/// Inform the renderer that the rendering epoch has advanced. This typically happens after
|
/// Inform the renderer that the rendering epoch has advanced. This typically happens after
|
||||||
/// a new display list is sent and/or canvas and animated images are updated.
|
/// a new display list is sent and/or canvas and animated images are updated.
|
||||||
pub fn update_epoch(&self, webview_id: WebViewId, pipeline_id: PipelineId, epoch: Epoch) {
|
pub fn update_epoch(&self, webview_id: WebViewId, pipeline_id: PipelineId, epoch: Epoch) {
|
||||||
if let Err(error) = self.0.send(CompositorMsg::UpdateEpoch {
|
if let Err(error) = self.0.send(PaintMessage::UpdateEpoch {
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
epoch,
|
epoch,
|
||||||
@@ -314,12 +314,12 @@ impl CrossProcessCompositorApi {
|
|||||||
pub fn send_display_list(
|
pub fn send_display_list(
|
||||||
&self,
|
&self,
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
display_list_info: &CompositorDisplayListInfo,
|
display_list_info: &PaintDisplayListInfo,
|
||||||
list: BuiltDisplayList,
|
list: BuiltDisplayList,
|
||||||
) {
|
) {
|
||||||
let (display_list_data, display_list_descriptor) = list.into_data();
|
let (display_list_data, display_list_descriptor) = list.into_data();
|
||||||
let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
|
let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
|
||||||
if let Err(e) = self.0.send(CompositorMsg::SendDisplayList {
|
if let Err(e) = self.0.send(PaintMessage::SendDisplayList {
|
||||||
webview_id,
|
webview_id,
|
||||||
display_list_descriptor,
|
display_list_descriptor,
|
||||||
display_list_receiver,
|
display_list_receiver,
|
||||||
@@ -344,7 +344,7 @@ impl CrossProcessCompositorApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send the largest contentful paint candidate to the compositor.
|
/// Send the largest contentful paint candidate to `Paint`.
|
||||||
pub fn send_lcp_candidate(
|
pub fn send_lcp_candidate(
|
||||||
&self,
|
&self,
|
||||||
lcp_candidate: LCPCandidate,
|
lcp_candidate: LCPCandidate,
|
||||||
@@ -352,7 +352,7 @@ impl CrossProcessCompositorApi {
|
|||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
epoch: Epoch,
|
epoch: Epoch,
|
||||||
) {
|
) {
|
||||||
if let Err(error) = self.0.send(CompositorMsg::SendLCPCandidate(
|
if let Err(error) = self.0.send(PaintMessage::SendLCPCandidate(
|
||||||
lcp_candidate,
|
lcp_candidate,
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
@@ -364,7 +364,7 @@ impl CrossProcessCompositorApi {
|
|||||||
|
|
||||||
/// Ask the Servo renderer to generate a new frame after having new display lists.
|
/// Ask the Servo renderer to generate a new frame after having new display lists.
|
||||||
pub fn generate_frame(&self, painter_ids: Vec<PainterId>) {
|
pub fn generate_frame(&self, painter_ids: Vec<PainterId>) {
|
||||||
if let Err(error) = self.0.send(CompositorMsg::GenerateFrame(painter_ids)) {
|
if let Err(error) = self.0.send(PaintMessage::GenerateFrame(painter_ids)) {
|
||||||
warn!("Error generating frame: {error}");
|
warn!("Error generating frame: {error}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -373,20 +373,20 @@ impl CrossProcessCompositorApi {
|
|||||||
pub fn generate_image_key_blocking(&self, webview_id: WebViewId) -> Option<ImageKey> {
|
pub fn generate_image_key_blocking(&self, webview_id: WebViewId) -> Option<ImageKey> {
|
||||||
let (sender, receiver) = generic_channel::channel().unwrap();
|
let (sender, receiver) = generic_channel::channel().unwrap();
|
||||||
self.0
|
self.0
|
||||||
.send(CompositorMsg::GenerateImageKey(webview_id, sender))
|
.send(PaintMessage::GenerateImageKey(webview_id, sender))
|
||||||
.ok()?;
|
.ok()?;
|
||||||
receiver.recv().ok()
|
receiver.recv().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends a message to the compositor for creating new image keys.
|
/// Sends a message to `Paint` for creating new image keys.
|
||||||
/// The compositor will then send a batch of keys over the constellation to the script_thread
|
/// `Paint` will then send a batch of keys over the constellation to the script_thread
|
||||||
/// and the appropriate pipeline.
|
/// and the appropriate pipeline.
|
||||||
pub fn generate_image_key_async(&self, webview_id: WebViewId, pipeline_id: PipelineId) {
|
pub fn generate_image_key_async(&self, webview_id: WebViewId, pipeline_id: PipelineId) {
|
||||||
if let Err(e) = self.0.send(CompositorMsg::GenerateImageKeysForPipeline(
|
if let Err(e) = self.0.send(PaintMessage::GenerateImageKeysForPipeline(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
)) {
|
)) {
|
||||||
warn!("Could not send image keys to Compositor {}", e);
|
warn!("Could not send image keys to Paint {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,10 +421,7 @@ impl CrossProcessCompositorApi {
|
|||||||
|
|
||||||
/// Perform an image resource update operation.
|
/// Perform an image resource update operation.
|
||||||
pub fn update_images(&self, painter_id: PainterId, updates: SmallVec<[ImageUpdate; 1]>) {
|
pub fn update_images(&self, painter_id: PainterId, updates: SmallVec<[ImageUpdate; 1]>) {
|
||||||
if let Err(e) = self
|
if let Err(e) = self.0.send(PaintMessage::UpdateImages(painter_id, updates)) {
|
||||||
.0
|
|
||||||
.send(CompositorMsg::UpdateImages(painter_id, updates))
|
|
||||||
{
|
|
||||||
warn!("error sending image updates: {}", e);
|
warn!("error sending image updates: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,7 +437,7 @@ impl CrossProcessCompositorApi {
|
|||||||
}
|
}
|
||||||
let _ = self
|
let _ = self
|
||||||
.0
|
.0
|
||||||
.send(CompositorMsg::RemoveFonts(painter_id, keys, instance_keys));
|
.send(PaintMessage::RemoveFonts(painter_id, keys, instance_keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_font_instance(
|
pub fn add_font_instance(
|
||||||
@@ -451,7 +448,7 @@ impl CrossProcessCompositorApi {
|
|||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
variations: Vec<FontVariation>,
|
variations: Vec<FontVariation>,
|
||||||
) {
|
) {
|
||||||
let _x = self.0.send(CompositorMsg::AddFontInstance(
|
let _x = self.0.send(PaintMessage::AddFontInstance(
|
||||||
font_key.into(),
|
font_key.into(),
|
||||||
font_instance_key,
|
font_instance_key,
|
||||||
font_key,
|
font_key,
|
||||||
@@ -462,7 +459,7 @@ impl CrossProcessCompositorApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
|
pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
|
||||||
let _ = self.0.send(CompositorMsg::AddFont(
|
let _ = self.0.send(PaintMessage::AddFont(
|
||||||
font_key.into(),
|
font_key.into(),
|
||||||
font_key,
|
font_key,
|
||||||
data,
|
data,
|
||||||
@@ -471,7 +468,7 @@ impl CrossProcessCompositorApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
|
pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
|
||||||
let _ = self.0.send(CompositorMsg::AddSystemFont(
|
let _ = self.0.send(PaintMessage::AddSystemFont(
|
||||||
font_key.into(),
|
font_key.into(),
|
||||||
font_key,
|
font_key,
|
||||||
handle,
|
handle,
|
||||||
@@ -485,7 +482,7 @@ impl CrossProcessCompositorApi {
|
|||||||
painter_id: PainterId,
|
painter_id: PainterId,
|
||||||
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
|
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
|
||||||
let (sender, receiver) = generic_channel::channel().expect("Could not create IPC channel");
|
let (sender, receiver) = generic_channel::channel().expect("Could not create IPC channel");
|
||||||
let _ = self.0.send(CompositorMsg::GenerateFontKeys(
|
let _ = self.0.send(PaintMessage::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
sender,
|
sender,
|
||||||
@@ -495,9 +492,7 @@ impl CrossProcessCompositorApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn viewport(&self, webview_id: WebViewId, description: ViewportDescription) {
|
pub fn viewport(&self, webview_id: WebViewId, description: ViewportDescription) {
|
||||||
let _ = self
|
let _ = self.0.send(PaintMessage::Viewport(webview_id, description));
|
||||||
.0
|
|
||||||
.send(CompositorMsg::Viewport(webview_id, description));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pipeline_exited(
|
pub fn pipeline_exited(
|
||||||
@@ -506,7 +501,7 @@ impl CrossProcessCompositorApi {
|
|||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
source: PipelineExitSource,
|
source: PipelineExitSource,
|
||||||
) {
|
) {
|
||||||
let _ = self.0.send(CompositorMsg::PipelineExited(
|
let _ = self.0.send(PaintMessage::PipelineExited(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
source,
|
source,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use base::id::{
|
|||||||
ServiceWorkerRegistrationId, WebViewId,
|
ServiceWorkerRegistrationId, WebViewId,
|
||||||
};
|
};
|
||||||
use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use content_security_policy::sandboxing_directive::SandboxingFlagSet;
|
use content_security_policy::sandboxing_directive::SandboxingFlagSet;
|
||||||
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
|
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
@@ -236,8 +236,8 @@ pub struct SWManagerSenders {
|
|||||||
pub swmanager_sender: GenericSender<SWManagerMsg>,
|
pub swmanager_sender: GenericSender<SWManagerMsg>,
|
||||||
/// [`ResourceThreads`] for initating fetches or using i/o.
|
/// [`ResourceThreads`] for initating fetches or using i/o.
|
||||||
pub resource_threads: ResourceThreads,
|
pub resource_threads: ResourceThreads,
|
||||||
/// [`CrossProcessCompositorApi`] for communicating with the compositor.
|
/// [`CrossProcessPaintApi`] for communicating with `Paint`.
|
||||||
pub compositor_api: CrossProcessCompositorApi,
|
pub paint_api: CrossProcessPaintApi,
|
||||||
/// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
|
/// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
|
||||||
pub system_font_service_sender: SystemFontServiceProxySender,
|
pub system_font_service_sender: SystemFontServiceProxySender,
|
||||||
/// Sender of messages to the manager.
|
/// Sender of messages to the manager.
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ use base::cross_process_instant::CrossProcessInstant;
|
|||||||
use base::id::{MessagePortId, PipelineId, ScriptEventLoopId, WebViewId};
|
use base::id::{MessagePortId, PipelineId, ScriptEventLoopId, WebViewId};
|
||||||
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
|
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, InputEventAndId,
|
EmbedderControlId, EmbedderControlResponse, InputEventAndId, JavaScriptEvaluationId,
|
||||||
JavaScriptEvaluationId, MediaSessionActionType, Theme, TraversalId, ViewportDetails,
|
MediaSessionActionType, PaintHitTestResult, Theme, TraversalId, ViewportDetails,
|
||||||
WebDriverCommandMsg,
|
WebDriverCommandMsg,
|
||||||
};
|
};
|
||||||
pub use from_script_message::*;
|
pub use from_script_message::*;
|
||||||
@@ -79,7 +79,7 @@ pub enum EmbedderToConstellationMessage {
|
|||||||
/// Make none of the webviews focused.
|
/// Make none of the webviews focused.
|
||||||
BlurWebView,
|
BlurWebView,
|
||||||
/// Forward an input event to an appropriate ScriptTask.
|
/// Forward an input event to an appropriate ScriptTask.
|
||||||
ForwardInputEvent(WebViewId, InputEventAndId, Option<CompositorHitTestResult>),
|
ForwardInputEvent(WebViewId, InputEventAndId, Option<PaintHitTestResult>),
|
||||||
/// Request that the given pipeline refresh the cursor by doing a hit test at the most
|
/// Request that the given pipeline refresh the cursor by doing a hit test at the most
|
||||||
/// recently hovered cursor position and resetting the cursor. This happens after a
|
/// recently hovered cursor position and resetting the cursor. This happens after a
|
||||||
/// display list update is rendered.
|
/// display list update is rendered.
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ pub struct ViewportDetails {
|
|||||||
pub size: Size2D<f32, CSSPixel>,
|
pub size: Size2D<f32, CSSPixel>,
|
||||||
|
|
||||||
/// The scale factor to use to account for HiDPI scaling. This does not take into account
|
/// The scale factor to use to account for HiDPI scaling. This does not take into account
|
||||||
/// any page or pinch zoom applied by the compositor to the contents.
|
/// any page or pinch zoom applied by `Paint` to the contents.
|
||||||
pub hidpi_scale_factor: Scale<f32, CSSPixel, DevicePixel>,
|
pub hidpi_scale_factor: Scale<f32, CSSPixel, DevicePixel>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -877,9 +877,9 @@ impl UntrustedNodeAddress {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of a hit test in the compositor.
|
/// The result of a hit test in `Paint`.
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct CompositorHitTestResult {
|
pub struct PaintHitTestResult {
|
||||||
/// The pipeline id of the resulting item.
|
/// The pipeline id of the resulting item.
|
||||||
pub pipeline_id: PipelineId,
|
pub pipeline_id: PipelineId,
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use base::Epoch;
|
|||||||
use base::generic_channel::GenericSender;
|
use base::generic_channel::GenericSender;
|
||||||
use base::id::{BrowsingContextId, PipelineId, WebViewId};
|
use base::id::{BrowsingContextId, PipelineId, WebViewId};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails};
|
use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails};
|
||||||
use euclid::Point2D;
|
use euclid::Point2D;
|
||||||
use euclid::default::{Point2D as UntypedPoint2D, Rect};
|
use euclid::default::{Point2D as UntypedPoint2D, Rect};
|
||||||
@@ -209,7 +209,7 @@ pub struct LayoutConfig {
|
|||||||
pub image_cache: Arc<dyn ImageCache>,
|
pub image_cache: Arc<dyn ImageCache>,
|
||||||
pub font_context: Arc<FontContext>,
|
pub font_context: Arc<FontContext>,
|
||||||
pub time_profiler_chan: time::ProfilerChan,
|
pub time_profiler_chan: time::ProfilerChan,
|
||||||
pub compositor_api: CrossProcessCompositorApi,
|
pub paint_api: CrossProcessPaintApi,
|
||||||
pub viewport_details: ViewportDetails,
|
pub viewport_details: ViewportDetails,
|
||||||
pub theme: Theme,
|
pub theme: Theme,
|
||||||
}
|
}
|
||||||
@@ -297,7 +297,7 @@ pub trait Layout {
|
|||||||
painter: Box<dyn Painter>,
|
painter: Box<dyn Painter>,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Set the scroll states of this layout after a compositor scroll.
|
/// Set the scroll states of this layout after a `Paint` scroll.
|
||||||
fn set_scroll_offsets_from_renderer(
|
fn set_scroll_offsets_from_renderer(
|
||||||
&mut self,
|
&mut self,
|
||||||
scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>,
|
scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use base::id::{PipelineId, WebViewId};
|
use base::id::{PipelineId, WebViewId};
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use malloc_size_of::MallocSizeOfOps;
|
use malloc_size_of::MallocSizeOfOps;
|
||||||
use malloc_size_of_derive::MallocSizeOf;
|
use malloc_size_of_derive::MallocSizeOf;
|
||||||
@@ -164,7 +164,7 @@ pub trait ImageCacheFactory: Sync + Send {
|
|||||||
&self,
|
&self,
|
||||||
webview_id: WebViewId,
|
webview_id: WebViewId,
|
||||||
pipeline_id: PipelineId,
|
pipeline_id: PipelineId,
|
||||||
compositor_api: &CrossProcessCompositorApi,
|
paint_api: &CrossProcessPaintApi,
|
||||||
) -> Arc<dyn ImageCache>;
|
) -> Arc<dyn ImageCache>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ pub enum ProfilerMsg {
|
|||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
|
||||||
pub enum ProfilerCategory {
|
pub enum ProfilerCategory {
|
||||||
/// The compositor is rasterising or presenting.
|
/// `Paint` is rasterising or presenting.
|
||||||
///
|
///
|
||||||
/// Not associated with a specific URL.
|
/// Not associated with a specific URL.
|
||||||
Compositing = 0x00,
|
Painting = 0x00,
|
||||||
|
|
||||||
/// The script thread is doing layout work.
|
/// The script thread is doing layout work.
|
||||||
Layout = 0x10,
|
Layout = 0x10,
|
||||||
@@ -128,7 +128,7 @@ pub enum ProfilerCategory {
|
|||||||
impl ProfilerCategory {
|
impl ProfilerCategory {
|
||||||
pub const fn variant_name(&self) -> &'static str {
|
pub const fn variant_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
ProfilerCategory::Compositing => "Compositing",
|
ProfilerCategory::Painting => "Painting",
|
||||||
ProfilerCategory::Layout => "Layout",
|
ProfilerCategory::Layout => "Layout",
|
||||||
ProfilerCategory::ImageSaving => "ImageSaving",
|
ProfilerCategory::ImageSaving => "ImageSaving",
|
||||||
ProfilerCategory::ScriptSpawnPipeline => "ScriptSpawnPipeline",
|
ProfilerCategory::ScriptSpawnPipeline => "ScriptSpawnPipeline",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use base::id::{
|
|||||||
#[cfg(feature = "bluetooth")]
|
#[cfg(feature = "bluetooth")]
|
||||||
use bluetooth_traits::BluetoothRequest;
|
use bluetooth_traits::BluetoothRequest;
|
||||||
use canvas_traits::webgl::WebGLPipeline;
|
use canvas_traits::webgl::WebGLPipeline;
|
||||||
use compositing_traits::CrossProcessCompositorApi;
|
use compositing_traits::CrossProcessPaintApi;
|
||||||
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
|
use compositing_traits::largest_contentful_paint_candidate::LargestContentfulPaintType;
|
||||||
use constellation_traits::{
|
use constellation_traits::{
|
||||||
KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationSender,
|
KeyboardScroll, LoadData, NavigationHistoryBehavior, ScriptToConstellationSender,
|
||||||
@@ -30,9 +30,9 @@ use crossbeam_channel::RecvTimeoutError;
|
|||||||
use devtools_traits::ScriptToDevtoolsControlMsg;
|
use devtools_traits::ScriptToDevtoolsControlMsg;
|
||||||
use embedder_traits::user_content_manager::UserContentManager;
|
use embedder_traits::user_content_manager::UserContentManager;
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
CompositorHitTestResult, EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber,
|
EmbedderControlId, EmbedderControlResponse, FocusSequenceNumber, InputEventAndId,
|
||||||
InputEventAndId, JavaScriptEvaluationId, MediaSessionActionType, ScriptToEmbedderChan, Theme,
|
JavaScriptEvaluationId, MediaSessionActionType, PaintHitTestResult, ScriptToEmbedderChan,
|
||||||
ViewportDetails, WebDriverScriptCommand,
|
Theme, ViewportDetails, WebDriverScriptCommand,
|
||||||
};
|
};
|
||||||
use euclid::{Scale, Size2D};
|
use euclid::{Scale, Size2D};
|
||||||
use fonts_traits::SystemFontServiceProxySender;
|
use fonts_traits::SystemFontServiceProxySender;
|
||||||
@@ -142,7 +142,7 @@ pub enum UpdatePipelineIdReason {
|
|||||||
Traversal,
|
Traversal,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Messages sent to the `ScriptThread` event loop from the `Constellation`, `Compositor`, and (for
|
/// Messages sent to the `ScriptThread` event loop from the `Constellation`, `Paint`, and (for
|
||||||
/// now) `Layout`.
|
/// now) `Layout`.
|
||||||
#[derive(Deserialize, IntoStaticStr, Serialize)]
|
#[derive(Deserialize, IntoStaticStr, Serialize)]
|
||||||
pub enum ScriptThreadMessage {
|
pub enum ScriptThreadMessage {
|
||||||
@@ -273,7 +273,7 @@ pub enum ScriptThreadMessage {
|
|||||||
/// Notifies script thread that WebGPU server has started
|
/// Notifies script thread that WebGPU server has started
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
SetWebGPUPort(IpcReceiver<WebGPUMsg>),
|
SetWebGPUPort(IpcReceiver<WebGPUMsg>),
|
||||||
/// The compositor scrolled and is updating the scroll states of the nodes in the given
|
/// `Paint` scrolled and is updating the scroll states of the nodes in the given
|
||||||
/// pipeline via the Constellation.
|
/// pipeline via the Constellation.
|
||||||
SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>),
|
SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>),
|
||||||
/// Evaluate the given JavaScript and return a result via a corresponding message
|
/// Evaluate the given JavaScript and return a result via a corresponding message
|
||||||
@@ -317,7 +317,7 @@ pub enum DocumentState {
|
|||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
pub struct ConstellationInputEvent {
|
pub struct ConstellationInputEvent {
|
||||||
/// The hit test result of this input event, if any.
|
/// The hit test result of this input event, if any.
|
||||||
pub hit_test_result: Option<CompositorHitTestResult>,
|
pub hit_test_result: Option<PaintHitTestResult>,
|
||||||
/// The pressed mouse button state of the constellation when this input
|
/// The pressed mouse button state of the constellation when this input
|
||||||
/// event was triggered.
|
/// event was triggered.
|
||||||
pub pressed_mouse_buttons: u16,
|
pub pressed_mouse_buttons: u16,
|
||||||
@@ -368,8 +368,8 @@ pub struct InitialScriptState {
|
|||||||
pub webgl_chan: Option<WebGLPipeline>,
|
pub webgl_chan: Option<WebGLPipeline>,
|
||||||
/// The XR device registry
|
/// The XR device registry
|
||||||
pub webxr_registry: Option<webxr_api::Registry>,
|
pub webxr_registry: Option<webxr_api::Registry>,
|
||||||
/// Access to the compositor across a process boundary.
|
/// Access to `Paint` across a process boundary.
|
||||||
pub cross_process_compositor_api: CrossProcessCompositorApi,
|
pub cross_process_paint_api: CrossProcessPaintApi,
|
||||||
/// Application window's GL Context for Media player
|
/// Application window's GL Context for Media player
|
||||||
pub player_context: WindowGLContext,
|
pub player_context: WindowGLContext,
|
||||||
/// User content manager
|
/// User content manager
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads, webgl_channel};
|
use canvas_traits::webgl::{WebGLContextId, WebGLMsg, WebGLThreads, webgl_channel};
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CrossProcessCompositorApi, PainterSurfmanDetailsMap, WebRenderExternalImageIdManager,
|
CrossProcessPaintApi, PainterSurfmanDetailsMap, WebRenderExternalImageIdManager,
|
||||||
};
|
};
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use surfman::Device;
|
use surfman::Device;
|
||||||
@@ -27,7 +27,7 @@ pub struct WebGLComm {
|
|||||||
impl WebGLComm {
|
impl WebGLComm {
|
||||||
/// Creates a new `WebGLComm` object.
|
/// Creates a new `WebGLComm` object.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
external_image_id_manager: WebRenderExternalImageIdManager,
|
external_image_id_manager: WebRenderExternalImageIdManager,
|
||||||
painter_surfman_details_map: PainterSurfmanDetailsMap,
|
painter_surfman_details_map: PainterSurfmanDetailsMap,
|
||||||
) -> WebGLComm {
|
) -> WebGLComm {
|
||||||
@@ -43,7 +43,7 @@ impl WebGLComm {
|
|||||||
|
|
||||||
// This implementation creates a single `WebGLThread` for all the pipelines.
|
// This implementation creates a single `WebGLThread` for all the pipelines.
|
||||||
let init = WebGLThreadInit {
|
let init = WebGLThreadInit {
|
||||||
compositor_api,
|
paint_api,
|
||||||
external_image_id_manager,
|
external_image_id_manager,
|
||||||
sender: sender.clone(),
|
sender: sender.clone(),
|
||||||
receiver,
|
receiver,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ use canvas_traits::webgl::{
|
|||||||
WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
|
WebGLVersion, WebGLVertexArrayId, YAxisTreatment,
|
||||||
};
|
};
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CrossProcessCompositorApi, PainterSurfmanDetailsMap, SerializableImageData,
|
CrossProcessPaintApi, PainterSurfmanDetailsMap, SerializableImageData,
|
||||||
WebRenderExternalImageIdManager, WebRenderImageHandlerType,
|
WebRenderExternalImageIdManager, WebRenderImageHandlerType,
|
||||||
};
|
};
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
@@ -220,7 +220,7 @@ pub(crate) struct WebGLThread {
|
|||||||
/// The GPU device.
|
/// The GPU device.
|
||||||
device_map: HashMap<PainterId, Rc<Device>>,
|
device_map: HashMap<PainterId, Rc<Device>>,
|
||||||
/// Channel used to generate/update or delete `ImageKey`s.
|
/// Channel used to generate/update or delete `ImageKey`s.
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
/// Map of live WebGLContexts.
|
/// Map of live WebGLContexts.
|
||||||
contexts: FxHashMap<WebGLContextId, GLContextData>,
|
contexts: FxHashMap<WebGLContextId, GLContextData>,
|
||||||
/// Cached information for WebGLContexts.
|
/// Cached information for WebGLContexts.
|
||||||
@@ -249,7 +249,7 @@ pub(crate) struct WebGLThread {
|
|||||||
|
|
||||||
/// The data required to initialize an instance of the WebGLThread type.
|
/// The data required to initialize an instance of the WebGLThread type.
|
||||||
pub(crate) struct WebGLThreadInit {
|
pub(crate) struct WebGLThreadInit {
|
||||||
pub compositor_api: CrossProcessCompositorApi,
|
pub paint_api: CrossProcessPaintApi,
|
||||||
pub external_image_id_manager: WebRenderExternalImageIdManager,
|
pub external_image_id_manager: WebRenderExternalImageIdManager,
|
||||||
pub sender: WebGLSender<WebGLMsg>,
|
pub sender: WebGLSender<WebGLMsg>,
|
||||||
pub receiver: WebGLReceiver<WebGLMsg>,
|
pub receiver: WebGLReceiver<WebGLMsg>,
|
||||||
@@ -267,7 +267,7 @@ impl WebGLThread {
|
|||||||
/// Create a new instance of WebGLThread.
|
/// Create a new instance of WebGLThread.
|
||||||
pub(crate) fn new(
|
pub(crate) fn new(
|
||||||
WebGLThreadInit {
|
WebGLThreadInit {
|
||||||
compositor_api,
|
paint_api,
|
||||||
external_image_id_manager: external_images,
|
external_image_id_manager: external_images,
|
||||||
sender,
|
sender,
|
||||||
receiver,
|
receiver,
|
||||||
@@ -280,7 +280,7 @@ impl WebGLThread {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
WebGLThread {
|
WebGLThread {
|
||||||
device_map: Default::default(),
|
device_map: Default::default(),
|
||||||
compositor_api,
|
paint_api,
|
||||||
contexts: Default::default(),
|
contexts: Default::default(),
|
||||||
cached_context_info: Default::default(),
|
cached_context_info: Default::default(),
|
||||||
bound_context_id: None,
|
bound_context_id: None,
|
||||||
@@ -770,7 +770,7 @@ impl WebGLThread {
|
|||||||
.remove(&context_id)
|
.remove(&context_id)
|
||||||
.and_then(|info| info.image_key)
|
.and_then(|info| info.image_key)
|
||||||
{
|
{
|
||||||
self.compositor_api.delete_image(image_key);
|
self.paint_api.delete_image(image_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.contexts.contains_key(&context_id) {
|
if !self.contexts.contains_key(&context_id) {
|
||||||
@@ -951,7 +951,7 @@ impl WebGLThread {
|
|||||||
info.alpha = has_alpha;
|
info.alpha = has_alpha;
|
||||||
|
|
||||||
if let Some(image_key) = info.image_key {
|
if let Some(image_key) = info.image_key {
|
||||||
self.compositor_api.update_image(
|
self.paint_api.update_image(
|
||||||
image_key,
|
image_key,
|
||||||
info.image_descriptor(),
|
info.image_descriptor(),
|
||||||
image_data,
|
image_data,
|
||||||
@@ -998,16 +998,16 @@ impl WebGLThread {
|
|||||||
fn handle_set_image_key(&mut self, context_id: WebGLContextId, image_key: ImageKey) {
|
fn handle_set_image_key(&mut self, context_id: WebGLContextId, image_key: ImageKey) {
|
||||||
let external_image_data = self.external_image_data(context_id);
|
let external_image_data = self.external_image_data(context_id);
|
||||||
let Some(info) = self.cached_context_info.get_mut(&context_id) else {
|
let Some(info) = self.cached_context_info.get_mut(&context_id) else {
|
||||||
self.compositor_api.delete_image(image_key);
|
self.paint_api.delete_image(image_key);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(old_image_key) = info.image_key.replace(image_key) {
|
if let Some(old_image_key) = info.image_key.replace(image_key) {
|
||||||
self.compositor_api.delete_image(old_image_key);
|
self.paint_api.delete_image(old_image_key);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compositor_api
|
self.paint_api
|
||||||
.add_image(image_key, info.image_descriptor(), external_image_data);
|
.add_image(image_key, info.image_descriptor(), external_image_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use base::Epoch;
|
use base::Epoch;
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CrossProcessCompositorApi, ExternalImageSource, SerializableImageData,
|
CrossProcessPaintApi, ExternalImageSource, SerializableImageData, WebRenderExternalImageApi,
|
||||||
WebRenderExternalImageApi,
|
|
||||||
};
|
};
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::IpcSender;
|
||||||
@@ -466,11 +465,7 @@ impl ContextData {
|
|||||||
|
|
||||||
/// Destroy the context that this [`ContextData`] represents,
|
/// Destroy the context that this [`ContextData`] represents,
|
||||||
/// freeing all of its buffers, and deleting the associated WebRender image.
|
/// freeing all of its buffers, and deleting the associated WebRender image.
|
||||||
fn destroy(
|
fn destroy(mut self, script_sender: &IpcSender<WebGPUMsg>, paint_api: &CrossProcessPaintApi) {
|
||||||
mut self,
|
|
||||||
script_sender: &IpcSender<WebGPUMsg>,
|
|
||||||
compositor_api: &CrossProcessCompositorApi,
|
|
||||||
) {
|
|
||||||
// This frees the id in the `ScriptThread`.
|
// This frees the id in the `ScriptThread`.
|
||||||
for staging_buffer in self.inactive_staging_buffers {
|
for staging_buffer in self.inactive_staging_buffers {
|
||||||
if let Err(error) = script_sender.send(WebGPUMsg::FreeBuffer(staging_buffer.buffer_id))
|
if let Err(error) = script_sender.send(WebGPUMsg::FreeBuffer(staging_buffer.buffer_id))
|
||||||
@@ -482,7 +477,7 @@ impl ContextData {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if let Some(image_key) = self.image_key.take() {
|
if let Some(image_key) = self.image_key.take() {
|
||||||
compositor_api.delete_image(image_key);
|
paint_api.delete_image(image_key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,10 +540,10 @@ impl crate::WGPU {
|
|||||||
let context_data = webgpu_contexts.get_mut(&context_id).unwrap();
|
let context_data = webgpu_contexts.get_mut(&context_id).unwrap();
|
||||||
|
|
||||||
if let Some(old_image_key) = context_data.image_key.replace(image_key) {
|
if let Some(old_image_key) = context_data.image_key.replace(image_key) {
|
||||||
self.compositor_api.delete_image(old_image_key);
|
self.paint_api.delete_image(old_image_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.compositor_api.add_image(
|
self.paint_api.add_image(
|
||||||
image_key,
|
image_key,
|
||||||
ImageDescriptor {
|
ImageDescriptor {
|
||||||
format: ImageFormat::BGRA8,
|
format: ImageFormat::BGRA8,
|
||||||
@@ -655,7 +650,7 @@ impl crate::WGPU {
|
|||||||
}) = pending_texture
|
}) = pending_texture
|
||||||
else {
|
else {
|
||||||
context_data.clear_presentation();
|
context_data.clear_presentation();
|
||||||
self.compositor_api.update_image(
|
self.paint_api.update_image(
|
||||||
image_key,
|
image_key,
|
||||||
ImageDescriptor {
|
ImageDescriptor {
|
||||||
format: ImageFormat::BGRA8,
|
format: ImageFormat::BGRA8,
|
||||||
@@ -672,7 +667,7 @@ impl crate::WGPU {
|
|||||||
let Some(staging_buffer) = context_data.get_or_make_available_buffer(&configuration) else {
|
let Some(staging_buffer) = context_data.get_or_make_available_buffer(&configuration) else {
|
||||||
warn!("Failure obtaining available staging buffer");
|
warn!("Failure obtaining available staging buffer");
|
||||||
context_data.clear_presentation();
|
context_data.clear_presentation();
|
||||||
self.compositor_api.update_image(
|
self.paint_api.update_image(
|
||||||
image_key,
|
image_key,
|
||||||
configuration.into(),
|
configuration.into(),
|
||||||
SerializableImageData::External(image_data(context_id)),
|
SerializableImageData::External(image_data(context_id)),
|
||||||
@@ -682,7 +677,7 @@ impl crate::WGPU {
|
|||||||
};
|
};
|
||||||
let epoch = context_data.next_epoch();
|
let epoch = context_data.next_epoch();
|
||||||
let wgpu_image_map = self.wgpu_image_map.clone();
|
let wgpu_image_map = self.wgpu_image_map.clone();
|
||||||
let compositor_api = self.compositor_api.clone();
|
let paint_api = self.paint_api.clone();
|
||||||
drop(webgpu_contexts);
|
drop(webgpu_contexts);
|
||||||
self.texture_download(
|
self.texture_download(
|
||||||
texture_id,
|
texture_id,
|
||||||
@@ -702,7 +697,7 @@ impl crate::WGPU {
|
|||||||
context_data.clear_presentation();
|
context_data.clear_presentation();
|
||||||
}
|
}
|
||||||
// update image in WR
|
// update image in WR
|
||||||
compositor_api.update_image(
|
paint_api.update_image(
|
||||||
image_key,
|
image_key,
|
||||||
configuration.into(),
|
configuration.into(),
|
||||||
SerializableImageData::External(image_data(context_id)),
|
SerializableImageData::External(image_data(context_id)),
|
||||||
@@ -798,6 +793,6 @@ impl crate::WGPU {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.remove(&context_id)
|
.remove(&context_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.destroy(&self.script_sender, &self.compositor_api);
|
.destroy(&self.script_sender, &self.paint_api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,14 +14,14 @@ mod wgpu_thread;
|
|||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use compositing_traits::{CrossProcessCompositorApi, WebRenderExternalImageIdManager};
|
use compositing_traits::{CrossProcessPaintApi, WebRenderExternalImageIdManager};
|
||||||
use ipc_channel::ipc::{self, IpcReceiver};
|
use ipc_channel::ipc::{self, IpcReceiver};
|
||||||
use servo_config::pref;
|
use servo_config::pref;
|
||||||
|
|
||||||
pub mod canvas_context;
|
pub mod canvas_context;
|
||||||
|
|
||||||
pub fn start_webgpu_thread(
|
pub fn start_webgpu_thread(
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
webrender_external_image_id_manager: WebRenderExternalImageIdManager,
|
webrender_external_image_id_manager: WebRenderExternalImageIdManager,
|
||||||
wgpu_image_map: WebGpuExternalImageMap,
|
wgpu_image_map: WebGpuExternalImageMap,
|
||||||
) -> Option<(WebGPU, IpcReceiver<WebGPUMsg>)> {
|
) -> Option<(WebGPU, IpcReceiver<WebGPUMsg>)> {
|
||||||
@@ -58,7 +58,7 @@ pub fn start_webgpu_thread(
|
|||||||
receiver,
|
receiver,
|
||||||
sender_clone,
|
sender_clone,
|
||||||
script_sender,
|
script_sender,
|
||||||
compositor_api,
|
paint_api,
|
||||||
webrender_external_image_id_manager,
|
webrender_external_image_id_manager,
|
||||||
wgpu_image_map,
|
wgpu_image_map,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use base::id::PipelineId;
|
use base::id::PipelineId;
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CrossProcessCompositorApi, WebRenderExternalImageIdManager, WebRenderImageHandlerType,
|
CrossProcessPaintApi, WebRenderExternalImageIdManager, WebRenderImageHandlerType,
|
||||||
};
|
};
|
||||||
use ipc_channel::ipc::{IpcReceiver, IpcSender, IpcSharedMemory};
|
use ipc_channel::ipc::{IpcReceiver, IpcSender, IpcSharedMemory};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
@@ -104,7 +104,7 @@ pub(crate) struct WGPU {
|
|||||||
/// because wgpu does not invalidate command encoder object
|
/// because wgpu does not invalidate command encoder object
|
||||||
/// (this is also reused for invalidation of command buffers)
|
/// (this is also reused for invalidation of command buffers)
|
||||||
error_command_encoders: FxHashMap<id::CommandEncoderId, String>,
|
error_command_encoders: FxHashMap<id::CommandEncoderId, String>,
|
||||||
pub(crate) compositor_api: CrossProcessCompositorApi,
|
pub(crate) paint_api: CrossProcessPaintApi,
|
||||||
pub(crate) webrender_external_image_id_manager: WebRenderExternalImageIdManager,
|
pub(crate) webrender_external_image_id_manager: WebRenderExternalImageIdManager,
|
||||||
pub(crate) wgpu_image_map: WebGpuExternalImageMap,
|
pub(crate) wgpu_image_map: WebGpuExternalImageMap,
|
||||||
/// Provides access to poller thread
|
/// Provides access to poller thread
|
||||||
@@ -120,7 +120,7 @@ impl WGPU {
|
|||||||
receiver: IpcReceiver<WebGPURequest>,
|
receiver: IpcReceiver<WebGPURequest>,
|
||||||
sender: IpcSender<WebGPURequest>,
|
sender: IpcSender<WebGPURequest>,
|
||||||
script_sender: IpcSender<WebGPUMsg>,
|
script_sender: IpcSender<WebGPUMsg>,
|
||||||
compositor_api: CrossProcessCompositorApi,
|
paint_api: CrossProcessPaintApi,
|
||||||
webrender_external_image_id_manager: WebRenderExternalImageIdManager,
|
webrender_external_image_id_manager: WebRenderExternalImageIdManager,
|
||||||
wgpu_image_map: WebGpuExternalImageMap,
|
wgpu_image_map: WebGpuExternalImageMap,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -149,7 +149,7 @@ impl WGPU {
|
|||||||
global,
|
global,
|
||||||
devices: Arc::new(Mutex::new(FxHashMap::default())),
|
devices: Arc::new(Mutex::new(FxHashMap::default())),
|
||||||
error_command_encoders: FxHashMap::default(),
|
error_command_encoders: FxHashMap::default(),
|
||||||
compositor_api,
|
paint_api,
|
||||||
webrender_external_image_id_manager,
|
webrender_external_image_id_manager,
|
||||||
wgpu_image_map,
|
wgpu_image_map,
|
||||||
compute_passes: FxHashMap::default(),
|
compute_passes: FxHashMap::default(),
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl PlatformWindow for Window {
|
|||||||
|
|
||||||
// Because we are managing the rendering surface ourselves, there will be no other
|
// Because we are managing the rendering surface ourselves, there will be no other
|
||||||
// notification (such as from the display manager) that it has changed size, so we
|
// notification (such as from the display manager) that it has changed size, so we
|
||||||
// must notify the compositor here.
|
// must notify `Paint` here.
|
||||||
webview.resize(PhysicalSize::new(
|
webview.resize(PhysicalSize::new(
|
||||||
new_size.width as u32,
|
new_size.width as u32,
|
||||||
new_size.height as u32,
|
new_size.height as u32,
|
||||||
@@ -150,7 +150,7 @@ impl PlatformWindow for Window {
|
|||||||
self.inner_size.set(self.screen_size);
|
self.inner_size.set(self.screen_size);
|
||||||
// Because we are managing the rendering surface ourselves, there will be no other
|
// Because we are managing the rendering surface ourselves, there will be no other
|
||||||
// notification (such as from the display manager) that it has changed size, so we
|
// notification (such as from the display manager) that it has changed size, so we
|
||||||
// must notify the compositor here.
|
// must notify the `Paint` here.
|
||||||
webview.resize(PhysicalSize::new(
|
webview.resize(PhysicalSize::new(
|
||||||
self.screen_size.width as u32,
|
self.screen_size.width as u32,
|
||||||
self.screen_size.height as u32,
|
self.screen_size.height as u32,
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_init<'local>(
|
|||||||
"script::dom::bindings::error",
|
"script::dom::bindings::error",
|
||||||
// Show GL errors by default.
|
// Show GL errors by default.
|
||||||
"canvas::webgl_thread",
|
"canvas::webgl_thread",
|
||||||
"compositing::compositor",
|
"compositing::paint",
|
||||||
"constellation::constellation",
|
"constellation::constellation",
|
||||||
];
|
];
|
||||||
let mut filter_builder = FilterBuilder::new();
|
let mut filter_builder = FilterBuilder::new();
|
||||||
@@ -518,22 +518,19 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_click(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn Java_org_servo_servoview_JNIServo_pauseCompositor(
|
pub extern "C" fn Java_org_servo_servoview_JNIServo_pausePainting(mut env: JNIEnv, _: JClass<'_>) {
|
||||||
mut env: JNIEnv,
|
debug!("pausePainting");
|
||||||
_: JClass<'_>,
|
call(&mut env, |s| s.pause_painting());
|
||||||
) {
|
|
||||||
debug!("pauseCompositor");
|
|
||||||
call(&mut env, |s| s.pause_compositor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn Java_org_servo_servoview_JNIServo_resumeCompositor<'local>(
|
pub extern "C" fn Java_org_servo_servoview_JNIServo_resumePainting<'local>(
|
||||||
mut env: JNIEnv<'local>,
|
mut env: JNIEnv<'local>,
|
||||||
_: JClass<'local>,
|
_: JClass<'local>,
|
||||||
surface: JObject<'local>,
|
surface: JObject<'local>,
|
||||||
coordinates: JObject<'local>,
|
coordinates: JObject<'local>,
|
||||||
) {
|
) {
|
||||||
debug!("resumeCompositor");
|
debug!("resumePainting");
|
||||||
let viewport_rect = match jni_coordinate_to_rust_viewport_rect(&mut env, &coordinates) {
|
let viewport_rect = match jni_coordinate_to_rust_viewport_rect(&mut env, &coordinates) {
|
||||||
Ok(viewport_rect) => viewport_rect,
|
Ok(viewport_rect) => viewport_rect,
|
||||||
Err(error) => return throw(&mut env, &error),
|
Err(error) => return throw(&mut env, &error),
|
||||||
@@ -541,7 +538,7 @@ pub extern "C" fn Java_org_servo_servoview_JNIServo_resumeCompositor<'local>(
|
|||||||
|
|
||||||
let (_, window_handle) = display_and_window_handle(&mut env, &surface);
|
let (_, window_handle) = display_and_window_handle(&mut env, &surface);
|
||||||
call(&mut env, |app| {
|
call(&mut env, |app| {
|
||||||
app.resume_compositor(window_handle, viewport_rect);
|
app.resume_painting(window_handle, viewport_rect);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -583,14 +583,14 @@ impl App {
|
|||||||
self.spin_event_loop();
|
self.spin_event_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pause_compositor(&self) {
|
pub fn pause_painting(&self) {
|
||||||
if let Err(e) = self.platform_window.rendering_context.take_window() {
|
if let Err(e) = self.platform_window.rendering_context.take_window() {
|
||||||
warn!("Unbinding native surface from context failed ({:?})", e);
|
warn!("Unbinding native surface from context failed ({:?})", e);
|
||||||
}
|
}
|
||||||
self.spin_event_loop();
|
self.spin_event_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resume_compositor(
|
pub fn resume_painting(
|
||||||
&self,
|
&self,
|
||||||
window_handle: RawWindowHandle,
|
window_handle: RawWindowHandle,
|
||||||
viewport_rect: Rect<i32, DevicePixel>,
|
viewport_rect: Rect<i32, DevicePixel>,
|
||||||
|
|||||||
@@ -400,12 +400,12 @@ impl ServoAction {
|
|||||||
.expect("Should always start with at least one WebView");
|
.expect("Should always start with at least one WebView");
|
||||||
if webview.id() != native_webview_components.id {
|
if webview.id() != native_webview_components.id {
|
||||||
servo.activate_webview(native_webview_components.id);
|
servo.activate_webview(native_webview_components.id);
|
||||||
servo.pause_compositor();
|
servo.pause_painting();
|
||||||
let (window_handle, viewport_rect) = get_raw_window_handle(
|
let (window_handle, viewport_rect) = get_raw_window_handle(
|
||||||
native_webview_components.xcomponent.0,
|
native_webview_components.xcomponent.0,
|
||||||
native_webview_components.window.0,
|
native_webview_components.window.0,
|
||||||
);
|
);
|
||||||
servo.resume_compositor(window_handle, viewport_rect);
|
servo.resume_painting(window_handle, viewport_rect);
|
||||||
let url = webview
|
let url = webview
|
||||||
.url()
|
.url()
|
||||||
.map(|u| u.to_string())
|
.map(|u| u.to_string())
|
||||||
@@ -419,12 +419,12 @@ impl ServoAction {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
NewWebview(xcomponent, window) => {
|
NewWebview(xcomponent, window) => {
|
||||||
servo.pause_compositor();
|
servo.pause_painting();
|
||||||
let webview =
|
let webview =
|
||||||
servo.create_and_activate_toplevel_webview("about:blank".parse().unwrap());
|
servo.create_and_activate_toplevel_webview("about:blank".parse().unwrap());
|
||||||
let (window_handle, viewport_rect) = get_raw_window_handle(xcomponent.0, window.0);
|
let (window_handle, viewport_rect) = get_raw_window_handle(xcomponent.0, window.0);
|
||||||
|
|
||||||
servo.resume_compositor(window_handle, viewport_rect);
|
servo.resume_painting(window_handle, viewport_rect);
|
||||||
let id = webview.id();
|
let id = webview.id();
|
||||||
NATIVE_WEBVIEWS
|
NATIVE_WEBVIEWS
|
||||||
.lock()
|
.lock()
|
||||||
@@ -700,7 +700,7 @@ static LOGGER: LazyLock<hilog::Logger> = LazyLock::new(|| {
|
|||||||
"script::dom::console",
|
"script::dom::console",
|
||||||
// Show GL errors by default.
|
// Show GL errors by default.
|
||||||
"canvas::webgl_thread",
|
"canvas::webgl_thread",
|
||||||
"compositing::compositor",
|
"compositing::paint",
|
||||||
"compositing::touch",
|
"compositing::touch",
|
||||||
"constellation::constellation",
|
"constellation::constellation",
|
||||||
"ohos_ime",
|
"ohos_ime",
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! The `servo` test application.
|
//! The `servoshell` test application.
|
||||||
//!
|
//!
|
||||||
//! Creates a `Servo` instance with a simple implementation of
|
//! Creates a `Servo` instance with a example implementation of a working
|
||||||
//! the compositor's `WindowMethods` to create a working web browser.
|
//! web browser.
|
||||||
//!
|
//!
|
||||||
//! This browser's implementation of `WindowMethods` is built on top
|
//! This browser's implementation of `WindowMethods` is built on top
|
||||||
//! of [winit], the cross-platform windowing library.
|
//! of [winit], the cross-platform windowing library.
|
||||||
|
|||||||
@@ -309,7 +309,8 @@ impl RunningAppState {
|
|||||||
/// Spins the internal application event loop.
|
/// Spins the internal application event loop.
|
||||||
///
|
///
|
||||||
/// - Notifies Servo about incoming gamepad events
|
/// - Notifies Servo about incoming gamepad events
|
||||||
/// - Spin the Servo event loop, which will run the compositor and trigger delegate methods.
|
/// - Spin the Servo event loop, which will update Servo's embedding layer and trigger
|
||||||
|
/// delegate methods.
|
||||||
///
|
///
|
||||||
/// Returns true if the event loop should continue spinning and false if it should exit.
|
/// Returns true if the event loop should continue spinning and false if it should exit.
|
||||||
pub(crate) fn spin_event_loop(self: &Rc<Self>) -> bool {
|
pub(crate) fn spin_event_loop(self: &Rc<Self>) -> bool {
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ impl ServoShellWindow {
|
|||||||
self.platform_window
|
self.platform_window
|
||||||
.update_user_interface_state(state, self);
|
.update_user_interface_state(state, self);
|
||||||
|
|
||||||
// Delegate handlers may have asked us to present or update compositor contents.
|
// Delegate handlers may have asked us to present or update painted WebView contents.
|
||||||
// Currently, egui-file-dialog dialogs need to be constantly redrawn or animations aren't fluid.
|
// Currently, egui-file-dialog dialogs need to be constantly redrawn or animations aren't fluid.
|
||||||
let needs_repaint = self.needs_repaint.take();
|
let needs_repaint = self.needs_repaint.take();
|
||||||
if updated_user_interface || needs_repaint {
|
if updated_user_interface || needs_repaint {
|
||||||
|
|||||||
Reference in New Issue
Block a user