mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
canvas: Make 2D context state creation failable and use dom_canvas_backend
pref for backend selection (#38310)
Before script just crashed in those cases because IPCSender was dropped, now we send `None` to tell script about the failure and fail getContext or registerPainter accordingly. This PR also unifies `dom_canvas_{backends}_enabled` prefs into `dom_canvas_backend` which is more flexible in multi-backends scenarios. Reviewable per commit. Testing: Added servo specific WPT test. --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
93d234d270
commit
ae69646371
17 changed files with 116 additions and 61 deletions
|
@ -68,12 +68,12 @@ impl CanvasRenderingContext2D {
|
|||
global: &GlobalScope,
|
||||
canvas: HTMLCanvasElementOrOffscreenCanvas,
|
||||
size: Size2D<u32>,
|
||||
) -> CanvasRenderingContext2D {
|
||||
) -> Option<CanvasRenderingContext2D> {
|
||||
let canvas_state =
|
||||
CanvasState::new(global, Size2D::new(size.width as u64, size.height as u64));
|
||||
CanvasState::new(global, Size2D::new(size.width as u64, size.height as u64))?;
|
||||
let ipc_sender = canvas_state.get_ipc_renderer().clone();
|
||||
let canvas_id = canvas_state.get_canvas_id();
|
||||
CanvasRenderingContext2D {
|
||||
Some(CanvasRenderingContext2D {
|
||||
reflector_: Reflector::new(),
|
||||
canvas,
|
||||
canvas_state,
|
||||
|
@ -81,21 +81,22 @@ impl CanvasRenderingContext2D {
|
|||
ipc_sender,
|
||||
canvas_id,
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||
pub(crate) fn new(
|
||||
global: &GlobalScope,
|
||||
canvas: &HTMLCanvasElement,
|
||||
size: Size2D<u32>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<CanvasRenderingContext2D> {
|
||||
) -> Option<DomRoot<CanvasRenderingContext2D>> {
|
||||
let boxed = Box::new(CanvasRenderingContext2D::new_inherited(
|
||||
global,
|
||||
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(canvas)),
|
||||
size,
|
||||
));
|
||||
reflect_dom_object(boxed, global, can_gc)
|
||||
)?);
|
||||
Some(reflect_dom_object(boxed, global, can_gc))
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#reset-the-rendering-context-to-its-default-state
|
||||
|
|
|
@ -205,7 +205,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);
|
||||
let context = CanvasRenderingContext2D::new(window.as_global_scope(), self, size, can_gc)?;
|
||||
*self.context_mode.borrow_mut() =
|
||||
Some(RenderingContext::Context2d(Dom::from_ref(&*context)));
|
||||
Some(context)
|
||||
|
|
|
@ -135,7 +135,7 @@ impl OffscreenCanvas {
|
|||
_ => None,
|
||||
};
|
||||
}
|
||||
let context = OffscreenCanvasRenderingContext2D::new(&self.global(), self, can_gc);
|
||||
let context = OffscreenCanvasRenderingContext2D::new(&self.global(), self, can_gc)?;
|
||||
*self.context.borrow_mut() = Some(OffscreenRenderingContext::Context2d(Dom::from_ref(
|
||||
&*context,
|
||||
)));
|
||||
|
|
|
@ -39,29 +39,31 @@ pub(crate) struct OffscreenCanvasRenderingContext2D {
|
|||
}
|
||||
|
||||
impl OffscreenCanvasRenderingContext2D {
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||
fn new_inherited(
|
||||
global: &GlobalScope,
|
||||
canvas: &OffscreenCanvas,
|
||||
) -> OffscreenCanvasRenderingContext2D {
|
||||
) -> Option<OffscreenCanvasRenderingContext2D> {
|
||||
let size = canvas.get_size().cast();
|
||||
OffscreenCanvasRenderingContext2D {
|
||||
Some(OffscreenCanvasRenderingContext2D {
|
||||
context: CanvasRenderingContext2D::new_inherited(
|
||||
global,
|
||||
HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(DomRoot::from_ref(canvas)),
|
||||
size,
|
||||
),
|
||||
}
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||
pub(crate) fn new(
|
||||
global: &GlobalScope,
|
||||
canvas: &OffscreenCanvas,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<OffscreenCanvasRenderingContext2D> {
|
||||
) -> Option<DomRoot<OffscreenCanvasRenderingContext2D>> {
|
||||
let boxed = Box::new(OffscreenCanvasRenderingContext2D::new_inherited(
|
||||
global, canvas,
|
||||
));
|
||||
reflect_dom_object(boxed, global, can_gc)
|
||||
)?);
|
||||
Some(reflect_dom_object(boxed, global, can_gc))
|
||||
}
|
||||
|
||||
pub(crate) fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) {
|
||||
|
|
|
@ -42,23 +42,25 @@ pub(crate) struct PaintRenderingContext2D {
|
|||
}
|
||||
|
||||
impl PaintRenderingContext2D {
|
||||
fn new_inherited(global: &PaintWorkletGlobalScope) -> PaintRenderingContext2D {
|
||||
PaintRenderingContext2D {
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||
fn new_inherited(global: &PaintWorkletGlobalScope) -> Option<PaintRenderingContext2D> {
|
||||
Some(PaintRenderingContext2D {
|
||||
reflector_: Reflector::new(),
|
||||
canvas_state: CanvasState::new(global.upcast(), Size2D::zero()),
|
||||
canvas_state: CanvasState::new(global.upcast(), Size2D::zero())?,
|
||||
device_pixel_ratio: Cell::new(Scale::new(1.0)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||
pub(crate) fn new(
|
||||
global: &PaintWorkletGlobalScope,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<PaintRenderingContext2D> {
|
||||
reflect_dom_object(
|
||||
Box::new(PaintRenderingContext2D::new_inherited(global)),
|
||||
) -> Option<DomRoot<PaintRenderingContext2D>> {
|
||||
Some(reflect_dom_object(
|
||||
Box::new(PaintRenderingContext2D::new_inherited(global)?),
|
||||
global,
|
||||
can_gc,
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
/// Send update to canvas paint thread and returns [`ImageKey`]
|
||||
|
|
|
@ -563,7 +563,9 @@ impl PaintWorkletGlobalScopeMethods<crate::DomTypeHolder> for PaintWorkletGlobal
|
|||
}
|
||||
|
||||
// Step 19.
|
||||
let context = PaintRenderingContext2D::new(self, CanGc::note());
|
||||
let Some(context) = PaintRenderingContext2D::new(self, CanGc::note()) else {
|
||||
return Err(Error::Operation);
|
||||
};
|
||||
let definition = PaintDefinition::new(
|
||||
paint_val.handle(),
|
||||
paint_function.handle(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue