diff --git a/components/script/canvas_context.rs b/components/script/canvas_context.rs index 1a9235cdf9e..ed94128aeea 100644 --- a/components/script/canvas_context.rs +++ b/components/script/canvas_context.rs @@ -17,8 +17,8 @@ use crate::dom::node::{Node, NodeDamage}; #[cfg(feature = "webgpu")] use crate::dom::types::GPUCanvasContext; use crate::dom::types::{ - CanvasRenderingContext2D, OffscreenCanvas, OffscreenCanvasRenderingContext2D, - WebGL2RenderingContext, WebGLRenderingContext, + CanvasRenderingContext2D, ImageBitmapRenderingContext, OffscreenCanvas, + OffscreenCanvasRenderingContext2D, WebGL2RenderingContext, WebGLRenderingContext, }; pub(crate) trait LayoutCanvasRenderingContextHelpers { @@ -113,6 +113,7 @@ impl CanvasHelpers for HTMLCanvasElementOrOffscreenCanvas { pub(crate) enum RenderingContext { Placeholder(Dom), Context2d(Dom), + BitmapRenderer(Dom), WebGL(Dom), WebGL2(Dom), #[cfg(feature = "webgpu")] @@ -128,6 +129,7 @@ impl CanvasContext for RenderingContext { match self { RenderingContext::Placeholder(offscreen_canvas) => offscreen_canvas.context()?.canvas(), RenderingContext::Context2d(context) => context.canvas(), + RenderingContext::BitmapRenderer(context) => context.canvas(), RenderingContext::WebGL(context) => context.canvas(), RenderingContext::WebGL2(context) => context.canvas(), #[cfg(feature = "webgpu")] @@ -143,6 +145,7 @@ impl CanvasContext for RenderingContext { } }, RenderingContext::Context2d(context) => context.resize(), + RenderingContext::BitmapRenderer(context) => context.resize(), RenderingContext::WebGL(context) => context.resize(), RenderingContext::WebGL2(context) => context.resize(), #[cfg(feature = "webgpu")] @@ -158,6 +161,7 @@ impl CanvasContext for RenderingContext { } }, RenderingContext::Context2d(context) => context.reset_bitmap(), + RenderingContext::BitmapRenderer(context) => context.reset_bitmap(), RenderingContext::WebGL(context) => context.reset_bitmap(), RenderingContext::WebGL2(context) => context.reset_bitmap(), #[cfg(feature = "webgpu")] @@ -171,6 +175,7 @@ impl CanvasContext for RenderingContext { offscreen_canvas.context()?.get_image_data() }, RenderingContext::Context2d(context) => context.get_image_data(), + RenderingContext::BitmapRenderer(context) => context.get_image_data(), RenderingContext::WebGL(context) => context.get_image_data(), RenderingContext::WebGL2(context) => context.get_image_data(), #[cfg(feature = "webgpu")] @@ -184,6 +189,7 @@ impl CanvasContext for RenderingContext { .context() .is_none_or(|context| context.origin_is_clean()), RenderingContext::Context2d(context) => context.origin_is_clean(), + RenderingContext::BitmapRenderer(context) => context.origin_is_clean(), RenderingContext::WebGL(context) => context.origin_is_clean(), RenderingContext::WebGL2(context) => context.origin_is_clean(), #[cfg(feature = "webgpu")] @@ -198,6 +204,7 @@ impl CanvasContext for RenderingContext { .map(|context| context.size()) .unwrap_or_default(), RenderingContext::Context2d(context) => context.size(), + RenderingContext::BitmapRenderer(context) => context.size(), RenderingContext::WebGL(context) => context.size(), RenderingContext::WebGL2(context) => context.size(), #[cfg(feature = "webgpu")] @@ -213,6 +220,7 @@ impl CanvasContext for RenderingContext { } }, RenderingContext::Context2d(context) => context.mark_as_dirty(), + RenderingContext::BitmapRenderer(context) => context.mark_as_dirty(), RenderingContext::WebGL(context) => context.mark_as_dirty(), RenderingContext::WebGL2(context) => context.mark_as_dirty(), #[cfg(feature = "webgpu")] @@ -228,6 +236,7 @@ impl CanvasContext for RenderingContext { } }, RenderingContext::Context2d(context) => context.update_rendering(), + RenderingContext::BitmapRenderer(context) => context.update_rendering(), RenderingContext::WebGL(context) => context.update_rendering(), RenderingContext::WebGL2(context) => context.update_rendering(), #[cfg(feature = "webgpu")] @@ -241,6 +250,7 @@ impl CanvasContext for RenderingContext { .context() .is_some_and(|context| context.onscreen()), RenderingContext::Context2d(context) => context.onscreen(), + RenderingContext::BitmapRenderer(context) => context.onscreen(), RenderingContext::WebGL(context) => context.onscreen(), RenderingContext::WebGL2(context) => context.onscreen(), #[cfg(feature = "webgpu")] @@ -254,6 +264,7 @@ impl CanvasContext for RenderingContext { #[derive(Clone, JSTraceable, MallocSizeOf)] pub(crate) enum OffscreenRenderingContext { Context2d(Dom), + BitmapRenderer(Dom), //WebGL(Dom), //WebGL2(Dom), //#[cfg(feature = "webgpu")] @@ -269,6 +280,7 @@ impl CanvasContext for OffscreenRenderingContext { fn canvas(&self) -> Option { match self { OffscreenRenderingContext::Context2d(context) => context.canvas(), + OffscreenRenderingContext::BitmapRenderer(context) => context.canvas(), OffscreenRenderingContext::Detached => None, } } @@ -276,6 +288,7 @@ impl CanvasContext for OffscreenRenderingContext { fn resize(&self) { match self { OffscreenRenderingContext::Context2d(context) => context.resize(), + OffscreenRenderingContext::BitmapRenderer(context) => context.resize(), OffscreenRenderingContext::Detached => {}, } } @@ -283,6 +296,7 @@ impl CanvasContext for OffscreenRenderingContext { fn reset_bitmap(&self) { match self { OffscreenRenderingContext::Context2d(context) => context.reset_bitmap(), + OffscreenRenderingContext::BitmapRenderer(context) => context.reset_bitmap(), OffscreenRenderingContext::Detached => {}, } } @@ -290,6 +304,7 @@ impl CanvasContext for OffscreenRenderingContext { fn get_image_data(&self) -> Option { match self { OffscreenRenderingContext::Context2d(context) => context.get_image_data(), + OffscreenRenderingContext::BitmapRenderer(context) => context.get_image_data(), OffscreenRenderingContext::Detached => None, } } @@ -297,6 +312,7 @@ impl CanvasContext for OffscreenRenderingContext { fn origin_is_clean(&self) -> bool { match self { OffscreenRenderingContext::Context2d(context) => context.origin_is_clean(), + OffscreenRenderingContext::BitmapRenderer(context) => context.origin_is_clean(), OffscreenRenderingContext::Detached => true, } } @@ -304,6 +320,7 @@ impl CanvasContext for OffscreenRenderingContext { fn size(&self) -> Size2D { match self { OffscreenRenderingContext::Context2d(context) => context.size(), + OffscreenRenderingContext::BitmapRenderer(context) => context.size(), OffscreenRenderingContext::Detached => Size2D::default(), } } @@ -311,6 +328,7 @@ impl CanvasContext for OffscreenRenderingContext { fn mark_as_dirty(&self) { match self { OffscreenRenderingContext::Context2d(context) => context.mark_as_dirty(), + OffscreenRenderingContext::BitmapRenderer(context) => context.mark_as_dirty(), OffscreenRenderingContext::Detached => {}, } } @@ -318,6 +336,7 @@ impl CanvasContext for OffscreenRenderingContext { fn update_rendering(&self) { match self { OffscreenRenderingContext::Context2d(context) => context.update_rendering(), + OffscreenRenderingContext::BitmapRenderer(context) => context.update_rendering(), OffscreenRenderingContext::Detached => {}, } } @@ -325,6 +344,7 @@ impl CanvasContext for OffscreenRenderingContext { fn onscreen(&self) -> bool { match self { OffscreenRenderingContext::Context2d(context) => context.onscreen(), + OffscreenRenderingContext::BitmapRenderer(context) => context.onscreen(), OffscreenRenderingContext::Detached => false, } } diff --git a/components/script/canvas_state.rs b/components/script/canvas_state.rs index 49767a77dd4..f557075fd25 100644 --- a/components/script/canvas_state.rs +++ b/components/script/canvas_state.rs @@ -36,7 +36,7 @@ use style_traits::{CssWriter, ParsingMode}; use url::Url; use webrender_api::ImageKey; -use crate::canvas_context::{OffscreenRenderingContext, RenderingContext}; +use crate::canvas_context::{CanvasContext, OffscreenRenderingContext, RenderingContext}; use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{ CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin, @@ -623,7 +623,10 @@ impl CanvasState { dw: Option, dh: Option, ) -> ErrorResult { - let canvas_size = canvas.get_size(); + let canvas_size = canvas + .context() + .map_or_else(|| canvas.get_size(), |context| context.size()); + let dw = dw.unwrap_or(canvas_size.width as f64); let dh = dh.unwrap_or(canvas_size.height as f64); let sw = sw.unwrap_or(canvas_size.width as f64); @@ -651,6 +654,18 @@ impl CanvasState { smoothing_enabled, )); }, + OffscreenRenderingContext::BitmapRenderer(ref context) => { + let Some(snapshot) = context.get_image_data() else { + return Ok(()); + }; + + self.send_canvas_2d_msg(Canvas2dMsg::DrawImage( + snapshot.as_ipc(), + dest_rect, + source_rect, + smoothing_enabled, + )); + }, OffscreenRenderingContext::Detached => return Err(Error::InvalidState), } } else { @@ -679,7 +694,10 @@ impl CanvasState { dw: Option, dh: Option, ) -> ErrorResult { - let canvas_size = canvas.get_size(); + let canvas_size = canvas + .context() + .map_or_else(|| canvas.get_size(), |context| context.size()); + let dw = dw.unwrap_or(canvas_size.width as f64); let dh = dh.unwrap_or(canvas_size.height as f64); let sw = sw.unwrap_or(canvas_size.width as f64); @@ -707,6 +725,18 @@ impl CanvasState { smoothing_enabled, )); }, + RenderingContext::BitmapRenderer(ref context) => { + let Some(snapshot) = context.get_image_data() else { + return Ok(()); + }; + + self.send_canvas_2d_msg(Canvas2dMsg::DrawImage( + snapshot.as_ipc(), + dest_rect, + source_rect, + smoothing_enabled, + )); + }, RenderingContext::Placeholder(ref context) => { let Some(context) = context.context() else { return Err(Error::InvalidState); @@ -720,6 +750,18 @@ impl CanvasState { source_rect, smoothing_enabled, )), + OffscreenRenderingContext::BitmapRenderer(ref context) => { + let Some(snapshot) = context.get_image_data() else { + return Ok(()); + }; + + self.send_canvas_2d_msg(Canvas2dMsg::DrawImage( + snapshot.as_ipc(), + dest_rect, + source_rect, + smoothing_enabled, + )); + }, OffscreenRenderingContext::Detached => return Err(Error::InvalidState), } }, diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 158bfb9def0..136e787b083 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -51,6 +51,7 @@ use crate::dom::element::{AttributeMutation, Element, LayoutElementHelpers}; #[cfg(not(feature = "webgpu"))] use crate::dom::gpucanvascontext::GPUCanvasContext; use crate::dom::htmlelement::HTMLElement; +use crate::dom::imagebitmaprenderingcontext::ImageBitmapRenderingContext; use crate::dom::mediastream::MediaStream; use crate::dom::mediastreamtrack::MediaStreamTrack; use crate::dom::node::{Node, NodeTraits}; @@ -164,6 +165,9 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> { Some(RenderingContext::Context2d(context)) => { context.to_layout().canvas_data_source() }, + Some(RenderingContext::BitmapRenderer(context)) => { + context.to_layout().canvas_data_source() + }, Some(RenderingContext::WebGL(context)) => context.to_layout().canvas_data_source(), Some(RenderingContext::WebGL2(context)) => context.to_layout().canvas_data_source(), #[cfg(feature = "webgpu")] @@ -207,6 +211,37 @@ impl HTMLCanvasElement { Some(context) } + /// + fn get_or_init_bitmaprenderer_context( + &self, + can_gc: CanGc, + ) -> Option> { + // Return the same object as was returned the last time the method was + // invoked with this same first argument. + if let Some(ctx) = self.context() { + return match *ctx { + RenderingContext::BitmapRenderer(ref ctx) => Some(DomRoot::from_ref(ctx)), + _ => None, + }; + } + + // Step 1. Let context be the result of running the + // ImageBitmapRenderingContext creation algorithm given this and + // options. + let context = ImageBitmapRenderingContext::new( + &self.owner_global(), + HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(self)), + can_gc, + ); + + // Step 2. Set this's context mode to bitmaprenderer. + *self.context_mode.borrow_mut() = + Some(RenderingContext::BitmapRenderer(Dom::from_ref(&*context))); + + // Step 3. Return context. + Some(context) + } + fn get_or_init_webgl_context( &self, cx: JSContext, @@ -410,6 +445,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { "2d" => self .get_or_init_2d_context(can_gc) .map(RootedRenderingContext::CanvasRenderingContext2D), + "bitmaprenderer" => self + .get_or_init_bitmaprenderer_context(can_gc) + .map(RootedRenderingContext::ImageBitmapRenderingContext), "webgl" | "experimental-webgl" => self .get_or_init_webgl_context(cx, options, can_gc) .map(RootedRenderingContext::WebGLRenderingContext), diff --git a/components/script/dom/imagebitmaprenderingcontext.rs b/components/script/dom/imagebitmaprenderingcontext.rs new file mode 100644 index 00000000000..f07b332a12b --- /dev/null +++ b/components/script/dom/imagebitmaprenderingcontext.rs @@ -0,0 +1,193 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use std::cell::Cell; + +use dom_struct::dom_struct; +use euclid::default::Size2D; +use pixels::Snapshot; +use webrender_api::ImageKey; + +use crate::canvas_context::{CanvasContext, CanvasHelpers, LayoutCanvasRenderingContextHelpers}; +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::ImageBitmapMethods; +use crate::dom::bindings::codegen::Bindings::ImageBitmapRenderingContextBinding::ImageBitmapRenderingContextMethods; +use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; +use crate::dom::bindings::error::{Error, Fallible}; +use crate::dom::bindings::reflector::{Reflector, reflect_dom_object}; +use crate::dom::bindings::root::{DomRoot, LayoutDom}; +use crate::dom::globalscope::GlobalScope; +use crate::dom::imagebitmap::ImageBitmap; +use crate::script_runtime::CanGc; + +/// +#[dom_struct] +pub(crate) struct ImageBitmapRenderingContext { + reflector_: Reflector, + /// + canvas: HTMLCanvasElementOrOffscreenCanvas, + /// Represents both the [output bitmap] and the [bitmap mode] of the context. + /// + /// + #[no_trace] + bitmap: DomRefCell>, + origin_clean: Cell, +} + +impl ImageBitmapRenderingContext { + /// + fn new_inherited(canvas: HTMLCanvasElementOrOffscreenCanvas) -> ImageBitmapRenderingContext { + ImageBitmapRenderingContext { + reflector_: Reflector::new(), + canvas, + bitmap: DomRefCell::new(None), + origin_clean: Cell::new(true), + } + } + + pub(crate) fn new( + global: &GlobalScope, + canvas: HTMLCanvasElementOrOffscreenCanvas, + can_gc: CanGc, + ) -> DomRoot { + reflect_dom_object( + Box::new(ImageBitmapRenderingContext::new_inherited(canvas)), + global, + can_gc, + ) + } + + /// + fn set_bitmap(&self, image_bitmap: Option<&ImageBitmap>) { + match image_bitmap { + Some(image_bitmap) => { + // Step 2.1. Set context's bitmap mode to valid. + // Step 2.2. Set context's output bitmap to refer to the same + // underlying bitmap data as bitmap, without making a copy. + *self.bitmap.borrow_mut() = image_bitmap.bitmap_data().clone(); + + // The origin-clean flag of bitmap is included in the bitmap + // data to be referenced by context's output bitmap. + self.origin_clean.set(image_bitmap.origin_is_clean()); + }, + None => { + // Step 1.1. Set context's bitmap mode to blank. + // Step 1.2. Let canvas be the canvas element to which context is bound. + // Step 1.3. Set context's output bitmap to be transparent black + // with a natural width equal to the numeric value of canvas's + // width attribute and a natural height equal to the numeric + // value of canvas's height attribute, those values being + // interpreted in CSS pixels. + *self.bitmap.borrow_mut() = None; + + // Step 1.4. Set the output bitmap's origin-clean flag to true. + self.origin_clean.set(true); + }, + } + } +} + +impl LayoutCanvasRenderingContextHelpers for LayoutDom<'_, ImageBitmapRenderingContext> { + fn canvas_data_source(self) -> Option { + None + } +} + +impl CanvasContext for ImageBitmapRenderingContext { + type ID = (); + + fn context_id(&self) -> Self::ID {} + + fn canvas(&self) -> Option { + Some(self.canvas.clone()) + } + + /// + fn resize(&self) { + // The absence of the bitmap is the context's blank bitmap mode so the + // steps to set output bitmap could be omitted. + } + + fn reset_bitmap(&self) { + // The newly created bitmap should be of the same dimensions as the + // previous bitmap if the context's bitmap mode is valid. + if self.bitmap.borrow().is_none() { + return; + } + + let size = self.bitmap.borrow().as_ref().unwrap().size(); + *self.bitmap.borrow_mut() = Some(Snapshot::cleared(size)); + } + + fn get_image_data(&self) -> Option { + match self.bitmap.borrow().as_ref() { + Some(bitmap) => Some(bitmap.clone()), + None => { + let size = self.canvas.size(); + if size.is_empty() || + pixels::compute_rgba8_byte_length_if_within_limit( + size.width as usize, + size.height as usize, + ) + .is_none() + { + None + } else { + Some(Snapshot::cleared(size)) + } + }, + } + } + + fn origin_is_clean(&self) -> bool { + self.origin_clean.get() + } + + fn size(&self) -> Size2D { + self.bitmap + .borrow() + .as_ref() + .map_or_else(|| self.canvas.size(), |bitmap| bitmap.size()) + } +} + +impl ImageBitmapRenderingContextMethods for ImageBitmapRenderingContext { + /// + fn Canvas(&self) -> HTMLCanvasElementOrOffscreenCanvas { + self.canvas.clone() + } + + /// + fn TransferFromImageBitmap(&self, image_bitmap: Option<&ImageBitmap>) -> Fallible<()> { + let Some(image_bitmap) = image_bitmap else { + // Step 2. If bitmap is null, then run the steps to set an + // ImageBitmapRenderingContext's output bitmap, with + // bitmapContext as the context argument and no bitmap argument, + // then return. + self.set_bitmap(None); + + return Ok(()); + }; + + // Step 3. If the value of bitmap's [[Detached]] internal slot + // is set to true, then throw an "InvalidStateError" + // DOMException. + if image_bitmap.is_detached() { + return Err(Error::InvalidState); + } + + // Step 4. Run the steps to set an ImageBitmapRenderingContext's + // output bitmap, with the context argument equal to + // bitmapContext, and the bitmap argument referring to bitmap's + // underlying bitmap data. + self.set_bitmap(Some(image_bitmap)); + + // Step 5. Set the value of bitmap's [[Detached]] internal slot + // to true. + // Step 6. Unset bitmap's bitmap data. + image_bitmap.Close(); + + Ok(()) + } +} diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index c962ad38b7f..8190a0b1dda 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -429,6 +429,7 @@ pub(crate) mod idbtransaction; pub(crate) mod idbversionchangeevent; pub(crate) mod iirfilternode; pub(crate) mod imagebitmap; +pub(crate) mod imagebitmaprenderingcontext; pub(crate) mod imagedata; pub(crate) mod inputevent; pub(crate) mod intersectionobserver; diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs index b64c3d30825..ece5d17ec1b 100644 --- a/components/script/dom/offscreencanvas.rs +++ b/components/script/dom/offscreencanvas.rs @@ -20,6 +20,7 @@ use crate::dom::bindings::codegen::Bindings::OffscreenCanvasBinding::{ ImageEncodeOptions, OffscreenCanvasMethods, OffscreenRenderingContext as RootedOffscreenRenderingContext, }; +use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::refcounted::{Trusted, TrustedPromise}; use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto}; @@ -32,6 +33,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::htmlcanvaselement::HTMLCanvasElement; use crate::dom::imagebitmap::ImageBitmap; +use crate::dom::imagebitmaprenderingcontext::ImageBitmapRenderingContext; use crate::dom::offscreencanvasrenderingcontext2d::OffscreenCanvasRenderingContext2D; use crate::dom::promise::Promise; use crate::realms::{AlreadyInRealm, InRealm}; @@ -140,6 +142,38 @@ impl OffscreenCanvas { Some(context) } + /// + pub(crate) fn get_or_init_bitmaprenderer_context( + &self, + can_gc: CanGc, + ) -> Option> { + // Return the same object as was returned the last time the method was + // invoked with this same first argument. + if let Some(ctx) = self.context() { + return match *ctx { + OffscreenRenderingContext::BitmapRenderer(ref ctx) => Some(DomRoot::from_ref(ctx)), + _ => None, + }; + } + + // Step 1. Let context be the result of running the + // ImageBitmapRenderingContext creation algorithm given this and + // options. + let context = ImageBitmapRenderingContext::new( + &self.global(), + HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(DomRoot::from_ref(self)), + can_gc, + ); + + // Step 2. Set this's context mode to bitmaprenderer. + *self.context.borrow_mut() = Some(OffscreenRenderingContext::BitmapRenderer( + Dom::from_ref(&*context), + )); + + // Step 3. Return context. + Some(context) + } + pub(crate) fn placeholder(&self) -> Option> { self.placeholder .as_ref() @@ -267,6 +301,9 @@ impl OffscreenCanvasMethods for OffscreenCanvas { "2d" => Ok(self .get_or_init_2d_context(can_gc) .map(RootedOffscreenRenderingContext::OffscreenCanvasRenderingContext2D)), + "bitmaprenderer" => Ok(self + .get_or_init_bitmaprenderer_context(can_gc) + .map(RootedOffscreenRenderingContext::ImageBitmapRenderingContext)), /*"webgl" | "experimental-webgl" => self .get_or_init_webgl_context(cx, options) .map(OffscreenRenderingContext::WebGLRenderingContext), diff --git a/components/script_bindings/webidls/HTMLCanvasElement.webidl b/components/script_bindings/webidls/HTMLCanvasElement.webidl index 2e7be0389be..5b04d7dcf33 100644 --- a/components/script_bindings/webidls/HTMLCanvasElement.webidl +++ b/components/script_bindings/webidls/HTMLCanvasElement.webidl @@ -4,6 +4,7 @@ // https://html.spec.whatwg.org/multipage/#htmlcanvaselement typedef (CanvasRenderingContext2D + or ImageBitmapRenderingContext or WebGLRenderingContext or WebGL2RenderingContext or GPUCanvasContext) RenderingContext; diff --git a/components/script_bindings/webidls/ImageBitmapRenderingContext.webidl b/components/script_bindings/webidls/ImageBitmapRenderingContext.webidl new file mode 100644 index 00000000000..438185f7798 --- /dev/null +++ b/components/script_bindings/webidls/ImageBitmapRenderingContext.webidl @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +/// +[Exposed=(Window,Worker)] +interface ImageBitmapRenderingContext { + readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas; + [Throws] undefined transferFromImageBitmap(ImageBitmap? bitmap); +}; + +dictionary ImageBitmapRenderingContextSettings { + boolean alpha = true; +}; diff --git a/components/script_bindings/webidls/OffscreenCanvas.webidl b/components/script_bindings/webidls/OffscreenCanvas.webidl index 75c936e7437..a0de55119df 100644 --- a/components/script_bindings/webidls/OffscreenCanvas.webidl +++ b/components/script_bindings/webidls/OffscreenCanvas.webidl @@ -3,15 +3,17 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ // https://html.spec.whatwg.org/multipage/#the-offscreencanvas-interface -typedef (OffscreenCanvasRenderingContext2D or WebGLRenderingContext or WebGL2RenderingContext) -OffscreenRenderingContext; +typedef (OffscreenCanvasRenderingContext2D + or ImageBitmapRenderingContext + or WebGLRenderingContext + or WebGL2RenderingContext) OffscreenRenderingContext; dictionary ImageEncodeOptions { DOMString type = "image/png"; unrestricted double quality; }; -//enum OffscreenRenderingContextId { "2d", "webgl", "webgl2" }; +//enum OffscreenRenderingContextId { "2d", "bitmaprenderer", "webgl", "webgl2" }; [Exposed=(Window,Worker), Transferable, Pref="dom_offscreen_canvas_enabled"] interface OffscreenCanvas : EventTarget { diff --git a/tests/wpt/include.ini b/tests/wpt/include.ini index ef8ee807fc5..65abe149cf6 100644 --- a/tests/wpt/include.ini +++ b/tests/wpt/include.ini @@ -176,6 +176,8 @@ skip: true skip: true [moving-between-documents] skip: true +[imagebitmap-renderingcontext] + skip: false [import-maps] skip: false [IndexedDB] diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini index 22ec677f4ea..1006f356584 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini @@ -1,27 +1,9 @@ [createImageBitmap-origin.sub.html] - [redirected to cross-origin HTMLVideoElement: origin unclear bitmaprenderer.transferFromImageBitmap] - expected: FAIL - - [unclean HTMLCanvasElement: origin unclear bitmaprenderer.transferFromImageBitmap] - expected: FAIL - [cross-origin SVGImageElement: origin unclear bitmaprenderer.transferFromImageBitmap] expected: FAIL - [cross-origin HTMLVideoElement: origin unclear bitmaprenderer.transferFromImageBitmap] - expected: FAIL - [cross-origin SVGImageElement: origin unclear 2dContext.drawImage] expected: FAIL - [cross-origin HTMLImageElement: origin unclear bitmaprenderer.transferFromImageBitmap] - expected: FAIL - - [unclean ImageBitmap: origin unclear bitmaprenderer.transferFromImageBitmap] - expected: FAIL - - [redirected to same-origin HTMLVideoElement: origin unclear bitmaprenderer.transferFromImageBitmap] - expected: FAIL - [cross-origin SVGImageElement: origin unclear getImageData] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.direction.html.ini b/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.direction.html.ini index f75841ed095..c213a362cfc 100644 --- a/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.direction.html.ini +++ b/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.direction.html.ini @@ -1,2 +1,2 @@ [canvas.2d.offscreen.direction.html] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.html.ini b/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.html.ini index 1d927b88e05..5544627aa21 100644 --- a/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.html.ini +++ b/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.html.ini @@ -1,2 +1,2 @@ [canvas.2d.offscreen.lang.html] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.inherit.html.ini b/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.inherit.html.ini index b89123e21a2..46ed1107ac1 100644 --- a/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.inherit.html.ini +++ b/tests/wpt/meta/html/canvas/offscreen/manual/text/canvas.2d.offscreen.lang.inherit.html.ini @@ -1,2 +1,2 @@ [canvas.2d.offscreen.lang.inherit.html] - expected: TIMEOUT + expected: FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html.ini b/tests/wpt/meta/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html.ini deleted file mode 100644 index d62315da852..00000000000 --- a/tests/wpt/meta/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.nocrash.html.ini +++ /dev/null @@ -1,3 +0,0 @@ -[offscreencanvas.transfer.to.imagebitmap.nocrash.html] - [offscreencanvas] - expected: FAIL diff --git a/tests/wpt/meta/html/dom/idlharness.any.js.ini b/tests/wpt/meta/html/dom/idlharness.any.js.ini index bd95386b7f8..a8ffc90d850 100644 --- a/tests/wpt/meta/html/dom/idlharness.any.js.ini +++ b/tests/wpt/meta/html/dom/idlharness.any.js.ini @@ -2,30 +2,6 @@ [Path2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional (unrestricted double or DOMPointInit or sequence<(unrestricted double or DOMPointInit)>))] expected: FAIL - [ImageBitmapRenderingContext interface: existence and properties of interface object] - expected: FAIL - - [ImageBitmapRenderingContext interface object length] - expected: FAIL - - [ImageBitmapRenderingContext interface object name] - expected: FAIL - - [ImageBitmapRenderingContext interface: existence and properties of interface prototype object] - expected: FAIL - - [ImageBitmapRenderingContext interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [ImageBitmapRenderingContext interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [ImageBitmapRenderingContext interface: attribute canvas] - expected: FAIL - - [ImageBitmapRenderingContext interface: operation transferFromImageBitmap(ImageBitmap?)] - expected: FAIL - [OffscreenCanvas interface: attribute oncontextlost] expected: FAIL diff --git a/tests/wpt/meta/html/dom/idlharness.https.html.ini b/tests/wpt/meta/html/dom/idlharness.https.html.ini index ff38923d7e9..540fae2ccb6 100644 --- a/tests/wpt/meta/html/dom/idlharness.https.html.ini +++ b/tests/wpt/meta/html/dom/idlharness.https.html.ini @@ -4346,30 +4346,6 @@ [Path2D interface: operation roundRect(unrestricted double, unrestricted double, unrestricted double, unrestricted double, optional (unrestricted double or DOMPointInit or sequence<(unrestricted double or DOMPointInit)>))] expected: FAIL - [ImageBitmapRenderingContext interface: existence and properties of interface object] - expected: FAIL - - [ImageBitmapRenderingContext interface object length] - expected: FAIL - - [ImageBitmapRenderingContext interface object name] - expected: FAIL - - [ImageBitmapRenderingContext interface: existence and properties of interface prototype object] - expected: FAIL - - [ImageBitmapRenderingContext interface: existence and properties of interface prototype object's "constructor" property] - expected: FAIL - - [ImageBitmapRenderingContext interface: existence and properties of interface prototype object's @@unscopables property] - expected: FAIL - - [ImageBitmapRenderingContext interface: attribute canvas] - expected: FAIL - - [ImageBitmapRenderingContext interface: operation transferFromImageBitmap(ImageBitmap?)] - expected: FAIL - [OffscreenCanvas interface: attribute oncontextlost] expected: FAIL diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json index 4599cc850b4..6a0074e9a5d 100644 --- a/tests/wpt/mozilla/meta/MANIFEST.json +++ b/tests/wpt/mozilla/meta/MANIFEST.json @@ -13623,14 +13623,14 @@ ] ], "interfaces.https.html": [ - "8a9345525360e7a7ce69e84e394b65a4cbc0ab34", + "641c5ba19d389390b7b51da7644f011b0c42f33a", [ null, {} ] ], "interfaces.worker.js": [ - "f217fd8fb6b46144bc3576a081cc6ce5db3129d5", + "463bfc25211014203a5094baae4b4e2d890bf9aa", [ "mozilla/interfaces.worker.html", {} diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.https.html b/tests/wpt/mozilla/tests/mozilla/interfaces.https.html index 8a934552536..641c5ba19d3 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.https.html +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.https.html @@ -225,6 +225,7 @@ test_interfaces([ "ImageData", "Image", "ImageBitmap", + "ImageBitmapRenderingContext", "InputEvent", "IntersectionObserver", "IntersectionObserverEntry", diff --git a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js index f217fd8fb6b..463bfc25211 100644 --- a/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js +++ b/tests/wpt/mozilla/tests/mozilla/interfaces.worker.js @@ -77,6 +77,7 @@ test_interfaces([ "Headers", "History", "ImageBitmap", + "ImageBitmapRenderingContext", "ImageData", "MessageChannel", "MessageEvent",