aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/Cargo.toml1
-rw-r--r--components/script/canvas_context.rs11
-rw-r--r--components/script/canvas_state.rs64
-rw-r--r--components/script/dom/bindings/serializable.rs29
-rw-r--r--components/script/dom/bindings/structuredclone.rs24
-rw-r--r--components/script/dom/bindings/transferable.rs26
-rw-r--r--components/script/dom/blob.rs31
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs16
-rw-r--r--components/script/dom/domexception.rs34
-rw-r--r--components/script/dom/dompoint.rs10
-rw-r--r--components/script/dom/dompointreadonly.rs34
-rw-r--r--components/script/dom/globalscope.rs19
-rw-r--r--components/script/dom/htmlcanvaselement.rs78
-rw-r--r--components/script/dom/messageport.rs26
-rw-r--r--components/script/dom/offscreencanvas.rs27
-rw-r--r--components/script/dom/offscreencanvasrenderingcontext2d.rs6
-rw-r--r--components/script/dom/readablestream.rs10
-rw-r--r--components/script/dom/webgl2renderingcontext.rs11
-rw-r--r--components/script/dom/webglrenderingcontext.rs36
-rw-r--r--components/script/dom/webgpu/gpucanvascontext.rs9
-rw-r--r--components/script/dom/window.rs17
-rw-r--r--components/script/dom/writablestream.rs8
-rw-r--r--components/script/dom/writablestreamdefaultcontroller.rs2
-rw-r--r--components/script/script_thread.rs7
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,