canvas: Use snapshot in canvas backends (#37863)

This removes assumption about pixel format from backend abstraction to
actual backend implementation. This is important for vello.

Testing: WPT tests

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
sagudev 2025-07-04 22:22:20 +02:00 committed by GitHub
parent 8df5e1e74d
commit e1a891ea96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 174 additions and 292 deletions

View file

@ -5,6 +5,7 @@
use canvas_traits::canvas::{FillOrStrokeStyle, RepetitionStyle, SurfaceStyle};
use dom_struct::dom_struct;
use euclid::default::{Size2D, Transform2D};
use pixels::{IpcSnapshot, Snapshot};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::CanvasPatternMethods;
@ -21,7 +22,8 @@ use crate::script_runtime::CanGc;
#[dom_struct]
pub(crate) struct CanvasPattern {
reflector_: Reflector,
surface_data: Vec<u8>,
#[no_trace]
surface_data: IpcSnapshot,
#[no_trace]
surface_size: Size2D<u32>,
repeat_x: bool,
@ -33,7 +35,7 @@ pub(crate) struct CanvasPattern {
impl CanvasPattern {
fn new_inherited(
surface_data: Vec<u8>,
surface_data: Snapshot,
surface_size: Size2D<u32>,
repeat: RepetitionStyle,
origin_clean: bool,
@ -47,7 +49,7 @@ impl CanvasPattern {
CanvasPattern {
reflector_: Reflector::new(),
surface_data,
surface_data: surface_data.as_ipc(),
surface_size,
repeat_x: x,
repeat_y: y,
@ -57,7 +59,7 @@ impl CanvasPattern {
}
pub(crate) fn new(
global: &GlobalScope,
surface_data: Vec<u8>,
surface_data: Snapshot,
surface_size: Size2D<u32>,
repeat: RepetitionStyle,
origin_clean: bool,

View file

@ -12,6 +12,7 @@ use js::gc::CustomAutoRooterGuard;
use js::jsapi::JSObject;
use js::rust::HandleObject;
use js::typedarray::{ClampedU8, Uint8ClampedArray};
use pixels::{Snapshot, SnapshotAlphaMode, SnapshotPixelFormat};
use super::bindings::buffer_source::{HeapBufferSource, create_heap_buffer_source_with_length};
use crate::dom::bindings::buffer_source::create_buffer_source;
@ -183,6 +184,18 @@ impl ImageData {
pixels::rgba8_get_rect(unsafe { self.as_slice() }, self.get_size().to_u32(), rect)
}
#[allow(unsafe_code)]
pub(crate) fn get_snapshot_rect(&self, rect: Rect<u32>) -> Snapshot {
Snapshot::from_vec(
rect.size,
SnapshotPixelFormat::RGBA,
SnapshotAlphaMode::Transparent {
premultiplied: false,
},
unsafe { self.get_rect(rect).into_owned() },
)
}
#[allow(unsafe_code)]
pub(crate) fn to_shared_memory(&self) -> IpcSharedMemory {
// This is safe because we copy the slice content