diff options
Diffstat (limited to 'components/script')
24 files changed, 218 insertions, 318 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 37e80d0e748..1aa821cdbd3 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -114,6 +114,7 @@ servo_config = { path = "../config" } servo_geometry = { path = "../geometry" } servo_rand = { path = "../rand" } servo_url = { path = "../url" } +snapshot = { workspace = true } smallvec = { workspace = true, features = ["union"] } strum = { workspace = true } strum_macros = { workspace = true } diff --git a/components/script/canvas_context.rs b/components/script/canvas_context.rs index 8bf188a5aa9..d49d31997e1 100644 --- a/components/script/canvas_context.rs +++ b/components/script/canvas_context.rs @@ -5,8 +5,8 @@ //! Common interfaces for Canvas Contexts use euclid::default::Size2D; -use ipc_channel::ipc::IpcSharedMemory; use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; +use snapshot::Snapshot; use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; use crate::dom::bindings::inheritance::Castable; @@ -30,11 +30,10 @@ pub(crate) trait CanvasContext { fn resize(&self); - fn get_image_data_as_shared_memory(&self) -> Option<IpcSharedMemory>; - - fn get_image_data(&self) -> Option<Vec<u8>> { - self.get_image_data_as_shared_memory().map(|sm| sm.to_vec()) - } + /// Returns none if area of canvas is zero. + /// + /// In case of other errors it returns cleared snapshot + fn get_image_data(&self) -> Option<Snapshot>; fn origin_is_clean(&self) -> bool { true diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index aea3012b365..408c94c124a 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -17,7 +17,7 @@ use cssparser::color::clamp_unit_f32; use cssparser::{Parser, ParserInput}; use euclid::default::{Point2D, Rect, Size2D, Transform2D}; use euclid::vec2; -use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory}; +use ipc_channel::ipc::{self, IpcSender}; use net_traits::image_cache::{ImageCache, ImageResponse}; use net_traits::request::CorsSettings; use pixels::PixelFormat; @@ -298,7 +298,7 @@ impl CanvasState { &self, url: ServoUrl, cors_setting: Option<CorsSettings>, - ) -> Option<(IpcSharedMemory, Size2D<u32>)> { + ) -> Option<snapshot::Snapshot> { let img = match self.request_image_from_cache(url, cors_setting) { ImageResponse::Loaded(img, _) => img, ImageResponse::PlaceholderLoaded(_, _) | @@ -308,13 +308,22 @@ impl CanvasState { }, }; - let image_size = Size2D::new(img.width, img.height); - let image_data = match img.format { - PixelFormat::BGRA8 => img.bytes(), + let size = Size2D::new(img.width, img.height); + let format = match img.format { + PixelFormat::BGRA8 => snapshot::PixelFormat::BGRA, + PixelFormat::RGBA8 => snapshot::PixelFormat::RGBA, pixel_format => unimplemented!("unsupported pixel format ({:?})", pixel_format), }; + let alpha_mode = snapshot::AlphaMode::Transparent { + premultiplied: false, + }; - Some((image_data, image_size)) + Some(snapshot::Snapshot::from_shared_memory( + size.cast(), + format, + alpha_mode, + img.bytes(), + )) } fn request_image_from_cache( @@ -341,13 +350,16 @@ impl CanvasState { assert!(Rect::from_size(canvas_size).contains_rect(&rect)); - let (sender, receiver) = ipc::bytes_channel().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); self.send_canvas_2d_msg(Canvas2dMsg::GetImageData(rect, canvas_size, sender)); - let mut pixels = receiver.recv().unwrap().to_vec(); - - pixels::unmultiply_inplace::<true>(&mut pixels); - - pixels + let mut snapshot = receiver.recv().unwrap().to_owned(); + snapshot.transform( + snapshot::AlphaMode::Transparent { + premultiplied: false, + }, + snapshot::PixelFormat::RGBA, + ); + snapshot.to_vec() } /// @@ -594,10 +606,10 @@ impl CanvasState { dh: Option<f64>, ) -> ErrorResult { debug!("Fetching image {}.", url); - let (image_data, image_size) = self + let snapshot = self .fetch_image_data(url, cors_setting) .ok_or(Error::InvalidState)?; - let image_size = image_size.to_f64(); + let image_size = snapshot.size().to_f64(); let dw = dw.unwrap_or(image_size.width); let dh = dh.unwrap_or(image_size.height); @@ -614,8 +626,7 @@ impl CanvasState { let smoothing_enabled = self.state.borrow().image_smoothing_enabled; self.send_canvas_2d_msg(Canvas2dMsg::DrawImage( - image_data, - image_size, + snapshot.as_ipc(), dest_rect, source_rect, smoothing_enabled, @@ -929,7 +940,7 @@ impl CanvasState { mut repetition: DOMString, can_gc: CanGc, ) -> Fallible<Option<DomRoot<CanvasPattern>>> { - let (image_data, image_size) = match image { + let snapshot = match image { CanvasImageSource::HTMLImageElement(ref image) => { // https://html.spec.whatwg.org/multipage/#check-the-usability-of-the-image-argument if !image.is_usable()? { @@ -941,27 +952,17 @@ impl CanvasState { .and_then(|url| { self.fetch_image_data(url, cors_setting_for_element(image.upcast())) }) - .map(|data| (data.0.to_vec(), data.1)) .ok_or(Error::InvalidState)? }, CanvasImageSource::HTMLCanvasElement(ref canvas) => { - let (data, size) = canvas.fetch_all_data().ok_or(Error::InvalidState)?; - let data = data - .map(|data| data.to_vec()) - .unwrap_or_else(|| vec![0; size.area() as usize * 4]); - (data, size) + canvas.get_image_data().ok_or(Error::InvalidState)? }, CanvasImageSource::OffscreenCanvas(ref canvas) => { - let (data, size) = canvas.fetch_all_data().ok_or(Error::InvalidState)?; - let data = data - .map(|data| data.to_vec()) - .unwrap_or_else(|| vec![0; size.area() as usize * 4]); - (data, size) + canvas.get_image_data().ok_or(Error::InvalidState)? }, CanvasImageSource::CSSStyleValue(ref value) => value .get_url(self.base_url.clone()) .and_then(|url| self.fetch_image_data(url, None)) - .map(|data| (data.0.to_vec(), data.1)) .ok_or(Error::InvalidState)?, }; @@ -970,10 +971,11 @@ impl CanvasState { } if let Ok(rep) = RepetitionStyle::from_str(&repetition) { + let size = snapshot.size(); Ok(Some(CanvasPattern::new( global, - image_data, - image_size, + snapshot.to_vec(), + size.cast(), rep, self.is_origin_clean(image), can_gc, diff --git a/components/script/dom/bindings/serializable.rs b/components/script/dom/bindings/serializable.rs index b791b0ebc1a..4aa1a94a0a4 100644 --- a/components/script/dom/bindings/serializable.rs +++ b/components/script/dom/bindings/serializable.rs @@ -6,9 +6,8 @@ //! (<https://html.spec.whatwg.org/multipage/#serializable-objects>). use std::collections::HashMap; -use std::num::NonZeroU32; -use base::id::PipelineNamespaceId; +use base::id::{Index, NamespaceIndex, PipelineNamespaceId}; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; @@ -25,9 +24,9 @@ pub(crate) struct StorageKey { } impl StorageKey { - pub(crate) fn new(name_space: PipelineNamespaceId, index: NonZeroU32) -> StorageKey { - let name_space = name_space.0.to_ne_bytes(); - let index = index.get().to_ne_bytes(); + pub(crate) fn new<T>(index: NamespaceIndex<T>) -> StorageKey { + let name_space = index.namespace_id.0.to_ne_bytes(); + let index = index.index.0.get().to_ne_bytes(); StorageKey { index: u32::from_ne_bytes(index), name_space: u32::from_ne_bytes(name_space), @@ -35,11 +34,13 @@ impl StorageKey { } } -pub(crate) trait IntoStorageKey -where - Self: Sized, -{ - fn into_storage_key(self) -> StorageKey; +impl<T> From<StorageKey> for NamespaceIndex<T> { + fn from(key: StorageKey) -> NamespaceIndex<T> { + NamespaceIndex { + namespace_id: PipelineNamespaceId(key.name_space), + index: Index::new(key.index).expect("Index must not be zero"), + } + } } /// Interface for serializable platform objects. @@ -48,11 +49,11 @@ pub(crate) trait Serializable: DomObject where Self: Sized, { - type Id: Copy + Eq + std::hash::Hash + IntoStorageKey + From<StorageKey>; + type Index: Copy + Eq + std::hash::Hash; type Data; /// <https://html.spec.whatwg.org/multipage/#serialization-steps> - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()>; + fn serialize(&self) -> Result<(NamespaceIndex<Self::Index>, Self::Data), ()>; /// <https://html.spec.whatwg.org/multipage/#deserialization-steps> fn deserialize( owner: &GlobalScope, @@ -64,7 +65,9 @@ where /// Returns the field of [StructuredDataReader]/[StructuredDataWriter] that /// should be used to read/store serialized instances of this type. - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>>; + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>; /// Returns the field of [StructuredDataReader] that should be used to store /// deserialized instances of this type. diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index ebd881a04f5..915a4951bb5 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -6,11 +6,12 @@ use std::collections::HashMap; use std::ffi::CStr; -use std::num::NonZeroU32; use std::os::raw; use std::ptr; -use base::id::{BlobId, DomExceptionId, DomPointId, MessagePortId, PipelineNamespaceId}; +use base::id::{ + BlobId, DomExceptionId, DomPointId, Index, MessagePortId, NamespaceIndex, PipelineNamespaceId, +}; use constellation_traits::{ BlobImpl, DomException, DomPoint, MessagePortImpl, Serializable as SerializableInterface, StructuredSerializedData, Transferrable as TransferrableInterface, @@ -34,8 +35,8 @@ use strum::IntoEnumIterator; use crate::dom::bindings::conversions::{ToJSValConvertible, root_from_object}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; -use crate::dom::bindings::transferable::{ExtractComponents, IdFromComponents, Transferable}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; +use crate::dom::bindings::transferable::Transferable; use crate::dom::blob::Blob; use crate::dom::dompoint::DOMPoint; use crate::dom::dompointreadonly::DOMPointReadOnly; @@ -120,7 +121,7 @@ unsafe fn read_object<T: Serializable>( // 1. Re-build the key for the storage location // of the serialized object. - let id = T::Id::from(storage_key); + let id: NamespaceIndex<T::Index> = storage_key.into(); // 2. Get the transferred object from its storage, using the key. let objects = T::serialized_storage(StructuredData::Reader(sc_reader)); @@ -155,7 +156,7 @@ unsafe fn write_object<T: Serializable>( let objects = T::serialized_storage(StructuredData::Writer(sc_writer)) .get_or_insert_with(HashMap::new); objects.insert(new_id, serialized); - let storage_key = new_id.into_storage_key(); + let storage_key = StorageKey::new(new_id); assert!(JS_WriteUint32Pair( w, @@ -282,13 +283,13 @@ fn receive_object<T: Transferable>( .try_into() .expect("name_space to be a slice of four."), )); - let id = <T::Id as IdFromComponents>::from( + let id: NamespaceIndex<T::Index> = NamespaceIndex { namespace_id, - NonZeroU32::new(u32::from_ne_bytes( + index: Index::new(u32::from_ne_bytes( index.try_into().expect("index to be a slice of four."), )) .expect("Index to be non-zero"), - ); + }; // 2. Get the transferred object from its storage, using the key. let storage = T::serialized_storage(StructuredData::Reader(sc_reader)); @@ -356,11 +357,10 @@ unsafe fn try_transfer<T: Transferable + IDLInterface>( .get_or_insert_with(HashMap::new); objects.insert(id, object); - let (PipelineNamespaceId(name_space), index) = id.components(); - let index = index.get(); + let index = id.index.0.get(); let mut big: [u8; 8] = [0; 8]; - let name_space = name_space.to_ne_bytes(); + let name_space = id.namespace_id.0.to_ne_bytes(); let index = index.to_ne_bytes(); let (left, right) = big.split_at_mut(4); diff --git a/components/script/dom/bindings/transferable.rs b/components/script/dom/bindings/transferable.rs index 7c052e41294..b720c05ae37 100644 --- a/components/script/dom/bindings/transferable.rs +++ b/components/script/dom/bindings/transferable.rs @@ -6,44 +6,34 @@ //! (<https://html.spec.whatwg.org/multipage/#transferable-objects>). use std::collections::HashMap; -use std::num::NonZeroU32; +use std::hash::Hash; -use base::id::PipelineNamespaceId; +use base::id::NamespaceIndex; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; - -pub(crate) trait IdFromComponents -where - Self: Sized, -{ - fn from(namespace_id: PipelineNamespaceId, index: NonZeroU32) -> Self; -} - -pub(crate) trait ExtractComponents { - fn components(&self) -> (PipelineNamespaceId, NonZeroU32); -} - pub(crate) trait Transferable: DomObject where Self: Sized, { - type Id: Eq + std::hash::Hash + Copy + IdFromComponents + ExtractComponents; + type Index: Copy + Eq + Hash; type Data; fn can_transfer(&self) -> bool { true } - fn transfer(&self) -> Result<(Self::Id, Self::Data), ()>; + fn transfer(&self) -> Result<(NamespaceIndex<Self::Index>, Self::Data), ()>; fn transfer_receive( owner: &GlobalScope, - id: Self::Id, + id: NamespaceIndex<Self::Index>, serialized: Self::Data, ) -> Result<DomRoot<Self>, ()>; - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>>; + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>; fn deserialized_storage(reader: &mut StructuredDataReader) -> &mut Option<Vec<DomRoot<Self>>>; } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 5f9d4052929..df2afafd698 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -3,11 +3,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::collections::HashMap; -use std::num::NonZeroU32; use std::ptr; use std::rc::Rc; -use base::id::{BlobId, BlobIndex, PipelineNamespaceId}; +use base::id::{BlobId, BlobIndex}; use constellation_traits::BlobImpl; use dom_struct::dom_struct; use encoding_rs::UTF_8; @@ -25,7 +24,7 @@ use crate::dom::bindings::codegen::UnionTypes::ArrayBufferOrArrayBufferViewOrBlo use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; @@ -94,7 +93,7 @@ impl Blob { } impl Serializable for Blob { - type Id = BlobId; + type Index = BlobIndex; type Data = BlobImpl; /// <https://w3c.github.io/FileAPI/#ref-for-serialization-steps> @@ -120,9 +119,7 @@ impl Serializable for Blob { Ok(deserialized_blob) } - fn serialized_storage( - reader: StructuredData<'_>, - ) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage(reader: StructuredData<'_>) -> &mut Option<HashMap<BlobId, Self::Data>> { match reader { StructuredData::Reader(r) => &mut r.blob_impls, StructuredData::Writer(w) => &mut w.blobs, @@ -136,26 +133,6 @@ impl Serializable for Blob { } } -impl From<StorageKey> for BlobId { - fn from(storage_key: StorageKey) -> BlobId { - let namespace_id = PipelineNamespaceId(storage_key.name_space); - let index = - BlobIndex(NonZeroU32::new(storage_key.index).expect("Deserialized blob index is zero")); - - BlobId { - namespace_id, - index, - } - } -} - -impl IntoStorageKey for BlobId { - fn into_storage_key(self) -> StorageKey { - let BlobIndex(index) = self.index; - StorageKey::new(self.namespace_id, index) - } -} - /// Extract bytes from BlobParts, used by Blob and File constructor /// <https://w3c.github.io/FileAPI/#constructorBlob> #[allow(unsafe_code)] diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index f6bf432de69..73052e6906e 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -5,11 +5,11 @@ use canvas_traits::canvas::{Canvas2dMsg, CanvasId, CanvasMsg, FromScriptMsg}; use dom_struct::dom_struct; use euclid::default::{Point2D, Rect, Size2D}; -use ipc_channel::ipc::IpcSharedMemory; use profile_traits::ipc; use script_bindings::inheritance::Castable; use script_layout_interface::HTMLCanvasDataSource; use servo_url::ServoUrl; +use snapshot::Snapshot; use crate::canvas_context::{CanvasContext, CanvasHelpers, LayoutCanvasRenderingContextHelpers}; use crate::canvas_state::CanvasState; @@ -142,16 +142,18 @@ impl CanvasContext for CanvasRenderingContext2D { self.set_bitmap_dimensions(self.size().cast()) } - fn get_image_data_as_shared_memory(&self) -> Option<IpcSharedMemory> { + fn get_image_data(&self) -> Option<Snapshot> { + let size = self.size(); + + if size.is_empty() { + return None; + } + let (sender, receiver) = ipc::channel(self.global().time_profiler_chan().clone()).unwrap(); let msg = CanvasMsg::FromScript(FromScriptMsg::SendPixels(sender), self.get_canvas_id()); self.canvas_state.get_ipc_renderer().send(msg).unwrap(); - Some(receiver.recv().unwrap()) - } - - fn get_image_data(&self) -> Option<Vec<u8>> { - Some(self.get_rect(Rect::from_size(self.size().cast()))) + Some(receiver.recv().unwrap().to_owned()) } fn origin_is_clean(&self) -> bool { diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs index 35a21556a2d..e63c3ff1f53 100644 --- a/components/script/dom/domexception.rs +++ b/components/script/dom/domexception.rs @@ -3,9 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::collections::HashMap; -use std::num::NonZeroU32; -use base::id::{DomExceptionId, DomExceptionIndex, PipelineNamespaceId}; +use base::id::{DomExceptionId, DomExceptionIndex}; use constellation_traits::DomException; use dom_struct::dom_struct; use js::rust::HandleObject; @@ -18,7 +17,7 @@ use crate::dom::bindings::reflector::{ Reflector, reflect_dom_object, reflect_dom_object_with_proto, }; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; @@ -224,11 +223,11 @@ impl DOMExceptionMethods<crate::DomTypeHolder> for DOMException { } impl Serializable for DOMException { - type Id = DomExceptionId; + type Index = DomExceptionIndex; type Data = DomException; // https://webidl.spec.whatwg.org/#idl-DOMException - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()> { + fn serialize(&self) -> Result<(DomExceptionId, Self::Data), ()> { let serialized = DomException { message: self.message.to_string(), name: self.name.to_string(), @@ -253,7 +252,9 @@ impl Serializable for DOMException { )) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<DomExceptionId, Self::Data>> { match data { StructuredData::Reader(reader) => &mut reader.exceptions, StructuredData::Writer(writer) => &mut writer.exceptions, @@ -266,24 +267,3 @@ impl Serializable for DOMException { &mut reader.dom_exceptions } } - -impl From<StorageKey> for DomExceptionId { - fn from(storage_key: StorageKey) -> DomExceptionId { - let namespace_id = PipelineNamespaceId(storage_key.name_space); - let index = DomExceptionIndex( - NonZeroU32::new(storage_key.index).expect("Deserialized exception index is zero"), - ); - - DomExceptionId { - namespace_id, - index, - } - } -} - -impl IntoStorageKey for DomExceptionId { - fn into_storage_key(self) -> StorageKey { - let DomExceptionIndex(index) = self.index; - StorageKey::new(self.namespace_id, index) - } -} diff --git a/components/script/dom/dompoint.rs b/components/script/dom/dompoint.rs index c6323b28cf7..006abb50def 100644 --- a/components/script/dom/dompoint.rs +++ b/components/script/dom/dompoint.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; -use base::id::DomPointId; +use base::id::{DomPointId, DomPointIndex}; use constellation_traits::DomPoint; use dom_struct::dom_struct; use js::rust::HandleObject; @@ -132,10 +132,10 @@ impl DOMPointMethods<crate::DomTypeHolder> for DOMPoint { } impl Serializable for DOMPoint { - type Id = DomPointId; + type Index = DomPointIndex; type Data = DomPoint; - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()> { + fn serialize(&self) -> Result<(DomPointId, Self::Data), ()> { let serialized = DomPoint { x: self.X(), y: self.Y(), @@ -163,7 +163,9 @@ impl Serializable for DOMPoint { )) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<DomPointId, Self::Data>> { match data { StructuredData::Reader(reader) => &mut reader.points, StructuredData::Writer(writer) => &mut writer.points, diff --git a/components/script/dom/dompointreadonly.rs b/components/script/dom/dompointreadonly.rs index 0bd6d5742c7..44e4a70b680 100644 --- a/components/script/dom/dompointreadonly.rs +++ b/components/script/dom/dompointreadonly.rs @@ -4,9 +4,8 @@ use std::cell::Cell; use std::collections::HashMap; -use std::num::NonZeroU32; -use base::id::{DomPointId, DomPointIndex, PipelineNamespaceId}; +use base::id::{DomPointId, DomPointIndex}; use constellation_traits::DomPoint; use dom_struct::dom_struct; use js::rust::HandleObject; @@ -16,7 +15,7 @@ use crate::dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::DOMPointRe use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::CanGc; @@ -142,10 +141,10 @@ impl DOMPointWriteMethods for DOMPointReadOnly { } impl Serializable for DOMPointReadOnly { - type Id = DomPointId; + type Index = DomPointIndex; type Data = DomPoint; - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()> { + fn serialize(&self) -> Result<(DomPointId, Self::Data), ()> { let serialized = DomPoint { x: self.x.get(), y: self.y.get(), @@ -173,7 +172,9 @@ impl Serializable for DOMPointReadOnly { )) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<DomPointId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.points, StructuredData::Writer(w) => &mut w.points, @@ -186,24 +187,3 @@ impl Serializable for DOMPointReadOnly { &mut reader.points_read_only } } - -impl From<StorageKey> for DomPointId { - fn from(storage_key: StorageKey) -> DomPointId { - let namespace_id = PipelineNamespaceId(storage_key.name_space); - let index = DomPointIndex( - NonZeroU32::new(storage_key.index).expect("Deserialized point index is zero"), - ); - - DomPointId { - namespace_id, - index, - } - } -} - -impl IntoStorageKey for DomPointId { - fn into_storage_key(self) -> StorageKey { - let DomPointIndex(index) = self.index; - StorageKey::new(self.namespace_id, index) - } -} diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 2658911c795..77d1ee37c03 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2880,15 +2880,11 @@ impl GlobalScope { return p; } - if let Some((data, size)) = canvas.fetch_all_data() { - let data = data - .map(|data| data.to_vec()) - .unwrap_or_else(|| vec![0; size.area() as usize * 4]); - + if let Some(snapshot) = canvas.get_image_data() { + let size = snapshot.size().cast(); let image_bitmap = ImageBitmap::new(self, size.width, size.height, can_gc).unwrap(); - - image_bitmap.set_bitmap_data(data); + image_bitmap.set_bitmap_data(snapshot.to_vec()); image_bitmap.set_origin_clean(canvas.origin_is_clean()); p.resolve_native(&(image_bitmap), can_gc); } @@ -2901,14 +2897,11 @@ impl GlobalScope { return p; } - if let Some((data, size)) = canvas.fetch_all_data() { - let data = data - .map(|data| data.to_vec()) - .unwrap_or_else(|| vec![0; size.area() as usize * 4]); - + if let Some(snapshot) = canvas.get_image_data() { + let size = snapshot.size().cast(); let image_bitmap = ImageBitmap::new(self, size.width, size.height, can_gc).unwrap(); - image_bitmap.set_bitmap_data(data); + image_bitmap.set_bitmap_data(snapshot.to_vec()); image_bitmap.set_origin_clean(canvas.origin_is_clean()); p.resolve_native(&(image_bitmap), can_gc); } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 9e20539ceca..303c781c8b3 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -17,7 +17,6 @@ use image::codecs::jpeg::JpegEncoder; use image::codecs::png::PngEncoder; use image::codecs::webp::WebPEncoder; use image::{ColorType, ImageEncoder}; -use ipc_channel::ipc::IpcSharedMemory; #[cfg(feature = "webgpu")] use ipc_channel::ipc::{self as ipcchan}; use js::error::throw_type_error; @@ -25,6 +24,7 @@ use js::rust::{HandleObject, HandleValue}; use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource}; use servo_media::streams::MediaStreamType; use servo_media::streams::registry::MediaStreamId; +use snapshot::Snapshot; use style::attr::AttrValue; use crate::canvas_context::CanvasContext as _; @@ -69,6 +69,7 @@ use crate::script_runtime::{CanGc, JSContext}; const DEFAULT_WIDTH: u32 = 300; const DEFAULT_HEIGHT: u32 = 150; +#[derive(PartialEq)] enum EncodedImageType { Png, Jpeg, @@ -375,42 +376,21 @@ impl HTMLCanvasElement { self.Height() != 0 && self.Width() != 0 } - pub(crate) fn fetch_all_data(&self) -> Option<(Option<IpcSharedMemory>, Size2D<u32>)> { - let size = self.get_size(); - - if size.width == 0 || size.height == 0 { - return None; - } - - let data = match self.context.borrow().as_ref() { - Some(CanvasContext::Context2d(context)) => context.get_image_data_as_shared_memory(), - Some(CanvasContext::WebGL(_context)) => { - // TODO: add a method in WebGLRenderingContext to get the pixels. - return None; - }, - Some(CanvasContext::WebGL2(_context)) => { - // TODO: add a method in WebGL2RenderingContext to get the pixels. - return None; - }, - #[cfg(feature = "webgpu")] - Some(CanvasContext::WebGPU(context)) => context.get_image_data_as_shared_memory(), - Some(CanvasContext::Placeholder(context)) => return context.fetch_all_data(), - None => None, - }; - - Some((data, size)) - } - - fn get_content(&self) -> Option<Vec<u8>> { - match *self.context.borrow() { - Some(CanvasContext::Context2d(ref context)) => context.get_image_data(), - Some(CanvasContext::WebGL(ref context)) => context.get_image_data(), - Some(CanvasContext::WebGL2(ref context)) => context.get_image_data(), + pub(crate) fn get_image_data(&self) -> Option<Snapshot> { + match self.context.borrow().as_ref() { + Some(CanvasContext::Context2d(context)) => context.get_image_data(), + Some(CanvasContext::WebGL(context)) => context.get_image_data(), + Some(CanvasContext::WebGL2(context)) => context.get_image_data(), #[cfg(feature = "webgpu")] - Some(CanvasContext::WebGPU(ref context)) => context.get_image_data(), - Some(CanvasContext::Placeholder(_)) | None => { - // Each pixel is fully-transparent black. - Some(vec![0; (self.Width() * self.Height() * 4) as usize]) + Some(CanvasContext::WebGPU(context)) => context.get_image_data(), + Some(CanvasContext::Placeholder(context)) => context.get_image_data(), + None => { + let size = self.get_size(); + if size.width == 0 || size.height == 0 { + None + } else { + Some(Snapshot::cleared(size.cast())) + } }, } } @@ -560,11 +540,23 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { } // Step 3. - let Some(file) = self.get_content() else { + let Some(mut snapshot) = self.get_image_data() else { return Ok(USVString("data:,".into())); }; let image_type = EncodedImageType::from(mime_type); + snapshot.transform( + if image_type == EncodedImageType::Jpeg { + snapshot::AlphaMode::AsOpaque { + premultiplied: true, + } + } else { + snapshot::AlphaMode::Transparent { + premultiplied: false, + } + }, + snapshot::PixelFormat::RGBA, + ); let mut url = format!("data:{};base64,", image_type.as_mime_type()); let mut encoder = base64::write::EncoderStringWriter::from_consumer( @@ -575,7 +567,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { self.encode_for_mime_type( &image_type, Self::maybe_quality(quality), - &file, + snapshot.data(), &mut encoder, ); encoder.into_inner(); @@ -604,7 +596,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { let result = if self.Width() == 0 || self.Height() == 0 { None } else { - self.get_content() + self.get_image_data() }; let this = Trusted::new(self); @@ -625,13 +617,17 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement { return error!("Expected blob callback, but found none!"); }; - if let Some(bytes) = result { + if let Some(mut snapshot) = result { + snapshot.transform( + snapshot::AlphaMode::Transparent{ premultiplied: false }, + snapshot::PixelFormat::RGBA + ); // Step 4.1 // If result is non-null, then set result to a serialization of result as a file with // type and quality if given. let mut encoded: Vec<u8> = vec![]; - this.encode_for_mime_type(&image_type, quality, &bytes, &mut encoded); + this.encode_for_mime_type(&image_type, quality, snapshot.data(), &mut encoded); let blob_impl = BlobImpl::new_from_bytes(encoded, image_type.as_mime_type()); // Step 4.2.1 & 4.2.2 // Set result to a new Blob object, created in the relevant realm of this canvas element diff --git a/components/script/dom/messageport.rs b/components/script/dom/messageport.rs index c3904dbb19a..fe590052db4 100644 --- a/components/script/dom/messageport.rs +++ b/components/script/dom/messageport.rs @@ -4,11 +4,10 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; -use std::num::NonZeroU32; use std::ptr; use std::rc::Rc; -use base::id::{MessagePortId, MessagePortIndex, PipelineNamespaceId}; +use base::id::{MessagePortId, MessagePortIndex}; use constellation_traits::{MessagePortImpl, PortMessageTask}; use dom_struct::dom_struct; use js::jsapi::{Heap, JS_NewObject, JSObject}; @@ -26,7 +25,7 @@ use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::structuredclone::{self, StructuredData, StructuredDataReader}; use crate::dom::bindings::trace::RootedTraceableBox; -use crate::dom::bindings::transferable::{ExtractComponents, IdFromComponents, Transferable}; +use crate::dom::bindings::transferable::Transferable; use crate::dom::bindings::utils::set_dictionary_property; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; @@ -239,7 +238,7 @@ impl MessagePort { } impl Transferable for MessagePort { - type Id = MessagePortId; + type Index = MessagePortIndex; type Data = MessagePortImpl; /// <https://html.spec.whatwg.org/multipage/#message-ports:transfer-steps> @@ -269,7 +268,9 @@ impl Transferable for MessagePort { Ok(transferred_port) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<MessagePortId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.port_impls, StructuredData::Writer(w) => &mut w.ports, @@ -281,21 +282,6 @@ impl Transferable for MessagePort { } } -impl IdFromComponents for MessagePortId { - fn from(namespace_id: PipelineNamespaceId, index: NonZeroU32) -> MessagePortId { - MessagePortId { - namespace_id, - index: MessagePortIndex(index), - } - } -} - -impl ExtractComponents for MessagePortId { - fn components(&self) -> (PipelineNamespaceId, NonZeroU32) { - (self.namespace_id, self.index.0) - } -} - impl MessagePortMethods<crate::DomTypeHolder> for MessagePort { /// <https://html.spec.whatwg.org/multipage/#dom-messageport-postmessage> fn PostMessage( diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs index 0587fbad12b..aabe5955e12 100644 --- a/components/script/dom/offscreencanvas.rs +++ b/components/script/dom/offscreencanvas.rs @@ -6,8 +6,8 @@ use std::cell::Cell; use dom_struct::dom_struct; use euclid::default::Size2D; -use ipc_channel::ipc::IpcSharedMemory; use js::rust::{HandleObject, HandleValue}; +use snapshot::Snapshot; use crate::dom::bindings::cell::{DomRefCell, Ref, ref_filter_map}; use crate::dom::bindings::codegen::Bindings::OffscreenCanvasBinding::{ @@ -88,21 +88,18 @@ impl OffscreenCanvas { ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) } - pub(crate) fn fetch_all_data(&self) -> Option<(Option<IpcSharedMemory>, Size2D<u32>)> { - let size = self.get_size(); - - if size.width == 0 || size.height == 0 { - return None; - } - - let data = match self.context.borrow().as_ref() { - Some(OffscreenCanvasContext::OffscreenContext2d(context)) => { - context.get_image_data_as_shared_memory() + pub(crate) fn get_image_data(&self) -> Option<Snapshot> { + match self.context.borrow().as_ref() { + Some(OffscreenCanvasContext::OffscreenContext2d(context)) => context.get_image_data(), + None => { + let size = self.get_size(); + if size.width == 0 || size.height == 0 { + None + } else { + Some(Snapshot::cleared(size)) + } }, - None => None, - }; - - Some((data, size.to_u32())) + } } pub(crate) fn get_or_init_2d_context( diff --git a/components/script/dom/offscreencanvasrenderingcontext2d.rs b/components/script/dom/offscreencanvasrenderingcontext2d.rs index 69a1d41af2e..2f9b52640e6 100644 --- a/components/script/dom/offscreencanvasrenderingcontext2d.rs +++ b/components/script/dom/offscreencanvasrenderingcontext2d.rs @@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanva use canvas_traits::canvas::Canvas2dMsg; use dom_struct::dom_struct; use euclid::default::Size2D; -use ipc_channel::ipc::IpcSharedMemory; +use snapshot::Snapshot; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{ CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin, @@ -76,8 +76,8 @@ impl OffscreenCanvasRenderingContext2D { self.context.origin_is_clean() } - pub(crate) fn get_image_data_as_shared_memory(&self) -> Option<IpcSharedMemory> { - self.context.get_image_data_as_shared_memory() + pub(crate) fn get_image_data(&self) -> Option<Snapshot> { + self.context.get_image_data() } } diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index 49e740c6d6e..b445fb4b9fc 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -8,6 +8,8 @@ use std::ptr::{self}; use std::rc::Rc; use std::collections::HashMap; +use base::id::{MessagePortId, MessagePortIndex}; +use constellation_traits::MessagePortImpl; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; use js::jsapi::{Heap, JSObject}; @@ -56,8 +58,6 @@ use crate::js::conversions::FromJSValConvertible; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::{CanGc, JSContext as SafeJSContext}; use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler}; -use base::id::MessagePortId; -use constellation_traits::MessagePortImpl; use crate::dom::bindings::transferable::Transferable; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; @@ -2179,7 +2179,7 @@ pub(crate) fn get_read_promise_bytes( /// <https://streams.spec.whatwg.org/#rs-transfer> impl Transferable for ReadableStream { - type Id = MessagePortId; + type Index = MessagePortIndex; type Data = MessagePortImpl; /// <https://streams.spec.whatwg.org/#ref-for-readablestream%E2%91%A1%E2%91%A0> @@ -2247,7 +2247,9 @@ impl Transferable for ReadableStream { } /// Note: we are relying on the port transfer, so the data returned here are related to the port. - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<MessagePortId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.port_impls, StructuredData::Writer(w) => &mut w.ports, diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index bb6ffa11849..416454d8719 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -24,6 +24,7 @@ use js::typedarray::{ArrayBufferView, CreateWith, Float32, Int32Array, Uint32, U use script_bindings::interfaces::WebGL2RenderingContextHelpers; use script_layout_interface::HTMLCanvasDataSource; use servo_config::pref; +use snapshot::Snapshot; use url::Host; use crate::canvas_context::CanvasContext; @@ -549,11 +550,11 @@ impl WebGL2RenderingContext { return ); - let (sender, receiver) = ipc::bytes_channel().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); self.base.send_command(WebGLCommand::ReadPixels( src_rect, format, pixel_type, sender, )); - let src = receiver.recv().unwrap(); + let (src, _) = receiver.recv().unwrap(); for i in 0..src_rect.size.height as usize { let src_start = i * src_row_bytes as usize; @@ -916,11 +917,7 @@ impl CanvasContext for WebGL2RenderingContext { self.base.resize(); } - fn get_image_data_as_shared_memory(&self) -> Option<IpcSharedMemory> { - self.base.get_image_data_as_shared_memory() - } - - fn get_image_data(&self) -> Option<Vec<u8>> { + fn get_image_data(&self) -> Option<Snapshot> { self.base.get_image_data() } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 1e51ac4baf9..9996a3cf504 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -34,6 +34,7 @@ use pixels::{self, PixelFormat}; use script_layout_interface::HTMLCanvasDataSource; use serde::{Deserialize, Serialize}; use servo_config::pref; +use snapshot::Snapshot; use webrender_api::ImageKey; use crate::canvas_context::CanvasContext; @@ -628,11 +629,15 @@ impl WebGLRenderingContext { if !canvas.origin_is_clean() { return Err(Error::Security); } - if let Some((data, size)) = canvas.fetch_all_data() { - let data = data.unwrap_or_else(|| { - IpcSharedMemory::from_bytes(&vec![0; size.area() as usize * 4]) - }); - TexPixels::new(data, size, PixelFormat::BGRA8, true) + if let Some(snapshot) = canvas.get_image_data() { + let snapshot = snapshot.as_ipc(); + let size = snapshot.size().cast(); + let format = match snapshot.format() { + snapshot::PixelFormat::RGBA => PixelFormat::RGBA8, + snapshot::PixelFormat::BGRA => PixelFormat::BGRA8, + }; + let premultiply = snapshot.alpha_mode().is_premultiplied(); + TexPixels::new(snapshot.to_ipc_shared_memory(), size, format, premultiply) } else { return Ok(None); } @@ -1922,18 +1927,13 @@ impl CanvasContext for WebGLRenderingContext { } } - fn get_image_data_as_shared_memory(&self) -> Option<IpcSharedMemory> { - // TODO: add a method in WebGLRenderingContext to get the pixels. - None - } - // Used by HTMLCanvasElement.toDataURL // // This emits errors quite liberally, but the spec says that this operation // can fail and that it is UB what happens in that case. // // https://www.khronos.org/registry/webgl/specs/latest/1.0/#2.2 - fn get_image_data(&self) -> Option<Vec<u8>> { + fn get_image_data(&self) -> Option<Snapshot> { handle_potential_webgl_error!(self, self.validate_framebuffer(), return None); let mut size = self.size().cast(); @@ -1945,14 +1945,20 @@ impl CanvasContext for WebGLRenderingContext { size.width = cmp::min(size.width, fb_width as u32); size.height = cmp::min(size.height, fb_height as u32); - let (sender, receiver) = ipc::bytes_channel().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); self.send_command(WebGLCommand::ReadPixels( Rect::from_size(size), constants::RGBA, constants::UNSIGNED_BYTE, sender, )); - Some(receiver.recv().unwrap()) + let (data, alpha_mode) = receiver.recv().unwrap(); + Some(Snapshot::from_vec( + size.cast(), + snapshot::PixelFormat::RGBA, + alpha_mode, + data.to_vec(), + )) } fn mark_as_dirty(&self) { @@ -3826,11 +3832,11 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex dest_offset += -y * row_len; } - let (sender, receiver) = ipc::bytes_channel().unwrap(); + let (sender, receiver) = ipc::channel().unwrap(); self.send_command(WebGLCommand::ReadPixels( src_rect, format, pixel_type, sender, )); - let src = receiver.recv().unwrap(); + let (src, _) = receiver.recv().unwrap(); let src_row_len = src_rect.size.width as usize * bytes_per_pixel as usize; for i in 0..src_rect.size.height { diff --git a/components/script/dom/webgpu/gpucanvascontext.rs b/components/script/dom/webgpu/gpucanvascontext.rs index 595b54c58d7..c81f96f651f 100644 --- a/components/script/dom/webgpu/gpucanvascontext.rs +++ b/components/script/dom/webgpu/gpucanvascontext.rs @@ -7,8 +7,9 @@ use std::cell::RefCell; use arrayvec::ArrayVec; use dom_struct::dom_struct; -use ipc_channel::ipc::{self, IpcSharedMemory}; +use ipc_channel::ipc::{self}; use script_layout_interface::HTMLCanvasDataSource; +use snapshot::Snapshot; use webgpu_traits::{ ContextConfiguration, PRESENTATION_BUFFER_COUNT, WebGPU, WebGPUContextId, WebGPURequest, WebGPUTexture, @@ -277,10 +278,10 @@ impl CanvasContext for GPUCanvasContext { } /// <https://gpuweb.github.io/gpuweb/#ref-for-abstract-opdef-get-a-copy-of-the-image-contents-of-a-context%E2%91%A5> - fn get_image_data_as_shared_memory(&self) -> Option<IpcSharedMemory> { + fn get_image_data(&self) -> Option<Snapshot> { // 1. Return a copy of the image contents of context. Some(if self.drawing_buffer.borrow().cleared { - IpcSharedMemory::from_byte(0, self.size().area() as usize * 4) + Snapshot::cleared(self.size()) } else { let (sender, receiver) = ipc::channel().unwrap(); self.channel @@ -290,7 +291,7 @@ impl CanvasContext for GPUCanvasContext { sender, }) .unwrap(); - receiver.recv().unwrap() + receiver.recv().unwrap().to_owned() }) } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 0308e207e65..efe61007ef8 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -83,8 +83,8 @@ use style::stylesheets::UrlExtraData; use style_traits::CSSPixel; use stylo_atoms::Atom; use url::Position; +use webrender_api::ExternalScrollId; use webrender_api::units::{DevicePixel, LayoutPixel}; -use webrender_api::{DocumentId, ExternalScrollId}; use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions; use super::bindings::trace::HashMapTracedValues; @@ -353,10 +353,6 @@ pub(crate) struct Window { test_worklet: MutNullableDom<Worklet>, /// <https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet> paint_worklet: MutNullableDom<Worklet>, - /// The Webrender Document id associated with this window. - #[ignore_malloc_size_of = "defined in webrender_api"] - #[no_trace] - webrender_document: DocumentId, /// Flag to identify whether mutation observers are present(true)/absent(false) exists_mut_observer: Cell<bool>, @@ -2285,11 +2281,12 @@ impl Window { node: Option<&Node>, can_gc: CanGc, ) -> UntypedRect<i32> { - let opaque = node.map(|node| node.to_opaque()); if !self.layout_reflow(QueryMsg::ScrollingAreaQuery, can_gc) { return Rect::zero(); } - self.layout.borrow().query_scrolling_area(opaque) + self.layout + .borrow() + .query_scrolling_area(node.map(Node::to_trusted_node_address)) } pub(crate) fn scroll_offset_query(&self, node: &Node) -> Vector2D<f32, LayoutPixel> { @@ -2775,10 +2772,6 @@ impl Window { .unwrap(); } - pub(crate) fn webrender_document(&self) -> DocumentId { - self.webrender_document - } - #[cfg(feature = "webxr")] pub(crate) fn in_immersive_xr_session(&self) -> bool { self.navigator @@ -2821,7 +2814,6 @@ impl Window { webgl_chan: Option<WebGLChan>, #[cfg(feature = "webxr")] webxr_registry: Option<webxr_api::Registry>, microtask_queue: Rc<MicrotaskQueue>, - webrender_document: DocumentId, compositor_api: CrossProcessCompositorApi, relayout_event: bool, unminify_js: bool, @@ -2906,7 +2898,6 @@ impl Window { local_script_source, test_worklet: Default::default(), paint_worklet: Default::default(), - webrender_document, exists_mut_observer: Cell::new(false), compositor_api, has_sent_idle_message: Cell::new(false), diff --git a/components/script/dom/writablestream.rs b/components/script/dom/writablestream.rs index da0fe3b5957..1490fc694ef 100644 --- a/components/script/dom/writablestream.rs +++ b/components/script/dom/writablestream.rs @@ -8,7 +8,7 @@ use std::mem; use std::ptr::{self}; use std::rc::Rc; -use base::id::MessagePortId; +use base::id::{MessagePortId, MessagePortIndex}; use constellation_traits::MessagePortImpl; use dom_struct::dom_struct; use js::jsapi::{Heap, JSObject}; @@ -1114,7 +1114,7 @@ impl CrossRealmTransformWritable { /// <https://streams.spec.whatwg.org/#ws-transfer> impl Transferable for WritableStream { - type Id = MessagePortId; + type Index = MessagePortIndex; type Data = MessagePortImpl; /// <https://streams.spec.whatwg.org/#ref-for-writablestream%E2%91%A0%E2%91%A4> @@ -1182,7 +1182,9 @@ impl Transferable for WritableStream { } /// Note: we are relying on the port transfer, so the data returned here are related to the port. - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<MessagePortId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.port_impls, StructuredData::Writer(w) => &mut w.ports, diff --git a/components/script/dom/writablestreamdefaultcontroller.rs b/components/script/dom/writablestreamdefaultcontroller.rs index 4e6a44b9f5a..751f5d8d976 100644 --- a/components/script/dom/writablestreamdefaultcontroller.rs +++ b/components/script/dom/writablestreamdefaultcontroller.rs @@ -555,7 +555,7 @@ impl WritableStreamDefaultController { promise.reject_error(error, can_gc); } else { // Otherwise, return a promise resolved with undefined. - promise.reject_native(&(), can_gc); + promise.resolve_native(&(), can_gc); } promise }, diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index da37a12c8a7..c9b27bb6c56 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -98,7 +98,6 @@ use timers::{TimerEventRequest, TimerScheduler}; use url::Position; #[cfg(feature = "webgpu")] use webgpu_traits::{WebGPUDevice, WebGPUMsg}; -use webrender_api::DocumentId; use webrender_api::units::DevicePixel; use crate::document_collection::DocumentCollection; @@ -284,10 +283,6 @@ pub struct ScriptThread { /// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack> custom_element_reaction_stack: CustomElementReactionStack, - /// The Webrender Document ID associated with this thread. - #[no_trace] - webrender_document: DocumentId, - /// Cross-process access to the compositor's API. #[no_trace] compositor_api: CrossProcessCompositorApi, @@ -938,7 +933,6 @@ impl ScriptThread { worklet_thread_pool: Default::default(), docs_with_no_blocking_loads: Default::default(), custom_element_reaction_stack: CustomElementReactionStack::new(), - webrender_document: state.webrender_document, compositor_api: state.compositor_api, profile_script_events: opts.debug.profile_script_events, print_pwm: opts.print_pwm, @@ -3136,7 +3130,6 @@ impl ScriptThread { #[cfg(feature = "webxr")] self.webxr_registry.clone(), self.microtask_queue.clone(), - self.webrender_document, self.compositor_api.clone(), self.relayout_event, self.unminify_js, |