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

@ -17,7 +17,7 @@ use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use log::warn;
use net_traits::ResourceThreads;
use pixels::{Snapshot, SnapshotPixelFormat};
use pixels::Snapshot;
use style::color::AbsoluteColor;
use style::properties::style_structs::Font as FontStyleStruct;
use webrender_api::ImageKey;
@ -175,29 +175,16 @@ impl<'a> CanvasPaintThread<'a> {
.canvas(canvas_id)
.is_point_in_path_(&path[..], x, y, fill_rule, chan),
Canvas2dMsg::DrawImage(snapshot, dest_rect, source_rect, smoothing_enabled) => {
let mut snapshot = snapshot.to_owned();
let size = snapshot.size();
let (data, alpha_mode, _) =
snapshot.as_bytes(None, Some(SnapshotPixelFormat::BGRA));
self.canvas(canvas_id).draw_image(
data,
size,
snapshot.to_owned(),
dest_rect,
source_rect,
smoothing_enabled,
alpha_mode.alpha().needs_alpha_multiplication(),
)
},
Canvas2dMsg::DrawEmptyImage(image_size, dest_rect, source_rect) => {
self.canvas(canvas_id).draw_image(
&vec![0; image_size.area() as usize * 4],
image_size,
dest_rect,
source_rect,
false,
false,
)
},
Canvas2dMsg::DrawEmptyImage(image_size, dest_rect, source_rect) => self
.canvas(canvas_id)
.draw_image(Snapshot::cleared(image_size), dest_rect, source_rect, false),
Canvas2dMsg::DrawImageInOther(
other_canvas_id,
image_size,
@ -205,18 +192,14 @@ impl<'a> CanvasPaintThread<'a> {
source_rect,
smoothing,
) => {
let mut snapshot = self
let snapshot = self
.canvas(canvas_id)
.read_pixels(Some(source_rect.to_u32()), Some(image_size));
let (data, alpha_mode, _) =
snapshot.as_bytes(None, Some(SnapshotPixelFormat::BGRA));
self.canvas(other_canvas_id).draw_image(
data,
source_rect.size.to_u32(),
snapshot,
dest_rect,
source_rect,
smoothing,
alpha_mode.alpha().needs_alpha_multiplication(),
);
},
Canvas2dMsg::MoveTo(ref point) => self.canvas(canvas_id).move_to(point),
@ -266,9 +249,9 @@ impl<'a> CanvasPaintThread<'a> {
.read_pixels(Some(dest_rect), Some(canvas_size));
sender.send(snapshot.as_ipc()).unwrap();
},
Canvas2dMsg::PutImageData(rect, receiver) => {
Canvas2dMsg::PutImageData(rect, snapshot) => {
self.canvas(canvas_id)
.put_image_data(receiver.recv().unwrap(), rect);
.put_image_data(snapshot.to_owned(), rect);
},
Canvas2dMsg::SetShadowOffsetX(value) => {
self.canvas(canvas_id).set_shadow_offset_x(value)
@ -403,22 +386,15 @@ impl Canvas<'_> {
fn draw_image(
&mut self,
data: &[u8],
size: Size2D<u32>,
snapshot: Snapshot,
dest_rect: Rect<f64>,
source_rect: Rect<f64>,
smoothing_enabled: bool,
premultiply: bool,
) {
match self {
Canvas::Raqote(canvas_data) => canvas_data.draw_image(
data,
size,
dest_rect,
source_rect,
smoothing_enabled,
premultiply,
),
Canvas::Raqote(canvas_data) => {
canvas_data.draw_image(snapshot, dest_rect, source_rect, smoothing_enabled)
},
}
}
@ -618,9 +594,9 @@ impl Canvas<'_> {
}
}
fn put_image_data(&mut self, unwrap: Vec<u8>, rect: Rect<u32>) {
fn put_image_data(&mut self, snapshot: Snapshot, rect: Rect<u32>) {
match self {
Canvas::Raqote(canvas_data) => canvas_data.put_image_data(unwrap, rect),
Canvas::Raqote(canvas_data) => canvas_data.put_image_data(snapshot, rect),
}
}