mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Set the placeholder canvas element of offscreenCanvas to a weak reference in transferControlToOffscreen() (#37764)
Set the placeholder canvas element of offscreenCanvas to a weak reference in transferControlToOffscreen() Testing: I do not understand how to test it, suggestions appreciated Fixes: https://github.com/servo/servo/issues/35626 --------- Signed-off-by: Rodion Borovyk <rodion.borovyk@gmail.com>
This commit is contained in:
parent
4cd7c5196b
commit
60c10d710d
5 changed files with 52 additions and 27 deletions
|
@ -7,7 +7,7 @@
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
use layout_api::HTMLCanvasData;
|
use layout_api::HTMLCanvasData;
|
||||||
use pixels::Snapshot;
|
use pixels::Snapshot;
|
||||||
use script_bindings::root::Dom;
|
use script_bindings::root::{Dom, DomRoot};
|
||||||
use webrender_api::ImageKey;
|
use webrender_api::ImageKey;
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
|
use crate::dom::bindings::codegen::UnionTypes::HTMLCanvasElementOrOffscreenCanvas;
|
||||||
|
@ -81,7 +81,7 @@ pub(crate) trait CanvasContext {
|
||||||
|
|
||||||
pub(crate) trait CanvasHelpers {
|
pub(crate) trait CanvasHelpers {
|
||||||
fn size(&self) -> Size2D<u32>;
|
fn size(&self) -> Size2D<u32>;
|
||||||
fn canvas(&self) -> Option<&HTMLCanvasElement>;
|
fn canvas(&self) -> Option<DomRoot<HTMLCanvasElement>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CanvasHelpers for HTMLCanvasElementOrOffscreenCanvas {
|
impl CanvasHelpers for HTMLCanvasElementOrOffscreenCanvas {
|
||||||
|
@ -94,9 +94,9 @@ impl CanvasHelpers for HTMLCanvasElementOrOffscreenCanvas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn canvas(&self) -> Option<&HTMLCanvasElement> {
|
fn canvas(&self) -> Option<DomRoot<HTMLCanvasElement>> {
|
||||||
match self {
|
match self {
|
||||||
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => Some(canvas),
|
HTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(canvas) => Some(canvas.clone()),
|
||||||
HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas) => canvas.placeholder(),
|
HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas) => canvas.placeholder(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,15 +348,25 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
|
||||||
fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>, can_gc: CanGc) {
|
fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state.fill_text(
|
||||||
.fill_text(self.canvas.canvas(), text, x, y, max_width, can_gc);
|
self.canvas.canvas().as_deref(),
|
||||||
|
text,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
max_width,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
self.mark_as_dirty();
|
self.mark_as_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#textmetrics
|
// https://html.spec.whatwg.org/multipage/#textmetrics
|
||||||
fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> {
|
fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> {
|
||||||
self.canvas_state
|
self.canvas_state.measure_text(
|
||||||
.measure_text(&self.global(), self.canvas.canvas(), text, can_gc)
|
&self.global(),
|
||||||
|
self.canvas.canvas().as_deref(),
|
||||||
|
text,
|
||||||
|
can_gc,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
|
@ -367,7 +377,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-font
|
||||||
fn SetFont(&self, value: DOMString, can_gc: CanGc) {
|
fn SetFont(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_font(self.canvas.canvas(), value, can_gc)
|
.set_font(self.canvas.canvas().as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
|
||||||
|
@ -403,7 +413,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
||||||
fn DrawImage(&self, image: CanvasImageSource, dx: f64, dy: f64) -> ErrorResult {
|
fn DrawImage(&self, image: CanvasImageSource, dx: f64, dy: f64) -> ErrorResult {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.draw_image(self.canvas.canvas(), image, dx, dy)
|
.draw_image(self.canvas.canvas().as_deref(), image, dx, dy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
||||||
|
@ -416,7 +426,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
dh: f64,
|
dh: f64,
|
||||||
) -> ErrorResult {
|
) -> ErrorResult {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.draw_image_(self.canvas.canvas(), image, dx, dy, dw, dh)
|
.draw_image_(self.canvas.canvas().as_deref(), image, dx, dy, dw, dh)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
|
||||||
|
@ -432,8 +442,18 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
dw: f64,
|
dw: f64,
|
||||||
dh: f64,
|
dh: f64,
|
||||||
) -> ErrorResult {
|
) -> ErrorResult {
|
||||||
self.canvas_state
|
self.canvas_state.draw_image__(
|
||||||
.draw_image__(self.canvas.canvas(), image, sx, sy, sw, sh, dx, dy, dw, dh)
|
self.canvas.canvas().as_deref(),
|
||||||
|
image,
|
||||||
|
sx,
|
||||||
|
sy,
|
||||||
|
sw,
|
||||||
|
sh,
|
||||||
|
dx,
|
||||||
|
dy,
|
||||||
|
dw,
|
||||||
|
dh,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-moveto
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-moveto
|
||||||
|
@ -506,7 +526,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_stroke_style(self.canvas.canvas(), value, can_gc)
|
.set_stroke_style(self.canvas.canvas().as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
|
@ -517,7 +537,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
|
||||||
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_fill_style(self.canvas.canvas(), value, can_gc)
|
.set_fill_style(self.canvas.canvas().as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
||||||
|
@ -717,6 +737,6 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
|
||||||
fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) {
|
fn SetShadowColor(&self, value: DOMString, can_gc: CanGc) {
|
||||||
self.canvas_state
|
self.canvas_state
|
||||||
.set_shadow_color(self.canvas.canvas(), value, can_gc)
|
.set_shadow_color(self.canvas.canvas().as_deref(), value, can_gc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ use js::error::throw_type_error;
|
||||||
use js::rust::{HandleObject, HandleValue};
|
use js::rust::{HandleObject, HandleValue};
|
||||||
use layout_api::HTMLCanvasData;
|
use layout_api::HTMLCanvasData;
|
||||||
use pixels::{Snapshot, SnapshotAlphaMode, SnapshotPixelFormat};
|
use pixels::{Snapshot, SnapshotAlphaMode, SnapshotPixelFormat};
|
||||||
|
use script_bindings::weakref::WeakRef;
|
||||||
use servo_media::streams::MediaStreamType;
|
use servo_media::streams::MediaStreamType;
|
||||||
use servo_media::streams::registry::MediaStreamId;
|
use servo_media::streams::registry::MediaStreamId;
|
||||||
use style::attr::AttrValue;
|
use style::attr::AttrValue;
|
||||||
|
@ -675,7 +676,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
|
||||||
None,
|
None,
|
||||||
self.Width().into(),
|
self.Width().into(),
|
||||||
self.Height().into(),
|
self.Height().into(),
|
||||||
Some(&Dom::from_ref(self)),
|
Some(WeakRef::new(self)),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ use dom_struct::dom_struct;
|
||||||
use euclid::default::Size2D;
|
use euclid::default::Size2D;
|
||||||
use js::rust::{HandleObject, HandleValue};
|
use js::rust::{HandleObject, HandleValue};
|
||||||
use pixels::Snapshot;
|
use pixels::Snapshot;
|
||||||
|
use script_bindings::weakref::WeakRef;
|
||||||
|
|
||||||
use crate::canvas_context::{CanvasContext, OffscreenRenderingContext};
|
use crate::canvas_context::{CanvasContext, OffscreenRenderingContext};
|
||||||
use crate::dom::bindings::cell::{DomRefCell, Ref};
|
use crate::dom::bindings::cell::{DomRefCell, Ref};
|
||||||
|
@ -38,21 +39,21 @@ pub(crate) struct OffscreenCanvas {
|
||||||
context: DomRefCell<Option<OffscreenRenderingContext>>,
|
context: DomRefCell<Option<OffscreenRenderingContext>>,
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#offscreencanvas-placeholder>
|
/// <https://html.spec.whatwg.org/multipage/#offscreencanvas-placeholder>
|
||||||
placeholder: Option<Dom<HTMLCanvasElement>>,
|
placeholder: Option<WeakRef<HTMLCanvasElement>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OffscreenCanvas {
|
impl OffscreenCanvas {
|
||||||
pub(crate) fn new_inherited(
|
pub(crate) fn new_inherited(
|
||||||
width: u64,
|
width: u64,
|
||||||
height: u64,
|
height: u64,
|
||||||
placeholder: Option<&HTMLCanvasElement>,
|
placeholder: Option<WeakRef<HTMLCanvasElement>>,
|
||||||
) -> OffscreenCanvas {
|
) -> OffscreenCanvas {
|
||||||
OffscreenCanvas {
|
OffscreenCanvas {
|
||||||
eventtarget: EventTarget::new_inherited(),
|
eventtarget: EventTarget::new_inherited(),
|
||||||
width: Cell::new(width),
|
width: Cell::new(width),
|
||||||
height: Cell::new(height),
|
height: Cell::new(height),
|
||||||
context: DomRefCell::new(None),
|
context: DomRefCell::new(None),
|
||||||
placeholder: placeholder.map(Dom::from_ref),
|
placeholder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +62,7 @@ impl OffscreenCanvas {
|
||||||
proto: Option<HandleObject>,
|
proto: Option<HandleObject>,
|
||||||
width: u64,
|
width: u64,
|
||||||
height: u64,
|
height: u64,
|
||||||
placeholder: Option<&HTMLCanvasElement>,
|
placeholder: Option<WeakRef<HTMLCanvasElement>>,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> DomRoot<OffscreenCanvas> {
|
) -> DomRoot<OffscreenCanvas> {
|
||||||
reflect_dom_object_with_proto(
|
reflect_dom_object_with_proto(
|
||||||
|
@ -126,8 +127,10 @@ impl OffscreenCanvas {
|
||||||
Some(context)
|
Some(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn placeholder(&self) -> Option<&HTMLCanvasElement> {
|
pub(crate) fn placeholder(&self) -> Option<DomRoot<HTMLCanvasElement>> {
|
||||||
self.placeholder.as_deref()
|
self.placeholder
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|placeholder| placeholder.root())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,8 +184,8 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas {
|
||||||
canvas_context.resize();
|
canvas_context.resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(canvas) = &self.placeholder {
|
if let Some(canvas) = self.placeholder() {
|
||||||
canvas.set_natural_width(value as _, can_gc);
|
canvas.set_natural_width(value as _, can_gc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,8 +202,8 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas {
|
||||||
canvas_context.resize();
|
canvas_context.resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(canvas) = &self.placeholder {
|
if let Some(canvas) = self.placeholder() {
|
||||||
canvas.set_natural_height(value as _, can_gc);
|
canvas.set_natural_height(value as _, can_gc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -345,6 +345,7 @@ DOMInterfaces = {
|
||||||
|
|
||||||
'HTMLCanvasElement': {
|
'HTMLCanvasElement': {
|
||||||
'canGc': ['CaptureStream', 'GetContext', 'SetHeight', 'SetWidth', 'TransferControlToOffscreen'],
|
'canGc': ['CaptureStream', 'GetContext', 'SetHeight', 'SetWidth', 'TransferControlToOffscreen'],
|
||||||
|
'weakReferenceable': True,
|
||||||
},
|
},
|
||||||
|
|
||||||
'HTMLDataListElement': {
|
'HTMLDataListElement': {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue