aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlcanvaselement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmlcanvaselement.rs')
-rw-r--r--components/script/dom/htmlcanvaselement.rs101
1 files changed, 36 insertions, 65 deletions
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs
index bb27d28cea8..56e008839ba 100644
--- a/components/script/dom/htmlcanvaselement.rs
+++ b/components/script/dom/htmlcanvaselement.rs
@@ -21,20 +21,19 @@ use image::{ColorType, ImageEncoder};
use ipc_channel::ipc::{self as ipcchan};
use js::error::throw_type_error;
use js::rust::{HandleObject, HandleValue};
-use script_layout_interface::{HTMLCanvasData, HTMLCanvasDataSource};
+use script_layout_interface::HTMLCanvasData;
use servo_media::streams::MediaStreamType;
use servo_media::streams::registry::MediaStreamId;
use snapshot::Snapshot;
use style::attr::AttrValue;
-use crate::canvas_context::CanvasContext as _;
pub(crate) use crate::canvas_context::*;
use crate::conversions::Convert;
use crate::dom::attr::Attr;
use crate::dom::bindings::callback::ExceptionHandling;
use crate::dom::bindings::cell::{DomRefCell, Ref, ref_filter_map};
use crate::dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::{
- BlobCallback, HTMLCanvasElementMethods, RenderingContext,
+ BlobCallback, HTMLCanvasElementMethods, RenderingContext as RootedRenderingContext,
};
use crate::dom::bindings::codegen::Bindings::MediaStreamBinding::MediaStreamMethods;
use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLContextAttributes;
@@ -104,21 +103,10 @@ impl EncodedImageType {
}
}
-#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
-#[derive(Clone, JSTraceable, MallocSizeOf)]
-pub(crate) enum CanvasContext {
- Placeholder(Dom<OffscreenCanvas>),
- Context2d(Dom<CanvasRenderingContext2D>),
- WebGL(Dom<WebGLRenderingContext>),
- WebGL2(Dom<WebGL2RenderingContext>),
- #[cfg(feature = "webgpu")]
- WebGPU(Dom<GPUCanvasContext>),
-}
-
#[dom_struct]
pub(crate) struct HTMLCanvasElement {
htmlelement: HTMLElement,
- context: DomRefCell<Option<CanvasContext>>,
+ context: DomRefCell<Option<RenderingContext>>,
// This id and hashmap are used to keep track of ongoing toBlob() calls.
callback_id: Cell<u32>,
#[ignore_malloc_size_of = "not implemented for webidl callbacks"]
@@ -159,14 +147,7 @@ impl HTMLCanvasElement {
fn recreate_contexts_after_resize(&self) {
if let Some(ref context) = *self.context.borrow() {
- match *context {
- CanvasContext::Context2d(ref context) => context.resize(),
- CanvasContext::WebGL(ref context) => context.resize(),
- CanvasContext::WebGL2(ref context) => context.resize(),
- #[cfg(feature = "webgpu")]
- CanvasContext::WebGPU(ref context) => context.resize(),
- CanvasContext::Placeholder(ref context) => context.resize(self.get_size().cast()),
- }
+ context.resize()
}
}
@@ -176,23 +157,14 @@ impl HTMLCanvasElement {
pub(crate) fn origin_is_clean(&self) -> bool {
match *self.context.borrow() {
- Some(CanvasContext::Context2d(ref context)) => context.origin_is_clean(),
+ Some(ref context) => context.origin_is_clean(),
_ => true,
}
}
pub(crate) fn mark_as_dirty(&self) {
if let Some(ref context) = *self.context.borrow() {
- match *context {
- CanvasContext::Context2d(ref context) => context.mark_as_dirty(),
- CanvasContext::WebGL(ref context) => context.mark_as_dirty(),
- CanvasContext::WebGL2(ref context) => context.mark_as_dirty(),
- #[cfg(feature = "webgpu")]
- CanvasContext::WebGPU(ref context) => context.mark_as_dirty(),
- CanvasContext::Placeholder(ref _context) => {
- // TODO: Should this be marked as dirty?
- },
- }
+ context.mark_as_dirty()
}
}
@@ -222,12 +194,14 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> {
fn data(self) -> HTMLCanvasData {
let source = unsafe {
match self.unsafe_get().context.borrow_for_layout().as_ref() {
- Some(CanvasContext::Context2d(context)) => context.to_layout().canvas_data_source(),
- Some(CanvasContext::WebGL(context)) => context.to_layout().canvas_data_source(),
- Some(CanvasContext::WebGL2(context)) => context.to_layout().canvas_data_source(),
+ Some(RenderingContext::Context2d(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")]
- Some(CanvasContext::WebGPU(context)) => context.to_layout().canvas_data_source(),
- Some(CanvasContext::Placeholder(_)) | None => HTMLCanvasDataSource::Empty,
+ Some(RenderingContext::WebGPU(context)) => context.to_layout().canvas_data_source(),
+ Some(RenderingContext::Placeholder(_)) | None => None,
}
};
@@ -246,14 +220,14 @@ impl LayoutHTMLCanvasElementHelpers for LayoutDom<'_, HTMLCanvasElement> {
}
impl HTMLCanvasElement {
- pub(crate) fn context(&self) -> Option<Ref<CanvasContext>> {
+ pub(crate) fn context(&self) -> Option<Ref<RenderingContext>> {
ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref())
}
fn get_or_init_2d_context(&self, can_gc: CanGc) -> Option<DomRoot<CanvasRenderingContext2D>> {
if let Some(ctx) = self.context() {
return match *ctx {
- CanvasContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)),
+ RenderingContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)),
_ => None,
};
}
@@ -261,7 +235,7 @@ impl HTMLCanvasElement {
let window = self.owner_window();
let size = self.get_size();
let context = CanvasRenderingContext2D::new(window.as_global_scope(), self, size, can_gc);
- *self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context)));
+ *self.context.borrow_mut() = Some(RenderingContext::Context2d(Dom::from_ref(&*context)));
Some(context)
}
@@ -273,7 +247,7 @@ impl HTMLCanvasElement {
) -> Option<DomRoot<WebGLRenderingContext>> {
if let Some(ctx) = self.context() {
return match *ctx {
- CanvasContext::WebGL(ref ctx) => Some(DomRoot::from_ref(ctx)),
+ RenderingContext::WebGL(ref ctx) => Some(DomRoot::from_ref(ctx)),
_ => None,
};
}
@@ -289,7 +263,7 @@ impl HTMLCanvasElement {
attrs,
can_gc,
)?;
- *self.context.borrow_mut() = Some(CanvasContext::WebGL(Dom::from_ref(&*context)));
+ *self.context.borrow_mut() = Some(RenderingContext::WebGL(Dom::from_ref(&*context)));
Some(context)
}
@@ -305,7 +279,7 @@ impl HTMLCanvasElement {
}
if let Some(ctx) = self.context() {
return match *ctx {
- CanvasContext::WebGL2(ref ctx) => Some(DomRoot::from_ref(ctx)),
+ RenderingContext::WebGL2(ref ctx) => Some(DomRoot::from_ref(ctx)),
_ => None,
};
}
@@ -314,7 +288,7 @@ impl HTMLCanvasElement {
let attrs = Self::get_gl_attributes(cx, options)?;
let canvas = HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(self));
let context = WebGL2RenderingContext::new(&window, &canvas, size, attrs, can_gc)?;
- *self.context.borrow_mut() = Some(CanvasContext::WebGL2(Dom::from_ref(&*context)));
+ *self.context.borrow_mut() = Some(RenderingContext::WebGL2(Dom::from_ref(&*context)));
Some(context)
}
@@ -327,7 +301,7 @@ impl HTMLCanvasElement {
fn get_or_init_webgpu_context(&self, can_gc: CanGc) -> Option<DomRoot<GPUCanvasContext>> {
if let Some(ctx) = self.context() {
return match *ctx {
- CanvasContext::WebGPU(ref ctx) => Some(DomRoot::from_ref(ctx)),
+ RenderingContext::WebGPU(ref ctx) => Some(DomRoot::from_ref(ctx)),
_ => None,
};
}
@@ -341,7 +315,8 @@ impl HTMLCanvasElement {
.expect("Failed to get WebGPU channel")
.map(|channel| {
let context = GPUCanvasContext::new(&global_scope, self, channel, can_gc);
- *self.context.borrow_mut() = Some(CanvasContext::WebGPU(Dom::from_ref(&*context)));
+ *self.context.borrow_mut() =
+ Some(RenderingContext::WebGPU(Dom::from_ref(&*context)));
context
})
}
@@ -349,8 +324,8 @@ impl HTMLCanvasElement {
/// Gets the base WebGLRenderingContext for WebGL or WebGL 2, if exists.
pub(crate) fn get_base_webgl_context(&self) -> Option<DomRoot<WebGLRenderingContext>> {
match *self.context.borrow() {
- Some(CanvasContext::WebGL(ref context)) => Some(DomRoot::from_ref(context)),
- Some(CanvasContext::WebGL2(ref context)) => Some(context.base_context()),
+ Some(RenderingContext::WebGL(ref context)) => Some(DomRoot::from_ref(context)),
+ Some(RenderingContext::WebGL2(ref context)) => Some(context.base_context()),
_ => None,
}
}
@@ -378,12 +353,7 @@ impl HTMLCanvasElement {
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(context)) => context.get_image_data(),
- Some(CanvasContext::Placeholder(context)) => context.get_image_data(),
+ Some(context) => context.get_image_data(),
None => {
let size = self.get_size();
if size.width == 0 || size.height == 0 {
@@ -466,7 +436,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
// is set to placeholder, the user agent must throw an "InvalidStateError" DOMException and leave the
// attribute's value unchanged.
fn SetWidth(&self, value: u32, can_gc: CanGc) -> Fallible<()> {
- if let Some(CanvasContext::Placeholder(_)) = *self.context.borrow() {
+ if let Some(RenderingContext::Placeholder(_)) = *self.context.borrow() {
return Err(Error::InvalidState);
}
@@ -485,7 +455,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
// https://html.spec.whatwg.org/multipage/#dom-canvas-height
fn SetHeight(&self, value: u32, can_gc: CanGc) -> Fallible<()> {
- if let Some(CanvasContext::Placeholder(_)) = *self.context.borrow() {
+ if let Some(RenderingContext::Placeholder(_)) = *self.context.borrow() {
return Err(Error::InvalidState);
}
@@ -506,26 +476,26 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
id: DOMString,
options: HandleValue,
can_gc: CanGc,
- ) -> Fallible<Option<RenderingContext>> {
+ ) -> Fallible<Option<RootedRenderingContext>> {
// Always throw an InvalidState exception when the canvas is in Placeholder mode (See table in the spec).
- if let Some(CanvasContext::Placeholder(_)) = *self.context.borrow() {
+ if let Some(RenderingContext::Placeholder(_)) = *self.context.borrow() {
return Err(Error::InvalidState);
}
Ok(match &*id {
"2d" => self
.get_or_init_2d_context(can_gc)
- .map(RenderingContext::CanvasRenderingContext2D),
+ .map(RootedRenderingContext::CanvasRenderingContext2D),
"webgl" | "experimental-webgl" => self
.get_or_init_webgl_context(cx, options, can_gc)
- .map(RenderingContext::WebGLRenderingContext),
+ .map(RootedRenderingContext::WebGLRenderingContext),
"webgl2" | "experimental-webgl2" => self
.get_or_init_webgl2_context(cx, options, can_gc)
- .map(RenderingContext::WebGL2RenderingContext),
+ .map(RootedRenderingContext::WebGL2RenderingContext),
#[cfg(feature = "webgpu")]
"webgpu" => self
.get_or_init_webgpu_context(can_gc)
- .map(RenderingContext::GPUCanvasContext),
+ .map(RootedRenderingContext::GPUCanvasContext),
_ => None,
})
}
@@ -672,7 +642,8 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
can_gc,
);
// Step 4. Set this canvas element's context mode to placeholder.
- *self.context.borrow_mut() = Some(CanvasContext::Placeholder(offscreen_canvas.as_traced()));
+ *self.context.borrow_mut() =
+ Some(RenderingContext::Placeholder(offscreen_canvas.as_traced()));
// Step 5. Return offscreenCanvas.
Ok(offscreen_canvas)