aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMukilan Thiyagarajan <mukilan@igalia.com>2024-05-20 16:05:18 +0530
committerGitHub <noreply@github.com>2024-05-20 10:35:18 +0000
commit2af6fe0b30a275e5fd8a43eca4126d82639fbaa9 (patch)
tree2687a12c392b30cba7cdcd849133d0d382b79cbe
parentc2076580f352f3c61f90969e03d78ada609935eb (diff)
downloadservo-2af6fe0b30a275e5fd8a43eca4126d82639fbaa9.tar.gz
servo-2af6fe0b30a275e5fd8a43eca4126d82639fbaa9.zip
compositor: Move WebRender-ish messages and types to `webrender_traits` (#32315)
* Move WebRender related types to `webrender_traits` This refactor moves several WebRender related types from `compositing_traits`, `script_traits` and `net_traits` crates to the `webrender_traits` crate. This change also moves the `Image` type and associated function out of `net_traits` and into the `pixels` crate. Co-authored-by: Martin Robinson <mrobinson@igalia.com> Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> * Move `script_traits::WebrenderIpcSender` to `webrender_traits::WebRenderScriptApi` --------- Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
-rw-r--r--Cargo.lock28
-rw-r--r--components/canvas/canvas_data.rs13
-rw-r--r--components/canvas/canvas_paint_thread.rs9
-rw-r--r--components/compositing/Cargo.toml1
-rw-r--r--components/compositing/compositor.rs93
-rw-r--r--components/constellation/constellation.rs14
-rw-r--r--components/constellation/pipeline.rs8
-rw-r--r--components/layout/Cargo.toml2
-rw-r--r--components/layout/display_list/builder.rs2
-rw-r--r--components/layout/display_list/items.rs4
-rw-r--r--components/layout/display_list/webrender_helpers.rs6
-rw-r--r--components/layout/fragment.rs2
-rw-r--r--components/layout_2020/Cargo.toml2
-rw-r--r--components/layout_2020/display_list/mod.rs4
-rw-r--r--components/layout_2020/display_list/stacking_context.rs2
-rw-r--r--components/layout_2020/dom.rs6
-rw-r--r--components/layout_2020/flow/root.rs2
-rw-r--r--components/layout_2020/fragment_tree/fragment_tree.rs2
-rw-r--r--components/layout_2020/replaced.rs2
-rw-r--r--components/layout_thread/Cargo.toml1
-rw-r--r--components/layout_thread/lib.rs9
-rw-r--r--components/layout_thread_2020/Cargo.toml1
-rw-r--r--components/layout_thread_2020/lib.rs9
-rw-r--r--components/net/Cargo.toml1
-rw-r--r--components/net/image_cache.rs20
-rw-r--r--components/pixels/Cargo.toml4
-rw-r--r--components/pixels/lib.rs150
-rw-r--r--components/script/Cargo.toml1
-rw-r--r--components/script/dom/htmlimageelement.rs6
-rw-r--r--components/script/dom/htmlmediaelement.rs8
-rwxr-xr-xcomponents/script/dom/htmlobjectelement.rs2
-rw-r--r--components/script/dom/node.rs2
-rw-r--r--components/script/dom/window.rs9
-rw-r--r--components/script/layout_dom/node.rs2
-rw-r--r--components/script/script_thread.rs5
-rw-r--r--components/servo/lib.rs9
-rw-r--r--components/shared/compositing/Cargo.toml4
-rw-r--r--components/shared/compositing/lib.rs20
-rw-r--r--components/shared/net/Cargo.toml1
-rw-r--r--components/shared/net/image/base.rs121
-rw-r--r--components/shared/net/image_cache.rs18
-rw-r--r--components/shared/net/lib.rs43
-rw-r--r--components/shared/net/tests/image.rs28
-rw-r--r--components/shared/script/Cargo.toml1
-rw-r--r--components/shared/script/lib.rs259
-rw-r--r--components/shared/script/tests/compositor.rs6
-rw-r--r--components/shared/script_layout/Cargo.toml2
-rw-r--r--components/shared/script_layout/lib.rs5
-rw-r--r--components/shared/script_layout/wrapper_traits.rs2
-rw-r--r--components/shared/webrender/Cargo.toml7
-rw-r--r--components/shared/webrender/display_list.rs (renamed from components/shared/script/compositor.rs)0
-rw-r--r--components/shared/webrender/lib.rs324
-rw-r--r--python/servo/testing_commands.py1
53 files changed, 666 insertions, 617 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2b8ec154adc..4588765b317 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -879,6 +879,7 @@ dependencies = [
"toml 0.5.11",
"webrender",
"webrender_api",
+ "webrender_traits",
"webxr",
]
@@ -887,7 +888,6 @@ name = "compositing_traits"
version = "0.0.1"
dependencies = [
"base",
- "canvas",
"crossbeam-channel",
"embedder_traits",
"euclid",
@@ -895,11 +895,12 @@ dependencies = [
"ipc-channel",
"keyboard-types",
"log",
- "net_traits",
+ "pixels",
"script_traits",
"servo_url",
"style_traits",
"webrender_api",
+ "webrender_traits",
]
[[package]]
@@ -3239,6 +3240,7 @@ dependencies = [
"malloc_size_of_derive",
"net_traits",
"parking_lot",
+ "pixels",
"profile_traits",
"range",
"rayon",
@@ -3258,6 +3260,7 @@ dependencies = [
"unicode-bidi",
"unicode-script",
"webrender_api",
+ "webrender_traits",
"xi-unicode",
]
@@ -3284,6 +3287,7 @@ dependencies = [
"log",
"net_traits",
"parking_lot",
+ "pixels",
"quickcheck",
"range",
"rayon",
@@ -3301,6 +3305,7 @@ dependencies = [
"unicode-segmentation",
"url",
"webrender_api",
+ "webrender_traits",
"xi-unicode",
]
@@ -3342,6 +3347,7 @@ dependencies = [
"time 0.1.45",
"url",
"webrender_api",
+ "webrender_traits",
]
[[package]]
@@ -3378,6 +3384,7 @@ dependencies = [
"style_traits",
"url",
"webrender_api",
+ "webrender_traits",
]
[[package]]
@@ -4026,6 +4033,7 @@ dependencies = [
"uuid",
"webpki-roots",
"webrender_api",
+ "webrender_traits",
]
[[package]]
@@ -4058,6 +4066,7 @@ dependencies = [
"url",
"uuid",
"webrender_api",
+ "webrender_traits",
]
[[package]]
@@ -4527,9 +4536,13 @@ name = "pixels"
version = "0.0.1"
dependencies = [
"euclid",
+ "image",
+ "ipc-channel",
+ "log",
"malloc_size_of",
"malloc_size_of_derive",
"serde",
+ "webrender_api",
]
[[package]]
@@ -5123,6 +5136,7 @@ dependencies = [
"webdriver",
"webgpu",
"webrender_api",
+ "webrender_traits",
"webxr-api",
"xml5ever",
]
@@ -5146,6 +5160,7 @@ dependencies = [
"malloc_size_of_derive",
"metrics",
"net_traits",
+ "pixels",
"profile_traits",
"range",
"script_traits",
@@ -5157,6 +5172,7 @@ dependencies = [
"style",
"style_traits",
"webrender_api",
+ "webrender_traits",
]
[[package]]
@@ -5206,6 +5222,7 @@ dependencies = [
"webdriver",
"webgpu",
"webrender_api",
+ "webrender_traits",
"webxr-api",
]
@@ -7186,7 +7203,14 @@ dependencies = [
name = "webrender_traits"
version = "0.0.1"
dependencies = [
+ "base",
+ "crossbeam-channel",
+ "embedder_traits",
"euclid",
+ "ipc-channel",
+ "libc",
+ "log",
+ "serde",
"webrender_api",
]
diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs
index 0175242521e..5396eaddea6 100644
--- a/components/canvas/canvas_data.rs
+++ b/components/canvas/canvas_data.rs
@@ -26,8 +26,9 @@ use style::values::computed::font;
use style_traits::values::ToCss;
use webrender_api::units::{DeviceIntSize, RectExt as RectExt_};
use webrender_api::{ImageData, ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey};
+use webrender_traits::ImageUpdate;
-use crate::canvas_paint_thread::{AntialiasMode, ImageUpdate, WebrenderApi};
+use crate::canvas_paint_thread::{AntialiasMode, WebrenderApi};
use crate::raqote_backend::Repetition;
/// The canvas data stores a state machine for the current status of
@@ -1082,13 +1083,13 @@ impl<'a> CanvasData<'a> {
match self.image_key {
Some(image_key) => {
debug!("Updating image {:?}.", image_key);
- updates.push(ImageUpdate::Update(image_key, descriptor, data));
+ updates.push(ImageUpdate::UpdateImage(image_key, descriptor, data));
},
None => {
let Some(key) = self.webrender_api.generate_key() else {
return;
};
- updates.push(ImageUpdate::Add(key, descriptor, data));
+ updates.push(ImageUpdate::AddImage(key, descriptor, data));
self.image_key = Some(key);
debug!("New image {:?}.", self.image_key);
},
@@ -1097,7 +1098,7 @@ impl<'a> CanvasData<'a> {
if let Some(image_key) =
mem::replace(&mut self.very_old_image_key, self.old_image_key.take())
{
- updates.push(ImageUpdate::Delete(image_key));
+ updates.push(ImageUpdate::DeleteImage(image_key));
}
self.webrender_api.update_images(updates);
@@ -1215,10 +1216,10 @@ impl<'a> Drop for CanvasData<'a> {
fn drop(&mut self) {
let mut updates = vec![];
if let Some(image_key) = self.old_image_key.take() {
- updates.push(ImageUpdate::Delete(image_key));
+ updates.push(ImageUpdate::DeleteImage(image_key));
}
if let Some(image_key) = self.very_old_image_key.take() {
- updates.push(ImageUpdate::Delete(image_key));
+ updates.push(ImageUpdate::DeleteImage(image_key));
}
self.webrender_api.update_images(updates);
diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs
index 2176ad8d636..63f881ddacf 100644
--- a/components/canvas/canvas_paint_thread.rs
+++ b/components/canvas/canvas_paint_thread.rs
@@ -16,7 +16,8 @@ use gfx::font_context::FontContext;
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use log::warn;
-use webrender_api::{ImageData, ImageDescriptor, ImageKey};
+use webrender_api::ImageKey;
+use webrender_traits::ImageUpdate;
use crate::canvas_data::*;
@@ -25,12 +26,6 @@ pub enum AntialiasMode {
None,
}
-pub enum ImageUpdate {
- Add(ImageKey, ImageDescriptor, ImageData),
- Update(ImageKey, ImageDescriptor, ImageData),
- Delete(ImageKey),
-}
-
pub trait WebrenderApi {
/// Attempt to generate an [`ImageKey`], returning `None` in case of failure.
fn generate_key(&self) -> Option<ImageKey>;
diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml
index 37c1b6b6a21..3269f61ae02 100644
--- a/components/compositing/Cargo.toml
+++ b/components/compositing/Cargo.toml
@@ -43,6 +43,7 @@ style_traits = { workspace = true }
time = { workspace = true }
webrender = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
webxr = { git = "https://github.com/servo/webxr" }
[build-dependencies]
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index d211a4c4783..826c48dc836 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -13,10 +13,9 @@ use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use base::id::{PipelineId, TopLevelBrowsingContextId, WebViewId};
use base::{Epoch, WebRenderEpochToU16};
-use canvas::canvas_paint_thread::ImageUpdate;
use compositing_traits::{
- CanvasToCompositorMsg, CompositionPipeline, CompositorMsg, CompositorReceiver,
- ConstellationMsg, FontToCompositorMsg, ForwardedToCompositorMsg, SendableFrameTree,
+ CompositionPipeline, CompositorMsg, CompositorReceiver, ConstellationMsg,
+ ForwardedToCompositorMsg, SendableFrameTree,
};
use crossbeam_channel::Sender;
use embedder_traits::Cursor;
@@ -27,16 +26,13 @@ use image::{DynamicImage, ImageFormat};
use ipc_channel::ipc;
use libc::c_void;
use log::{debug, error, info, trace, warn};
-use net_traits::image::base::Image;
-use net_traits::image_cache::CorsStatus;
-use pixels::PixelFormat;
+use pixels::{CorsStatus, Image, PixelFormat};
use profile_traits::time::{self as profile_time, profile, ProfilerCategory};
-use script_traits::compositor::{HitTestInfo, ScrollTree};
use script_traits::CompositorEvent::{MouseButtonEvent, MouseMoveEvent, TouchEvent, WheelEvent};
use script_traits::{
- AnimationState, AnimationTickType, CompositorHitTestResult, ConstellationControlMsg,
- LayoutControlMsg, MouseButton, MouseEventType, ScrollState, TouchEventType, TouchId,
- UntrustedNodeAddress, WheelDelta, WindowSizeData, WindowSizeType,
+ AnimationState, AnimationTickType, ConstellationControlMsg, LayoutControlMsg, MouseButton,
+ MouseEventType, ScrollState, TouchEventType, TouchId, WheelDelta, WindowSizeData,
+ WindowSizeType,
};
use servo_geometry::{DeviceIndependentPixel, FramebufferUintLength};
use style_traits::{CSSPixel, DevicePixel, PinchZoomFactor};
@@ -51,6 +47,11 @@ use webrender_api::{
PropertyBinding, ReferenceFrameKind, RenderReasons, SampledScrollOffset, ScrollLocation,
SpaceAndClipInfo, SpatialId, SpatialTreeItemKey, TransformStyle,
};
+use webrender_traits::display_list::{HitTestInfo, ScrollTree};
+use webrender_traits::{
+ CanvasToCompositorMsg, CompositorHitTestResult, FontToCompositorMsg, ImageUpdate,
+ NetToCompositorMsg, ScriptToCompositorMsg, SerializedImageUpdate, UntrustedNodeAddress,
+};
use crate::gl::RenderTargetInfo;
use crate::touch::{TouchAction, TouchHandler};
@@ -695,9 +696,9 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
/// instance in the parent process.
fn handle_webrender_message(&mut self, msg: ForwardedToCompositorMsg) {
match msg {
- ForwardedToCompositorMsg::Layout(
- script_traits::ScriptToCompositorMsg::SendInitialTransaction(pipeline),
- ) => {
+ ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::SendInitialTransaction(
+ pipeline,
+ )) => {
let mut txn = Transaction::new();
txn.set_display_list(WebRenderEpoch(0), (pipeline, Default::default()));
self.generate_frame(&mut txn, RenderReasons::SCENE);
@@ -705,13 +706,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.send_transaction(self.webrender_document, txn);
},
- ForwardedToCompositorMsg::Layout(
- script_traits::ScriptToCompositorMsg::SendScrollNode(
- pipeline_id,
- point,
- external_scroll_id,
- ),
- ) => {
+ ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::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,
@@ -743,13 +742,11 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.send_transaction(self.webrender_document, txn);
},
- ForwardedToCompositorMsg::Layout(
- script_traits::ScriptToCompositorMsg::SendDisplayList {
- display_list_info,
- display_list_descriptor,
- display_list_receiver,
- },
- ) => {
+ ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::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,
@@ -799,7 +796,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.send_transaction(self.webrender_document, transaction);
},
- ForwardedToCompositorMsg::Layout(script_traits::ScriptToCompositorMsg::HitTest(
+ ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::HitTest(
pipeline,
point,
flags,
@@ -821,31 +818,23 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
let _ = sender.send(result);
},
- ForwardedToCompositorMsg::Layout(
- script_traits::ScriptToCompositorMsg::GenerateImageKey(sender),
- ) |
- ForwardedToCompositorMsg::Net(net_traits::NetToCompositorMsg::GenerateImageKey(
- sender,
- )) => {
+ ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::GenerateImageKey(sender)) |
+ ForwardedToCompositorMsg::Net(NetToCompositorMsg::GenerateImageKey(sender)) => {
let _ = sender.send(self.webrender_api.generate_image_key());
},
- ForwardedToCompositorMsg::Layout(
- script_traits::ScriptToCompositorMsg::UpdateImages(updates),
- ) => {
+ ForwardedToCompositorMsg::Layout(ScriptToCompositorMsg::UpdateImages(updates)) => {
let mut txn = Transaction::new();
for update in updates {
match update {
- script_traits::SerializedImageUpdate::AddImage(key, desc, data) => {
+ 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),
}
},
- script_traits::SerializedImageUpdate::DeleteImage(key) => {
- txn.delete_image(key)
- },
- script_traits::SerializedImageUpdate::UpdateImage(key, desc, data) => {
+ 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),
@@ -857,11 +846,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
.send_transaction(self.webrender_document, txn);
},
- ForwardedToCompositorMsg::Net(net_traits::NetToCompositorMsg::AddImage(
- key,
- desc,
- data,
- )) => {
+ ForwardedToCompositorMsg::Net(NetToCompositorMsg::AddImage(key, desc, data)) => {
let mut txn = Transaction::new();
txn.add_image(key, desc, data, None);
self.webrender_api
@@ -929,13 +914,13 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
let mut txn = Transaction::new();
for update in updates {
match update {
- ImageUpdate::Add(key, descriptor, data) => {
+ ImageUpdate::AddImage(key, descriptor, data) => {
txn.add_image(key, descriptor, data, None)
},
- ImageUpdate::Update(key, descriptor, data) => {
+ ImageUpdate::UpdateImage(key, descriptor, data) => {
txn.update_image(key, descriptor, data, &DirtyRect::All)
},
- ImageUpdate::Delete(key) => txn.delete_image(key),
+ ImageUpdate::DeleteImage(key) => txn.delete_image(key),
}
}
self.webrender_api
@@ -1469,7 +1454,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
event_type,
button,
result.point_in_viewport.to_untyped(),
- Some(result.node),
+ Some(result.node.into()),
Some(result.point_relative_to_item),
button as u16,
);
@@ -1549,7 +1534,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
None => return,
};
- let event = MouseMoveEvent(result.point_in_viewport, Some(result.node), 0);
+ let event = MouseMoveEvent(result.point_in_viewport, Some(result.node.into()), 0);
let msg = ConstellationMsg::ForwardEvent(result.pipeline_id, event);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Sending event to constellation failed ({:?}).", e);
@@ -1568,7 +1553,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
event_type,
identifier,
result.point_in_viewport,
- Some(result.node),
+ Some(result.node.into()),
);
let msg = ConstellationMsg::ForwardEvent(result.pipeline_id, event);
if let Err(e) = self.constellation_chan.send(msg) {
@@ -1579,7 +1564,7 @@ impl<Window: WindowMethods + ?Sized> IOCompositor<Window> {
pub fn send_wheel_event(&mut self, delta: WheelDelta, point: DevicePoint) {
if let Some(result) = self.hit_test_at_point(point) {
- let event = WheelEvent(delta, result.point_in_viewport, Some(result.node));
+ let event = WheelEvent(delta, result.point_in_viewport, Some(result.node.into()));
let msg = ConstellationMsg::ForwardEvent(result.pipeline_id, event);
if let Err(e) = self.constellation_chan.send(msg) {
warn!("Sending event to constellation failed ({:?}).", e);
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 14176fc0739..00211847c92 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -155,7 +155,7 @@ use style_traits::CSSPixel;
use webgpu::{self, WebGPU, WebGPURequest};
use webrender::{RenderApi, RenderApiSender};
use webrender_api::DocumentId;
-use webrender_traits::WebrenderExternalImageRegistry;
+use webrender_traits::{WebRenderNetApi, WebRenderScriptApi, WebrenderExternalImageRegistry};
use crate::browsingcontext::{
AllBrowsingContextsIterator, BrowsingContext, FullyActiveBrowsingContextsIterator,
@@ -392,11 +392,11 @@ pub struct Constellation<STF, SWF> {
/// A channel for content processes to send messages that will
/// be relayed to the WebRender thread.
- webrender_api_ipc_sender: script_traits::WebrenderIpcSender,
+ 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: net_traits::WebrenderIpcSender,
+ webrender_image_api_sender: WebRenderNetApi,
/// A map of message-port Id to info.
message_ports: HashMap<MessagePortId, MessagePortInfo>,
@@ -785,12 +785,8 @@ where
scheduler_receiver,
document_states: HashMap::new(),
webrender_document: state.webrender_document,
- webrender_api_ipc_sender: script_traits::WebrenderIpcSender::new(
- webrender_ipc_sender,
- ),
- webrender_image_api_sender: net_traits::WebrenderIpcSender::new(
- webrender_image_ipc_sender,
- ),
+ 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(),
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 000a52768ac..9547aa8a354 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -185,10 +185,10 @@ pub struct InitialPipelineState {
pub prev_throttled: bool,
/// Webrender api.
- pub webrender_image_api_sender: net_traits::WebrenderIpcSender,
+ pub webrender_image_api_sender: webrender_traits::WebRenderNetApi,
/// Webrender api.
- pub webrender_api_sender: script_traits::WebrenderIpcSender,
+ pub webrender_api_sender: webrender_traits::WebRenderScriptApi,
/// The ID of the document processed by this script thread.
pub webrender_document: DocumentId,
@@ -502,8 +502,8 @@ pub struct UnprivilegedPipelineContent {
opts: Opts,
prefs: HashMap<String, PrefValue>,
pipeline_namespace_id: PipelineNamespaceId,
- webrender_api_sender: script_traits::WebrenderIpcSender,
- webrender_image_api_sender: net_traits::WebrenderIpcSender,
+ webrender_api_sender: webrender_traits::WebRenderScriptApi,
+ webrender_image_api_sender: webrender_traits::WebRenderNetApi,
webrender_document: DocumentId,
webgl_chan: Option<WebGLPipeline>,
webxr_registry: webxr_api::Registry,
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml
index f63002b5fe3..f7b50524604 100644
--- a/components/layout/Cargo.toml
+++ b/components/layout/Cargo.toml
@@ -30,6 +30,7 @@ log = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
net_traits = { workspace = true }
+pixels = { path = "../pixels" }
parking_lot = { workspace = true }
profile_traits = { workspace = true }
range = { path = "../range" }
@@ -50,4 +51,5 @@ style_traits = { workspace = true }
unicode-bidi = { workspace = true, features = ["with_serde"] }
unicode-script = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
xi-unicode = { workspace = true }
diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs
index 0fba6875d2f..62257e17d8b 100644
--- a/components/layout/display_list/builder.rs
+++ b/components/layout/display_list/builder.rs
@@ -27,7 +27,6 @@ use log::{debug, warn};
use net_traits::image_cache::UsePlaceholder;
use range::Range;
use script_layout_interface::{combine_id_with_fragment_type, FragmentType};
-use script_traits::compositor::ScrollSensitivity;
use servo_config::opts;
use servo_geometry::{self, MaxRect};
use style::color::AbsoluteColor;
@@ -52,6 +51,7 @@ use webrender_api::{
ExternalScrollId, FilterOp, GlyphInstance, ImageRendering, LineStyle, NinePatchBorder,
NinePatchBorderSource, NormalBorder, PropertyBinding, StickyOffsetBounds,
};
+use webrender_traits::display_list::ScrollSensitivity;
use super::StackingContextId;
use crate::block::BlockFlow;
diff --git a/components/layout/display_list/items.rs b/components/layout/display_list/items.rs
index 6fe14f03143..92117a118df 100644
--- a/components/layout/display_list/items.rs
+++ b/components/layout/display_list/items.rs
@@ -20,8 +20,7 @@ use base::id::PipelineId;
use base::print_tree::PrintTree;
use embedder_traits::Cursor;
use euclid::{SideOffsets2D, Vector2D};
-use net_traits::image::base::Image;
-use script_traits::compositor::{ScrollSensitivity, ScrollTreeNodeId};
+use pixels::Image;
use serde::Serialize;
use servo_geometry::MaxRect;
use style::computed_values::_servo_top_layer::T as InTopLayer;
@@ -33,6 +32,7 @@ use webrender_api::{
FilterOp, GlyphInstance, GradientStop, ImageKey, MixBlendMode, PrimitiveFlags, Shadow,
SpatialId, StickyOffsetBounds, TransformStyle,
};
+use webrender_traits::display_list::{ScrollSensitivity, ScrollTreeNodeId};
use super::StackingContextId;
diff --git a/components/layout/display_list/webrender_helpers.rs b/components/layout/display_list/webrender_helpers.rs
index 0ac79b4d8ca..c6c2abfdd34 100644
--- a/components/layout/display_list/webrender_helpers.rs
+++ b/components/layout/display_list/webrender_helpers.rs
@@ -10,15 +10,15 @@
use base::id::PipelineId;
use base::WebRenderEpochToU16;
use log::trace;
-use script_traits::compositor::{
- CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo,
-};
use webrender_api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
use webrender_api::{
self, ClipChainId, ClipId, CommonItemProperties, DisplayItem as WrDisplayItem,
DisplayListBuilder, Epoch, HasScrollLinkedEffect, PrimitiveFlags, PropertyBinding, RasterSpace,
ReferenceFrameKind, SpaceAndClipInfo, SpatialId, SpatialTreeItemKey,
};
+use webrender_traits::display_list::{
+ CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo,
+};
use crate::display_list::items::{
BaseDisplayItem, ClipScrollNode, ClipScrollNodeType, ClipType, DisplayItem, DisplayList,
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 171c529babc..7ddcbdb2e6b 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -20,8 +20,8 @@ use gfx::text::text_run::{TextRun, TextRunSlice};
use html5ever::{local_name, namespace_url, ns};
use ipc_channel::ipc::IpcSender;
use log::debug;
-use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
+use pixels::{Image, ImageMetadata};
use range::*;
use script_layout_interface::wrapper_traits::{
PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
diff --git a/components/layout_2020/Cargo.toml b/components/layout_2020/Cargo.toml
index 99446a0f59c..5810cfee983 100644
--- a/components/layout_2020/Cargo.toml
+++ b/components/layout_2020/Cargo.toml
@@ -30,6 +30,7 @@ ipc-channel = { workspace = true }
log = { workspace = true }
net_traits = { workspace = true }
parking_lot = { workspace = true }
+pixels = { path = "../pixels" }
range = { path = "../range" }
rayon = { workspace = true }
script_layout_interface = { workspace = true }
@@ -47,6 +48,7 @@ unicode-segmentation = { workspace = true }
url = { workspace = true }
data-url = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
xi-unicode = { workspace = true }
[dev-dependencies]
diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs
index d4be0e26b71..41236cdc413 100644
--- a/components/layout_2020/display_list/mod.rs
+++ b/components/layout_2020/display_list/mod.rs
@@ -12,7 +12,6 @@ use euclid::{Point2D, SideOffsets2D, Size2D};
use fnv::FnvHashMap;
use gfx::text::glyph::GlyphStore;
use net_traits::image_cache::UsePlaceholder;
-use script_traits::compositor::{CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId};
use servo_geometry::MaxRect;
use style::color::{AbsoluteColor, ColorSpace};
use style::computed_values::text_decoration_style::T as ComputedTextDecorationStyle;
@@ -24,6 +23,9 @@ use style::values::specified::text::TextDecorationLine;
use style::values::specified::ui::CursorKind;
use style_traits::CSSPixel;
use webrender_api::{self as wr, units, BoxShadowClipMode, ClipChainId};
+use webrender_traits::display_list::{
+ CompositorDisplayListInfo, ScrollSensitivity, ScrollTreeNodeId,
+};
use wr::units::LayoutVector2D;
use crate::context::LayoutContext;
diff --git a/components/layout_2020/display_list/stacking_context.rs b/components/layout_2020/display_list/stacking_context.rs
index 0b37949b1b8..2833fa459fc 100644
--- a/components/layout_2020/display_list/stacking_context.rs
+++ b/components/layout_2020/display_list/stacking_context.rs
@@ -9,7 +9,6 @@ use base::print_tree::PrintTree;
use euclid::default::Rect;
use euclid::SideOffsets2D;
use log::warn;
-use script_traits::compositor::{ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo};
use servo_arc::Arc as ServoArc;
use servo_config::opts::DebugOptions;
use style::computed_values::float::T as ComputedFloat;
@@ -24,6 +23,7 @@ use style::values::specified::box_::DisplayOutside;
use style::Zero;
use webrender_api as wr;
use webrender_api::units::{LayoutPoint, LayoutRect, LayoutTransform, LayoutVector2D};
+use webrender_traits::display_list::{ScrollSensitivity, ScrollTreeNodeId, ScrollableNodeInfo};
use wr::units::{LayoutPixel, LayoutSize};
use wr::{ClipChainId, SpatialTreeItemKey, StickyOffsetBounds};
diff --git a/components/layout_2020/dom.rs b/components/layout_2020/dom.rs
index 24d4647e0a5..2c8209c9b3c 100644
--- a/components/layout_2020/dom.rs
+++ b/components/layout_2020/dom.rs
@@ -8,7 +8,7 @@ use std::sync::{Arc, Mutex};
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
use base::id::{BrowsingContextId, PipelineId};
use html5ever::{local_name, namespace_url, ns};
-use net_traits::image::base::Image as NetImage;
+use pixels::Image;
use script_layout_interface::wrapper_traits::{
LayoutDataTrait, LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
@@ -96,7 +96,7 @@ impl Drop for BoxSlot<'_> {
pub(crate) trait NodeExt<'dom>: 'dom + LayoutNode<'dom> {
/// Returns the image if it’s loaded, and its size in image pixels
/// adjusted for `image_density`.
- fn as_image(self) -> Option<(Option<Arc<NetImage>>, PhysicalSize<f64>)>;
+ fn as_image(self) -> Option<(Option<Arc<Image>>, PhysicalSize<f64>)>;
fn as_canvas(self) -> Option<(CanvasInfo, PhysicalSize<f64>)>;
fn as_iframe(self) -> Option<(PipelineId, BrowsingContextId)>;
fn as_video(self) -> Option<(webrender_api::ImageKey, PhysicalSize<f64>)>;
@@ -117,7 +117,7 @@ impl<'dom, LayoutNodeType> NodeExt<'dom> for LayoutNodeType
where
LayoutNodeType: 'dom + LayoutNode<'dom>,
{
- fn as_image(self) -> Option<(Option<Arc<NetImage>>, PhysicalSize<f64>)> {
+ fn as_image(self) -> Option<(Option<Arc<Image>>, PhysicalSize<f64>)> {
let node = self.to_threadsafe();
let (resource, metadata) = node.image_data()?;
let (width, height) = resource
diff --git a/components/layout_2020/flow/root.rs b/components/layout_2020/flow/root.rs
index b3b436ce23d..6dae0291a71 100644
--- a/components/layout_2020/flow/root.rs
+++ b/components/layout_2020/flow/root.rs
@@ -7,13 +7,13 @@ use script_layout_interface::wrapper_traits::{
LayoutNode, ThreadSafeLayoutElement, ThreadSafeLayoutNode,
};
use script_layout_interface::{LayoutElementType, LayoutNodeType};
-use script_traits::compositor::ScrollSensitivity;
use serde::Serialize;
use servo_arc::Arc;
use style::dom::OpaqueNode;
use style::properties::ComputedValues;
use style::values::computed::{Length, Overflow};
use style_traits::CSSPixel;
+use webrender_traits::display_list::ScrollSensitivity;
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
diff --git a/components/layout_2020/fragment_tree/fragment_tree.rs b/components/layout_2020/fragment_tree/fragment_tree.rs
index 77d07a65847..085274d4035 100644
--- a/components/layout_2020/fragment_tree/fragment_tree.rs
+++ b/components/layout_2020/fragment_tree/fragment_tree.rs
@@ -6,12 +6,12 @@ use app_units::Au;
use base::print_tree::PrintTree;
use euclid::default::{Point2D, Rect, Size2D};
use fxhash::FxHashSet;
-use script_traits::compositor::ScrollSensitivity;
use serde::Serialize;
use style::animation::AnimationSetKey;
use style::dom::OpaqueNode;
use style::values::computed::Length;
use webrender_api::units;
+use webrender_traits::display_list::ScrollSensitivity;
use super::{ContainingBlockManager, Fragment, Tag};
use crate::cell::ArcRefCell;
diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs
index ac3f1621d85..fbd359709c2 100644
--- a/components/layout_2020/replaced.rs
+++ b/components/layout_2020/replaced.rs
@@ -10,8 +10,8 @@ use base::id::{BrowsingContextId, PipelineId};
use canvas_traits::canvas::{CanvasId, CanvasMsg, FromLayoutMsg};
use data_url::DataUrl;
use ipc_channel::ipc::{self, IpcSender};
-use net_traits::image::base::Image;
use net_traits::image_cache::{ImageOrMetadataAvailable, UsePlaceholder};
+use pixels::Image;
use serde::Serialize;
use servo_arc::Arc as ServoArc;
use style::properties::ComputedValues;
diff --git a/components/layout_thread/Cargo.toml b/components/layout_thread/Cargo.toml
index 978b597212b..a95c7f9b8aa 100644
--- a/components/layout_thread/Cargo.toml
+++ b/components/layout_thread/Cargo.toml
@@ -45,3 +45,4 @@ style_traits = { workspace = true }
time = { workspace = true }
url = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs
index e279f10221d..8cb612bd1de 100644
--- a/components/layout_thread/lib.rs
+++ b/components/layout_thread/lib.rs
@@ -69,7 +69,7 @@ use script_layout_interface::{
use script_traits::{
ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg,
LayoutMsg as ConstellationMsg, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress,
- WebrenderIpcSender, WindowSizeData, WindowSizeType,
+ WindowSizeData, WindowSizeType,
};
use servo_arc::Arc as ServoArc;
use servo_atoms::Atom;
@@ -102,6 +102,7 @@ use style::traversal_flags::TraversalFlags;
use style_traits::{CSSPixel, DevicePixel, SpeculativePainter};
use url::Url;
use webrender_api::{units, ColorF, HitTestFlags};
+use webrender_traits::WebRenderScriptApi;
/// Information needed by layout.
pub struct LayoutThread {
@@ -176,7 +177,7 @@ pub struct LayoutThread {
registered_painters: RegisteredPaintersImpl,
/// Webrender interface.
- webrender_api: WebrenderIpcSender,
+ webrender_api: WebRenderScriptApi,
/// Paint time metrics.
paint_time_metrics: PaintTimeMetrics,
@@ -365,7 +366,7 @@ impl Layout for LayoutThread {
.webrender_api
.hit_test(Some(self.id.into()), client_point, flags);
- results.iter().map(|result| result.node).collect()
+ results.iter().map(|result| result.node.into()).collect()
}
fn query_offset_parent(&self, node: OpaqueNode) -> OffsetParentResponse {
@@ -567,7 +568,7 @@ impl LayoutThread {
image_cache: Arc<dyn ImageCache>,
font_cache_thread: FontCacheThread,
time_profiler_chan: profile_time::ProfilerChan,
- webrender_api: WebrenderIpcSender,
+ webrender_api: WebRenderScriptApi,
paint_time_metrics: PaintTimeMetrics,
window_size: WindowSizeData,
) -> LayoutThread {
diff --git a/components/layout_thread_2020/Cargo.toml b/components/layout_thread_2020/Cargo.toml
index 633b903e509..6b96f358b2a 100644
--- a/components/layout_thread_2020/Cargo.toml
+++ b/components/layout_thread_2020/Cargo.toml
@@ -41,3 +41,4 @@ style = { workspace = true }
style_traits = { workspace = true }
url = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
diff --git a/components/layout_thread_2020/lib.rs b/components/layout_thread_2020/lib.rs
index 048a5d86216..4dd245a4925 100644
--- a/components/layout_thread_2020/lib.rs
+++ b/components/layout_thread_2020/lib.rs
@@ -55,7 +55,7 @@ use script_layout_interface::{
use script_traits::{
ConstellationControlMsg, DrawAPaintImageResult, IFrameSizeMsg, LayoutControlMsg,
LayoutMsg as ConstellationMsg, PaintWorkletError, Painter, ScrollState, UntrustedNodeAddress,
- WebrenderIpcSender, WindowSizeData, WindowSizeType,
+ WindowSizeData, WindowSizeType,
};
use servo_arc::Arc as ServoArc;
use servo_atoms::Atom;
@@ -89,6 +89,7 @@ use style_traits::{CSSPixel, DevicePixel, SpeculativePainter};
use url::Url;
use webrender_api::units::LayoutPixel;
use webrender_api::{units, ExternalScrollId, HitTestFlags};
+use webrender_traits::WebRenderScriptApi;
/// Information needed by layout.
pub struct LayoutThread {
@@ -158,7 +159,7 @@ pub struct LayoutThread {
registered_painters: RegisteredPaintersImpl,
/// Webrender interface.
- webrender_api: WebrenderIpcSender,
+ webrender_api: WebRenderScriptApi,
/// Paint time metrics.
paint_time_metrics: PaintTimeMetrics,
@@ -328,7 +329,7 @@ impl Layout for LayoutThread {
.webrender_api
.hit_test(Some(self.id.into()), client_point, flags);
- results.iter().map(|result| result.node).collect()
+ results.iter().map(|result| result.node.into()).collect()
}
fn query_offset_parent(&self, node: OpaqueNode) -> OffsetParentResponse {
@@ -484,7 +485,7 @@ impl LayoutThread {
image_cache: Arc<dyn ImageCache>,
font_cache_thread: FontCacheThread,
time_profiler_chan: profile_time::ProfilerChan,
- webrender_api_sender: WebrenderIpcSender,
+ webrender_api_sender: WebRenderScriptApi,
paint_time_metrics: PaintTimeMetrics,
window_size: WindowSizeData,
) -> LayoutThread {
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index bce568c034a..fb6c47209cb 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -65,6 +65,7 @@ tungstenite = { workspace = true }
url = { workspace = true }
uuid = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
webpki-roots = { workspace = true }
[dev-dependencies]
diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs
index 9235c8d251e..2f0968f3aa4 100644
--- a/components/net/image_cache.rs
+++ b/components/net/image_cache.rs
@@ -12,19 +12,17 @@ use embedder_traits::resources::{self, Resource};
use imsz::imsz_from_reader;
use ipc_channel::ipc::IpcSender;
use log::{debug, warn};
-use net_traits::image::base::{load_from_memory, Image, ImageMetadata};
use net_traits::image_cache::{
- CorsStatus, ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponder,
- ImageResponse, PendingImageId, PendingImageResponse, UsePlaceholder,
+ ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponder, ImageResponse,
+ PendingImageId, PendingImageResponse, UsePlaceholder,
};
use net_traits::request::CorsSettings;
-use net_traits::{
- FetchMetadata, FetchResponseMsg, FilteredMetadata, NetworkError, WebrenderIpcSender,
-};
-use pixels::PixelFormat;
+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 crate::resource_thread::CoreResourceThreadPool;
@@ -47,13 +45,13 @@ fn decode_bytes_sync(key: LoadKey, bytes: &[u8], cors: CorsStatus) -> DecoderMsg
DecoderMsg { key, image }
}
-fn get_placeholder_image(webrender_api: &WebrenderIpcSender, data: &[u8]) -> Arc<Image> {
+fn get_placeholder_image(webrender_api: &WebRenderNetApi, data: &[u8]) -> Arc<Image> {
let mut image = load_from_memory(data, CorsStatus::Unsafe).unwrap();
set_webrender_image_key(webrender_api, &mut image);
Arc::new(image)
}
-fn set_webrender_image_key(webrender_api: &WebrenderIpcSender, image: &mut Image) {
+fn set_webrender_image_key(webrender_api: &WebRenderNetApi, image: &mut Image) {
if image.id.is_some() {
return;
}
@@ -331,7 +329,7 @@ struct ImageCacheStore {
placeholder_url: ServoUrl,
// Webrender API instance.
- webrender_api: WebrenderIpcSender,
+ webrender_api: WebRenderNetApi,
}
impl ImageCacheStore {
@@ -418,7 +416,7 @@ pub struct ImageCacheImpl {
}
impl ImageCache for ImageCacheImpl {
- fn new(webrender_api: WebrenderIpcSender) -> ImageCacheImpl {
+ fn new(webrender_api: WebRenderNetApi) -> ImageCacheImpl {
debug!("New image cache");
let rippy_data = resources::read_bytes(Resource::RippyPNG);
diff --git a/components/pixels/Cargo.toml b/components/pixels/Cargo.toml
index f201ff7c0e4..3330ca1a34c 100644
--- a/components/pixels/Cargo.toml
+++ b/components/pixels/Cargo.toml
@@ -12,6 +12,10 @@ path = "lib.rs"
[dependencies]
euclid = { workspace = true }
+ipc-channel = { workspace = true }
+image = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
+log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
+webrender_api = { workspace = true }
diff --git a/components/pixels/lib.rs b/components/pixels/lib.rs
index 2b26af3dd7c..bd2aea5b410 100644
--- a/components/pixels/lib.rs
+++ b/components/pixels/lib.rs
@@ -3,10 +3,15 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::borrow::Cow;
+use std::fmt;
use euclid::default::{Point2D, Rect, Size2D};
+use image::ImageFormat;
+use ipc_channel::ipc::IpcSharedMemory;
+use log::debug;
use malloc_size_of_derive::MallocSizeOf;
use serde::{Deserialize, Serialize};
+use webrender_api::ImageKey;
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
pub enum PixelFormat {
@@ -98,3 +103,148 @@ pub fn clip(
.intersection(&Rect::from_size(surface))
.filter(|rect| !rect.is_empty())
}
+
+/// Whether this response passed any CORS checks, and is thus safe to read from
+/// in cross-origin environments.
+#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
+pub enum CorsStatus {
+ /// The response is either same-origin or cross-origin but passed CORS checks.
+ Safe,
+ /// The response is cross-origin and did not pass CORS checks. It is unsafe
+ /// to expose pixel data to the requesting environment.
+ Unsafe,
+}
+
+#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
+pub struct Image {
+ pub width: u32,
+ pub height: u32,
+ pub format: PixelFormat,
+ #[ignore_malloc_size_of = "Defined in ipc-channel"]
+ pub bytes: IpcSharedMemory,
+ #[ignore_malloc_size_of = "Defined in webrender_api"]
+ pub id: Option<ImageKey>,
+ pub cors_status: CorsStatus,
+}
+
+impl fmt::Debug for Image {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "Image {{ width: {}, height: {}, format: {:?}, ..., id: {:?} }}",
+ self.width, self.height, self.format, self.id
+ )
+ }
+}
+
+#[derive(Clone, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
+pub struct ImageMetadata {
+ pub width: u32,
+ pub height: u32,
+}
+
+// FIXME: Images must not be copied every frame. Instead we should atomically
+// reference count them.
+
+pub fn load_from_memory(buffer: &[u8], cors_status: CorsStatus) -> Option<Image> {
+ if buffer.is_empty() {
+ return None;
+ }
+
+ let image_fmt_result = detect_image_format(buffer);
+ match image_fmt_result {
+ Err(msg) => {
+ debug!("{}", msg);
+ None
+ },
+ Ok(_) => match image::load_from_memory(buffer) {
+ Ok(image) => {
+ let mut rgba = image.into_rgba8();
+ rgba8_byte_swap_colors_inplace(&mut rgba);
+ Some(Image {
+ width: rgba.width(),
+ height: rgba.height(),
+ format: PixelFormat::BGRA8,
+ bytes: IpcSharedMemory::from_bytes(&rgba),
+ id: None,
+ cors_status,
+ })
+ },
+ Err(e) => {
+ debug!("Image decoding error: {:?}", e);
+ None
+ },
+ },
+ }
+}
+
+// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
+pub fn detect_image_format(buffer: &[u8]) -> Result<ImageFormat, &str> {
+ if is_gif(buffer) {
+ Ok(ImageFormat::Gif)
+ } else if is_jpeg(buffer) {
+ Ok(ImageFormat::Jpeg)
+ } else if is_png(buffer) {
+ Ok(ImageFormat::Png)
+ } else if is_webp(buffer) {
+ Ok(ImageFormat::WebP)
+ } else if is_bmp(buffer) {
+ Ok(ImageFormat::Bmp)
+ } else if is_ico(buffer) {
+ Ok(ImageFormat::Ico)
+ } else {
+ Err("Image Format Not Supported")
+ }
+}
+
+fn is_gif(buffer: &[u8]) -> bool {
+ buffer.starts_with(b"GIF87a") || buffer.starts_with(b"GIF89a")
+}
+
+fn is_jpeg(buffer: &[u8]) -> bool {
+ buffer.starts_with(&[0xff, 0xd8, 0xff])
+}
+
+fn is_png(buffer: &[u8]) -> bool {
+ buffer.starts_with(&[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
+}
+
+fn is_bmp(buffer: &[u8]) -> bool {
+ buffer.starts_with(&[0x42, 0x4D])
+}
+
+fn is_ico(buffer: &[u8]) -> bool {
+ buffer.starts_with(&[0x00, 0x00, 0x01, 0x00])
+}
+
+fn is_webp(buffer: &[u8]) -> bool {
+ buffer.starts_with(b"RIFF") && buffer.len() >= 14 && &buffer[8..14] == b"WEBPVP"
+}
+
+#[cfg(test)]
+mod test {
+ use super::detect_image_format;
+
+ #[test]
+ fn test_supported_images() {
+ let gif1 = [b'G', b'I', b'F', b'8', b'7', b'a'];
+ let gif2 = [b'G', b'I', b'F', b'8', b'9', b'a'];
+ let jpeg = [0xff, 0xd8, 0xff];
+ let png = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
+ let webp = [
+ b'R', b'I', b'F', b'F', 0x01, 0x02, 0x03, 0x04, b'W', b'E', b'B', b'P', b'V', b'P',
+ ];
+ let bmp = [0x42, 0x4D];
+ let ico = [0x00, 0x00, 0x01, 0x00];
+ let junk_format = [0x01, 0x02, 0x03, 0x04, 0x05];
+
+ assert!(detect_image_format(&gif1).is_ok());
+ assert!(detect_image_format(&gif2).is_ok());
+ assert!(detect_image_format(&jpeg).is_ok());
+ assert!(detect_image_format(&png).is_ok());
+ assert!(detect_image_format(&webp).is_ok());
+ assert!(detect_image_format(&bmp).is_ok());
+ assert!(detect_image_format(&ico).is_ok());
+ assert!(detect_image_format(&junk_format).is_err());
+ }
+}
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 45926d07f40..5cf7b65ba4d 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -116,6 +116,7 @@ uuid = { workspace = true, features = ["serde"] }
webdriver = { workspace = true }
webgpu = { path = "../webgpu" }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
xml5ever = { workspace = true }
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index 96d4b1183cd..301c4e17b22 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -20,10 +20,9 @@ use ipc_channel::router::ROUTER;
use js::jsapi::JSAutoRealm;
use js::rust::HandleObject;
use mime::{self, Mime};
-use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache::{
- CorsStatus, ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponse,
- PendingImageId, PendingImageResponse, UsePlaceholder,
+ ImageCache, ImageCacheResult, ImageOrMetadataAvailable, ImageResponse, PendingImageId,
+ PendingImageResponse, UsePlaceholder,
};
use net_traits::request::{CorsSettings, Destination, Initiator, Referrer, RequestBuilder};
use net_traits::{
@@ -31,6 +30,7 @@ use net_traits::{
ResourceFetchTiming, ResourceTimingType,
};
use num_traits::ToPrimitive;
+use pixels::{CorsStatus, Image, ImageMetadata};
use servo_url::origin::{ImmutableOrigin, MutableOrigin};
use servo_url::ServoUrl;
use style::attr::{
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index f64ec676dc1..59f38e42c17 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -20,14 +20,13 @@ use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use js::jsapi::JSAutoRealm;
use media::{glplayer_channel, GLPlayerMsg, GLPlayerMsgForward, WindowGLContext};
-use net_traits::image::base::Image;
use net_traits::request::Destination;
use net_traits::{
CoreResourceMsg, FetchChannels, FetchMetadata, FetchResponseListener, Metadata, NetworkError,
ResourceFetchTiming, ResourceTimingType,
};
+use pixels::Image;
use script_layout_interface::HTMLMediaData;
-use script_traits::{ImageUpdate, WebrenderIpcSender};
use servo_config::pref;
use servo_media::player::audio::AudioRenderer;
use servo_media::player::video::{VideoFrame, VideoFrameRenderer};
@@ -38,6 +37,7 @@ use webrender_api::{
ExternalImageData, ExternalImageId, ExternalImageType, ImageBufferKind, ImageData,
ImageDescriptor, ImageDescriptorFlags, ImageFormat, ImageKey,
};
+use webrender_traits::{ImageUpdate, WebRenderScriptApi};
use crate::document_loader::{LoadBlocker, LoadType};
use crate::dom::attr::Attr;
@@ -154,7 +154,7 @@ impl FrameHolder {
pub struct MediaFrameRenderer {
player_id: Option<u64>,
- api: WebrenderIpcSender,
+ api: WebRenderScriptApi,
current_frame: Option<(ImageKey, i32, i32)>,
old_frame: Option<ImageKey>,
very_old_frame: Option<ImageKey>,
@@ -163,7 +163,7 @@ pub struct MediaFrameRenderer {
}
impl MediaFrameRenderer {
- fn new(render_api_sender: WebrenderIpcSender) -> Self {
+ fn new(render_api_sender: WebRenderScriptApi) -> Self {
Self {
player_id: None,
api: render_api_sender,
diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs
index 318b39ee06f..25794aca176 100755
--- a/components/script/dom/htmlobjectelement.rs
+++ b/components/script/dom/htmlobjectelement.rs
@@ -7,7 +7,7 @@ use std::default::Default;
use dom_struct::dom_struct;
use html5ever::{local_name, namespace_url, ns, LocalName, Prefix};
use js::rust::HandleObject;
-use net_traits::image::base::Image;
+use pixels::Image;
use servo_arc::Arc;
use crate::dom::attr::Attr;
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index 3531fb1b9f3..bbe09601d57 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -23,7 +23,7 @@ use js::jsapi::JSObject;
use js::rust::HandleObject;
use libc::{self, c_void, uintptr_t};
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
-use net_traits::image::base::{Image, ImageMetadata};
+use pixels::{Image, ImageMetadata};
use script_layout_interface::{
GenericLayoutData, HTMLCanvasData, HTMLMediaData, LayoutElementType, LayoutNodeType, QueryMsg,
SVGSVGData, StyleData, TrustedNodeAddress,
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index b034c9c5d29..fcba7ffcbeb 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -56,7 +56,7 @@ use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use script_traits::{
ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData, ScriptMsg,
ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEventId,
- TimerSchedulerMsg, WebrenderIpcSender, WindowSizeData, WindowSizeType,
+ TimerSchedulerMsg, WindowSizeData, WindowSizeType,
};
use selectors::attr::CaseSensitivity;
use servo_arc::Arc as ServoArc;
@@ -76,6 +76,7 @@ use style_traits::{CSSPixel, DevicePixel, ParsingMode};
use url::Position;
use webrender_api::units::{DeviceIntPoint, DeviceIntSize, LayoutPixel};
use webrender_api::{DocumentId, ExternalScrollId};
+use webrender_traits::WebRenderScriptApi;
use super::bindings::trace::HashMapTracedValues;
use crate::dom::bindings::cell::{DomRefCell, Ref};
@@ -318,7 +319,7 @@ pub struct Window {
/// Webrender API Sender
#[ignore_malloc_size_of = "Wraps an IpcSender"]
#[no_trace]
- webrender_api_sender: WebrenderIpcSender,
+ webrender_api_sender: WebRenderScriptApi,
/// 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.
@@ -521,7 +522,7 @@ impl Window {
self.add_pending_reflow();
}
- pub fn get_webrender_api_sender(&self) -> WebrenderIpcSender {
+ pub fn get_webrender_api_sender(&self) -> WebRenderScriptApi {
self.webrender_api_sender.clone()
}
@@ -2537,7 +2538,7 @@ impl Window {
webxr_registry: webxr_api::Registry,
microtask_queue: Rc<MicrotaskQueue>,
webrender_document: DocumentId,
- webrender_api_sender: WebrenderIpcSender,
+ webrender_api_sender: WebRenderScriptApi,
relayout_event: bool,
prepare_for_screenshot: bool,
unminify_js: bool,
diff --git a/components/script/layout_dom/node.rs b/components/script/layout_dom/node.rs
index 7a521d36220..fdbe615513c 100644
--- a/components/script/layout_dom/node.rs
+++ b/components/script/layout_dom/node.rs
@@ -11,7 +11,7 @@ use std::sync::Arc as StdArc;
use base::id::{BrowsingContextId, PipelineId};
use gfx_traits::ByteIndex;
use html5ever::{local_name, namespace_url, ns};
-use net_traits::image::base::{Image, ImageMetadata};
+use pixels::{Image, ImageMetadata};
use range::Range;
use script_layout_interface::wrapper_traits::{
LayoutDataTrait, LayoutNode, PseudoElementType, ThreadSafeLayoutNode,
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 7231dfc54dd..4c67071a7b0 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -83,7 +83,7 @@ use script_traits::{
LayoutMsg, LoadData, LoadOrigin, MediaSessionActionType, MouseButton, MouseEventType,
NewLayoutInfo, Painter, ProgressiveWebMetricType, ScriptMsg, ScriptToConstellationChan,
StructuredSerializedData, TimerSchedulerMsg, TouchEventType, TouchId, UntrustedNodeAddress,
- UpdatePipelineIdReason, WebrenderIpcSender, WheelDelta, WindowSizeData, WindowSizeType,
+ UpdatePipelineIdReason, WheelDelta, WindowSizeData, WindowSizeType,
};
use servo_atoms::Atom;
use servo_config::opts;
@@ -95,6 +95,7 @@ use url::Position;
use webgpu::WebGPUMsg;
use webrender_api::units::LayoutPixel;
use webrender_api::DocumentId;
+use webrender_traits::WebRenderScriptApi;
use crate::document_loader::DocumentLoader;
use crate::dom::bindings::cell::DomRefCell;
@@ -674,7 +675,7 @@ pub struct ScriptThread {
/// Webrender API sender.
#[no_trace]
- webrender_api_sender: WebrenderIpcSender,
+ webrender_api_sender: WebRenderScriptApi,
/// Periodically print out on which events script threads spend their processing time.
profile_script_events: bool,
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index fc15c830100..755538acf06 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -36,8 +36,7 @@ use compositing::webview::UnknownWebView;
use compositing::windowing::{EmbedderEvent, EmbedderMethods, WindowMethods};
use compositing::{CompositeTarget, IOCompositor, InitialCompositorState, ShutdownState};
use compositing_traits::{
- CanvasToCompositorMsg, CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg,
- FontToCompositorMsg, ForwardedToCompositorMsg,
+ CompositorMsg, CompositorProxy, CompositorReceiver, ConstellationMsg, ForwardedToCompositorMsg,
};
#[cfg(all(
not(target_os = "windows"),
@@ -96,8 +95,8 @@ use webrender_api::{
NativeFontHandle,
};
use webrender_traits::{
- WebRenderFontApi, WebrenderExternalImageHandlers, WebrenderExternalImageRegistry,
- WebrenderImageHandlerType,
+ CanvasToCompositorMsg, FontToCompositorMsg, ImageUpdate, WebRenderFontApi,
+ WebrenderExternalImageHandlers, WebrenderExternalImageRegistry, WebrenderImageHandlerType,
};
pub use {
background_hang_monitor, base, bluetooth, bluetooth_traits, canvas, canvas_traits, compositing,
@@ -1100,7 +1099,7 @@ impl canvas_paint_thread::WebrenderApi for CanvasWebrenderApi {
)));
receiver.recv().ok()
}
- fn update_images(&self, updates: Vec<canvas_paint_thread::ImageUpdate>) {
+ fn update_images(&self, updates: Vec<ImageUpdate>) {
self.0
.send(CompositorMsg::Forwarded(ForwardedToCompositorMsg::Canvas(
CanvasToCompositorMsg::UpdateImages(updates),
diff --git a/components/shared/compositing/Cargo.toml b/components/shared/compositing/Cargo.toml
index aed9a0e3565..b454cae37fa 100644
--- a/components/shared/compositing/Cargo.toml
+++ b/components/shared/compositing/Cargo.toml
@@ -12,7 +12,6 @@ path = "lib.rs"
[dependencies]
base = { workspace = true }
-canvas = { path = "../../canvas" }
crossbeam-channel = { workspace = true }
embedder_traits = { workspace = true }
euclid = { workspace = true }
@@ -20,8 +19,9 @@ gfx_traits = { workspace = true }
ipc-channel = { workspace = true }
keyboard-types = { workspace = true }
log = { workspace = true }
-net_traits = { workspace = true }
+pixels = { path = '../../pixels' }
script_traits = { workspace = true }
servo_url = { path = "../../url" }
style_traits = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
diff --git a/components/shared/compositing/lib.rs b/components/shared/compositing/lib.rs
index 34c390cca85..171b0676c2d 100644
--- a/components/shared/compositing/lib.rs
+++ b/components/shared/compositing/lib.rs
@@ -10,23 +10,20 @@ use std::fmt::{Debug, Error, Formatter};
use base::id::{PipelineId, TopLevelBrowsingContextId};
use base::Epoch;
-use canvas::canvas_paint_thread::ImageUpdate;
pub use constellation_msg::ConstellationMsg;
use crossbeam_channel::{Receiver, Sender};
use embedder_traits::EventLoopWaker;
use euclid::Rect;
use ipc_channel::ipc::IpcSender;
use log::warn;
-use net_traits::image::base::Image;
-use net_traits::NetToCompositorMsg;
+use pixels::Image;
use script_traits::{
AnimationState, ConstellationControlMsg, EventResult, MouseButton, MouseEventType,
- ScriptToCompositorMsg,
};
use style_traits::CSSPixel;
use webrender_api::units::{DeviceIntPoint, DeviceIntSize, DeviceRect};
-use webrender_api::{
- self, FontInstanceFlags, FontInstanceKey, FontKey, ImageKey, NativeFontHandle,
+use webrender_traits::{
+ CanvasToCompositorMsg, FontToCompositorMsg, NetToCompositorMsg, ScriptToCompositorMsg,
};
/// Sends messages to the compositor.
@@ -140,17 +137,6 @@ pub struct CompositionPipeline {
pub script_chan: IpcSender<ConstellationControlMsg>,
}
-pub enum FontToCompositorMsg {
- AddFontInstance(FontKey, f32, FontInstanceFlags, Sender<FontInstanceKey>),
- AddFont(Sender<FontKey>, u32, ipc_channel::ipc::IpcBytesReceiver),
- AddSystemFont(Sender<FontKey>, NativeFontHandle),
-}
-
-pub enum CanvasToCompositorMsg {
- GenerateKey(Sender<ImageKey>),
- UpdateImages(Vec<ImageUpdate>),
-}
-
/// Messages forwarded by the Constellation to the Compositor.
pub enum ForwardedToCompositorMsg {
Layout(ScriptToCompositorMsg),
diff --git a/components/shared/net/Cargo.toml b/components/shared/net/Cargo.toml
index 73db752aba6..cf174100feb 100644
--- a/components/shared/net/Cargo.toml
+++ b/components/shared/net/Cargo.toml
@@ -39,3 +39,4 @@ servo_url = { path = "../../url" }
url = { workspace = true }
uuid = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
diff --git a/components/shared/net/image/base.rs b/components/shared/net/image/base.rs
deleted file mode 100644
index 66257012df2..00000000000
--- a/components/shared/net/image/base.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-use std::fmt;
-
-use image::ImageFormat;
-use ipc_channel::ipc::IpcSharedMemory;
-use log::debug;
-use malloc_size_of_derive::MallocSizeOf;
-use pixels::PixelFormat;
-use serde::{Deserialize, Serialize};
-use webrender_api::ImageKey;
-
-use crate::image_cache::CorsStatus;
-
-#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
-pub struct Image {
- pub width: u32,
- pub height: u32,
- pub format: PixelFormat,
- #[ignore_malloc_size_of = "Defined in ipc-channel"]
- pub bytes: IpcSharedMemory,
- #[ignore_malloc_size_of = "Defined in webrender_api"]
- pub id: Option<ImageKey>,
- pub cors_status: CorsStatus,
-}
-
-impl fmt::Debug for Image {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(
- f,
- "Image {{ width: {}, height: {}, format: {:?}, ..., id: {:?} }}",
- self.width, self.height, self.format, self.id
- )
- }
-}
-
-#[derive(Clone, Debug, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)]
-pub struct ImageMetadata {
- pub width: u32,
- pub height: u32,
-}
-
-// FIXME: Images must not be copied every frame. Instead we should atomically
-// reference count them.
-
-pub fn load_from_memory(buffer: &[u8], cors_status: CorsStatus) -> Option<Image> {
- if buffer.is_empty() {
- return None;
- }
-
- let image_fmt_result = detect_image_format(buffer);
- match image_fmt_result {
- Err(msg) => {
- debug!("{}", msg);
- None
- },
- Ok(_) => match image::load_from_memory(buffer) {
- Ok(image) => {
- let mut rgba = image.into_rgba8();
- pixels::rgba8_byte_swap_colors_inplace(&mut rgba);
- Some(Image {
- width: rgba.width(),
- height: rgba.height(),
- format: PixelFormat::BGRA8,
- bytes: IpcSharedMemory::from_bytes(&rgba),
- id: None,
- cors_status,
- })
- },
- Err(e) => {
- debug!("Image decoding error: {:?}", e);
- None
- },
- },
- }
-}
-
-// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img
-pub fn detect_image_format(buffer: &[u8]) -> Result<ImageFormat, &str> {
- if is_gif(buffer) {
- Ok(ImageFormat::Gif)
- } else if is_jpeg(buffer) {
- Ok(ImageFormat::Jpeg)
- } else if is_png(buffer) {
- Ok(ImageFormat::Png)
- } else if is_webp(buffer) {
- Ok(ImageFormat::WebP)
- } else if is_bmp(buffer) {
- Ok(ImageFormat::Bmp)
- } else if is_ico(buffer) {
- Ok(ImageFormat::Ico)
- } else {
- Err("Image Format Not Supported")
- }
-}
-
-fn is_gif(buffer: &[u8]) -> bool {
- buffer.starts_with(b"GIF87a") || buffer.starts_with(b"GIF89a")
-}
-
-fn is_jpeg(buffer: &[u8]) -> bool {
- buffer.starts_with(&[0xff, 0xd8, 0xff])
-}
-
-fn is_png(buffer: &[u8]) -> bool {
- buffer.starts_with(&[0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])
-}
-
-fn is_bmp(buffer: &[u8]) -> bool {
- buffer.starts_with(&[0x42, 0x4D])
-}
-
-fn is_ico(buffer: &[u8]) -> bool {
- buffer.starts_with(&[0x00, 0x00, 0x01, 0x00])
-}
-
-fn is_webp(buffer: &[u8]) -> bool {
- buffer.starts_with(b"RIFF") && buffer.len() >= 14 && &buffer[8..14] == b"WEBPVP"
-}
diff --git a/components/shared/net/image_cache.rs b/components/shared/net/image_cache.rs
index d1087bace63..317fd1b66ef 100644
--- a/components/shared/net/image_cache.rs
+++ b/components/shared/net/image_cache.rs
@@ -7,12 +7,13 @@ use std::sync::Arc;
use ipc_channel::ipc::IpcSender;
use log::debug;
use malloc_size_of_derive::MallocSizeOf;
+use pixels::{Image, ImageMetadata};
use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl};
+use webrender_traits::WebRenderNetApi;
-use crate::image::base::{Image, ImageMetadata};
use crate::request::CorsSettings;
-use crate::{FetchResponseMsg, WebrenderIpcSender};
+use crate::FetchResponseMsg;
// ======================================================================
// Aux structs and enums.
@@ -98,7 +99,7 @@ pub enum ImageCacheResult {
}
pub trait ImageCache: Sync + Send {
- fn new(webrender_api: WebrenderIpcSender) -> Self
+ fn new(webrender_api: WebRenderNetApi) -> Self
where
Self: Sized;
@@ -140,14 +141,3 @@ pub trait ImageCache: Sync + Send {
/// Inform the image cache about a response for a pending request.
fn notify_pending_response(&self, id: PendingImageId, action: FetchResponseMsg);
}
-
-/// Whether this response passed any CORS checks, and is thus safe to read from
-/// in cross-origin environments.
-#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
-pub enum CorsStatus {
- /// The response is either same-origin or cross-origin but passed CORS checks.
- Safe,
- /// The response is cross-origin and did not pass CORS checks. It is unsafe
- /// to expose pixel data to the requesting environment.
- Unsafe,
-}
diff --git a/components/shared/net/lib.rs b/components/shared/net/lib.rs
index 436ccf5d645..595d47c7b06 100644
--- a/components/shared/net/lib.rs
+++ b/components/shared/net/lib.rs
@@ -16,7 +16,6 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use ipc_channel::Error as IpcError;
use lazy_static::lazy_static;
-use log::warn;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use mime::Mime;
@@ -25,7 +24,6 @@ use rustls::Certificate;
use serde::{Deserialize, Serialize};
use servo_rand::RngCore;
use servo_url::{ImmutableOrigin, ServoUrl};
-use webrender_api::{ImageData, ImageDescriptor, ImageKey};
use crate::filemanager_thread::FileManagerThreadMsg;
use crate::request::{Request, RequestBuilder};
@@ -41,15 +39,6 @@ pub mod request;
pub mod response;
pub mod storage_thread;
-/// Image handling.
-///
-/// It may be surprising that this goes in the network crate as opposed to the graphics crate.
-/// However, image handling is generally very integrated with the network stack (especially where
-/// caching is involved) and as a result it must live in here.
-pub mod image {
- pub mod base;
-}
-
/// An implementation of the [Fetch specification](https://fetch.spec.whatwg.org/)
pub mod fetch {
pub mod headers;
@@ -829,38 +818,6 @@ pub fn http_percent_encode(bytes: &[u8]) -> String {
percent_encoding::percent_encode(bytes, HTTP_VALUE).to_string()
}
-#[derive(Deserialize, Serialize)]
-pub enum NetToCompositorMsg {
- AddImage(ImageKey, ImageDescriptor, ImageData),
- GenerateImageKey(IpcSender<ImageKey>),
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-pub struct WebrenderIpcSender(IpcSender<NetToCompositorMsg>);
-
-impl WebrenderIpcSender {
- 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);
- }
- }
-}
-
lazy_static! {
pub static ref PRIVILEGED_SECRET: u32 = servo_rand::ServoRng::default().next_u32();
}
diff --git a/components/shared/net/tests/image.rs b/components/shared/net/tests/image.rs
deleted file mode 100644
index a4963702b57..00000000000
--- a/components/shared/net/tests/image.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-
-use net_traits::image::base::detect_image_format;
-
-#[test]
-fn test_supported_images() {
- let gif1 = [b'G', b'I', b'F', b'8', b'7', b'a'];
- let gif2 = [b'G', b'I', b'F', b'8', b'9', b'a'];
- let jpeg = [0xff, 0xd8, 0xff];
- let png = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
- let webp = [
- b'R', b'I', b'F', b'F', 0x01, 0x02, 0x03, 0x04, b'W', b'E', b'B', b'P', b'V', b'P',
- ];
- let bmp = [0x42, 0x4D];
- let ico = [0x00, 0x00, 0x01, 0x00];
- let junk_format = [0x01, 0x02, 0x03, 0x04, 0x05];
-
- assert!(detect_image_format(&gif1).is_ok());
- assert!(detect_image_format(&gif2).is_ok());
- assert!(detect_image_format(&jpeg).is_ok());
- assert!(detect_image_format(&png).is_ok());
- assert!(detect_image_format(&webp).is_ok());
- assert!(detect_image_format(&bmp).is_ok());
- assert!(detect_image_format(&ico).is_ok());
- assert!(detect_image_format(&junk_format).is_err());
-}
diff --git a/components/shared/script/Cargo.toml b/components/shared/script/Cargo.toml
index f95a0ffdcc9..6b3a2384d41 100644
--- a/components/shared/script/Cargo.toml
+++ b/components/shared/script/Cargo.toml
@@ -44,4 +44,5 @@ uuid = { workspace = true }
webdriver = { workspace = true }
webgpu = { path = "../../webgpu" }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] }
diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs
index 2f9822d2711..16f1e07710d 100644
--- a/components/shared/script/lib.rs
+++ b/components/shared/script/lib.rs
@@ -9,7 +9,6 @@
#![deny(missing_docs)]
#![deny(unsafe_code)]
-pub mod compositor;
mod script_msg;
pub mod serializable;
pub mod transferable;
@@ -29,14 +28,13 @@ use base::Epoch;
use bitflags::bitflags;
use bluetooth_traits::BluetoothRequest;
use canvas_traits::webgl::WebGLPipeline;
-use compositor::ScrollTreeNodeId;
use crossbeam_channel::{RecvTimeoutError, Sender};
use devtools_traits::{DevtoolScriptControlMsg, ScriptToDevtoolsControlMsg, WorkerId};
-use embedder_traits::{CompositorEventVariant, Cursor};
+use embedder_traits::CompositorEventVariant;
use euclid::default::Point2D;
use euclid::{Length, Rect, Scale, Size2D, UnknownUnit, Vector2D};
use http::{HeaderMap, Method};
-use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
+use ipc_channel::ipc::{IpcReceiver, IpcSender};
use ipc_channel::Error as IpcError;
use keyboard_types::webdriver::Event as WebDriverInputEvent;
use keyboard_types::{CompositionEvent, KeyboardEvent};
@@ -45,25 +43,21 @@ use log::warn;
use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf;
use media::WindowGLContext;
-use net_traits::image::base::Image;
use net_traits::image_cache::ImageCache;
use net_traits::request::{Referrer, RequestBody};
use net_traits::storage_thread::StorageType;
use net_traits::{FetchResponseMsg, ReferrerPolicy, ResourceThreads};
-use pixels::PixelFormat;
+use pixels::{Image, PixelFormat};
use profile_traits::{mem, time as profile_time};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use servo_atoms::Atom;
use servo_url::{ImmutableOrigin, ServoUrl};
use style_traits::{CSSPixel, SpeculativePainter};
use webgpu::WebGPUMsg;
-use webrender_api::units::{DeviceIntSize, DevicePixel, DevicePoint, LayoutPixel, LayoutPoint};
-use webrender_api::{
- BuiltDisplayList, BuiltDisplayListDescriptor, DocumentId, ExternalImageData, ExternalScrollId,
- HitTestFlags, ImageData, ImageDescriptor, ImageKey, PipelineId as WebRenderPipelineId,
-};
+use webrender_api::units::{DeviceIntSize, DevicePixel, LayoutPixel};
+use webrender_api::{DocumentId, ExternalScrollId, ImageKey};
+use webrender_traits::{UntrustedNodeAddress as WebRenderUntrustedNodeAddress, WebRenderScriptApi};
-use crate::compositor::CompositorDisplayListInfo;
pub use crate::script_msg::{
DOMMessage, EventResult, HistoryEntryReplacement, IFrameSizeMsg, Job, JobError, JobResult,
JobResultValue, JobType, LayoutMsg, LogEntry, SWManagerMsg, SWManagerSenders, ScopeThings,
@@ -83,6 +77,12 @@ malloc_size_of_is_0!(UntrustedNodeAddress);
#[allow(unsafe_code)]
unsafe impl Send for UntrustedNodeAddress {}
+impl From<WebRenderUntrustedNodeAddress> for UntrustedNodeAddress {
+ fn from(o: WebRenderUntrustedNodeAddress) -> Self {
+ UntrustedNodeAddress(o.0 as *const c_void)
+ }
+}
+
impl From<style_traits::dom::OpaqueNode> for UntrustedNodeAddress {
fn from(o: style_traits::dom::OpaqueNode) -> Self {
UntrustedNodeAddress(o.0 as *const c_void)
@@ -691,7 +691,7 @@ pub struct InitialScriptState {
/// 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: WebrenderIpcSender,
+ pub webrender_api_sender: WebRenderScriptApi,
/// Application window's GL Context for Media player
pub player_context: WindowGLContext,
}
@@ -1093,239 +1093,6 @@ impl From<i32> for MediaSessionActionType {
}
}
-/// The result of a hit test in the compositor.
-#[derive(Clone, Debug, Deserialize, Serialize)]
-pub struct CompositorHitTestResult {
- /// The pipeline id of the resulting item.
- pub pipeline_id: PipelineId,
-
- /// The hit test point in the item's viewport.
- pub point_in_viewport: euclid::default::Point2D<f32>,
-
- /// The hit test point relative to the item itself.
- pub point_relative_to_item: euclid::default::Point2D<f32>,
-
- /// The node address of the hit test result.
- pub node: UntrustedNodeAddress,
-
- /// The cursor that should be used when hovering the item hit by the hit test.
- pub cursor: Option<Cursor>,
-
- /// The scroll tree node associated with this hit test item.
- pub scroll_tree_node: ScrollTreeNodeId,
-}
-
-/// 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>),
-}
-
-#[derive(Clone, Deserialize, Serialize)]
-/// A mechanism to communicate with the parent process' WebRender instance.
-pub struct WebrenderIpcSender(IpcSender<ScriptToCompositorMsg>);
-
-impl WebrenderIpcSender {
- /// Create a new WebrenderIpcSender object that wraps the provided channel sender.
- pub fn new(sender: IpcSender<ScriptToCompositorMsg>) -> Self {
- Self(sender)
- }
-
- /// 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);
- }
- });
- }
-}
-
-#[derive(Deserialize, Serialize)]
-/// Serializable image updates that must be performed by WebRender.
-pub enum ImageUpdate {
- /// Register a new image.
- AddImage(ImageKey, ImageDescriptor, ImageData),
- /// 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),
-}
-
-#[derive(Debug, Deserialize, Serialize)]
-/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too
-/// slow.
-pub enum SerializedImageData {
- /// 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),
- /// 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)),
- }
- }
-}
-
#[derive(
Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize,
)]
diff --git a/components/shared/script/tests/compositor.rs b/components/shared/script/tests/compositor.rs
index 289f4ffebf1..ee3fd72ad49 100644
--- a/components/shared/script/tests/compositor.rs
+++ b/components/shared/script/tests/compositor.rs
@@ -3,11 +3,11 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use euclid::Size2D;
-use script_traits::compositor::{
- ScrollSensitivity, ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo,
-};
use webrender_api::units::LayoutVector2D;
use webrender_api::{ExternalScrollId, PipelineId, ScrollLocation, SpatialId};
+use webrender_traits::display_list::{
+ ScrollSensitivity, ScrollTree, ScrollTreeNodeId, ScrollableNodeInfo,
+};
fn add_mock_scroll_node(tree: &mut ScrollTree) -> ScrollTreeNodeId {
let pipeline_id = PipelineId(0, 0);
diff --git a/components/shared/script_layout/Cargo.toml b/components/shared/script_layout/Cargo.toml
index 57c4059b859..803a247bc2d 100644
--- a/components/shared/script_layout/Cargo.toml
+++ b/components/shared/script_layout/Cargo.toml
@@ -26,6 +26,7 @@ malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
metrics = { path = "../../metrics" }
net_traits = { workspace = true }
+pixels = { path = "../../pixels" }
profile_traits = { workspace = true }
range = { path = "../../range" }
script_traits = { workspace = true }
@@ -37,3 +38,4 @@ servo_url = { path = "../../url" }
style = { workspace = true }
style_traits = { workspace = true }
webrender_api = { workspace = true }
+webrender_traits = { workspace = true }
diff --git a/components/shared/script_layout/lib.rs b/components/shared/script_layout/lib.rs
index 7c1f4ee2162..d07a009af0e 100644
--- a/components/shared/script_layout/lib.rs
+++ b/components/shared/script_layout/lib.rs
@@ -33,7 +33,7 @@ use profile_traits::mem::Report;
use profile_traits::time;
use script_traits::{
ConstellationControlMsg, InitialScriptState, LayoutControlMsg, LayoutMsg, LoadData, Painter,
- ScrollState, UntrustedNodeAddress, WebrenderIpcSender, WindowSizeData,
+ ScrollState, UntrustedNodeAddress, WindowSizeData,
};
use serde::{Deserialize, Serialize};
use servo_arc::Arc as ServoArc;
@@ -51,6 +51,7 @@ use style::stylesheets::Stylesheet;
use style::Atom;
use style_traits::CSSPixel;
use webrender_api::ImageKey;
+use webrender_traits::WebRenderScriptApi;
pub type GenericLayoutData = dyn Any + Send + Sync;
@@ -165,7 +166,7 @@ pub struct LayoutConfig {
pub image_cache: Arc<dyn ImageCache>,
pub font_cache_thread: FontCacheThread,
pub time_profiler_chan: time::ProfilerChan,
- pub webrender_api_sender: WebrenderIpcSender,
+ pub webrender_api_sender: WebRenderScriptApi,
pub paint_time_metrics: PaintTimeMetrics,
pub window_size: WindowSizeData,
}
diff --git a/components/shared/script_layout/wrapper_traits.rs b/components/shared/script_layout/wrapper_traits.rs
index 0adb51be244..399c8bd3362 100644
--- a/components/shared/script_layout/wrapper_traits.rs
+++ b/components/shared/script_layout/wrapper_traits.rs
@@ -12,7 +12,7 @@ use atomic_refcell::AtomicRef;
use base::id::{BrowsingContextId, PipelineId};
use gfx_traits::ByteIndex;
use html5ever::{local_name, namespace_url, ns, LocalName, Namespace};
-use net_traits::image::base::{Image, ImageMetadata};
+use pixels::{Image, ImageMetadata};
use range::Range;
use servo_arc::Arc;
use servo_url::ServoUrl;
diff --git a/components/shared/webrender/Cargo.toml b/components/shared/webrender/Cargo.toml
index f078b96101d..158872b0494 100644
--- a/components/shared/webrender/Cargo.toml
+++ b/components/shared/webrender/Cargo.toml
@@ -11,5 +11,12 @@ name = "webrender_traits"
path = "lib.rs"
[dependencies]
+base = { workspace = true }
+crossbeam-channel = { workspace = true }
+embedder_traits = { workspace = true }
euclid = { workspace = true }
+ipc-channel = { workspace = true }
+log = { workspace = true }
+libc = { workspace = true }
webrender_api = { workspace = true }
+serde = { workspace = true }
diff --git a/components/shared/script/compositor.rs b/components/shared/webrender/display_list.rs
index e66c3bf8227..e66c3bf8227 100644
--- a/components/shared/script/compositor.rs
+++ b/components/shared/webrender/display_list.rs
diff --git a/components/shared/webrender/lib.rs b/components/shared/webrender/lib.rs
index 8af3a17b609..d4883d150e4 100644
--- a/components/shared/webrender/lib.rs
+++ b/components/shared/webrender/lib.rs
@@ -4,14 +4,26 @@
#![deny(unsafe_code)]
+pub mod display_list;
+
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;
-use webrender_api::units::TexelRect;
+use ipc_channel::ipc::{self, IpcBytesReceiver, IpcSender};
+use libc::c_void;
+use log::warn;
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+use webrender_api::units::{DevicePoint, LayoutPoint, TexelRect};
use webrender_api::{
- ExternalImage, ExternalImageHandler, ExternalImageId, ExternalImageSource, FontInstanceFlags,
- FontInstanceKey, FontKey, NativeFontHandle,
+ BuiltDisplayList, BuiltDisplayListDescriptor, ExternalImage, ExternalImageData,
+ ExternalImageHandler, ExternalImageId, ExternalImageSource, ExternalScrollId,
+ FontInstanceFlags, FontInstanceKey, FontKey, HitTestFlags, ImageData, ImageDescriptor,
+ ImageKey, NativeFontHandle, PipelineId as WebRenderPipelineId,
};
/// This trait is used as a bridge between the different GL clients
@@ -178,3 +190,309 @@ pub trait WebRenderFontApi {
fn add_font(&self, data: Arc<Vec<u8>>, index: u32) -> FontKey;
fn add_system_font(&self, handle: NativeFontHandle) -> FontKey;
}
+
+pub enum CanvasToCompositorMsg {
+ GenerateKey(Sender<ImageKey>),
+ UpdateImages(Vec<ImageUpdate>),
+}
+
+pub enum FontToCompositorMsg {
+ AddFontInstance(FontKey, f32, FontInstanceFlags, Sender<FontInstanceKey>),
+ AddFont(Sender<FontKey>, u32, IpcBytesReceiver),
+ AddSystemFont(Sender<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>),
+}
+
+/// 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 WebrenderIpcSender object that wraps the provided channel sender.
+ pub fn new(sender: IpcSender<ScriptToCompositorMsg>) -> Self {
+ Self(sender)
+ }
+
+ /// 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);
+ }
+ });
+ }
+}
+
+#[derive(Deserialize, Serialize)]
+/// Serializable image updates that must be performed by WebRender.
+pub enum ImageUpdate {
+ /// Register a new image.
+ AddImage(ImageKey, ImageDescriptor, ImageData),
+ /// 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),
+}
+
+#[derive(Debug, Deserialize, Serialize)]
+/// Serialized `ImageData`. It contains IPC byte channel receiver to prevent from loading bytes too
+/// slow.
+pub enum SerializedImageData {
+ /// 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),
+ /// 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)),
+ }
+ }
+}
+
+/// The address of a node. Layout sends these back. They must be validated via
+/// `from_untrusted_node_address` before they can be used, because we do not trust layout.
+#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
+pub struct UntrustedNodeAddress(pub *const c_void);
+
+#[allow(unsafe_code)]
+unsafe impl Send for UntrustedNodeAddress {}
+
+impl Serialize for UntrustedNodeAddress {
+ fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+ (self.0 as usize).serialize(s)
+ }
+}
+
+impl<'de> Deserialize<'de> for UntrustedNodeAddress {
+ fn deserialize<D: Deserializer<'de>>(d: D) -> Result<UntrustedNodeAddress, D::Error> {
+ let value: usize = Deserialize::deserialize(d)?;
+ Ok(UntrustedNodeAddress::from_id(value))
+ }
+}
+
+impl UntrustedNodeAddress {
+ /// Creates an `UntrustedNodeAddress` from the given pointer address value.
+ #[inline]
+ pub fn from_id(id: usize) -> UntrustedNodeAddress {
+ UntrustedNodeAddress(id as *const c_void)
+ }
+}
+
+/// The result of a hit test in the compositor.
+#[derive(Clone, Debug, Deserialize, Serialize)]
+pub struct CompositorHitTestResult {
+ /// The pipeline id of the resulting item.
+ pub pipeline_id: PipelineId,
+
+ /// The hit test point in the item's viewport.
+ pub point_in_viewport: euclid::default::Point2D<f32>,
+
+ /// The hit test point relative to the item itself.
+ pub point_relative_to_item: euclid::default::Point2D<f32>,
+
+ /// The node address of the hit test result.
+ pub node: UntrustedNodeAddress,
+
+ /// The cursor that should be used when hovering the item hit by the hit test.
+ pub cursor: Option<Cursor>,
+
+ /// The scroll tree node associated with this hit test item.
+ pub scroll_tree_node: ScrollTreeNodeId,
+}
diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py
index cf131f8b319..d6c4bea60e5 100644
--- a/python/servo/testing_commands.py
+++ b/python/servo/testing_commands.py
@@ -162,6 +162,7 @@ class MachCommands(CommandBase):
"constellation",
"style_config",
"compositing",
+ "pixels",
]
if not packages:
packages = set(os.listdir(path.join(self.context.topdir, "tests", "unit"))) - set(['.DS_Store'])