mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
compositor: Create a single cross-process compositor API (#33619)
Instead of exposing many different kinds of messages to the compositor that are routed through the constellation, expose a single message type which can be sent across IPC channels. In addition, this IPC channel and the route to the crossbeam channel with the compositor is created along with the `CompositorProxy`, simplifying what needs to be passed around during pipeline initialization. Previously, some image updates (from video) were sent over IPC with a special serialization routine and some were sent via crossbeam channels (canvas). Now all updates go over the IPC channel `IpcSharedMemory` is used to avoid serialization penalties. This should improve performance and reduce copies for video, but add a memory copy overhead for canvas. This will improve in the future when canvas renders directly into a texture. All-in-all this is a simplification which opens the path toward having a standard compositor API and reduces the number of duplicate messages and proxying that had to happen in libservo. Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
986c3a38a3
commit
f2f5614ad6
28 changed files with 547 additions and 801 deletions
|
@ -22,10 +22,10 @@ use style::color::AbsoluteColor;
|
|||
use style::properties::style_structs::Font as FontStyleStruct;
|
||||
use unicode_script::Script;
|
||||
use webrender_api::units::{DeviceIntSize, RectExt as RectExt_};
|
||||
use webrender_api::{ImageData, ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey};
|
||||
use webrender_traits::ImageUpdate;
|
||||
use webrender_api::{ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey};
|
||||
use webrender_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
|
||||
|
||||
use crate::canvas_paint_thread::{AntialiasMode, WebrenderApi};
|
||||
use crate::canvas_paint_thread::AntialiasMode;
|
||||
use crate::raqote_backend::Repetition;
|
||||
|
||||
/// The canvas data stores a state machine for the current status of
|
||||
|
@ -428,7 +428,7 @@ pub struct CanvasData<'a> {
|
|||
path_state: Option<PathState>,
|
||||
state: CanvasPaintState<'a>,
|
||||
saved_states: Vec<CanvasPaintState<'a>>,
|
||||
webrender_api: Box<dyn WebrenderApi>,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
image_key: Option<ImageKey>,
|
||||
/// An old webrender image key that can be deleted when the next epoch ends.
|
||||
old_image_key: Option<ImageKey>,
|
||||
|
@ -444,7 +444,7 @@ fn create_backend() -> Box<dyn Backend> {
|
|||
impl<'a> CanvasData<'a> {
|
||||
pub fn new(
|
||||
size: Size2D<u64>,
|
||||
webrender_api: Box<dyn WebrenderApi>,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
antialias: AntialiasMode,
|
||||
font_context: Arc<FontContext>,
|
||||
) -> CanvasData<'a> {
|
||||
|
@ -456,7 +456,7 @@ impl<'a> CanvasData<'a> {
|
|||
path_state: None,
|
||||
state: CanvasPaintState::new(antialias),
|
||||
saved_states: vec![],
|
||||
webrender_api,
|
||||
compositor_api,
|
||||
image_key: None,
|
||||
old_image_key: None,
|
||||
very_old_image_key: None,
|
||||
|
@ -1279,8 +1279,9 @@ impl<'a> CanvasData<'a> {
|
|||
offset: 0,
|
||||
flags: ImageDescriptorFlags::empty(),
|
||||
};
|
||||
let data = self.drawtarget.snapshot_data_owned();
|
||||
let data = ImageData::Raw(Arc::new(data));
|
||||
let data = SerializableImageData::Raw(IpcSharedMemory::from_bytes(
|
||||
&self.drawtarget.snapshot_data_owned(),
|
||||
));
|
||||
|
||||
let mut updates = vec![];
|
||||
|
||||
|
@ -1290,7 +1291,7 @@ impl<'a> CanvasData<'a> {
|
|||
updates.push(ImageUpdate::UpdateImage(image_key, descriptor, data));
|
||||
},
|
||||
None => {
|
||||
let Some(key) = self.webrender_api.generate_key() else {
|
||||
let Some(key) = self.compositor_api.generate_image_key() else {
|
||||
return;
|
||||
};
|
||||
updates.push(ImageUpdate::AddImage(key, descriptor, data));
|
||||
|
@ -1305,7 +1306,7 @@ impl<'a> CanvasData<'a> {
|
|||
updates.push(ImageUpdate::DeleteImage(image_key));
|
||||
}
|
||||
|
||||
self.webrender_api.update_images(updates);
|
||||
self.compositor_api.update_images(updates);
|
||||
|
||||
let data = CanvasImageData {
|
||||
image_key: self.image_key.unwrap(),
|
||||
|
@ -1426,7 +1427,7 @@ impl<'a> Drop for CanvasData<'a> {
|
|||
updates.push(ImageUpdate::DeleteImage(image_key));
|
||||
}
|
||||
|
||||
self.webrender_api.update_images(updates);
|
||||
self.compositor_api.update_images(updates);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@ use ipc_channel::ipc::{self, IpcSender};
|
|||
use ipc_channel::router::ROUTER;
|
||||
use log::warn;
|
||||
use net_traits::ResourceThreads;
|
||||
use webrender_api::ImageKey;
|
||||
use webrender_traits::{ImageUpdate, WebRenderScriptApi};
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use crate::canvas_data::*;
|
||||
|
||||
|
@ -26,36 +25,26 @@ pub enum AntialiasMode {
|
|||
None,
|
||||
}
|
||||
|
||||
pub trait WebrenderApi {
|
||||
/// Attempt to generate an [`ImageKey`], returning `None` in case of failure.
|
||||
fn generate_key(&self) -> Option<ImageKey>;
|
||||
fn update_images(&self, updates: Vec<ImageUpdate>);
|
||||
fn clone(&self) -> Box<dyn WebrenderApi>;
|
||||
}
|
||||
|
||||
pub struct CanvasPaintThread<'a> {
|
||||
canvases: HashMap<CanvasId, CanvasData<'a>>,
|
||||
next_canvas_id: CanvasId,
|
||||
webrender_api: Box<dyn WebrenderApi>,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
font_context: Arc<FontContext>,
|
||||
}
|
||||
|
||||
impl<'a> CanvasPaintThread<'a> {
|
||||
fn new(
|
||||
webrender_api: Box<dyn WebrenderApi>,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
system_font_service: Arc<SystemFontServiceProxy>,
|
||||
resource_threads: ResourceThreads,
|
||||
) -> CanvasPaintThread<'a> {
|
||||
// This is only used for web fonts and currently canvas never uses web fonts.
|
||||
let webrender_script_api = WebRenderScriptApi::dummy();
|
||||
|
||||
CanvasPaintThread {
|
||||
canvases: HashMap::new(),
|
||||
next_canvas_id: CanvasId(0),
|
||||
webrender_api,
|
||||
compositor_api: compositor_api.clone(),
|
||||
font_context: Arc::new(FontContext::new(
|
||||
system_font_service,
|
||||
webrender_script_api,
|
||||
compositor_api,
|
||||
resource_threads,
|
||||
)),
|
||||
}
|
||||
|
@ -64,7 +53,7 @@ impl<'a> CanvasPaintThread<'a> {
|
|||
/// Creates a new `CanvasPaintThread` and returns an `IpcSender` to
|
||||
/// communicate with it.
|
||||
pub fn start(
|
||||
webrender_api: Box<dyn WebrenderApi + Send>,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
system_font_service: Arc<SystemFontServiceProxy>,
|
||||
resource_threads: ResourceThreads,
|
||||
) -> (Sender<ConstellationCanvasMsg>, IpcSender<CanvasMsg>) {
|
||||
|
@ -75,7 +64,7 @@ impl<'a> CanvasPaintThread<'a> {
|
|||
.name("Canvas".to_owned())
|
||||
.spawn(move || {
|
||||
let mut canvas_paint_thread = CanvasPaintThread::new(
|
||||
webrender_api, system_font_service, resource_threads);
|
||||
compositor_api, system_font_service, resource_threads);
|
||||
loop {
|
||||
select! {
|
||||
recv(msg_receiver) -> msg => {
|
||||
|
@ -141,7 +130,7 @@ impl<'a> CanvasPaintThread<'a> {
|
|||
|
||||
let canvas_data = CanvasData::new(
|
||||
size,
|
||||
self.webrender_api.clone(),
|
||||
self.compositor_api.clone(),
|
||||
antialias,
|
||||
self.font_context.clone(),
|
||||
);
|
||||
|
|
|
@ -16,8 +16,7 @@ use base::cross_process_instant::CrossProcessInstant;
|
|||
use base::id::{PipelineId, TopLevelBrowsingContextId, WebViewId};
|
||||
use base::{Epoch, WebRenderEpochToU16};
|
||||
use compositing_traits::{
|
||||
CompositionPipeline, CompositorMsg, CompositorReceiver, ConstellationMsg,
|
||||
ForwardedToCompositorMsg, SendableFrameTree,
|
||||
CompositionPipeline, CompositorMsg, CompositorReceiver, ConstellationMsg, SendableFrameTree,
|
||||
};
|
||||
use crossbeam_channel::Sender;
|
||||
use embedder_traits::Cursor;
|
||||
|
@ -51,8 +50,7 @@ use webrender_api::{
|
|||
};
|
||||
use webrender_traits::display_list::{HitTestInfo, ScrollTree};
|
||||
use webrender_traits::{
|
||||
CanvasToCompositorMsg, CompositorHitTestResult, FontToCompositorMsg, ImageUpdate,
|
||||
NetToCompositorMsg, RenderingContext, ScriptToCompositorMsg, SerializedImageUpdate,
|
||||
CompositorHitTestResult, CrossProcessCompositorMessage, ImageUpdate, RenderingContext,
|
||||
UntrustedNodeAddress,
|
||||
};
|
||||
|
||||
|
@ -653,29 +651,8 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.pending_paint_metrics.insert(pipeline_id, epoch);
|
||||
},
|
||||
|
||||
CompositorMsg::GetClientWindow(req) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.window) {
|
||||
warn!("Sending response to get client window failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
|
||||
CompositorMsg::GetScreenSize(req) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.screen) {
|
||||
warn!("Sending response to get screen size failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
|
||||
CompositorMsg::GetScreenAvailSize(req) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.screen_avail) {
|
||||
warn!(
|
||||
"Sending response to get screen avail size failed ({:?}).",
|
||||
e
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
CompositorMsg::Forwarded(msg) => {
|
||||
self.handle_webrender_message(msg);
|
||||
CompositorMsg::CrossProcess(cross_proces_message) => {
|
||||
self.handle_cross_process_message(cross_proces_message);
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -685,11 +662,9 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
/// Accept messages from content processes that need to be relayed to the WebRender
|
||||
/// instance in the parent process.
|
||||
#[tracing::instrument(skip(self), fields(servo_profiling = true))]
|
||||
fn handle_webrender_message(&mut self, msg: ForwardedToCompositorMsg) {
|
||||
fn handle_cross_process_message(&mut self, msg: CrossProcessCompositorMessage) {
|
||||
match msg {
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::SendInitialTransaction(
|
||||
pipeline,
|
||||
)) => {
|
||||
CrossProcessCompositorMessage::SendInitialTransaction(pipeline) => {
|
||||
let mut txn = Transaction::new();
|
||||
txn.set_display_list(WebRenderEpoch(0), (pipeline, Default::default()));
|
||||
self.generate_frame(&mut txn, RenderReasons::SCENE);
|
||||
|
@ -697,11 +672,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::SendScrollNode(
|
||||
CrossProcessCompositorMessage::SendScrollNode(
|
||||
pipeline_id,
|
||||
point,
|
||||
external_scroll_id,
|
||||
)) => {
|
||||
) => {
|
||||
let pipeline_id = pipeline_id.into();
|
||||
let pipeline_details = match self.pipeline_details.get_mut(&pipeline_id) {
|
||||
Some(details) => details,
|
||||
|
@ -733,11 +708,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::SendDisplayList {
|
||||
CrossProcessCompositorMessage::SendDisplayList {
|
||||
display_list_info,
|
||||
display_list_descriptor,
|
||||
display_list_receiver,
|
||||
}) => {
|
||||
} => {
|
||||
// This must match the order from the sender, currently in `shared/script/lib.rs`.
|
||||
let items_data = match display_list_receiver.recv() {
|
||||
Ok(display_list_data) => display_list_data,
|
||||
|
@ -793,12 +768,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.send_transaction(self.webrender_document, transaction);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::HitTest(
|
||||
pipeline,
|
||||
point,
|
||||
flags,
|
||||
sender,
|
||||
)) => {
|
||||
CrossProcessCompositorMessage::HitTest(pipeline, point, flags, sender) => {
|
||||
// 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.
|
||||
// Without flushing scene building, any hit test we do might be done against
|
||||
|
@ -815,27 +785,20 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
let _ = sender.send(result);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::GenerateImageKey(sender)) |
|
||||
ForwardedToCompositorMsg::Net(NetToCompositorMsg::GenerateImageKey(sender)) => {
|
||||
CrossProcessCompositorMessage::GenerateImageKey(sender) => {
|
||||
let _ = sender.send(self.webrender_api.generate_image_key());
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::UpdateImages(updates)) => {
|
||||
CrossProcessCompositorMessage::UpdateImages(updates) => {
|
||||
let mut txn = Transaction::new();
|
||||
for update in updates {
|
||||
match update {
|
||||
SerializedImageUpdate::AddImage(key, desc, data) => {
|
||||
match data.to_image_data() {
|
||||
Ok(data) => txn.add_image(key, desc, data, None),
|
||||
Err(e) => warn!("error when sending image data: {:?}", e),
|
||||
}
|
||||
ImageUpdate::AddImage(key, desc, data) => {
|
||||
txn.add_image(key, desc, data.into(), None)
|
||||
},
|
||||
SerializedImageUpdate::DeleteImage(key) => txn.delete_image(key),
|
||||
SerializedImageUpdate::UpdateImage(key, desc, data) => {
|
||||
match data.to_image_data() {
|
||||
Ok(data) => txn.update_image(key, desc, data, &DirtyRect::All),
|
||||
Err(e) => warn!("error when sending image data: {:?}", e),
|
||||
}
|
||||
ImageUpdate::DeleteImage(key) => txn.delete_image(key),
|
||||
ImageUpdate::UpdateImage(key, desc, data) => {
|
||||
txn.update_image(key, desc, data.into(), &DirtyRect::All)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -843,27 +806,27 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::AddFont(
|
||||
font_key,
|
||||
data,
|
||||
index,
|
||||
)) => {
|
||||
CrossProcessCompositorMessage::AddFont(font_key, data, index) => {
|
||||
self.add_font(font_key, index, data);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::AddFontInstance(
|
||||
CrossProcessCompositorMessage::AddSystemFont(font_key, native_handle) => {
|
||||
let mut transaction = Transaction::new();
|
||||
transaction.add_native_font(font_key, native_handle);
|
||||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, transaction);
|
||||
},
|
||||
|
||||
CrossProcessCompositorMessage::AddFontInstance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
size,
|
||||
flags,
|
||||
)) => {
|
||||
) => {
|
||||
self.add_font_instance(font_instance_key, font_key, size, flags);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::RemoveFonts(
|
||||
keys,
|
||||
instance_keys,
|
||||
)) => {
|
||||
CrossProcessCompositorMessage::RemoveFonts(keys, instance_keys) => {
|
||||
let mut transaction = Transaction::new();
|
||||
|
||||
for instance in instance_keys.into_iter() {
|
||||
|
@ -877,18 +840,18 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.send_transaction(self.webrender_document, transaction);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Net(NetToCompositorMsg::AddImage(key, desc, data)) => {
|
||||
CrossProcessCompositorMessage::AddImage(key, desc, data) => {
|
||||
let mut txn = Transaction::new();
|
||||
txn.add_image(key, desc, data, None);
|
||||
txn.add_image(key, desc, data.into(), None);
|
||||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::GenerateKeys(
|
||||
CrossProcessCompositorMessage::GenerateFontKeys(
|
||||
number_of_font_keys,
|
||||
number_of_font_instance_keys,
|
||||
result_sender,
|
||||
)) => {
|
||||
) => {
|
||||
let font_keys = (0..number_of_font_keys)
|
||||
.map(|_| self.webrender_api.generate_font_key())
|
||||
.collect();
|
||||
|
@ -897,53 +860,23 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
.collect();
|
||||
let _ = result_sender.send((font_keys, font_instance_keys));
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddFontInstance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
size,
|
||||
flags,
|
||||
)) => {
|
||||
self.add_font_instance(font_instance_key, font_key, size, flags);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddFont(
|
||||
font_key,
|
||||
index,
|
||||
data,
|
||||
)) => {
|
||||
self.add_font(font_key, index, data);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddSystemFont(
|
||||
font_key,
|
||||
native_handle,
|
||||
)) => {
|
||||
let mut transaction = Transaction::new();
|
||||
transaction.add_native_font(font_key, native_handle);
|
||||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, transaction);
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Canvas(CanvasToCompositorMsg::GenerateKey(sender)) => {
|
||||
let _ = sender.send(self.webrender_api.generate_image_key());
|
||||
},
|
||||
|
||||
ForwardedToCompositorMsg::Canvas(CanvasToCompositorMsg::UpdateImages(updates)) => {
|
||||
let mut txn = Transaction::new();
|
||||
for update in updates {
|
||||
match update {
|
||||
ImageUpdate::AddImage(key, descriptor, data) => {
|
||||
txn.add_image(key, descriptor, data, None)
|
||||
},
|
||||
ImageUpdate::UpdateImage(key, descriptor, data) => {
|
||||
txn.update_image(key, descriptor, data, &DirtyRect::All)
|
||||
},
|
||||
ImageUpdate::DeleteImage(key) => txn.delete_image(key),
|
||||
}
|
||||
CrossProcessCompositorMessage::GetClientWindowRect(req) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.window_rect) {
|
||||
warn!("Sending response to get client window failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
CrossProcessCompositorMessage::GetScreenSize(req) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.screen_size) {
|
||||
warn!("Sending response to get screen size failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
CrossProcessCompositorMessage::GetAvailableScreenSize(req) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.available_screen_size) {
|
||||
warn!(
|
||||
"Sending response to get screen avail size failed ({:?}).",
|
||||
e
|
||||
);
|
||||
}
|
||||
self.webrender_api
|
||||
.send_transaction(self.webrender_document, txn);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -968,23 +901,40 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
|
|||
self.remove_pipeline_root_layer(pipeline_id);
|
||||
let _ = sender.send(());
|
||||
},
|
||||
CompositorMsg::Forwarded(ForwardedToCompositorMsg::Canvas(
|
||||
CanvasToCompositorMsg::GenerateKey(sender),
|
||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GenerateImageKey(
|
||||
sender,
|
||||
)) => {
|
||||
let _ = sender.send(self.webrender_api.generate_image_key());
|
||||
},
|
||||
CompositorMsg::GetClientWindow(sender) => {
|
||||
if let Err(e) = sender.send(self.embedder_coordinates.window) {
|
||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GenerateFontKeys(
|
||||
number_of_font_keys,
|
||||
number_of_font_instance_keys,
|
||||
result_sender,
|
||||
)) => {
|
||||
let font_keys = (0..number_of_font_keys)
|
||||
.map(|_| self.webrender_api.generate_font_key())
|
||||
.collect();
|
||||
let font_instance_keys = (0..number_of_font_instance_keys)
|
||||
.map(|_| self.webrender_api.generate_font_instance_key())
|
||||
.collect();
|
||||
let _ = result_sender.send((font_keys, font_instance_keys));
|
||||
},
|
||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetClientWindowRect(
|
||||
req,
|
||||
)) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.window_rect) {
|
||||
warn!("Sending response to get client window failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
CompositorMsg::GetScreenSize(sender) => {
|
||||
if let Err(e) = sender.send(self.embedder_coordinates.screen) {
|
||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetScreenSize(req)) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.screen_size) {
|
||||
warn!("Sending response to get screen size failed ({:?}).", e);
|
||||
}
|
||||
},
|
||||
CompositorMsg::GetScreenAvailSize(sender) => {
|
||||
if let Err(e) = sender.send(self.embedder_coordinates.screen_avail) {
|
||||
CompositorMsg::CrossProcess(CrossProcessCompositorMessage::GetAvailableScreenSize(
|
||||
req,
|
||||
)) => {
|
||||
if let Err(e) = req.send(self.embedder_coordinates.available_screen_size) {
|
||||
warn!(
|
||||
"Sending response to get screen avail size failed ({:?}).",
|
||||
e
|
||||
|
|
|
@ -48,10 +48,7 @@ mod from_constellation {
|
|||
Self::LoadComplete(..) => target!("LoadComplete"),
|
||||
Self::WebDriverMouseButtonEvent(..) => target!("WebDriverMouseButtonEvent"),
|
||||
Self::WebDriverMouseMoveEvent(..) => target!("WebDriverMouseMoveEvent"),
|
||||
Self::GetClientWindow(..) => target!("GetClientWindow"),
|
||||
Self::GetScreenSize(..) => target!("GetScreenSize"),
|
||||
Self::GetScreenAvailSize(..) => target!("GetScreenAvailSize"),
|
||||
Self::Forwarded(..) => target!("Forwarded"),
|
||||
Self::CrossProcess(_) => target!("CrossProcess"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,11 +241,11 @@ pub struct EmbedderCoordinates {
|
|||
/// The pixel density of the display.
|
||||
pub hidpi_factor: Scale<f32, DeviceIndependentPixel, DevicePixel>,
|
||||
/// Size of the screen.
|
||||
pub screen: DeviceIntSize,
|
||||
pub screen_size: DeviceIntSize,
|
||||
/// Size of the available screen space (screen without toolbars and docks).
|
||||
pub screen_avail: DeviceIntSize,
|
||||
/// Size of the native window.
|
||||
pub window: (DeviceIntSize, DeviceIntPoint),
|
||||
pub available_screen_size: DeviceIntSize,
|
||||
/// Position and size of the native window.
|
||||
pub window_rect: DeviceIntRect,
|
||||
/// Size of the GL buffer in the window.
|
||||
pub framebuffer: DeviceIntSize,
|
||||
/// Coordinates of the document within the framebuffer.
|
||||
|
@ -290,9 +290,9 @@ mod test {
|
|||
let screen = Size2D::new(1080, 720);
|
||||
let coordinates = EmbedderCoordinates {
|
||||
hidpi_factor: Scale::new(1.),
|
||||
screen,
|
||||
screen_avail: screen,
|
||||
window: (viewport, pos),
|
||||
screen_size: screen,
|
||||
available_screen_size: screen,
|
||||
window_rect: DeviceIntRect::from_origin_and_size(pos, viewport),
|
||||
framebuffer: viewport,
|
||||
viewport: DeviceIntRect::from_origin_and_size(pos, viewport),
|
||||
};
|
||||
|
|
|
@ -108,8 +108,7 @@ use canvas_traits::canvas::{CanvasId, CanvasMsg};
|
|||
use canvas_traits::webgl::WebGLThreads;
|
||||
use canvas_traits::ConstellationCanvasMsg;
|
||||
use compositing_traits::{
|
||||
CompositorMsg, CompositorProxy, ConstellationMsg as FromCompositorMsg,
|
||||
ForwardedToCompositorMsg, SendableFrameTree,
|
||||
CompositorMsg, CompositorProxy, ConstellationMsg as FromCompositorMsg, SendableFrameTree,
|
||||
};
|
||||
use crossbeam_channel::{after, never, select, unbounded, Receiver, Sender};
|
||||
use devtools_traits::{
|
||||
|
@ -157,7 +156,7 @@ use webgpu::swapchain::WGPUImageMap;
|
|||
use webgpu::{self, WebGPU, WebGPURequest, WebGPUResponse};
|
||||
use webrender::{RenderApi, RenderApiSender};
|
||||
use webrender_api::DocumentId;
|
||||
use webrender_traits::{WebRenderNetApi, WebRenderScriptApi, WebrenderExternalImageRegistry};
|
||||
use webrender_traits::WebrenderExternalImageRegistry;
|
||||
|
||||
use crate::browsingcontext::{
|
||||
AllBrowsingContextsIterator, BrowsingContext, FullyActiveBrowsingContextsIterator,
|
||||
|
@ -392,14 +391,6 @@ pub struct Constellation<STF, SWF> {
|
|||
/// Webrender related objects required by WebGPU threads
|
||||
webrender_wgpu: WebrenderWGPU,
|
||||
|
||||
/// A channel for content processes to send messages that will
|
||||
/// be relayed to the WebRender thread.
|
||||
webrender_api_ipc_sender: WebRenderScriptApi,
|
||||
|
||||
/// A channel for content process image caches to send messages
|
||||
/// that will be relayed to the WebRender thread.
|
||||
webrender_image_api_sender: WebRenderNetApi,
|
||||
|
||||
/// A map of message-port Id to info.
|
||||
message_ports: HashMap<MessagePortId, MessagePortInfo>,
|
||||
|
||||
|
@ -506,7 +497,7 @@ pub struct InitialConstellationState {
|
|||
/// A channel through which messages can be sent to the embedder.
|
||||
pub embedder_proxy: EmbedderProxy,
|
||||
|
||||
/// A channel through which messages can be sent to the compositor.
|
||||
/// A channel through which messages can be sent to the compositor in-process.
|
||||
pub compositor_proxy: CompositorProxy,
|
||||
|
||||
/// A channel to the developer tools, if applicable.
|
||||
|
@ -705,35 +696,6 @@ where
|
|||
// Zero is reserved for the embedder.
|
||||
PipelineNamespace::install(PipelineNamespaceId(1));
|
||||
|
||||
let (webrender_ipc_sender, webrender_ipc_receiver) =
|
||||
ipc::channel().expect("ipc channel failure");
|
||||
let (webrender_image_ipc_sender, webrender_image_ipc_receiver) =
|
||||
ipc::channel().expect("ipc channel failure");
|
||||
|
||||
let compositor_proxy = state.compositor_proxy.clone();
|
||||
ROUTER.add_route(
|
||||
webrender_ipc_receiver.to_opaque(),
|
||||
Box::new(move |message| {
|
||||
compositor_proxy.send(CompositorMsg::Forwarded(
|
||||
ForwardedToCompositorMsg::Layout(
|
||||
message.to().expect("conversion failure"),
|
||||
),
|
||||
));
|
||||
}),
|
||||
);
|
||||
|
||||
let compositor_proxy = state.compositor_proxy.clone();
|
||||
ROUTER.add_route(
|
||||
webrender_image_ipc_receiver.to_opaque(),
|
||||
Box::new(move |message| {
|
||||
compositor_proxy.send(CompositorMsg::Forwarded(
|
||||
ForwardedToCompositorMsg::Net(
|
||||
message.to().expect("conversion failure"),
|
||||
),
|
||||
));
|
||||
}),
|
||||
);
|
||||
|
||||
let webrender_wgpu = WebrenderWGPU {
|
||||
webrender_api: state.webrender_api_sender.create_api(),
|
||||
webrender_external_images: state.webrender_external_images,
|
||||
|
@ -788,8 +750,6 @@ where
|
|||
scheduler_receiver,
|
||||
document_states: HashMap::new(),
|
||||
webrender_document: state.webrender_document,
|
||||
webrender_api_ipc_sender: WebRenderScriptApi::new(webrender_ipc_sender),
|
||||
webrender_image_api_sender: WebRenderNetApi::new(webrender_image_ipc_sender),
|
||||
webrender_wgpu,
|
||||
shutting_down: false,
|
||||
handled_warnings: VecDeque::new(),
|
||||
|
@ -1053,8 +1013,6 @@ where
|
|||
event_loop,
|
||||
load_data,
|
||||
prev_throttled: throttled,
|
||||
webrender_api_sender: self.webrender_api_ipc_sender.clone(),
|
||||
webrender_image_api_sender: self.webrender_image_api_sender.clone(),
|
||||
webrender_document: self.webrender_document,
|
||||
webgl_chan: self
|
||||
.webgl_threads
|
||||
|
@ -1751,18 +1709,6 @@ where
|
|||
|
||||
response_sender.send(true).unwrap_or_default();
|
||||
},
|
||||
FromScriptMsg::GetClientWindow(response_sender) => {
|
||||
self.compositor_proxy
|
||||
.send(CompositorMsg::GetClientWindow(response_sender));
|
||||
},
|
||||
FromScriptMsg::GetScreenSize(response_sender) => {
|
||||
self.compositor_proxy
|
||||
.send(CompositorMsg::GetScreenSize(response_sender));
|
||||
},
|
||||
FromScriptMsg::GetScreenAvailSize(response_sender) => {
|
||||
self.compositor_proxy
|
||||
.send(CompositorMsg::GetScreenAvailSize(response_sender));
|
||||
},
|
||||
FromScriptMsg::LogEntry(thread_name, entry) => {
|
||||
self.handle_log_entry(Some(source_top_ctx_id), thread_name, entry);
|
||||
},
|
||||
|
|
|
@ -43,6 +43,7 @@ use servo_config::prefs;
|
|||
use servo_config::prefs::PrefValue;
|
||||
use servo_url::ServoUrl;
|
||||
use webrender_api::DocumentId;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use crate::event_loop::EventLoop;
|
||||
use crate::sandboxing::{spawn_multiprocess, UnprivilegedContent};
|
||||
|
@ -183,12 +184,6 @@ pub struct InitialPipelineState {
|
|||
/// compositor threads after spawning a pipeline.
|
||||
pub prev_throttled: bool,
|
||||
|
||||
/// Webrender api.
|
||||
pub webrender_image_api_sender: webrender_traits::WebRenderNetApi,
|
||||
|
||||
/// Webrender api.
|
||||
pub webrender_api_sender: webrender_traits::WebRenderScriptApi,
|
||||
|
||||
/// The ID of the document processed by this script thread.
|
||||
pub webrender_document: DocumentId,
|
||||
|
||||
|
@ -293,9 +288,11 @@ impl Pipeline {
|
|||
opts: (*opts::get()).clone(),
|
||||
prefs: prefs::pref_map().iter().collect(),
|
||||
pipeline_namespace_id: state.pipeline_namespace_id,
|
||||
webrender_api_sender: state.webrender_api_sender,
|
||||
webrender_image_api_sender: state.webrender_image_api_sender,
|
||||
webrender_document: state.webrender_document,
|
||||
cross_process_compositor_api: state
|
||||
.compositor_proxy
|
||||
.cross_process_compositor_api
|
||||
.clone(),
|
||||
webgl_chan: state.webgl_chan,
|
||||
webxr_registry: state.webxr_registry,
|
||||
player_context: state.player_context,
|
||||
|
@ -498,8 +495,7 @@ pub struct UnprivilegedPipelineContent {
|
|||
opts: Opts,
|
||||
prefs: HashMap<String, PrefValue>,
|
||||
pipeline_namespace_id: PipelineNamespaceId,
|
||||
webrender_api_sender: webrender_traits::WebRenderScriptApi,
|
||||
webrender_image_api_sender: webrender_traits::WebRenderNetApi,
|
||||
cross_process_compositor_api: CrossProcessCompositorApi,
|
||||
webrender_document: DocumentId,
|
||||
webgl_chan: Option<WebGLPipeline>,
|
||||
webxr_registry: webxr_api::Registry,
|
||||
|
@ -518,7 +514,9 @@ impl UnprivilegedPipelineContent {
|
|||
// Idempotent in single-process mode.
|
||||
PipelineNamespace::set_installer_sender(self.namespace_request_sender);
|
||||
|
||||
let image_cache = Arc::new(ImageCacheImpl::new(self.webrender_image_api_sender.clone()));
|
||||
let image_cache = Arc::new(ImageCacheImpl::new(
|
||||
self.cross_process_compositor_api.clone(),
|
||||
));
|
||||
let (content_process_shutdown_chan, content_process_shutdown_port) = unbounded();
|
||||
STF::create(
|
||||
InitialScriptState {
|
||||
|
@ -545,7 +543,7 @@ impl UnprivilegedPipelineContent {
|
|||
webgl_chan: self.webgl_chan,
|
||||
webxr_registry: self.webxr_registry,
|
||||
webrender_document: self.webrender_document,
|
||||
webrender_api_sender: self.webrender_api_sender.clone(),
|
||||
compositor_api: self.cross_process_compositor_api.clone(),
|
||||
player_context: self.player_context.clone(),
|
||||
inherited_secure_context: self.load_data.inherited_secure_context,
|
||||
},
|
||||
|
|
|
@ -181,9 +181,6 @@ mod from_script {
|
|||
Self::PipelineExited => target!("PipelineExited"),
|
||||
Self::ForwardDOMMessage(..) => target!("ForwardDOMMessage"),
|
||||
Self::ScheduleJob(..) => target!("ScheduleJob"),
|
||||
Self::GetClientWindow(..) => target!("GetClientWindow"),
|
||||
Self::GetScreenSize(..) => target!("GetScreenSize"),
|
||||
Self::GetScreenAvailSize(..) => target!("GetScreenAvailSize"),
|
||||
Self::MediaSessionEvent(..) => target!("MediaSessionEvent"),
|
||||
Self::RequestAdapter(..) => target!("RequestAdapter"),
|
||||
Self::GetWebGPUChan(..) => target!("GetWebGPUChan"),
|
||||
|
|
|
@ -30,7 +30,7 @@ use style::values::computed::font::{FamilyName, FontFamilyNameSyntax, SingleFont
|
|||
use style::Atom;
|
||||
use url::Url;
|
||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey};
|
||||
use webrender_traits::{ScriptToCompositorMsg, WebRenderScriptApi};
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use crate::font::{
|
||||
Font, FontDescriptor, FontFamilyDescriptor, FontGroup, FontRef, FontSearchScope,
|
||||
|
@ -52,7 +52,7 @@ pub struct FontContext {
|
|||
resource_threads: ReentrantMutex<CoreResourceThread>,
|
||||
|
||||
/// A sender that can send messages and receive replies from the compositor.
|
||||
webrender_api: ReentrantMutex<WebRenderScriptApi>,
|
||||
compositor_api: ReentrantMutex<CrossProcessCompositorApi>,
|
||||
|
||||
/// 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.
|
||||
|
@ -100,14 +100,14 @@ impl MallocSizeOf for FontContext {
|
|||
impl FontContext {
|
||||
pub fn new(
|
||||
system_font_service_proxy: Arc<SystemFontServiceProxy>,
|
||||
webrender_api: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
resource_threads: ResourceThreads,
|
||||
) -> Self {
|
||||
#[allow(clippy::default_constructed_unit_structs)]
|
||||
Self {
|
||||
system_font_service_proxy,
|
||||
resource_threads: ReentrantMutex::new(resource_threads.core_thread),
|
||||
webrender_api: ReentrantMutex::new(webrender_api),
|
||||
compositor_api: ReentrantMutex::new(compositor_api),
|
||||
fonts: Default::default(),
|
||||
resolved_font_groups: Default::default(),
|
||||
web_fonts: Arc::new(RwLock::default()),
|
||||
|
@ -324,15 +324,11 @@ impl FontContext {
|
|||
.entry(identifier.clone())
|
||||
.or_insert_with(|| {
|
||||
let font_key = self.system_font_service_proxy.generate_font_key();
|
||||
let _ = self
|
||||
.webrender_api
|
||||
.lock()
|
||||
.sender()
|
||||
.send(ScriptToCompositorMsg::AddFont(
|
||||
font_key,
|
||||
font_data.as_ipc_shared_memory(),
|
||||
identifier.index(),
|
||||
));
|
||||
self.compositor_api.lock().add_font(
|
||||
font_key,
|
||||
font_data.as_ipc_shared_memory(),
|
||||
identifier.index(),
|
||||
);
|
||||
font_key
|
||||
});
|
||||
|
||||
|
@ -342,13 +338,11 @@ impl FontContext {
|
|||
.entry((font_key, pt_size))
|
||||
.or_insert_with(|| {
|
||||
let font_instance_key = self.system_font_service_proxy.generate_font_instance_key();
|
||||
let _ = self.webrender_api.lock().sender().send(
|
||||
ScriptToCompositorMsg::AddFontInstance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
pt_size.to_f32_px(),
|
||||
flags,
|
||||
),
|
||||
self.compositor_api.lock().add_font_instance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
pt_size.to_f32_px(),
|
||||
flags,
|
||||
);
|
||||
font_instance_key
|
||||
});
|
||||
|
|
|
@ -27,7 +27,7 @@ use style::values::specified::FontStretch as SpecifiedFontStretch;
|
|||
use style::Atom;
|
||||
use tracing::{span, Level};
|
||||
use webrender_api::{FontInstanceFlags, FontInstanceKey, FontKey};
|
||||
use webrender_traits::WebRenderFontApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use crate::font::FontDescriptor;
|
||||
use crate::font_store::FontStore;
|
||||
|
@ -97,7 +97,7 @@ struct ResolvedGenericFontFamilies {
|
|||
pub struct SystemFontService {
|
||||
port: IpcReceiver<SystemFontServiceMessage>,
|
||||
local_families: FontStore,
|
||||
webrender_api: Box<dyn WebRenderFontApi>,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
webrender_fonts: HashMap<FontIdentifier, FontKey>,
|
||||
font_instances: HashMap<(FontKey, Au), FontInstanceKey>,
|
||||
generic_fonts: ResolvedGenericFontFamilies,
|
||||
|
@ -129,7 +129,7 @@ impl SystemFontServiceProxySender {
|
|||
}
|
||||
|
||||
impl SystemFontService {
|
||||
pub fn spawn(webrender_api: Box<dyn WebRenderFontApi + Send>) -> SystemFontServiceProxySender {
|
||||
pub fn spawn(compositor_api: CrossProcessCompositorApi) -> SystemFontServiceProxySender {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
|
||||
thread::Builder::new()
|
||||
|
@ -139,7 +139,7 @@ impl SystemFontService {
|
|||
let mut cache = SystemFontService {
|
||||
port: receiver,
|
||||
local_families: Default::default(),
|
||||
webrender_api,
|
||||
compositor_api,
|
||||
webrender_fonts: HashMap::new(),
|
||||
font_instances: HashMap::new(),
|
||||
generic_fonts: Default::default(),
|
||||
|
@ -198,7 +198,7 @@ impl SystemFontService {
|
|||
|
||||
const FREE_FONT_KEYS_BATCH_SIZE: usize = 20;
|
||||
const FREE_FONT_INSTANCE_KEYS_BATCH_SIZE: usize = 20;
|
||||
let (mut new_font_keys, mut new_font_instance_keys) = self.webrender_api.fetch_font_keys(
|
||||
let (mut new_font_keys, mut new_font_instance_keys) = self.compositor_api.fetch_font_keys(
|
||||
FREE_FONT_KEYS_BATCH_SIZE - self.free_font_keys.len(),
|
||||
FREE_FONT_INSTANCE_KEYS_BATCH_SIZE - self.free_font_instance_keys.len(),
|
||||
);
|
||||
|
@ -281,7 +281,7 @@ impl SystemFontService {
|
|||
) -> FontInstanceKey {
|
||||
self.fetch_new_keys();
|
||||
|
||||
let webrender_font_api = &self.webrender_api;
|
||||
let compositor_api = &self.compositor_api;
|
||||
let webrender_fonts = &mut self.webrender_fonts;
|
||||
let font_data = self.local_families.get_or_initialize_font_data(&identifier);
|
||||
|
||||
|
@ -296,12 +296,12 @@ impl SystemFontService {
|
|||
// this for those platforms.
|
||||
#[cfg(target_os = "macos")]
|
||||
if let FontIdentifier::Local(local_font_identifier) = identifier {
|
||||
webrender_font_api
|
||||
compositor_api
|
||||
.add_system_font(font_key, local_font_identifier.native_font_handle());
|
||||
return font_key;
|
||||
}
|
||||
|
||||
webrender_font_api.add_font(
|
||||
compositor_api.add_font(
|
||||
font_key,
|
||||
font_data.as_ipc_shared_memory(),
|
||||
identifier.index(),
|
||||
|
@ -314,7 +314,7 @@ impl SystemFontService {
|
|||
.entry((font_key, pt_size))
|
||||
.or_insert_with(|| {
|
||||
let font_instance_key = self.free_font_instance_keys.pop().unwrap();
|
||||
webrender_font_api.add_font_instance(
|
||||
compositor_api.add_font_instance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
pt_size.to_f32_px(),
|
||||
|
|
|
@ -33,7 +33,7 @@ use style::values::computed::{FontLanguageOverride, XLang};
|
|||
use style::values::generics::font::LineHeight;
|
||||
use style::ArcSlice;
|
||||
use webrender_api::{FontInstanceKey, FontKey, IdNamespace};
|
||||
use webrender_traits::WebRenderScriptApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
struct TestContext {
|
||||
context: FontContext,
|
||||
|
@ -47,11 +47,11 @@ impl TestContext {
|
|||
let (core_sender, _) = ipc::channel().unwrap();
|
||||
let (storage_sender, _) = ipc::channel().unwrap();
|
||||
let mock_resource_threads = ResourceThreads::new(core_sender, storage_sender);
|
||||
let mock_webrender_api = WebRenderScriptApi::dummy();
|
||||
let mock_compositor_api = CrossProcessCompositorApi::dummy();
|
||||
|
||||
let proxy_clone = Arc::new(system_font_service_proxy.to_sender().to_proxy());
|
||||
Self {
|
||||
context: FontContext::new(proxy_clone, mock_webrender_api, mock_resource_threads),
|
||||
context: FontContext::new(proxy_clone, mock_compositor_api, mock_resource_threads),
|
||||
system_font_service,
|
||||
system_font_service_proxy,
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ use style_traits::{CSSPixel, DevicePixel, SpeculativePainter};
|
|||
use time_03::Duration;
|
||||
use url::Url;
|
||||
use webrender_api::{units, ColorF, HitTestFlags};
|
||||
use webrender_traits::WebRenderScriptApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
/// Information needed by layout.
|
||||
pub struct LayoutThread {
|
||||
|
@ -170,8 +170,8 @@ pub struct LayoutThread {
|
|||
/// The executors for paint worklets.
|
||||
registered_painters: RegisteredPaintersImpl,
|
||||
|
||||
/// Webrender interface.
|
||||
webrender_api: WebRenderScriptApi,
|
||||
/// Cross-process access to the compositor API.
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
|
||||
/// Paint time metrics.
|
||||
paint_time_metrics: PaintTimeMetrics,
|
||||
|
@ -201,7 +201,7 @@ impl LayoutFactory for LayoutFactoryImpl {
|
|||
config.resource_threads,
|
||||
config.system_font_service,
|
||||
config.time_profiler_chan,
|
||||
config.webrender_api_sender,
|
||||
config.compositor_api,
|
||||
config.paint_time_metrics,
|
||||
config.window_size,
|
||||
))
|
||||
|
@ -249,7 +249,7 @@ impl Drop for LayoutThread {
|
|||
let (keys, instance_keys) = self
|
||||
.font_context
|
||||
.collect_unused_webrender_resources(true /* all */);
|
||||
self.webrender_api
|
||||
self.compositor_api
|
||||
.remove_unused_font_resources(keys, instance_keys)
|
||||
}
|
||||
}
|
||||
|
@ -359,7 +359,7 @@ impl Layout for LayoutThread {
|
|||
|
||||
let client_point = units::DevicePoint::from_untyped(point);
|
||||
let results = self
|
||||
.webrender_api
|
||||
.compositor_api
|
||||
.hit_test(Some(self.id.into()), client_point, flags);
|
||||
|
||||
results.iter().map(|result| result.node.into()).collect()
|
||||
|
@ -562,12 +562,12 @@ impl LayoutThread {
|
|||
resource_threads: ResourceThreads,
|
||||
system_font_service: Arc<SystemFontServiceProxy>,
|
||||
time_profiler_chan: profile_time::ProfilerChan,
|
||||
webrender_api: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
paint_time_metrics: PaintTimeMetrics,
|
||||
window_size: WindowSizeData,
|
||||
) -> LayoutThread {
|
||||
// Let webrender know about this pipeline by sending an empty display list.
|
||||
webrender_api.send_initial_transaction(id.into());
|
||||
compositor_api.send_initial_transaction(id.into());
|
||||
|
||||
let mut font = Font::initial_values();
|
||||
let default_font_size = pref!(fonts.default_size);
|
||||
|
@ -579,7 +579,7 @@ impl LayoutThread {
|
|||
|
||||
let font_context = Arc::new(FontContext::new(
|
||||
system_font_service,
|
||||
webrender_api.clone(),
|
||||
compositor_api.clone(),
|
||||
resource_threads,
|
||||
));
|
||||
let device = Device::new(
|
||||
|
@ -611,7 +611,7 @@ impl LayoutThread {
|
|||
Au::from_f32_px(window_size.initial_viewport.width),
|
||||
Au::from_f32_px(window_size.initial_viewport.height),
|
||||
),
|
||||
webrender_api,
|
||||
compositor_api,
|
||||
stylist: Stylist::new(device, QuirksMode::NoQuirks),
|
||||
display_list: Default::default(),
|
||||
indexable_text: Default::default(),
|
||||
|
@ -936,13 +936,13 @@ impl LayoutThread {
|
|||
self.paint_time_metrics
|
||||
.maybe_observe_paint_time(self, epoch, is_contentful.0);
|
||||
|
||||
self.webrender_api
|
||||
self.compositor_api
|
||||
.send_display_list(compositor_info, builder.end().1);
|
||||
|
||||
let (keys, instance_keys) = self
|
||||
.font_context
|
||||
.collect_unused_webrender_resources(false /* all */);
|
||||
self.webrender_api
|
||||
self.compositor_api
|
||||
.remove_unused_font_resources(keys, instance_keys)
|
||||
},
|
||||
);
|
||||
|
@ -1185,7 +1185,7 @@ impl LayoutThread {
|
|||
.insert(state.scroll_id, state.scroll_offset);
|
||||
|
||||
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
|
||||
self.webrender_api.send_scroll_node(
|
||||
self.compositor_api.send_scroll_node(
|
||||
self.id.into(),
|
||||
units::LayoutPoint::from_untyped(point),
|
||||
state.scroll_id,
|
||||
|
|
|
@ -92,7 +92,7 @@ use tracing::{span, Level};
|
|||
use url::Url;
|
||||
use webrender_api::units::LayoutPixel;
|
||||
use webrender_api::{units, ExternalScrollId, HitTestFlags};
|
||||
use webrender_traits::WebRenderScriptApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
/// Information needed by layout.
|
||||
pub struct LayoutThread {
|
||||
|
@ -151,8 +151,8 @@ pub struct LayoutThread {
|
|||
/// The executors for paint worklets.
|
||||
registered_painters: RegisteredPaintersImpl,
|
||||
|
||||
/// Webrender interface.
|
||||
webrender_api: WebRenderScriptApi,
|
||||
/// Cross-process access to the Compositor API.
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
|
||||
/// Paint time metrics.
|
||||
paint_time_metrics: PaintTimeMetrics,
|
||||
|
@ -179,7 +179,7 @@ impl LayoutFactory for LayoutFactoryImpl {
|
|||
config.resource_threads,
|
||||
config.system_font_service,
|
||||
config.time_profiler_chan,
|
||||
config.webrender_api_sender,
|
||||
config.compositor_api,
|
||||
config.paint_time_metrics,
|
||||
config.window_size,
|
||||
))
|
||||
|
@ -228,7 +228,7 @@ impl Drop for LayoutThread {
|
|||
let (keys, instance_keys) = self
|
||||
.font_context
|
||||
.collect_unused_webrender_resources(true /* all */);
|
||||
self.webrender_api
|
||||
self.compositor_api
|
||||
.remove_unused_font_resources(keys, instance_keys)
|
||||
}
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ impl Layout for LayoutThread {
|
|||
|
||||
let client_point = units::DevicePoint::from_untyped(point);
|
||||
let results = self
|
||||
.webrender_api
|
||||
.compositor_api
|
||||
.hit_test(Some(self.id.into()), client_point, flags);
|
||||
|
||||
results.iter().map(|result| result.node.into()).collect()
|
||||
|
@ -504,12 +504,12 @@ impl LayoutThread {
|
|||
resource_threads: ResourceThreads,
|
||||
system_font_service: Arc<SystemFontServiceProxy>,
|
||||
time_profiler_chan: profile_time::ProfilerChan,
|
||||
webrender_api_sender: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
paint_time_metrics: PaintTimeMetrics,
|
||||
window_size: WindowSizeData,
|
||||
) -> LayoutThread {
|
||||
// Let webrender know about this pipeline by sending an empty display list.
|
||||
webrender_api_sender.send_initial_transaction(id.into());
|
||||
compositor_api.send_initial_transaction(id.into());
|
||||
|
||||
let mut font = Font::initial_values();
|
||||
let default_font_size = pref!(fonts.default_size);
|
||||
|
@ -523,7 +523,7 @@ impl LayoutThread {
|
|||
// but it will be set correctly when the initial reflow takes place.
|
||||
let font_context = Arc::new(FontContext::new(
|
||||
system_font_service,
|
||||
webrender_api_sender.clone(),
|
||||
compositor_api.clone(),
|
||||
resource_threads,
|
||||
));
|
||||
let device = Device::new(
|
||||
|
@ -555,7 +555,7 @@ impl LayoutThread {
|
|||
Au::from_f32_px(window_size.initial_viewport.width),
|
||||
Au::from_f32_px(window_size.initial_viewport.height),
|
||||
),
|
||||
webrender_api: webrender_api_sender,
|
||||
compositor_api,
|
||||
scroll_offsets: Default::default(),
|
||||
stylist: Stylist::new(device, QuirksMode::NoQuirks),
|
||||
webrender_image_cache: Default::default(),
|
||||
|
@ -864,7 +864,7 @@ impl LayoutThread {
|
|||
.borrow_mut()
|
||||
.insert(state.scroll_id, state.scroll_offset);
|
||||
let point = Point2D::new(-state.scroll_offset.x, -state.scroll_offset.y);
|
||||
self.webrender_api.send_scroll_node(
|
||||
self.compositor_api.send_scroll_node(
|
||||
self.id.into(),
|
||||
units::LayoutPoint::from_untyped(point),
|
||||
state.scroll_id,
|
||||
|
@ -954,13 +954,13 @@ impl LayoutThread {
|
|||
.maybe_observe_paint_time(self, epoch, is_contentful);
|
||||
|
||||
if reflow_goal.needs_display() {
|
||||
self.webrender_api
|
||||
self.compositor_api
|
||||
.send_display_list(display_list.compositor_info, display_list.wr.end().1);
|
||||
|
||||
let (keys, instance_keys) = self
|
||||
.font_context
|
||||
.collect_unused_webrender_resources(false /* all */);
|
||||
self.webrender_api
|
||||
self.compositor_api
|
||||
.remove_unused_font_resources(keys, instance_keys)
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::{mem, thread};
|
|||
|
||||
use embedder_traits::resources::{self, Resource};
|
||||
use imsz::imsz_from_reader;
|
||||
use ipc_channel::ipc::IpcSender;
|
||||
use ipc_channel::ipc::{IpcSender, IpcSharedMemory};
|
||||
use log::{debug, warn};
|
||||
use net_traits::image_cache::{
|
||||
ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponder, ImageResponse,
|
||||
|
@ -21,8 +21,8 @@ use net_traits::{FetchMetadata, FetchResponseMsg, FilteredMetadata, NetworkError
|
|||
use pixels::{load_from_memory, CorsStatus, Image, ImageMetadata, PixelFormat};
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use webrender_api::units::DeviceIntSize;
|
||||
use webrender_api::{ImageData, ImageDescriptor, ImageDescriptorFlags, ImageFormat};
|
||||
use webrender_traits::WebRenderNetApi;
|
||||
use webrender_api::{ImageDescriptor, ImageDescriptorFlags, ImageFormat};
|
||||
use webrender_traits::{CrossProcessCompositorApi, SerializableImageData};
|
||||
|
||||
use crate::resource_thread::CoreResourceThreadPool;
|
||||
|
||||
|
@ -45,13 +45,13 @@ fn decode_bytes_sync(key: LoadKey, bytes: &[u8], cors: CorsStatus) -> DecoderMsg
|
|||
DecoderMsg { key, image }
|
||||
}
|
||||
|
||||
fn get_placeholder_image(webrender_api: &WebRenderNetApi, data: &[u8]) -> Arc<Image> {
|
||||
fn get_placeholder_image(compositor_api: &CrossProcessCompositorApi, data: &[u8]) -> Arc<Image> {
|
||||
let mut image = load_from_memory(data, CorsStatus::Unsafe).unwrap();
|
||||
set_webrender_image_key(webrender_api, &mut image);
|
||||
set_webrender_image_key(compositor_api, &mut image);
|
||||
Arc::new(image)
|
||||
}
|
||||
|
||||
fn set_webrender_image_key(webrender_api: &WebRenderNetApi, image: &mut Image) {
|
||||
fn set_webrender_image_key(compositor_api: &CrossProcessCompositorApi, image: &mut Image) {
|
||||
if image.id.is_some() {
|
||||
return;
|
||||
}
|
||||
|
@ -82,10 +82,11 @@ fn set_webrender_image_key(webrender_api: &WebRenderNetApi, image: &mut Image) {
|
|||
offset: 0,
|
||||
flags,
|
||||
};
|
||||
let data = ImageData::new(bytes);
|
||||
let image_key = webrender_api.generate_image_key();
|
||||
webrender_api.add_image(image_key, descriptor, data);
|
||||
image.id = Some(image_key);
|
||||
if let Some(image_key) = compositor_api.generate_image_key() {
|
||||
let data = SerializableImageData::Raw(IpcSharedMemory::from_bytes(&bytes));
|
||||
compositor_api.add_image(image_key, descriptor, data);
|
||||
image.id = Some(image_key);
|
||||
}
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
@ -328,8 +329,8 @@ struct ImageCacheStore {
|
|||
// The URL used for the placeholder image
|
||||
placeholder_url: ServoUrl,
|
||||
|
||||
// Webrender API instance.
|
||||
webrender_api: WebRenderNetApi,
|
||||
// Cross-process compositor API instance.
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
}
|
||||
|
||||
impl ImageCacheStore {
|
||||
|
@ -343,7 +344,7 @@ impl ImageCacheStore {
|
|||
|
||||
match load_result {
|
||||
LoadResult::Loaded(ref mut image) => {
|
||||
set_webrender_image_key(&self.webrender_api, image)
|
||||
set_webrender_image_key(&self.compositor_api, image)
|
||||
},
|
||||
LoadResult::PlaceholderLoaded(..) | LoadResult::None => {},
|
||||
}
|
||||
|
@ -416,7 +417,7 @@ pub struct ImageCacheImpl {
|
|||
}
|
||||
|
||||
impl ImageCache for ImageCacheImpl {
|
||||
fn new(webrender_api: WebRenderNetApi) -> ImageCacheImpl {
|
||||
fn new(compositor_api: CrossProcessCompositorApi) -> ImageCacheImpl {
|
||||
debug!("New image cache");
|
||||
|
||||
let rippy_data = resources::read_bytes(Resource::RippyPNG);
|
||||
|
@ -431,9 +432,9 @@ impl ImageCache for ImageCacheImpl {
|
|||
store: Arc::new(Mutex::new(ImageCacheStore {
|
||||
pending_loads: AllPendingLoads::new(),
|
||||
completed_loads: HashMap::new(),
|
||||
placeholder_image: get_placeholder_image(&webrender_api, &rippy_data),
|
||||
placeholder_image: get_placeholder_image(&compositor_api, &rippy_data),
|
||||
placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(),
|
||||
webrender_api,
|
||||
compositor_api,
|
||||
})),
|
||||
thread_pool: CoreResourceThreadPool::new(thread_count),
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use headers::{ContentLength, ContentRange, HeaderMapExt};
|
|||
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
|
||||
use http::header::{self, HeaderMap, HeaderValue};
|
||||
use http::StatusCode;
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::ipc::{self, IpcSharedMemory};
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::jsapi::JSAutoRealm;
|
||||
use media::{glplayer_channel, GLPlayerMsg, GLPlayerMsgForward, WindowGLContext};
|
||||
|
@ -35,10 +35,10 @@ use servo_media::player::{PlaybackState, Player, PlayerError, PlayerEvent, SeekL
|
|||
use servo_media::{ClientContextId, ServoMedia, SupportsMediaType};
|
||||
use servo_url::ServoUrl;
|
||||
use webrender_api::{
|
||||
ExternalImageData, ExternalImageId, ExternalImageType, ImageBufferKind, ImageData,
|
||||
ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey,
|
||||
ExternalImageData, ExternalImageId, ExternalImageType, ImageBufferKind, ImageDescriptor,
|
||||
ImageDescriptorFlags, ImageFormat, ImageKey,
|
||||
};
|
||||
use webrender_traits::{ImageUpdate, WebRenderScriptApi};
|
||||
use webrender_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
|
||||
|
||||
use crate::document_loader::{LoadBlocker, LoadType};
|
||||
use crate::dom::attr::Attr;
|
||||
|
@ -156,7 +156,7 @@ impl FrameHolder {
|
|||
|
||||
pub struct MediaFrameRenderer {
|
||||
player_id: Option<u64>,
|
||||
api: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
current_frame: Option<(ImageKey, i32, i32)>,
|
||||
old_frame: Option<ImageKey>,
|
||||
very_old_frame: Option<ImageKey>,
|
||||
|
@ -165,10 +165,10 @@ pub struct MediaFrameRenderer {
|
|||
}
|
||||
|
||||
impl MediaFrameRenderer {
|
||||
fn new(render_api_sender: WebRenderScriptApi) -> Self {
|
||||
fn new(compositor_api: CrossProcessCompositorApi) -> Self {
|
||||
Self {
|
||||
player_id: None,
|
||||
api: render_api_sender,
|
||||
compositor_api,
|
||||
current_frame: None,
|
||||
old_frame: None,
|
||||
very_old_frame: None,
|
||||
|
@ -213,7 +213,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||
updates.push(ImageUpdate::UpdateImage(
|
||||
*image_key,
|
||||
descriptor,
|
||||
ImageData::Raw(frame.get_data()),
|
||||
SerializableImageData::Raw(IpcSharedMemory::from_bytes(&frame.get_data())),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||
Some((ref mut image_key, ref mut width, ref mut height)) => {
|
||||
self.old_frame = Some(*image_key);
|
||||
|
||||
let Some(new_image_key) = self.api.generate_image_key() else {
|
||||
let Some(new_image_key) = self.compositor_api.generate_image_key() else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -244,13 +244,13 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||
ImageBufferKind::Texture2D
|
||||
};
|
||||
|
||||
ImageData::External(ExternalImageData {
|
||||
SerializableImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(self.player_id.unwrap()),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(texture_target),
|
||||
})
|
||||
} else {
|
||||
ImageData::Raw(frame.get_data())
|
||||
SerializableImageData::Raw(IpcSharedMemory::from_bytes(&frame.get_data()))
|
||||
};
|
||||
|
||||
self.current_frame_holder
|
||||
|
@ -260,7 +260,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||
updates.push(ImageUpdate::AddImage(new_image_key, descriptor, image_data));
|
||||
},
|
||||
None => {
|
||||
let Some(image_key) = self.api.generate_image_key() else {
|
||||
let Some(image_key) = self.compositor_api.generate_image_key() else {
|
||||
return;
|
||||
};
|
||||
self.current_frame = Some((image_key, frame.get_width(), frame.get_height()));
|
||||
|
@ -272,13 +272,13 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||
ImageBufferKind::Texture2D
|
||||
};
|
||||
|
||||
ImageData::External(ExternalImageData {
|
||||
SerializableImageData::External(ExternalImageData {
|
||||
id: ExternalImageId(self.player_id.unwrap()),
|
||||
channel_index: 0,
|
||||
image_type: ExternalImageType::TextureHandle(texture_target),
|
||||
})
|
||||
} else {
|
||||
ImageData::Raw(frame.get_data())
|
||||
SerializableImageData::Raw(IpcSharedMemory::from_bytes(&frame.get_data()))
|
||||
};
|
||||
|
||||
self.current_frame_holder = Some(FrameHolder::new(frame));
|
||||
|
@ -286,7 +286,7 @@ impl VideoFrameRenderer for MediaFrameRenderer {
|
|||
updates.push(ImageUpdate::AddImage(image_key, descriptor, image_data));
|
||||
},
|
||||
}
|
||||
self.api.update_images(updates);
|
||||
self.compositor_api.update_images(updates);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ impl HTMLMediaElement {
|
|||
in_flight_play_promises_queue: Default::default(),
|
||||
player: Default::default(),
|
||||
video_renderer: Arc::new(Mutex::new(MediaFrameRenderer::new(
|
||||
document.window().get_webrender_api_sender(),
|
||||
document.window().compositor_api().clone(),
|
||||
))),
|
||||
audio_renderer: Default::default(),
|
||||
show_poster: Cell::new(true),
|
||||
|
|
|
@ -5,16 +5,14 @@
|
|||
use dom_struct::dom_struct;
|
||||
use euclid::Size2D;
|
||||
use profile_traits::ipc;
|
||||
use script_traits::ScriptMsg;
|
||||
use style_traits::CSSPixel;
|
||||
use webrender_api::units::DeviceIntSize;
|
||||
use webrender_traits::CrossProcessCompositorMessage;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::num::Finite;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::window::Window;
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -39,9 +37,9 @@ impl Screen {
|
|||
let (send, recv) =
|
||||
ipc::channel::<DeviceIntSize>(self.global().time_profiler_chan().clone()).unwrap();
|
||||
self.window
|
||||
.upcast::<GlobalScope>()
|
||||
.script_to_constellation_chan()
|
||||
.send(ScriptMsg::GetScreenSize(send))
|
||||
.compositor_api()
|
||||
.sender()
|
||||
.send(CrossProcessCompositorMessage::GetScreenSize(send))
|
||||
.unwrap();
|
||||
let dpr = self.window.device_pixel_ratio();
|
||||
let screen = recv.recv().unwrap_or(Size2D::zero());
|
||||
|
@ -52,9 +50,9 @@ impl Screen {
|
|||
let (send, recv) =
|
||||
ipc::channel::<DeviceIntSize>(self.global().time_profiler_chan().clone()).unwrap();
|
||||
self.window
|
||||
.upcast::<GlobalScope>()
|
||||
.script_to_constellation_chan()
|
||||
.send(ScriptMsg::GetScreenAvailSize(send))
|
||||
.compositor_api()
|
||||
.sender()
|
||||
.send(CrossProcessCompositorMessage::GetAvailableScreenSize(send))
|
||||
.unwrap();
|
||||
let dpr = self.window.device_pixel_ratio();
|
||||
let screen = recv.recv().unwrap_or(Size2D::zero());
|
||||
|
|
|
@ -76,9 +76,9 @@ use style::str::HTML_SPACE_CHARACTERS;
|
|||
use style::stylesheets::{CssRuleType, Origin, UrlExtraData};
|
||||
use style_traits::{CSSPixel, DevicePixel, ParsingMode};
|
||||
use url::Position;
|
||||
use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel};
|
||||
use webrender_api::units::{DeviceIntRect, LayoutPixel};
|
||||
use webrender_api::{DocumentId, ExternalScrollId};
|
||||
use webrender_traits::WebRenderScriptApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
|
||||
use super::bindings::trace::HashMapTracedValues;
|
||||
|
@ -312,10 +312,10 @@ pub struct Window {
|
|||
/// Flag to identify whether mutation observers are present(true)/absent(false)
|
||||
exists_mut_observer: Cell<bool>,
|
||||
|
||||
/// Webrender API Sender
|
||||
/// Cross-process access to the compositor.
|
||||
#[ignore_malloc_size_of = "Wraps an IpcSender"]
|
||||
#[no_trace]
|
||||
webrender_api_sender: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
|
||||
/// 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 unneccessary.
|
||||
|
@ -526,8 +526,8 @@ impl Window {
|
|||
self.add_pending_reflow();
|
||||
}
|
||||
|
||||
pub fn get_webrender_api_sender(&self) -> WebRenderScriptApi {
|
||||
self.webrender_api_sender.clone()
|
||||
pub fn compositor_api(&self) -> &CrossProcessCompositorApi {
|
||||
&self.compositor_api
|
||||
}
|
||||
|
||||
pub fn get_userscripts_path(&self) -> Option<String> {
|
||||
|
@ -1773,14 +1773,16 @@ impl Window {
|
|||
|
||||
fn client_window(&self) -> (Size2D<u32, CSSPixel>, Point2D<i32, CSSPixel>) {
|
||||
let timer_profile_chan = self.global().time_profiler_chan().clone();
|
||||
let (send, recv) =
|
||||
ProfiledIpc::channel::<(DeviceIntSize, DeviceIntPoint)>(timer_profile_chan).unwrap();
|
||||
self.send_to_constellation(ScriptMsg::GetClientWindow(send));
|
||||
let (size, point) = recv.recv().unwrap_or((Size2D::zero(), Point2D::zero()));
|
||||
let (send, recv) = ProfiledIpc::channel::<DeviceIntRect>(timer_profile_chan).unwrap();
|
||||
let _ = self
|
||||
.compositor_api
|
||||
.sender()
|
||||
.send(webrender_traits::CrossProcessCompositorMessage::GetClientWindowRect(send));
|
||||
let rect = recv.recv().unwrap_or_default();
|
||||
let dpr = self.device_pixel_ratio();
|
||||
(
|
||||
(size.to_f32() / dpr).to_u32(),
|
||||
(point.to_f32() / dpr).to_i32(),
|
||||
(rect.size().to_f32() / dpr).to_u32(),
|
||||
(rect.min.to_f32() / dpr).to_i32(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -2548,7 +2550,7 @@ impl Window {
|
|||
webxr_registry: webxr_api::Registry,
|
||||
microtask_queue: Rc<MicrotaskQueue>,
|
||||
webrender_document: DocumentId,
|
||||
webrender_api_sender: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
relayout_event: bool,
|
||||
prepare_for_screenshot: bool,
|
||||
unminify_js: bool,
|
||||
|
@ -2633,7 +2635,7 @@ impl Window {
|
|||
paint_worklet: Default::default(),
|
||||
webrender_document,
|
||||
exists_mut_observer: Cell::new(false),
|
||||
webrender_api_sender,
|
||||
compositor_api,
|
||||
has_sent_idle_message: Cell::new(false),
|
||||
relayout_event,
|
||||
prepare_for_screenshot,
|
||||
|
|
|
@ -95,7 +95,7 @@ use style::thread_state::{self, ThreadState};
|
|||
use url::Position;
|
||||
use webgpu::{WebGPUDevice, WebGPUMsg};
|
||||
use webrender_api::DocumentId;
|
||||
use webrender_traits::WebRenderScriptApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use crate::document_loader::DocumentLoader;
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
|
@ -669,9 +669,9 @@ pub struct ScriptThread {
|
|||
#[no_trace]
|
||||
webrender_document: DocumentId,
|
||||
|
||||
/// Webrender API sender.
|
||||
/// Cross-process access to the compositor's API.
|
||||
#[no_trace]
|
||||
webrender_api_sender: WebRenderScriptApi,
|
||||
compositor_api: CrossProcessCompositorApi,
|
||||
|
||||
/// Periodically print out on which events script threads spend their processing time.
|
||||
profile_script_events: bool,
|
||||
|
@ -1399,7 +1399,7 @@ impl ScriptThread {
|
|||
custom_element_reaction_stack: CustomElementReactionStack::new(),
|
||||
|
||||
webrender_document: state.webrender_document,
|
||||
webrender_api_sender: state.webrender_api_sender,
|
||||
compositor_api: state.compositor_api,
|
||||
|
||||
profile_script_events: opts.debug.profile_script_events,
|
||||
print_pwm: opts.print_pwm,
|
||||
|
@ -3661,7 +3661,7 @@ impl ScriptThread {
|
|||
system_font_service: self.system_font_service.clone(),
|
||||
resource_threads: self.resource_threads.clone(),
|
||||
time_profiler_chan: self.time_profiler_chan.clone(),
|
||||
webrender_api_sender: self.webrender_api_sender.clone(),
|
||||
compositor_api: self.compositor_api.clone(),
|
||||
paint_time_metrics,
|
||||
window_size: incomplete.window_size,
|
||||
};
|
||||
|
@ -3692,7 +3692,7 @@ impl ScriptThread {
|
|||
self.webxr_registry.clone(),
|
||||
self.microtask_queue.clone(),
|
||||
self.webrender_document,
|
||||
self.webrender_api_sender.clone(),
|
||||
self.compositor_api.clone(),
|
||||
self.relayout_event,
|
||||
self.prepare_for_screenshot,
|
||||
self.unminify_js,
|
||||
|
|
|
@ -28,15 +28,13 @@ pub use base::id::TopLevelBrowsingContextId;
|
|||
use base::id::{PipelineNamespace, PipelineNamespaceId};
|
||||
use bluetooth::BluetoothThreadFactory;
|
||||
use bluetooth_traits::BluetoothRequest;
|
||||
use canvas::canvas_paint_thread::{self, CanvasPaintThread};
|
||||
use canvas::canvas_paint_thread::CanvasPaintThread;
|
||||
use canvas::WebGLComm;
|
||||
use canvas_traits::webgl::WebGLThreads;
|
||||
use compositing::webview::UnknownWebView;
|
||||
use compositing::windowing::{EmbedderEvent, EmbedderMethods, WindowMethods};
|
||||
use compositing::{CompositeTarget, IOCompositor, InitialCompositorState, ShutdownState};
|
||||
use compositing_traits::{
|
||||
CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg, ForwardedToCompositorMsg,
|
||||
};
|
||||
use compositing_traits::{CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg};
|
||||
#[cfg(all(
|
||||
not(target_os = "windows"),
|
||||
not(target_os = "ios"),
|
||||
|
@ -66,7 +64,8 @@ use fonts::SystemFontService;
|
|||
use gaol::sandbox::{ChildSandbox, ChildSandboxMethods};
|
||||
pub use gleam::gl;
|
||||
use gleam::gl::RENDERER;
|
||||
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use ipc_channel::router::ROUTER;
|
||||
#[cfg(feature = "layout_2013")]
|
||||
pub use layout_thread_2013;
|
||||
use log::{error, trace, warn, Log, Metadata, Record};
|
||||
|
@ -91,13 +90,10 @@ use surfman::{GLApi, GLVersion};
|
|||
use surfman::{NativeConnection, NativeContext};
|
||||
use webgpu::swapchain::WGPUImageMap;
|
||||
use webrender::{RenderApiSender, ShaderPrecacheFlags, UploadMethod, ONE_TIME_USAGE_HINT};
|
||||
use webrender_api::{
|
||||
ColorF, DocumentId, FontInstanceFlags, FontInstanceKey, FontKey, FramePublishId, ImageKey,
|
||||
NativeFontHandle,
|
||||
};
|
||||
use webrender_api::{ColorF, DocumentId, FramePublishId};
|
||||
use webrender_traits::{
|
||||
CanvasToCompositorMsg, FontToCompositorMsg, ImageUpdate, RenderingContext, WebRenderFontApi,
|
||||
WebrenderExternalImageHandlers, WebrenderExternalImageRegistry, WebrenderImageHandlerType,
|
||||
CrossProcessCompositorApi, RenderingContext, WebrenderExternalImageHandlers,
|
||||
WebrenderExternalImageRegistry, WebrenderImageHandlerType,
|
||||
};
|
||||
pub use {
|
||||
background_hang_monitor, base, bluetooth, bluetooth_traits, canvas, canvas_traits, compositing,
|
||||
|
@ -979,9 +975,24 @@ 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 sender_clone = sender.clone();
|
||||
ROUTER.add_route(
|
||||
compositor_ipc_receiver.to_opaque(),
|
||||
Box::new(move |message| {
|
||||
let _ = sender_clone.send(CompositorMsg::CrossProcess(
|
||||
message.to().expect("Could not convert Compositor message"),
|
||||
));
|
||||
}),
|
||||
);
|
||||
let cross_process_compositor_api = CrossProcessCompositorApi(compositor_ipc_sender);
|
||||
|
||||
(
|
||||
CompositorProxy {
|
||||
sender,
|
||||
cross_process_compositor_api,
|
||||
event_loop_waker,
|
||||
},
|
||||
CompositorReceiver { receiver },
|
||||
|
@ -1043,14 +1054,11 @@ fn create_constellation(
|
|||
);
|
||||
|
||||
let system_font_service = Arc::new(
|
||||
SystemFontService::spawn(Box::new(WebRenderFontApiCompositorProxy(
|
||||
compositor_proxy.clone(),
|
||||
)))
|
||||
.to_proxy(),
|
||||
SystemFontService::spawn(compositor_proxy.cross_process_compositor_api.clone()).to_proxy(),
|
||||
);
|
||||
|
||||
let (canvas_create_sender, canvas_ipc_sender) = CanvasPaintThread::start(
|
||||
Box::new(CanvasWebrenderApi(compositor_proxy.clone())),
|
||||
compositor_proxy.cross_process_compositor_api.clone(),
|
||||
system_font_service.clone(),
|
||||
public_resource_threads.clone(),
|
||||
);
|
||||
|
@ -1094,82 +1102,6 @@ fn create_constellation(
|
|||
)
|
||||
}
|
||||
|
||||
struct WebRenderFontApiCompositorProxy(CompositorProxy);
|
||||
|
||||
impl WebRenderFontApi for WebRenderFontApiCompositorProxy {
|
||||
fn add_font_instance(
|
||||
&self,
|
||||
font_instance_key: FontInstanceKey,
|
||||
font_key: FontKey,
|
||||
size: f32,
|
||||
flags: FontInstanceFlags,
|
||||
) {
|
||||
self.0.send(CompositorMsg::Forwarded(
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddFontInstance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
size,
|
||||
flags,
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
|
||||
self.0.send(CompositorMsg::Forwarded(
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddFont(
|
||||
font_key, index, data,
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
|
||||
self.0.send(CompositorMsg::Forwarded(
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::AddSystemFont(
|
||||
font_key, handle,
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
fn fetch_font_keys(
|
||||
&self,
|
||||
number_of_font_keys: usize,
|
||||
number_of_font_instance_keys: usize,
|
||||
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
|
||||
let (sender, receiver) = unbounded();
|
||||
self.0.send(CompositorMsg::Forwarded(
|
||||
ForwardedToCompositorMsg::SystemFontService(FontToCompositorMsg::GenerateKeys(
|
||||
number_of_font_keys,
|
||||
number_of_font_instance_keys,
|
||||
sender,
|
||||
)),
|
||||
));
|
||||
receiver.recv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CanvasWebrenderApi(CompositorProxy);
|
||||
|
||||
impl canvas_paint_thread::WebrenderApi for CanvasWebrenderApi {
|
||||
fn generate_key(&self) -> Option<ImageKey> {
|
||||
let (sender, receiver) = unbounded();
|
||||
self.0
|
||||
.send(CompositorMsg::Forwarded(ForwardedToCompositorMsg::Canvas(
|
||||
CanvasToCompositorMsg::GenerateKey(sender),
|
||||
)));
|
||||
receiver.recv().ok()
|
||||
}
|
||||
fn update_images(&self, updates: Vec<ImageUpdate>) {
|
||||
self.0
|
||||
.send(CompositorMsg::Forwarded(ForwardedToCompositorMsg::Canvas(
|
||||
CanvasToCompositorMsg::UpdateImages(updates),
|
||||
)));
|
||||
}
|
||||
fn clone(&self) -> Box<dyn canvas_paint_thread::WebrenderApi> {
|
||||
Box::new(<Self as Clone>::clone(self))
|
||||
}
|
||||
}
|
||||
|
||||
// A logger that logs to two downstream loggers.
|
||||
// This should probably be in the log crate.
|
||||
struct BothLogger<Log1, Log2>(Log1, Log2);
|
||||
|
|
|
@ -21,15 +21,18 @@ use script_traits::{
|
|||
AnimationState, ConstellationControlMsg, EventResult, MouseButton, MouseEventType,
|
||||
};
|
||||
use style_traits::CSSPixel;
|
||||
use webrender_api::units::{DeviceIntPoint, DeviceIntSize, DeviceRect};
|
||||
use webrender_api::units::DeviceRect;
|
||||
use webrender_api::DocumentId;
|
||||
use webrender_traits::{
|
||||
CanvasToCompositorMsg, FontToCompositorMsg, NetToCompositorMsg, ScriptToCompositorMsg,
|
||||
};
|
||||
use webrender_traits::{CrossProcessCompositorApi, CrossProcessCompositorMessage};
|
||||
|
||||
/// Sends messages to the compositor.
|
||||
#[derive(Clone)]
|
||||
pub struct CompositorProxy {
|
||||
pub sender: Sender<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>,
|
||||
}
|
||||
|
||||
|
@ -42,15 +45,6 @@ impl CompositorProxy {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for CompositorProxy {
|
||||
fn clone(&self) -> CompositorProxy {
|
||||
CompositorProxy {
|
||||
sender: self.sender.clone(),
|
||||
event_loop_waker: self.event_loop_waker.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The port that the compositor receives messages on.
|
||||
pub struct CompositorReceiver {
|
||||
pub receiver: Receiver<CompositorMsg>,
|
||||
|
@ -114,16 +108,9 @@ pub enum CompositorMsg {
|
|||
/// WebDriver mouse move event
|
||||
WebDriverMouseMoveEvent(f32, f32),
|
||||
|
||||
/// Get Window Informations size and position.
|
||||
GetClientWindow(IpcSender<(DeviceIntSize, DeviceIntPoint)>),
|
||||
/// Get screen size.
|
||||
GetScreenSize(IpcSender<DeviceIntSize>),
|
||||
/// Get screen available size.
|
||||
GetScreenAvailSize(IpcSender<DeviceIntSize>),
|
||||
|
||||
/// Messages forwarded to the compositor by the constellation from other crates. These
|
||||
/// messages are mainly passed on from the compositor to WebRender.
|
||||
Forwarded(ForwardedToCompositorMsg),
|
||||
CrossProcess(CrossProcessCompositorMessage),
|
||||
}
|
||||
|
||||
pub struct SendableFrameTree {
|
||||
|
@ -139,27 +126,6 @@ pub struct CompositionPipeline {
|
|||
pub script_chan: IpcSender<ConstellationControlMsg>,
|
||||
}
|
||||
|
||||
/// Messages forwarded by the Constellation to the Compositor.
|
||||
pub enum ForwardedToCompositorMsg {
|
||||
Layout(ScriptToCompositorMsg),
|
||||
Net(NetToCompositorMsg),
|
||||
SystemFontService(FontToCompositorMsg),
|
||||
Canvas(CanvasToCompositorMsg),
|
||||
}
|
||||
|
||||
impl Debug for ForwardedToCompositorMsg {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
|
||||
match self {
|
||||
ForwardedToCompositorMsg::Layout(_) => write!(f, "Layout(ScriptToCompositorMsg)"),
|
||||
ForwardedToCompositorMsg::Net(_) => write!(f, "Net(NetToCompositorMsg)"),
|
||||
ForwardedToCompositorMsg::SystemFontService(_) => {
|
||||
write!(f, "SystemFontService(FontToCompositorMsg)")
|
||||
},
|
||||
ForwardedToCompositorMsg::Canvas(_) => write!(f, "Canvas(CanvasToCompositorMsg)"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for CompositorMsg {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||
match *self {
|
||||
|
@ -183,10 +149,7 @@ impl Debug for CompositorMsg {
|
|||
CompositorMsg::LoadComplete(..) => write!(f, "LoadComplete"),
|
||||
CompositorMsg::WebDriverMouseButtonEvent(..) => write!(f, "WebDriverMouseButtonEvent"),
|
||||
CompositorMsg::WebDriverMouseMoveEvent(..) => write!(f, "WebDriverMouseMoveEvent"),
|
||||
CompositorMsg::GetClientWindow(..) => write!(f, "GetClientWindow"),
|
||||
CompositorMsg::GetScreenSize(..) => write!(f, "GetScreenSize"),
|
||||
CompositorMsg::GetScreenAvailSize(..) => write!(f, "GetScreenAvailSize"),
|
||||
CompositorMsg::Forwarded(..) => write!(f, "Webrender"),
|
||||
CompositorMsg::CrossProcess(..) => write!(f, "CrossProcess"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use malloc_size_of_derive::MallocSizeOf;
|
|||
use pixels::{Image, ImageMetadata};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use webrender_traits::WebRenderNetApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
use crate::request::CorsSettings;
|
||||
use crate::FetchResponseMsg;
|
||||
|
@ -99,7 +99,7 @@ pub enum ImageCacheResult {
|
|||
}
|
||||
|
||||
pub trait ImageCache: Sync + Send {
|
||||
fn new(webrender_api: WebRenderNetApi) -> Self
|
||||
fn new(compositor_api: CrossProcessCompositorApi) -> Self
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
|
|
|
@ -58,7 +58,9 @@ use style_traits::{CSSPixel, SpeculativePainter};
|
|||
use webgpu::WebGPUMsg;
|
||||
use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel};
|
||||
use webrender_api::{DocumentId, ExternalScrollId, ImageKey};
|
||||
use webrender_traits::{UntrustedNodeAddress as WebRenderUntrustedNodeAddress, WebRenderScriptApi};
|
||||
use webrender_traits::{
|
||||
CrossProcessCompositorApi, UntrustedNodeAddress as WebRenderUntrustedNodeAddress,
|
||||
};
|
||||
|
||||
pub use crate::script_msg::{
|
||||
DOMMessage, EventResult, HistoryEntryReplacement, IFrameSizeMsg, Job, JobError, JobResult,
|
||||
|
@ -659,8 +661,8 @@ pub struct InitialScriptState {
|
|||
pub webxr_registry: webxr_api::Registry,
|
||||
/// The Webrender document ID associated with this thread.
|
||||
pub webrender_document: DocumentId,
|
||||
/// FIXME(victor): The Webrender API sender in this constellation's pipeline
|
||||
pub webrender_api_sender: WebRenderScriptApi,
|
||||
/// Access to the compositor across a process boundary.
|
||||
pub compositor_api: CrossProcessCompositorApi,
|
||||
/// Application window's GL Context for Media player
|
||||
pub player_context: WindowGLContext,
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ use serde::{Deserialize, Serialize};
|
|||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use style_traits::CSSPixel;
|
||||
use webgpu::{wgc, WebGPU, WebGPUResponse};
|
||||
use webrender_api::units::{DeviceIntPoint, DeviceIntSize};
|
||||
|
||||
use crate::{
|
||||
AnimationState, AuxiliaryBrowsingContextLoadInfo, BroadcastMsg, DocumentState,
|
||||
|
@ -245,12 +244,6 @@ pub enum ScriptMsg {
|
|||
ForwardDOMMessage(DOMMessage, ServoUrl),
|
||||
/// <https://w3c.github.io/ServiceWorker/#schedule-job-algorithm>
|
||||
ScheduleJob(Job),
|
||||
/// Get Window Informations size and position
|
||||
GetClientWindow(IpcSender<(DeviceIntSize, DeviceIntPoint)>),
|
||||
/// Get the screen size (pixel)
|
||||
GetScreenSize(IpcSender<DeviceIntSize>),
|
||||
/// Get the available screen size (pixel)
|
||||
GetScreenAvailSize(IpcSender<DeviceIntSize>),
|
||||
/// Notifies the constellation about media session events
|
||||
/// (i.e. when there is metadata for the active media session, playback state changes...).
|
||||
MediaSessionEvent(PipelineId, MediaSessionEvent),
|
||||
|
@ -318,9 +311,6 @@ impl fmt::Debug for ScriptMsg {
|
|||
PipelineExited => "PipelineExited",
|
||||
ForwardDOMMessage(..) => "ForwardDOMMessage",
|
||||
ScheduleJob(..) => "ScheduleJob",
|
||||
GetClientWindow(..) => "GetClientWindow",
|
||||
GetScreenSize(..) => "GetScreenSize",
|
||||
GetScreenAvailSize(..) => "GetScreenAvailSize",
|
||||
MediaSessionEvent(..) => "MediaSessionEvent",
|
||||
RequestAdapter(..) => "RequestAdapter",
|
||||
GetWebGPUChan(..) => "GetWebGPUChan",
|
||||
|
|
|
@ -53,7 +53,7 @@ use style::stylesheets::Stylesheet;
|
|||
use style::Atom;
|
||||
use style_traits::CSSPixel;
|
||||
use webrender_api::ImageKey;
|
||||
use webrender_traits::WebRenderScriptApi;
|
||||
use webrender_traits::CrossProcessCompositorApi;
|
||||
|
||||
pub type GenericLayoutData = dyn Any + Send + Sync;
|
||||
|
||||
|
@ -177,7 +177,7 @@ pub struct LayoutConfig {
|
|||
pub resource_threads: ResourceThreads,
|
||||
pub system_font_service: Arc<SystemFontServiceProxy>,
|
||||
pub time_profiler_chan: time::ProfilerChan,
|
||||
pub webrender_api_sender: WebRenderScriptApi,
|
||||
pub compositor_api: CrossProcessCompositorApi,
|
||||
pub paint_time_metrics: PaintTimeMetrics,
|
||||
pub window_size: WindowSizeData,
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
pub mod display_list;
|
||||
pub mod rendering_context;
|
||||
|
||||
use core::fmt;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use base::id::PipelineId;
|
||||
use crossbeam_channel::Sender;
|
||||
use display_list::{CompositorDisplayListInfo, ScrollTreeNodeId};
|
||||
use embedder_traits::Cursor;
|
||||
use euclid::default::Size2D;
|
||||
|
@ -19,7 +19,7 @@ use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
|
|||
use libc::c_void;
|
||||
use log::warn;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect};
|
||||
use webrender_api::units::{DeviceIntRect, DeviceIntSize, DevicePoint, LayoutPoint, TexelRect};
|
||||
use webrender_api::{
|
||||
BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData,
|
||||
ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId,
|
||||
|
@ -29,6 +29,261 @@ use webrender_api::{
|
|||
|
||||
pub use crate::rendering_context::RenderingContext;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum CrossProcessCompositorMessage {
|
||||
/// Inform WebRender of the existence of this pipeline.
|
||||
SendInitialTransaction(WebRenderPipelineId),
|
||||
/// Perform a scroll operation.
|
||||
SendScrollNode(WebRenderPipelineId, LayoutPoint, ExternalScrollId),
|
||||
/// Inform WebRender of a new display list for the given pipeline.
|
||||
SendDisplayList {
|
||||
/// The [CompositorDisplayListInfo] that describes the display list being sent.
|
||||
display_list_info: CompositorDisplayListInfo,
|
||||
/// A descriptor of this display list used to construct this display list from raw data.
|
||||
display_list_descriptor: BuiltDisplayListDescriptor,
|
||||
/// An [ipc::IpcBytesReceiver] used to send the raw data of the display list.
|
||||
display_list_receiver: ipc::IpcBytesReceiver,
|
||||
},
|
||||
/// Perform a hit test operation. The result will be returned via
|
||||
/// the provided channel sender.
|
||||
HitTest(
|
||||
Option<WebRenderPipelineId>,
|
||||
DevicePoint,
|
||||
HitTestFlags,
|
||||
IpcSender<Vec<CompositorHitTestResult>>,
|
||||
),
|
||||
/// Create a new image key. The result will be returned via the
|
||||
/// provided channel sender.
|
||||
GenerateImageKey(IpcSender<ImageKey>),
|
||||
/// Add an image with the given data and `ImageKey`.
|
||||
AddImage(ImageKey, ImageDescriptor, SerializableImageData),
|
||||
/// Perform a resource update operation.
|
||||
UpdateImages(Vec<ImageUpdate>),
|
||||
|
||||
/// Generate a new batch of font keys which can be used to allocate
|
||||
/// keys asynchronously.
|
||||
GenerateFontKeys(
|
||||
usize,
|
||||
usize,
|
||||
IpcSender<(Vec<FontKey>, Vec<FontInstanceKey>)>,
|
||||
),
|
||||
/// Add a font with the given data and font key.
|
||||
AddFont(FontKey, Arc<IpcSharedMemory>, u32),
|
||||
/// Add a system font with the given font key and handle.
|
||||
AddSystemFont(FontKey, NativeFontHandle),
|
||||
/// Add an instance of a font with the given instance key.
|
||||
AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
|
||||
/// Remove the given font resources from our WebRender instance.
|
||||
RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
|
||||
|
||||
/// Get the client window size and position.
|
||||
GetClientWindowRect(IpcSender<DeviceIntRect>),
|
||||
/// Get the size of the screen that the client window inhabits.
|
||||
GetScreenSize(IpcSender<DeviceIntSize>),
|
||||
/// Get the available screen size (without toolbars and docks) for the screen
|
||||
/// the client window inhabits.
|
||||
GetAvailableScreenSize(IpcSender<DeviceIntSize>),
|
||||
}
|
||||
|
||||
impl fmt::Debug for CrossProcessCompositorMessage {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::AddImage(..) => f.write_str("AddImage"),
|
||||
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"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct CrossProcessCompositorApi(pub IpcSender<CrossProcessCompositorMessage>);
|
||||
|
||||
impl CrossProcessCompositorApi {
|
||||
/// Create a new [`CrossProcessCompositorApi`] struct that does not have a listener on the other
|
||||
/// end to use for unit testing.
|
||||
pub fn dummy() -> Self {
|
||||
let (sender, _) = ipc::channel().unwrap();
|
||||
Self(sender)
|
||||
}
|
||||
|
||||
/// Get the sender for this proxy.
|
||||
pub fn sender(&self) -> &IpcSender<CrossProcessCompositorMessage> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Inform WebRender of the existence of this pipeline.
|
||||
pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
|
||||
if let Err(e) = self
|
||||
.0
|
||||
.send(CrossProcessCompositorMessage::SendInitialTransaction(
|
||||
pipeline,
|
||||
))
|
||||
{
|
||||
warn!("Error sending initial transaction: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a scroll operation.
|
||||
pub fn send_scroll_node(
|
||||
&self,
|
||||
pipeline_id: WebRenderPipelineId,
|
||||
point: LayoutPoint,
|
||||
scroll_id: ExternalScrollId,
|
||||
) {
|
||||
if let Err(e) = self.0.send(CrossProcessCompositorMessage::SendScrollNode(
|
||||
pipeline_id,
|
||||
point,
|
||||
scroll_id,
|
||||
)) {
|
||||
warn!("Error sending scroll node: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inform WebRender of a new display list for the given pipeline.
|
||||
pub fn send_display_list(
|
||||
&self,
|
||||
display_list_info: CompositorDisplayListInfo,
|
||||
list: BuiltDisplayList,
|
||||
) {
|
||||
let (display_list_data, display_list_descriptor) = list.into_data();
|
||||
let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
|
||||
if let Err(e) = self.0.send(CrossProcessCompositorMessage::SendDisplayList {
|
||||
display_list_info,
|
||||
display_list_descriptor,
|
||||
display_list_receiver,
|
||||
}) {
|
||||
warn!("Error sending display list: {}", e);
|
||||
}
|
||||
|
||||
if let Err(error) = display_list_sender.send(&display_list_data.items_data) {
|
||||
warn!("Error sending display list items: {}", error);
|
||||
}
|
||||
if let Err(error) = display_list_sender.send(&display_list_data.cache_data) {
|
||||
warn!("Error sending display list cache data: {}", error);
|
||||
}
|
||||
if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) {
|
||||
warn!("Error sending display spatial tree: {}", error);
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a hit test operation. Blocks until the operation is complete and
|
||||
/// and a result is available.
|
||||
pub fn hit_test(
|
||||
&self,
|
||||
pipeline: Option<WebRenderPipelineId>,
|
||||
point: DevicePoint,
|
||||
flags: HitTestFlags,
|
||||
) -> Vec<CompositorHitTestResult> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.0
|
||||
.send(CrossProcessCompositorMessage::HitTest(
|
||||
pipeline, point, flags, sender,
|
||||
))
|
||||
.expect("error sending hit test");
|
||||
receiver.recv().expect("error receiving hit test result")
|
||||
}
|
||||
|
||||
/// Create a new image key. Blocks until the key is available.
|
||||
pub fn generate_image_key(&self) -> Option<ImageKey> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.0
|
||||
.send(CrossProcessCompositorMessage::GenerateImageKey(sender))
|
||||
.ok()?;
|
||||
receiver.recv().ok()
|
||||
}
|
||||
|
||||
pub fn add_image(
|
||||
&self,
|
||||
key: ImageKey,
|
||||
descriptor: ImageDescriptor,
|
||||
data: SerializableImageData,
|
||||
) {
|
||||
if let Err(e) = self.0.send(CrossProcessCompositorMessage::AddImage(
|
||||
key, descriptor, data,
|
||||
)) {
|
||||
warn!("Error sending image update: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform an image resource update operation.
|
||||
pub fn update_images(&self, updates: Vec<ImageUpdate>) {
|
||||
if let Err(e) = self
|
||||
.0
|
||||
.send(CrossProcessCompositorMessage::UpdateImages(updates))
|
||||
{
|
||||
warn!("error sending image updates: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_unused_font_resources(
|
||||
&self,
|
||||
keys: Vec<FontKey>,
|
||||
instance_keys: Vec<FontInstanceKey>,
|
||||
) {
|
||||
if keys.is_empty() && instance_keys.is_empty() {
|
||||
return;
|
||||
}
|
||||
let _ = self.0.send(CrossProcessCompositorMessage::RemoveFonts(
|
||||
keys,
|
||||
instance_keys,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn add_font_instance(
|
||||
&self,
|
||||
font_instance_key: FontInstanceKey,
|
||||
font_key: FontKey,
|
||||
size: f32,
|
||||
flags: FontInstanceFlags,
|
||||
) {
|
||||
let _x = self.0.send(CrossProcessCompositorMessage::AddFontInstance(
|
||||
font_instance_key,
|
||||
font_key,
|
||||
size,
|
||||
flags,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32) {
|
||||
let _ = self.0.send(CrossProcessCompositorMessage::AddFont(
|
||||
font_key, data, index,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle) {
|
||||
let _ = self.0.send(CrossProcessCompositorMessage::AddSystemFont(
|
||||
font_key, handle,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn fetch_font_keys(
|
||||
&self,
|
||||
number_of_font_keys: usize,
|
||||
number_of_font_instance_keys: usize,
|
||||
) -> (Vec<FontKey>, Vec<FontInstanceKey>) {
|
||||
let (sender, receiver) = ipc_channel::ipc::channel().expect("Could not create IPC channel");
|
||||
let _ = self.0.send(CrossProcessCompositorMessage::GenerateFontKeys(
|
||||
number_of_font_keys,
|
||||
number_of_font_instance_keys,
|
||||
sender,
|
||||
));
|
||||
receiver.recv().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait is used as a bridge between the different GL clients
|
||||
/// in Servo that handles WebRender ExternalImages and the WebRender
|
||||
/// ExternalImageHandler API.
|
||||
|
@ -183,304 +438,34 @@ impl ExternalImageHandler for WebrenderExternalImageHandlers {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait WebRenderFontApi {
|
||||
fn add_font_instance(
|
||||
&self,
|
||||
font_instance_key: FontInstanceKey,
|
||||
font_key: FontKey,
|
||||
size: f32,
|
||||
flags: FontInstanceFlags,
|
||||
);
|
||||
fn add_font(&self, font_key: FontKey, data: Arc<IpcSharedMemory>, index: u32);
|
||||
fn add_system_font(&self, font_key: FontKey, handle: NativeFontHandle);
|
||||
fn fetch_font_keys(
|
||||
&self,
|
||||
number_of_font_keys: usize,
|
||||
number_of_font_instance_keys: usize,
|
||||
) -> (Vec<FontKey>, Vec<FontInstanceKey>);
|
||||
}
|
||||
|
||||
pub enum CanvasToCompositorMsg {
|
||||
GenerateKey(Sender<ImageKey>),
|
||||
UpdateImages(Vec<ImageUpdate>),
|
||||
}
|
||||
|
||||
pub enum FontToCompositorMsg {
|
||||
GenerateKeys(usize, usize, Sender<(Vec<FontKey>, Vec<FontInstanceKey>)>),
|
||||
AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
|
||||
AddFont(FontKey, u32, Arc<IpcSharedMemory>),
|
||||
AddSystemFont(FontKey, NativeFontHandle),
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum NetToCompositorMsg {
|
||||
AddImage(ImageKey, ImageDescriptor, ImageData),
|
||||
GenerateImageKey(IpcSender<ImageKey>),
|
||||
}
|
||||
|
||||
/// The set of WebRender operations that can be initiated by the content process.
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub enum ScriptToCompositorMsg {
|
||||
/// Inform WebRender of the existence of this pipeline.
|
||||
SendInitialTransaction(WebRenderPipelineId),
|
||||
/// Perform a scroll operation.
|
||||
SendScrollNode(WebRenderPipelineId, LayoutPoint, ExternalScrollId),
|
||||
/// Inform WebRender of a new display list for the given pipeline.
|
||||
SendDisplayList {
|
||||
/// The [CompositorDisplayListInfo] that describes the display list being sent.
|
||||
display_list_info: CompositorDisplayListInfo,
|
||||
/// A descriptor of this display list used to construct this display list from raw data.
|
||||
display_list_descriptor: BuiltDisplayListDescriptor,
|
||||
/// An [ipc::IpcBytesReceiver] used to send the raw data of the display list.
|
||||
display_list_receiver: ipc::IpcBytesReceiver,
|
||||
},
|
||||
/// Perform a hit test operation. The result will be returned via
|
||||
/// the provided channel sender.
|
||||
HitTest(
|
||||
Option<WebRenderPipelineId>,
|
||||
DevicePoint,
|
||||
HitTestFlags,
|
||||
IpcSender<Vec<CompositorHitTestResult>>,
|
||||
),
|
||||
/// Create a new image key. The result will be returned via the
|
||||
/// provided channel sender.
|
||||
GenerateImageKey(IpcSender<ImageKey>),
|
||||
/// Perform a resource update operation.
|
||||
UpdateImages(Vec<SerializedImageUpdate>),
|
||||
/// Remove the given font resources from our WebRender instance.
|
||||
RemoveFonts(Vec<FontKey>, Vec<FontInstanceKey>),
|
||||
AddFontInstance(FontInstanceKey, FontKey, f32, FontInstanceFlags),
|
||||
AddFont(FontKey, Arc<IpcSharedMemory>, u32),
|
||||
}
|
||||
|
||||
/// A mechanism to send messages from networking to the WebRender instance.
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct WebRenderNetApi(IpcSender<NetToCompositorMsg>);
|
||||
|
||||
impl WebRenderNetApi {
|
||||
pub fn new(sender: IpcSender<NetToCompositorMsg>) -> Self {
|
||||
Self(sender)
|
||||
}
|
||||
|
||||
pub fn generate_image_key(&self) -> ImageKey {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.0
|
||||
.send(NetToCompositorMsg::GenerateImageKey(sender))
|
||||
.expect("error sending image key generation");
|
||||
receiver.recv().expect("error receiving image key result")
|
||||
}
|
||||
|
||||
pub fn add_image(&self, key: ImageKey, descriptor: ImageDescriptor, data: ImageData) {
|
||||
if let Err(e) = self
|
||||
.0
|
||||
.send(NetToCompositorMsg::AddImage(key, descriptor, data))
|
||||
{
|
||||
warn!("Error sending image update: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mechanism to send messages from ScriptThread to the parent process' WebRender instance.
|
||||
#[derive(Clone, Deserialize, Serialize)]
|
||||
pub struct WebRenderScriptApi(IpcSender<ScriptToCompositorMsg>);
|
||||
|
||||
impl WebRenderScriptApi {
|
||||
/// Create a new [`WebRenderScriptApi`] object that wraps the provided channel sender.
|
||||
pub fn new(sender: IpcSender<ScriptToCompositorMsg>) -> Self {
|
||||
Self(sender)
|
||||
}
|
||||
|
||||
/// Create a new [`WebRenderScriptApi`] object that does not have a listener on the
|
||||
/// other end.
|
||||
pub fn dummy() -> Self {
|
||||
let (sender, _) = ipc::channel().unwrap();
|
||||
Self::new(sender)
|
||||
}
|
||||
|
||||
/// Get the sender for this proxy.
|
||||
pub fn sender(&self) -> &IpcSender<ScriptToCompositorMsg> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
/// Inform WebRender of the existence of this pipeline.
|
||||
pub fn send_initial_transaction(&self, pipeline: WebRenderPipelineId) {
|
||||
if let Err(e) = self
|
||||
.0
|
||||
.send(ScriptToCompositorMsg::SendInitialTransaction(pipeline))
|
||||
{
|
||||
warn!("Error sending initial transaction: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a scroll operation.
|
||||
pub fn send_scroll_node(
|
||||
&self,
|
||||
pipeline_id: WebRenderPipelineId,
|
||||
point: LayoutPoint,
|
||||
scroll_id: ExternalScrollId,
|
||||
) {
|
||||
if let Err(e) = self.0.send(ScriptToCompositorMsg::SendScrollNode(
|
||||
pipeline_id,
|
||||
point,
|
||||
scroll_id,
|
||||
)) {
|
||||
warn!("Error sending scroll node: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inform WebRender of a new display list for the given pipeline.
|
||||
pub fn send_display_list(
|
||||
&self,
|
||||
display_list_info: CompositorDisplayListInfo,
|
||||
list: BuiltDisplayList,
|
||||
) {
|
||||
let (display_list_data, display_list_descriptor) = list.into_data();
|
||||
let (display_list_sender, display_list_receiver) = ipc::bytes_channel().unwrap();
|
||||
if let Err(e) = self.0.send(ScriptToCompositorMsg::SendDisplayList {
|
||||
display_list_info,
|
||||
display_list_descriptor,
|
||||
display_list_receiver,
|
||||
}) {
|
||||
warn!("Error sending display list: {}", e);
|
||||
}
|
||||
|
||||
if let Err(error) = display_list_sender.send(&display_list_data.items_data) {
|
||||
warn!("Error sending display list items: {}", error);
|
||||
}
|
||||
if let Err(error) = display_list_sender.send(&display_list_data.cache_data) {
|
||||
warn!("Error sending display list cache data: {}", error);
|
||||
}
|
||||
if let Err(error) = display_list_sender.send(&display_list_data.spatial_tree) {
|
||||
warn!("Error sending display spatial tree: {}", error);
|
||||
}
|
||||
}
|
||||
|
||||
/// Perform a hit test operation. Blocks until the operation is complete and
|
||||
/// and a result is available.
|
||||
pub fn hit_test(
|
||||
&self,
|
||||
pipeline: Option<WebRenderPipelineId>,
|
||||
point: DevicePoint,
|
||||
flags: HitTestFlags,
|
||||
) -> Vec<CompositorHitTestResult> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.0
|
||||
.send(ScriptToCompositorMsg::HitTest(
|
||||
pipeline, point, flags, sender,
|
||||
))
|
||||
.expect("error sending hit test");
|
||||
receiver.recv().expect("error receiving hit test result")
|
||||
}
|
||||
|
||||
/// Create a new image key. Blocks until the key is available.
|
||||
pub fn generate_image_key(&self) -> Option<ImageKey> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
self.0
|
||||
.send(ScriptToCompositorMsg::GenerateImageKey(sender))
|
||||
.ok()?;
|
||||
receiver.recv().ok()
|
||||
}
|
||||
|
||||
/// Perform a resource update operation.
|
||||
pub fn update_images(&self, updates: Vec<ImageUpdate>) {
|
||||
let mut senders = Vec::new();
|
||||
// Convert `ImageUpdate` to `SerializedImageUpdate` because `ImageData` may contain large
|
||||
// byes. With this conversion, we send `IpcBytesReceiver` instead and use it to send the
|
||||
// actual bytes.
|
||||
let updates = updates
|
||||
.into_iter()
|
||||
.map(|update| match update {
|
||||
ImageUpdate::AddImage(k, d, data) => {
|
||||
let data = match data {
|
||||
ImageData::Raw(r) => {
|
||||
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||
senders.push((sender, r));
|
||||
SerializedImageData::Raw(receiver)
|
||||
},
|
||||
ImageData::External(e) => SerializedImageData::External(e),
|
||||
};
|
||||
SerializedImageUpdate::AddImage(k, d, data)
|
||||
},
|
||||
ImageUpdate::DeleteImage(k) => SerializedImageUpdate::DeleteImage(k),
|
||||
ImageUpdate::UpdateImage(k, d, data) => {
|
||||
let data = match data {
|
||||
ImageData::Raw(r) => {
|
||||
let (sender, receiver) = ipc::bytes_channel().unwrap();
|
||||
senders.push((sender, r));
|
||||
SerializedImageData::Raw(receiver)
|
||||
},
|
||||
ImageData::External(e) => SerializedImageData::External(e),
|
||||
};
|
||||
SerializedImageUpdate::UpdateImage(k, d, data)
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
|
||||
if let Err(e) = self.0.send(ScriptToCompositorMsg::UpdateImages(updates)) {
|
||||
warn!("error sending image updates: {}", e);
|
||||
}
|
||||
|
||||
senders.into_iter().for_each(|(tx, data)| {
|
||||
if let Err(e) = tx.send(&data) {
|
||||
warn!("error sending image data: {}", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub fn remove_unused_font_resources(
|
||||
&self,
|
||||
keys: Vec<FontKey>,
|
||||
instance_keys: Vec<FontInstanceKey>,
|
||||
) {
|
||||
if keys.is_empty() && instance_keys.is_empty() {
|
||||
return;
|
||||
}
|
||||
let _ = self
|
||||
.0
|
||||
.send(ScriptToCompositorMsg::RemoveFonts(keys, instance_keys));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
/// Serializable image updates that must be performed by WebRender.
|
||||
pub enum ImageUpdate {
|
||||
/// Register a new image.
|
||||
AddImage(ImageKey, ImageDescriptor, ImageData),
|
||||
AddImage(ImageKey, ImageDescriptor, SerializableImageData),
|
||||
/// Delete a previously registered image registration.
|
||||
DeleteImage(ImageKey),
|
||||
/// Update an existing image registration.
|
||||
UpdateImage(ImageKey, ImageDescriptor, ImageData),
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
/// Serialized `ImageUpdate`.
|
||||
pub enum SerializedImageUpdate {
|
||||
/// Register a new image.
|
||||
AddImage(ImageKey, ImageDescriptor, SerializedImageData),
|
||||
/// Delete a previously registered image registration.
|
||||
DeleteImage(ImageKey),
|
||||
/// Update an existing image registration.
|
||||
UpdateImage(ImageKey, ImageDescriptor, SerializedImageData),
|
||||
UpdateImage(ImageKey, ImageDescriptor, SerializableImageData),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too
|
||||
/// slow.
|
||||
pub enum SerializedImageData {
|
||||
pub enum SerializableImageData {
|
||||
/// A simple series of bytes, provided by the embedding and owned by WebRender.
|
||||
/// The format is stored out-of-band, currently in ImageDescriptor.
|
||||
Raw(ipc::IpcBytesReceiver),
|
||||
Raw(IpcSharedMemory),
|
||||
/// An image owned by the embedding, and referenced by WebRender. This may
|
||||
/// take the form of a texture or a heap-allocated buffer.
|
||||
External(ExternalImageData),
|
||||
}
|
||||
|
||||
impl SerializedImageData {
|
||||
/// Convert to ``ImageData`.
|
||||
pub fn to_image_data(&self) -> Result<ImageData, ipc::IpcError> {
|
||||
match self {
|
||||
SerializedImageData::Raw(rx) => rx.recv().map(ImageData::new),
|
||||
SerializedImageData::External(image) => Ok(ImageData::External(*image)),
|
||||
impl From<SerializableImageData> for ImageData {
|
||||
fn from(value: SerializableImageData) -> Self {
|
||||
match value {
|
||||
SerializableImageData::Raw(shared_memory) => ImageData::new(shared_memory.to_vec()),
|
||||
SerializableImageData::External(image) => ImageData::External(image),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -536,10 +536,10 @@ impl WindowMethods for Window {
|
|||
EmbedderCoordinates {
|
||||
viewport,
|
||||
framebuffer: viewport.size(),
|
||||
window: (window_size, window_origin),
|
||||
screen,
|
||||
window_rect: DeviceIntRect::from_origin_and_size(window_origin, window_size),
|
||||
screen_size: screen,
|
||||
// FIXME: Winit doesn't have API for available size. Fallback to screen size
|
||||
screen_avail: screen,
|
||||
available_screen_size: screen,
|
||||
hidpi_factor: self.hidpi_factor(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,9 +167,9 @@ impl WindowMethods for Window {
|
|||
EmbedderCoordinates {
|
||||
viewport,
|
||||
framebuffer: size,
|
||||
window: (size, Point2D::zero()),
|
||||
screen: size,
|
||||
screen_avail: size,
|
||||
window_rect: DeviceIntRect::from_origin_and_size(Point2D::zero(), size),
|
||||
screen_size: size,
|
||||
available_screen_size: size,
|
||||
hidpi_factor: dpr,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ use servo::script_traits::{
|
|||
};
|
||||
use servo::servo_url::ServoUrl;
|
||||
use servo::style_traits::DevicePixel;
|
||||
use servo::webrender_api::units::DeviceIntRect;
|
||||
use servo::webrender_api::ScrollLocation;
|
||||
use servo::webrender_traits::RenderingContext;
|
||||
use servo::{gl, Servo, TopLevelBrowsingContextId};
|
||||
|
@ -693,9 +694,9 @@ impl WindowMethods for ServoWindowCallbacks {
|
|||
EmbedderCoordinates {
|
||||
viewport: coords.viewport.to_box2d(),
|
||||
framebuffer: coords.framebuffer,
|
||||
window: (coords.viewport.size, Point2D::new(0, 0)),
|
||||
screen: coords.viewport.size,
|
||||
screen_avail: coords.viewport.size,
|
||||
window_rect: DeviceIntRect::from_origin_and_size(Point2D::zero(), coords.viewport.size),
|
||||
screen_size: coords.viewport.size,
|
||||
available_screen_size: coords.viewport.size,
|
||||
hidpi_factor: Scale::new(self.density),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue