canvas: Add HTMLVideoElement to CanvasImageSource union type (#37135)

Follow to the specification and add HTMLVideoElement to
CanvasImageSource union type
to allow use it as image source for createPattern/drawImage operations.
https://html.spec.whatwg.org/multipage/#canvasimagesource

https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage

The HTMLVideoElement media resource has an associated origin:
- media provider object (MediaStream/MediaSource/Blob): CORS-same-origin
 - URL record: CORS-cross-origin/CORS-same-origin

https://html.spec.whatwg.org/multipage/media.html#media-resource

Testing:
 - html/canvas/element/*
 - html/semantics/embedded-content/the-canvas-element/*

Signed-off-by: Andrei Volykhin <andrei.volykhin@gmail.com>
This commit is contained in:
Andrei Volykhin 2025-05-28 15:04:01 +03:00 committed by GitHub
parent 4f4c99a39e
commit 644138c1da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 184 additions and 88 deletions

View file

@ -658,14 +658,23 @@ impl WebGLRenderingContext {
return Ok(None);
}
},
TexImageSource::HTMLVideoElement(video) => match video.get_current_frame_data() {
Some((data, size)) => {
let data = data.unwrap_or_else(|| {
IpcSharedMemory::from_bytes(&vec![0; size.area() as usize * 4])
});
TexPixels::new(data, size, PixelFormat::BGRA8, false)
},
None => return Ok(None),
TexImageSource::HTMLVideoElement(video) => {
if !video.origin_is_clean() {
return Err(Error::Security);
}
let Some(snapshot) = video.get_current_frame_data() else {
return Ok(None);
};
let snapshot = snapshot.as_ipc();
let size = snapshot.size().cast();
let format: PixelFormat = 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)
},
}))
}