mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
compositor: Unify the cross process and in-process API (#36443)
Because there used to be two traits exposing messages to the compositor, there were two kinds of messages that could be sent: 1. In-process messages from the `Constellation` 2. Cross-process messages from other parts of Servo Now these two types of messages can be unified into one type. With that done the compositor can simply keep a single `IpcReceiver` for all messages, instead of having to set up a route for the cross-process messsages. This decreases overhead of cross proceses messages a bit, but more importantly solves an issue where Servo would rely on the compositor's cross-process message route after the `Constellation` had called `ROUTER.shutdown()`. This is part of #36442. Testing: This is covered by existing WPT tests. Signed-off-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
5f0f457ac3
commit
4c55104b36
8 changed files with 95 additions and 215 deletions
|
@ -19,8 +19,7 @@ use bitflags::bitflags;
|
||||||
use compositing_traits::display_list::{CompositorDisplayListInfo, HitTestInfo, ScrollTree};
|
use compositing_traits::display_list::{CompositorDisplayListInfo, HitTestInfo, ScrollTree};
|
||||||
use compositing_traits::rendering_context::RenderingContext;
|
use compositing_traits::rendering_context::RenderingContext;
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CompositionPipeline, CompositorMsg, CompositorReceiver, CrossProcessCompositorMessage,
|
CompositionPipeline, CompositorMsg, ImageUpdate, RendererWebView, SendableFrameTree,
|
||||||
ImageUpdate, RendererWebView, SendableFrameTree,
|
|
||||||
};
|
};
|
||||||
use constellation_traits::{
|
use constellation_traits::{
|
||||||
AnimationTickType, EmbedderToConstellationMessage, PaintMetricEvent, WindowSizeType,
|
AnimationTickType, EmbedderToConstellationMessage, PaintMetricEvent, WindowSizeType,
|
||||||
|
@ -33,7 +32,7 @@ use embedder_traits::{
|
||||||
};
|
};
|
||||||
use euclid::{Box2D, Point2D, Rect, Scale, Size2D, Transform3D};
|
use euclid::{Box2D, Point2D, Rect, Scale, Size2D, Transform3D};
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSharedMemory};
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
use log::{debug, info, trace, warn};
|
use log::{debug, info, trace, warn};
|
||||||
use pixels::{CorsStatus, Image, ImageFrame, PixelFormat};
|
use pixels::{CorsStatus, Image, ImageFrame, PixelFormat};
|
||||||
|
@ -96,7 +95,7 @@ pub struct ServoRenderer {
|
||||||
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: CompositorReceiver,
|
compositor_receiver: IpcReceiver<CompositorMsg>,
|
||||||
|
|
||||||
/// The channel on which messages can be sent to the constellation.
|
/// The channel on which messages can be sent to the constellation.
|
||||||
pub(crate) constellation_sender: Sender<EmbedderToConstellationMessage>,
|
pub(crate) constellation_sender: Sender<EmbedderToConstellationMessage>,
|
||||||
|
@ -515,8 +514,8 @@ impl IOCompositor {
|
||||||
.global
|
.global
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.compositor_receiver
|
.compositor_receiver
|
||||||
.try_recv_compositor_msg()
|
.try_recv()
|
||||||
.is_some()
|
.is_ok()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Tell the profiler, memory profiler, and scrolling timer to shut down.
|
// Tell the profiler, memory profiler, and scrolling timer to shut down.
|
||||||
|
@ -678,33 +677,14 @@ impl IOCompositor {
|
||||||
webview.dispatch_input_event(InputEvent::MouseMove(MouseMoveEvent { point }));
|
webview.dispatch_input_event(InputEvent::MouseMove(MouseMoveEvent { point }));
|
||||||
},
|
},
|
||||||
|
|
||||||
CompositorMsg::CrossProcess(cross_proces_message) => {
|
CompositorMsg::SendInitialTransaction(pipeline) => {
|
||||||
self.handle_cross_process_message(cross_proces_message);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Accept messages from content processes that need to be relayed to the WebRender
|
|
||||||
/// instance in the parent process.
|
|
||||||
#[cfg_attr(
|
|
||||||
feature = "tracing",
|
|
||||||
tracing::instrument(skip_all, fields(servo_profiling = true), level = "trace")
|
|
||||||
)]
|
|
||||||
fn handle_cross_process_message(&mut self, msg: CrossProcessCompositorMessage) {
|
|
||||||
match msg {
|
|
||||||
CrossProcessCompositorMessage::SendInitialTransaction(pipeline) => {
|
|
||||||
let mut txn = Transaction::new();
|
let mut txn = Transaction::new();
|
||||||
txn.set_display_list(WebRenderEpoch(0), (pipeline, Default::default()));
|
txn.set_display_list(WebRenderEpoch(0), (pipeline, Default::default()));
|
||||||
self.generate_frame(&mut txn, RenderReasons::SCENE);
|
self.generate_frame(&mut txn, RenderReasons::SCENE);
|
||||||
self.global.borrow_mut().send_transaction(txn);
|
self.global.borrow_mut().send_transaction(txn);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::SendScrollNode(
|
CompositorMsg::SendScrollNode(webview_id, pipeline_id, point, external_scroll_id) => {
|
||||||
webview_id,
|
|
||||||
pipeline_id,
|
|
||||||
point,
|
|
||||||
external_scroll_id,
|
|
||||||
) => {
|
|
||||||
let Some(webview) = self.webviews.get_mut(webview_id) else {
|
let Some(webview) = self.webviews.get_mut(webview_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -738,7 +718,7 @@ impl IOCompositor {
|
||||||
self.global.borrow_mut().send_transaction(txn);
|
self.global.borrow_mut().send_transaction(txn);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::SendDisplayList {
|
CompositorMsg::SendDisplayList {
|
||||||
webview_id,
|
webview_id,
|
||||||
display_list_descriptor,
|
display_list_descriptor,
|
||||||
display_list_receiver,
|
display_list_receiver,
|
||||||
|
@ -827,7 +807,7 @@ impl IOCompositor {
|
||||||
self.global.borrow_mut().send_transaction(transaction);
|
self.global.borrow_mut().send_transaction(transaction);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::HitTest(pipeline, point, flags, sender) => {
|
CompositorMsg::HitTest(pipeline, point, flags, sender) => {
|
||||||
// When a display list is sent to WebRender, it starts scene building in a
|
// When a display list is sent to WebRender, it starts scene building in a
|
||||||
// separate thread and then that display list is available for hit testing.
|
// separate thread and then that display list is available for hit testing.
|
||||||
// Without flushing scene building, any hit test we do might be done against
|
// Without flushing scene building, any hit test we do might be done against
|
||||||
|
@ -853,11 +833,11 @@ impl IOCompositor {
|
||||||
let _ = sender.send(result);
|
let _ = sender.send(result);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::GenerateImageKey(sender) => {
|
CompositorMsg::GenerateImageKey(sender) => {
|
||||||
let _ = sender.send(self.global.borrow().webrender_api.generate_image_key());
|
let _ = sender.send(self.global.borrow().webrender_api.generate_image_key());
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::UpdateImages(updates) => {
|
CompositorMsg::UpdateImages(updates) => {
|
||||||
let mut txn = Transaction::new();
|
let mut txn = Transaction::new();
|
||||||
for update in updates {
|
for update in updates {
|
||||||
match update {
|
match update {
|
||||||
|
@ -873,26 +853,21 @@ impl IOCompositor {
|
||||||
self.global.borrow_mut().send_transaction(txn);
|
self.global.borrow_mut().send_transaction(txn);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::AddFont(font_key, data, index) => {
|
CompositorMsg::AddFont(font_key, data, index) => {
|
||||||
self.add_font(font_key, index, data);
|
self.add_font(font_key, index, data);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::AddSystemFont(font_key, native_handle) => {
|
CompositorMsg::AddSystemFont(font_key, native_handle) => {
|
||||||
let mut transaction = Transaction::new();
|
let mut transaction = Transaction::new();
|
||||||
transaction.add_native_font(font_key, native_handle);
|
transaction.add_native_font(font_key, native_handle);
|
||||||
self.global.borrow_mut().send_transaction(transaction);
|
self.global.borrow_mut().send_transaction(transaction);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::AddFontInstance(
|
CompositorMsg::AddFontInstance(font_instance_key, font_key, size, flags) => {
|
||||||
font_instance_key,
|
|
||||||
font_key,
|
|
||||||
size,
|
|
||||||
flags,
|
|
||||||
) => {
|
|
||||||
self.add_font_instance(font_instance_key, font_key, size, flags);
|
self.add_font_instance(font_instance_key, font_key, size, flags);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::RemoveFonts(keys, instance_keys) => {
|
CompositorMsg::RemoveFonts(keys, instance_keys) => {
|
||||||
let mut transaction = Transaction::new();
|
let mut transaction = Transaction::new();
|
||||||
|
|
||||||
for instance in instance_keys.into_iter() {
|
for instance in instance_keys.into_iter() {
|
||||||
|
@ -905,13 +880,13 @@ impl IOCompositor {
|
||||||
self.global.borrow_mut().send_transaction(transaction);
|
self.global.borrow_mut().send_transaction(transaction);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::AddImage(key, desc, data) => {
|
CompositorMsg::AddImage(key, desc, data) => {
|
||||||
let mut txn = Transaction::new();
|
let mut txn = Transaction::new();
|
||||||
txn.add_image(key, desc, data.into(), None);
|
txn.add_image(key, desc, data.into(), None);
|
||||||
self.global.borrow_mut().send_transaction(txn);
|
self.global.borrow_mut().send_transaction(txn);
|
||||||
},
|
},
|
||||||
|
|
||||||
CrossProcessCompositorMessage::GenerateFontKeys(
|
CompositorMsg::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
result_sender,
|
result_sender,
|
||||||
|
@ -929,7 +904,7 @@ impl IOCompositor {
|
||||||
.collect();
|
.collect();
|
||||||
let _ = result_sender.send((font_keys, font_instance_keys));
|
let _ = result_sender.send((font_keys, font_instance_keys));
|
||||||
},
|
},
|
||||||
CrossProcessCompositorMessage::GetClientWindowRect(webview_id, response_sender) => {
|
CompositorMsg::GetClientWindowRect(webview_id, response_sender) => {
|
||||||
let screen_geometry = self.webview_screen_geometry(webview_id);
|
let screen_geometry = self.webview_screen_geometry(webview_id);
|
||||||
let rect = DeviceIntRect::from_origin_and_size(
|
let rect = DeviceIntRect::from_origin_and_size(
|
||||||
screen_geometry.offset,
|
screen_geometry.offset,
|
||||||
|
@ -942,7 +917,7 @@ impl IOCompositor {
|
||||||
warn!("Sending response to get client window failed ({error:?}).");
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CrossProcessCompositorMessage::GetScreenSize(webview_id, response_sender) => {
|
CompositorMsg::GetScreenSize(webview_id, response_sender) => {
|
||||||
let screen_geometry = self.webview_screen_geometry(webview_id);
|
let screen_geometry = self.webview_screen_geometry(webview_id);
|
||||||
let screen_size = screen_geometry.size.to_f32() / self.hidpi_factor;
|
let screen_size = screen_geometry.size.to_f32() / self.hidpi_factor;
|
||||||
|
|
||||||
|
@ -950,7 +925,7 @@ impl IOCompositor {
|
||||||
warn!("Sending response to get screen size failed ({error:?}).");
|
warn!("Sending response to get screen size failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CrossProcessCompositorMessage::GetAvailableScreenSize(webview_id, response_sender) => {
|
CompositorMsg::GetAvailableScreenSize(webview_id, response_sender) => {
|
||||||
let screen_geometry = self.webview_screen_geometry(webview_id);
|
let screen_geometry = self.webview_screen_geometry(webview_id);
|
||||||
let available_screen_size =
|
let available_screen_size =
|
||||||
screen_geometry.available_size.to_f32() / self.hidpi_factor;
|
screen_geometry.available_size.to_f32() / self.hidpi_factor;
|
||||||
|
@ -990,16 +965,14 @@ impl IOCompositor {
|
||||||
}
|
}
|
||||||
let _ = sender.send(());
|
let _ = sender.send(());
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GenerateImageKey(
|
CompositorMsg::GenerateImageKey(sender) => {
|
||||||
sender,
|
|
||||||
)) => {
|
|
||||||
let _ = sender.send(self.global.borrow().webrender_api.generate_image_key());
|
let _ = sender.send(self.global.borrow().webrender_api.generate_image_key());
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GenerateFontKeys(
|
CompositorMsg::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
result_sender,
|
result_sender,
|
||||||
)) => {
|
) => {
|
||||||
let font_keys = (0..number_of_font_keys)
|
let font_keys = (0..number_of_font_keys)
|
||||||
.map(|_| self.global.borrow().webrender_api.generate_font_key())
|
.map(|_| self.global.borrow().webrender_api.generate_font_key())
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -1013,26 +986,17 @@ impl IOCompositor {
|
||||||
.collect();
|
.collect();
|
||||||
let _ = result_sender.send((font_keys, font_instance_keys));
|
let _ = result_sender.send((font_keys, font_instance_keys));
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetClientWindowRect(
|
CompositorMsg::GetClientWindowRect(_, response_sender) => {
|
||||||
_,
|
|
||||||
response_sender,
|
|
||||||
)) => {
|
|
||||||
if let Err(error) = response_sender.send(Default::default()) {
|
if let Err(error) = response_sender.send(Default::default()) {
|
||||||
warn!("Sending response to get client window failed ({error:?}).");
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetScreenSize(
|
CompositorMsg::GetScreenSize(_, response_sender) => {
|
||||||
_,
|
|
||||||
response_sender,
|
|
||||||
)) => {
|
|
||||||
if let Err(error) = response_sender.send(Default::default()) {
|
if let Err(error) = response_sender.send(Default::default()) {
|
||||||
warn!("Sending response to get client window failed ({error:?}).");
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetAvailableScreenSize(
|
CompositorMsg::GetAvailableScreenSize(_, response_sender) => {
|
||||||
_,
|
|
||||||
response_sender,
|
|
||||||
)) => {
|
|
||||||
if let Err(error) = response_sender.send(Default::default()) {
|
if let Err(error) = response_sender.send(Default::default()) {
|
||||||
warn!("Sending response to get client window failed ({error:?}).");
|
warn!("Sending response to get client window failed ({error:?}).");
|
||||||
}
|
}
|
||||||
|
@ -1672,12 +1636,7 @@ impl IOCompositor {
|
||||||
// Check for new messages coming from the other threads in the system.
|
// Check for new messages coming from the other threads in the system.
|
||||||
let mut compositor_messages = vec![];
|
let mut compositor_messages = vec![];
|
||||||
let mut found_recomposite_msg = false;
|
let mut found_recomposite_msg = false;
|
||||||
while let Some(msg) = self
|
while let Ok(msg) = self.global.borrow_mut().compositor_receiver.try_recv() {
|
||||||
.global
|
|
||||||
.borrow_mut()
|
|
||||||
.compositor_receiver
|
|
||||||
.try_recv_compositor_msg()
|
|
||||||
{
|
|
||||||
match msg {
|
match msg {
|
||||||
CompositorMsg::NewWebRenderFrameReady(..) if found_recomposite_msg => {
|
CompositorMsg::NewWebRenderFrameReady(..) if found_recomposite_msg => {
|
||||||
// Only take one of duplicate NewWebRendeFrameReady messages, but do subtract
|
// Only take one of duplicate NewWebRendeFrameReady messages, but do subtract
|
||||||
|
|
|
@ -8,10 +8,11 @@ use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use compositing_traits::rendering_context::RenderingContext;
|
use compositing_traits::rendering_context::RenderingContext;
|
||||||
use compositing_traits::{CompositorProxy, CompositorReceiver};
|
use compositing_traits::{CompositorMsg, CompositorProxy};
|
||||||
use constellation_traits::EmbedderToConstellationMessage;
|
use constellation_traits::EmbedderToConstellationMessage;
|
||||||
use crossbeam_channel::Sender;
|
use crossbeam_channel::Sender;
|
||||||
use embedder_traits::ShutdownState;
|
use embedder_traits::ShutdownState;
|
||||||
|
use ipc_channel::ipc::IpcReceiver;
|
||||||
use profile_traits::{mem, time};
|
use profile_traits::{mem, time};
|
||||||
use webrender::RenderApi;
|
use webrender::RenderApi;
|
||||||
use webrender_api::DocumentId;
|
use webrender_api::DocumentId;
|
||||||
|
@ -32,7 +33,7 @@ pub struct InitialCompositorState {
|
||||||
/// A channel to the compositor.
|
/// A channel to the compositor.
|
||||||
pub sender: CompositorProxy,
|
pub sender: CompositorProxy,
|
||||||
/// A port on which messages inbound to the compositor can be received.
|
/// A port on which messages inbound to the compositor can be received.
|
||||||
pub receiver: CompositorReceiver,
|
pub receiver: IpcReceiver<CompositorMsg>,
|
||||||
/// A channel to the constellation.
|
/// A channel to the constellation.
|
||||||
pub constellation_chan: Sender<EmbedderToConstellationMessage>,
|
pub constellation_chan: Sender<EmbedderToConstellationMessage>,
|
||||||
/// A channel to the time profiler thread.
|
/// A channel to the time profiler thread.
|
||||||
|
|
|
@ -42,7 +42,21 @@ mod from_constellation {
|
||||||
Self::LoadComplete(..) => target!("LoadComplete"),
|
Self::LoadComplete(..) => target!("LoadComplete"),
|
||||||
Self::WebDriverMouseButtonEvent(..) => target!("WebDriverMouseButtonEvent"),
|
Self::WebDriverMouseButtonEvent(..) => target!("WebDriverMouseButtonEvent"),
|
||||||
Self::WebDriverMouseMoveEvent(..) => target!("WebDriverMouseMoveEvent"),
|
Self::WebDriverMouseMoveEvent(..) => target!("WebDriverMouseMoveEvent"),
|
||||||
Self::CrossProcess(_) => target!("CrossProcess"),
|
Self::SendInitialTransaction(..) => target!("SendInitialTransaction"),
|
||||||
|
Self::SendScrollNode(..) => target!("SendScrollNode"),
|
||||||
|
Self::SendDisplayList { .. } => todo!("SendDisplayList"),
|
||||||
|
Self::HitTest(..) => target!("HitTest"),
|
||||||
|
Self::GenerateImageKey(..) => target!("GenerateImageKey"),
|
||||||
|
Self::AddImage(..) => target!("AddImage"),
|
||||||
|
Self::UpdateImages(..) => target!("UpdateImages"),
|
||||||
|
Self::GenerateFontKeys(..) => target!("GenerateFontKeys"),
|
||||||
|
Self::AddFont(..) => target!("AddFont"),
|
||||||
|
Self::AddSystemFont(..) => target!("AddSystemFont"),
|
||||||
|
Self::AddFontInstance(..) => target!("AddFontInstance"),
|
||||||
|
Self::RemoveFonts(..) => target!("RemoveFonts"),
|
||||||
|
Self::GetClientWindowRect(..) => target!("GetClientWindowRect"),
|
||||||
|
Self::GetScreenSize(..) => target!("GetScreenSize"),
|
||||||
|
Self::GetAvailableScreenSize(..) => target!("GetAvailableScreenSize"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,8 +291,7 @@ impl Pipeline {
|
||||||
webrender_document: state.webrender_document,
|
webrender_document: state.webrender_document,
|
||||||
cross_process_compositor_api: state
|
cross_process_compositor_api: state
|
||||||
.compositor_proxy
|
.compositor_proxy
|
||||||
.cross_process_compositor_api
|
.cross_process_compositor_api(),
|
||||||
.clone(),
|
|
||||||
webgl_chan: state.webgl_chan,
|
webgl_chan: state.webgl_chan,
|
||||||
webxr_registry: state.webxr_registry,
|
webxr_registry: state.webxr_registry,
|
||||||
player_context: state.player_context,
|
player_context: state.player_context,
|
||||||
|
|
|
@ -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/. */
|
||||||
|
|
||||||
use compositing_traits::CrossProcessCompositorMessage;
|
use compositing_traits::CompositorMsg;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use euclid::Size2D;
|
use euclid::Size2D;
|
||||||
use profile_traits::ipc;
|
use profile_traits::ipc;
|
||||||
|
@ -41,7 +41,7 @@ impl Screen {
|
||||||
self.window
|
self.window
|
||||||
.compositor_api()
|
.compositor_api()
|
||||||
.sender()
|
.sender()
|
||||||
.send(CrossProcessCompositorMessage::GetScreenSize(
|
.send(CompositorMsg::GetScreenSize(
|
||||||
self.window.webview_id(),
|
self.window.webview_id(),
|
||||||
sender,
|
sender,
|
||||||
))
|
))
|
||||||
|
@ -57,7 +57,7 @@ impl Screen {
|
||||||
self.window
|
self.window
|
||||||
.compositor_api()
|
.compositor_api()
|
||||||
.sender()
|
.sender()
|
||||||
.send(CrossProcessCompositorMessage::GetAvailableScreenSize(
|
.send(CompositorMsg::GetAvailableScreenSize(
|
||||||
self.window.webview_id(),
|
self.window.webview_id(),
|
||||||
sender,
|
sender,
|
||||||
))
|
))
|
||||||
|
|
|
@ -1898,10 +1898,7 @@ impl Window {
|
||||||
let (sender, receiver) =
|
let (sender, receiver) =
|
||||||
ProfiledIpc::channel::<DeviceIndependentIntRect>(timer_profile_chan).unwrap();
|
ProfiledIpc::channel::<DeviceIndependentIntRect>(timer_profile_chan).unwrap();
|
||||||
let _ = self.compositor_api.sender().send(
|
let _ = self.compositor_api.sender().send(
|
||||||
compositing_traits::CrossProcessCompositorMessage::GetClientWindowRect(
|
compositing_traits::CompositorMsg::GetClientWindowRect(self.webview_id(), sender),
|
||||||
self.webview_id(),
|
|
||||||
sender,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
let rect = receiver.recv().unwrap_or_default();
|
let rect = receiver.recv().unwrap_or_default();
|
||||||
(
|
(
|
||||||
|
|
|
@ -48,8 +48,8 @@ pub use compositing_traits::rendering_context::{
|
||||||
OffscreenRenderingContext, RenderingContext, SoftwareRenderingContext, WindowRenderingContext,
|
OffscreenRenderingContext, RenderingContext, SoftwareRenderingContext, WindowRenderingContext,
|
||||||
};
|
};
|
||||||
use compositing_traits::{
|
use compositing_traits::{
|
||||||
CompositorMsg, CompositorProxy, CompositorReceiver, CrossProcessCompositorApi,
|
CompositorMsg, CompositorProxy, WebrenderExternalImageHandlers, WebrenderExternalImageRegistry,
|
||||||
WebrenderExternalImageHandlers, WebrenderExternalImageRegistry, WebrenderImageHandlerType,
|
WebrenderImageHandlerType,
|
||||||
};
|
};
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
not(target_os = "windows"),
|
not(target_os = "windows"),
|
||||||
|
@ -82,7 +82,6 @@ use gaol::sandbox::{ChildSandbox, ChildSandboxMethods};
|
||||||
pub use gleam::gl;
|
pub use gleam::gl;
|
||||||
use gleam::gl::RENDERER;
|
use gleam::gl::RENDERER;
|
||||||
use ipc_channel::ipc::{self, IpcSender};
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use ipc_channel::router::ROUTER;
|
|
||||||
pub use keyboard_types::*;
|
pub use keyboard_types::*;
|
||||||
use log::{Log, Metadata, Record, debug, warn};
|
use log::{Log, Metadata, Record, debug, warn};
|
||||||
use media::{GlApi, NativeDisplay, WindowGLContext};
|
use media::{GlApi, NativeDisplay, WindowGLContext};
|
||||||
|
@ -302,8 +301,6 @@ impl Servo {
|
||||||
// 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 = embedder.create_event_loop_waker();
|
let event_loop_waker = embedder.create_event_loop_waker();
|
||||||
let (compositor_proxy, compositor_receiver) =
|
|
||||||
create_compositor_channel(event_loop_waker.clone());
|
|
||||||
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(
|
||||||
&opts.time_profiling,
|
&opts.time_profiling,
|
||||||
|
@ -311,6 +308,12 @@ impl Servo {
|
||||||
);
|
);
|
||||||
let mem_profiler_chan = profile_mem::Profiler::create();
|
let mem_profiler_chan = profile_mem::Profiler::create();
|
||||||
|
|
||||||
|
let (compositor_sender, compositor_receiver) = ipc::channel().expect("ipc channel failure");
|
||||||
|
let compositor_proxy = CompositorProxy {
|
||||||
|
sender: compositor_sender,
|
||||||
|
event_loop_waker: event_loop_waker.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
let devtools_sender = if pref!(devtools_server_enabled) {
|
let devtools_sender = if pref!(devtools_server_enabled) {
|
||||||
Some(devtools::start_server(
|
Some(devtools::start_server(
|
||||||
pref!(devtools_server_port) as u16,
|
pref!(devtools_server_port) as u16,
|
||||||
|
@ -1007,34 +1010,6 @@ fn create_embedder_channel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_compositor_channel(
|
|
||||||
event_loop_waker: Box<dyn EventLoopWaker>,
|
|
||||||
) -> (CompositorProxy, CompositorReceiver) {
|
|
||||||
let (sender, receiver) = unbounded();
|
|
||||||
|
|
||||||
let (compositor_ipc_sender, compositor_ipc_receiver) =
|
|
||||||
ipc::channel().expect("ipc channel failure");
|
|
||||||
|
|
||||||
let cross_process_compositor_api = CrossProcessCompositorApi(compositor_ipc_sender);
|
|
||||||
let compositor_proxy = CompositorProxy {
|
|
||||||
sender,
|
|
||||||
cross_process_compositor_api,
|
|
||||||
event_loop_waker,
|
|
||||||
};
|
|
||||||
|
|
||||||
let compositor_proxy_clone = compositor_proxy.clone();
|
|
||||||
ROUTER.add_typed_route(
|
|
||||||
compositor_ipc_receiver,
|
|
||||||
Box::new(move |message| {
|
|
||||||
compositor_proxy_clone.send(CompositorMsg::CrossProcess(
|
|
||||||
message.expect("Could not convert Compositor message"),
|
|
||||||
));
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
(compositor_proxy, CompositorReceiver { receiver })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn create_constellation(
|
fn create_constellation(
|
||||||
config_dir: Option<PathBuf>,
|
config_dir: Option<PathBuf>,
|
||||||
|
@ -1071,11 +1046,11 @@ fn create_constellation(
|
||||||
);
|
);
|
||||||
|
|
||||||
let system_font_service = Arc::new(
|
let system_font_service = Arc::new(
|
||||||
SystemFontService::spawn(compositor_proxy.cross_process_compositor_api.clone()).to_proxy(),
|
SystemFontService::spawn(compositor_proxy.cross_process_compositor_api()).to_proxy(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (canvas_create_sender, canvas_ipc_sender) = CanvasPaintThread::start(
|
let (canvas_create_sender, canvas_ipc_sender) = CanvasPaintThread::start(
|
||||||
compositor_proxy.cross_process_compositor_api.clone(),
|
compositor_proxy.cross_process_compositor_api(),
|
||||||
system_font_service.clone(),
|
system_font_service.clone(),
|
||||||
public_resource_threads.clone(),
|
public_resource_threads.clone(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
use std::fmt::{Debug, Error, Formatter};
|
use std::fmt::{Debug, Error, Formatter};
|
||||||
|
|
||||||
use base::id::{PipelineId, WebViewId};
|
use base::id::{PipelineId, WebViewId};
|
||||||
use crossbeam_channel::{Receiver, Sender};
|
|
||||||
use embedder_traits::{
|
use embedder_traits::{
|
||||||
AnimationState, EventLoopWaker, MouseButton, MouseButtonAction, TouchEventResult,
|
AnimationState, EventLoopWaker, MouseButton, MouseButtonAction, TouchEventResult,
|
||||||
};
|
};
|
||||||
|
@ -22,7 +21,6 @@ use webrender_api::DocumentId;
|
||||||
pub mod display_list;
|
pub mod display_list;
|
||||||
pub mod rendering_context;
|
pub mod rendering_context;
|
||||||
|
|
||||||
use core::fmt;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
@ -43,11 +41,7 @@ use webrender_api::{
|
||||||
/// Sends messages to the compositor.
|
/// Sends messages to the compositor.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CompositorProxy {
|
pub struct CompositorProxy {
|
||||||
pub sender: Sender<CompositorMsg>,
|
pub sender: IpcSender<CompositorMsg>,
|
||||||
/// Access to [`Self::sender`] that is possible to send across an IPC
|
|
||||||
/// channel. These messages are routed via the router thread to
|
|
||||||
/// [`Self::sender`].
|
|
||||||
pub cross_process_compositor_api: CrossProcessCompositorApi,
|
|
||||||
pub event_loop_waker: Box<dyn EventLoopWaker>,
|
pub event_loop_waker: Box<dyn EventLoopWaker>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,24 +52,14 @@ impl CompositorProxy {
|
||||||
}
|
}
|
||||||
self.event_loop_waker.wake();
|
self.event_loop_waker.wake();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// The port that the compositor receives messages on.
|
pub fn cross_process_compositor_api(&self) -> CrossProcessCompositorApi {
|
||||||
pub struct CompositorReceiver {
|
CrossProcessCompositorApi(self.sender.clone())
|
||||||
pub receiver: Receiver<CompositorMsg>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CompositorReceiver {
|
|
||||||
pub fn try_recv_compositor_msg(&mut self) -> Option<CompositorMsg> {
|
|
||||||
self.receiver.try_recv().ok()
|
|
||||||
}
|
|
||||||
pub fn recv_compositor_msg(&mut self) -> CompositorMsg {
|
|
||||||
self.receiver.recv().unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Messages from (or via) the constellation thread to the compositor.
|
/// Messages from (or via) the constellation thread to the compositor.
|
||||||
#[derive(IntoStaticStr)]
|
#[derive(Deserialize, IntoStaticStr, Serialize)]
|
||||||
pub enum CompositorMsg {
|
pub enum CompositorMsg {
|
||||||
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
|
/// Alerts the compositor that the given pipeline has changed whether it is running animations.
|
||||||
ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
|
ChangeRunningAnimationsState(WebViewId, PipelineId, AnimationState),
|
||||||
|
@ -108,32 +92,6 @@ pub enum CompositorMsg {
|
||||||
/// WebDriver mouse move event
|
/// WebDriver mouse move event
|
||||||
WebDriverMouseMoveEvent(WebViewId, f32, f32),
|
WebDriverMouseMoveEvent(WebViewId, f32, f32),
|
||||||
|
|
||||||
/// Messages forwarded to the compositor by the constellation from other crates. These
|
|
||||||
/// messages are mainly passed on from the compositor to WebRender.
|
|
||||||
CrossProcess(CrossProcessCompositorMessage),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SendableFrameTree {
|
|
||||||
pub pipeline: CompositionPipeline,
|
|
||||||
pub children: Vec<SendableFrameTree>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The subset of the pipeline that is needed for layer composition.
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CompositionPipeline {
|
|
||||||
pub id: PipelineId,
|
|
||||||
pub webview_id: WebViewId,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Debug for CompositorMsg {
|
|
||||||
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
|
||||||
let string: &'static str = self.into();
|
|
||||||
write!(formatter, "{string}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub enum CrossProcessCompositorMessage {
|
|
||||||
/// Inform WebRender of the existence of this pipeline.
|
/// Inform WebRender of the existence of this pipeline.
|
||||||
SendInitialTransaction(WebRenderPipelineId),
|
SendInitialTransaction(WebRenderPipelineId),
|
||||||
/// Perform a scroll operation.
|
/// Perform a scroll operation.
|
||||||
|
@ -193,31 +151,29 @@ pub enum CrossProcessCompositorMessage {
|
||||||
GetAvailableScreenSize(WebViewId, IpcSender<DeviceIndependentIntSize>),
|
GetAvailableScreenSize(WebViewId, IpcSender<DeviceIndependentIntSize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for CrossProcessCompositorMessage {
|
impl Debug for CompositorMsg {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
|
||||||
match self {
|
let string: &'static str = self.into();
|
||||||
Self::AddImage(..) => f.write_str("AddImage"),
|
write!(formatter, "{string}")
|
||||||
Self::GenerateFontKeys(..) => f.write_str("GenerateFontKeys"),
|
|
||||||
Self::AddSystemFont(..) => f.write_str("AddSystemFont"),
|
|
||||||
Self::SendInitialTransaction(..) => f.write_str("SendInitialTransaction"),
|
|
||||||
Self::SendScrollNode(..) => f.write_str("SendScrollNode"),
|
|
||||||
Self::SendDisplayList { .. } => f.write_str("SendDisplayList"),
|
|
||||||
Self::HitTest(..) => f.write_str("HitTest"),
|
|
||||||
Self::GenerateImageKey(..) => f.write_str("GenerateImageKey"),
|
|
||||||
Self::UpdateImages(..) => f.write_str("UpdateImages"),
|
|
||||||
Self::RemoveFonts(..) => f.write_str("RemoveFonts"),
|
|
||||||
Self::AddFontInstance(..) => f.write_str("AddFontInstance"),
|
|
||||||
Self::AddFont(..) => f.write_str("AddFont"),
|
|
||||||
Self::GetClientWindowRect(..) => f.write_str("GetClientWindowRect"),
|
|
||||||
Self::GetScreenSize(..) => f.write_str("GetScreenSize"),
|
|
||||||
Self::GetAvailableScreenSize(..) => f.write_str("GetAvailableScreenSize"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct SendableFrameTree {
|
||||||
|
pub pipeline: CompositionPipeline,
|
||||||
|
pub children: Vec<SendableFrameTree>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The subset of the pipeline that is needed for layer composition.
|
||||||
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
pub struct CompositionPipeline {
|
||||||
|
pub id: PipelineId,
|
||||||
|
pub webview_id: WebViewId,
|
||||||
|
}
|
||||||
|
|
||||||
/// 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, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct CrossProcessCompositorApi(pub IpcSender<CrossProcessCompositorMessage>);
|
pub struct CrossProcessCompositorApi(pub IpcSender<CompositorMsg>);
|
||||||
|
|
||||||
impl CrossProcessCompositorApi {
|
impl CrossProcessCompositorApi {
|
||||||
/// Create a new [`CrossProcessCompositorApi`] struct that does not have a listener on the other
|
/// Create a new [`CrossProcessCompositorApi`] struct that does not have a listener on the other
|
||||||
|
@ -228,18 +184,13 @@ impl CrossProcessCompositorApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the sender for this proxy.
|
/// Get the sender for this proxy.
|
||||||
pub fn sender(&self) -> &IpcSender<CrossProcessCompositorMessage> {
|
pub fn sender(&self) -> &IpcSender<CompositorMsg> {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inform WebRender of the existence of this pipeline.
|
/// Inform WebRender of the existence of this pipeline.
|
||||||
pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
|
pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
|
||||||
if let Err(e) = self
|
if let Err(e) = self.0.send(CompositorMsg::SendInitialTransaction(pipeline)) {
|
||||||
.0
|
|
||||||
.send(CrossProcessCompositorMessage::SendInitialTransaction(
|
|
||||||
pipeline,
|
|
||||||
))
|
|
||||||
{
|
|
||||||
warn!("Error sending initial transaction: {}", e);
|
warn!("Error sending initial transaction: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,7 +203,7 @@ impl CrossProcessCompositorApi {
|
||||||
point: LayoutPoint,
|
point: LayoutPoint,
|
||||||
scroll_id: ExternalScrollId,
|
scroll_id: ExternalScrollId,
|
||||||
) {
|
) {
|
||||||
if let Err(e) = self.0.send(CrossProcessCompositorMessage::SendScrollNode(
|
if let Err(e) = self.0.send(CompositorMsg::SendScrollNode(
|
||||||
webview_id,
|
webview_id,
|
||||||
pipeline_id,
|
pipeline_id,
|
||||||
point,
|
point,
|
||||||
|
@ -271,7 +222,7 @@ impl CrossProcessCompositorApi {
|
||||||
) {
|
) {
|
||||||
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(CrossProcessCompositorMessage::SendDisplayList {
|
if let Err(e) = self.0.send(CompositorMsg::SendDisplayList {
|
||||||
webview_id,
|
webview_id,
|
||||||
display_list_descriptor,
|
display_list_descriptor,
|
||||||
display_list_receiver,
|
display_list_receiver,
|
||||||
|
@ -306,9 +257,7 @@ impl CrossProcessCompositorApi {
|
||||||
) -> Vec<CompositorHitTestResult> {
|
) -> Vec<CompositorHitTestResult> {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
self.0
|
self.0
|
||||||
.send(CrossProcessCompositorMessage::HitTest(
|
.send(CompositorMsg::HitTest(pipeline, point, flags, sender))
|
||||||
pipeline, point, flags, sender,
|
|
||||||
))
|
|
||||||
.expect("error sending hit test");
|
.expect("error sending hit test");
|
||||||
receiver.recv().expect("error receiving hit test result")
|
receiver.recv().expect("error receiving hit test result")
|
||||||
}
|
}
|
||||||
|
@ -316,9 +265,7 @@ impl CrossProcessCompositorApi {
|
||||||
/// Create a new image key. Blocks until the key is available.
|
/// Create a new image key. Blocks until the key is available.
|
||||||
pub fn generate_image_key(&self) -> Option<ImageKey> {
|
pub fn generate_image_key(&self) -> Option<ImageKey> {
|
||||||
let (sender, receiver) = ipc::channel().unwrap();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
self.0
|
self.0.send(CompositorMsg::GenerateImageKey(sender)).ok()?;
|
||||||
.send(CrossProcessCompositorMessage::GenerateImageKey(sender))
|
|
||||||
.ok()?;
|
|
||||||
receiver.recv().ok()
|
receiver.recv().ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,19 +275,14 @@ impl CrossProcessCompositorApi {
|
||||||
descriptor: ImageDescriptor,
|
descriptor: ImageDescriptor,
|
||||||
data: SerializableImageData,
|
data: SerializableImageData,
|
||||||
) {
|
) {
|
||||||
if let Err(e) = self.0.send(CrossProcessCompositorMessage::AddImage(
|
if let Err(e) = self.0.send(CompositorMsg::AddImage(key, descriptor, data)) {
|
||||||
key, descriptor, data,
|
|
||||||
)) {
|
|
||||||
warn!("Error sending image update: {}", e);
|
warn!("Error sending image update: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an image resource update operation.
|
/// Perform an image resource update operation.
|
||||||
pub fn update_images(&self, updates: Vec<ImageUpdate>) {
|
pub fn update_images(&self, updates: Vec<ImageUpdate>) {
|
||||||
if let Err(e) = self
|
if let Err(e) = self.0.send(CompositorMsg::UpdateImages(updates)) {
|
||||||
.0
|
|
||||||
.send(CrossProcessCompositorMessage::UpdateImages(updates))
|
|
||||||
{
|
|
||||||
warn!("error sending image updates: {}", e);
|
warn!("error sending image updates: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -353,10 +295,7 @@ impl CrossProcessCompositorApi {
|
||||||
if keys.is_empty() && instance_keys.is_empty() {
|
if keys.is_empty() && instance_keys.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let _ = self.0.send(CrossProcessCompositorMessage::RemoveFonts(
|
let _ = self.0.send(CompositorMsg::RemoveFonts(keys, instance_keys));
|
||||||
keys,
|
|
||||||
instance_keys,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_font_instance(
|
pub fn add_font_instance(
|
||||||
|
@ -366,7 +305,7 @@ impl CrossProcessCompositorApi {
|
||||||
size: f32,
|
size: f32,
|
||||||
flags: FontInstanceFlags,
|
flags: FontInstanceFlags,
|
||||||
) {
|
) {
|
||||||
let _x = self.0.send(CrossProcessCompositorMessage::AddFontInstance(
|
let _x = self.0.send(CompositorMsg::AddFontInstance(
|
||||||
font_instance_key,
|
font_instance_key,
|
||||||
font_key,
|
font_key,
|
||||||
size,
|
size,
|
||||||
|
@ -375,15 +314,11 @@ 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(CrossProcessCompositorMessage::AddFont(
|
let _ = self.0.send(CompositorMsg::AddFont(font_key, data, index));
|
||||||
font_key, data, index,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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(CrossProcessCompositorMessage::AddSystemFont(
|
let _ = self.0.send(CompositorMsg::AddSystemFont(font_key, handle));
|
||||||
font_key, handle,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_font_keys(
|
pub fn fetch_font_keys(
|
||||||
|
@ -392,7 +327,7 @@ impl CrossProcessCompositorApi {
|
||||||
number_of_font_instance_keys: usize,
|
number_of_font_instance_keys: usize,
|
||||||
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
|
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
|
||||||
let (sender, receiver) = ipc_channel::ipc::channel().expect("Could not create IPC channel");
|
let (sender, receiver) = ipc_channel::ipc::channel().expect("Could not create IPC channel");
|
||||||
let _ = self.0.send(CrossProcessCompositorMessage::GenerateFontKeys(
|
let _ = self.0.send(CompositorMsg::GenerateFontKeys(
|
||||||
number_of_font_keys,
|
number_of_font_keys,
|
||||||
number_of_font_instance_keys,
|
number_of_font_instance_keys,
|
||||||
sender,
|
sender,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue