From d678901122a654c71081ea0e99c393813e366c00 Mon Sep 17 00:00:00 2001 From: sagudev <16504129+sagudev@users.noreply.github.com> Date: Sat, 26 Jul 2025 06:53:10 +0200 Subject: [PATCH] canvas: Add vello backend (#36821) Add vello backend by implementing Backend traits in canvas crate (so this lives in canvas_paint_thread - embedded process). Current implementation uses normal wgpu, so we block on GPU work. Vello backend is gated behind `vello` feature and `dom_canvas_vello_enabled` pref. Feature-wise this backend is on on par with raqote (sometimes better sometimes worse), but performance wise it's worse. ## Known vello problems: - image roundtrip does not work (fixed in https://github.com/linebender/vello/pull/974) - https://github.com/linebender/vello/issues/1066 (fixed) - clip layers are not working properly: https://github.com/linebender/vello/issues/1061 - `/html/canvas/element/pixel-manipulation/2d.imageData.put.*` - `/html/canvas/element/path-objects/2d.path.clip.intersect.html` - https://github.com/linebender/vello/issues/1056 - `/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html` - `kurbo::Cap::Butt` is defect (only visible with big lineWidth) https://github.com/linebender/vello/issues/1063 - `/html/canvas/element/line-styles/2d.line.cross.html` - `/html/canvas/element/line-styles/2d.line.miter.acute.html` - other lack of strong correct problems (https://github.com/linebender/vello/issues/1063#issuecomment-2998084736): - `/html/canvas/element/path-objects/2d.path.rect.selfintersect.html` - There is currently no way to do put image properly in vello as we would need to ignore all clips and other stuff (we try to work around this on best effort basis) https://github.com/linebender/vello/issues/1088 - `/html/canvas/element/pixel-manipulation/2d.imageData.put.*` - precision problems - `/html/canvas/element/path-objects/2d.path.stroke.scale2.html` - `/html/canvas/element/path-objects/2d.path.arc.scale.1.html` ## Known servo problems - bad performance due to blocking on GPU work - some get/put intensive tests `TIMEOUT` - proper shadow support (non-blocker as we already are living without it now) - support for rect shadow is there but unimplemented currently as that's the state in raqote Testing: `mach try vello` will run normal WPT (with raqote) + vello_canvas subsuite that runs only on `/html/canvas/element`. All subsuite expectations are stored separately. Fixes: #36823 Fixes: #35230 --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com> --- Cargo.lock | 138 ++++ Cargo.toml | 1 + components/canvas/Cargo.toml | 7 + components/canvas/canvas_paint_thread.rs | 95 ++- components/canvas/lib.rs | 2 + components/canvas/vello_backend.rs | 752 ++++++++++++++++++ components/config/prefs.rs | 3 + components/constellation/Cargo.toml | 1 + components/servo/Cargo.toml | 1 + deny.toml | 2 +- ports/servoshell/Cargo.toml | 1 + python/servo/try_parser.py | 16 +- ...rid.no_filter.no_shadow.drawImage.html.ini | 3 +- ...grid.no_filter.no_shadow.fillRect.html.ini | 3 +- ....grid.no_filter.no_shadow.pattern.html.ini | 3 +- ...d.gradient.interpolate.coloralpha.html.ini | 5 + .../2d.gradient.radial.cone.behind.html.ini | 4 +- .../2d.gradient.radial.cone.shape2.html.ini | 4 +- .../2d.gradient.radial.outside2.html.ini | 4 +- .../2d.gradient.radial.outside3.html.ini | 4 +- ...2d.layer.globalCompositeOperation.html.ini | 4 + .../line-styles/2d.line.cross.html.ini | 5 + .../line-styles/2d.line.miter.acute.html.ini | 5 + .../canvas-createImageBitmap-resize.html.ini | 14 +- .../createImageBitmap-drawImage.html.ini | 38 + .../text/canvas.2d.lang.dynamic.html.ini | 3 + ...lay-p3-drawImage-ImageBitmap-Blob.html.ini | 2 + ...drawImage-ImageBitmap-ImageBitmap.html.ini | 3 + ...y-p3-drawImage-ImageBitmap-cloned.html.ini | 2 + ...ay-p3-drawImage-ImageBitmap-image.html.ini | 2 + ...canvas-display-p3-drawImage.https.html.ini | 738 ++++++++++++++--- .../canvas-display-p3-pattern-image.html.ini | 2 + .../path-objects/2d.path.arc.scale.1.html.ini | 4 + .../path-objects/2d.path.arc.scale.2.html.ini | 4 +- .../2d.path.arc.selfintersect.1.html.ini | 4 +- .../2d.path.arc.selfintersect.2.html.ini | 4 +- .../path-objects/2d.path.arc.shape.3.html.ini | 4 +- .../path-objects/2d.path.arc.shape.4.html.ini | 4 +- .../2d.path.clip.intersect.html.ini | 5 + .../2d.path.rect.selfintersect.html.ini | 5 + .../2d.path.stroke.scale2.html.ini | 4 + .../2d.imageData.put.clip.html.ini | 5 + .../2d.imageData.put.dirty.negative.html.ini | 5 + .../2d.imageData.put.dirty.rect1.html.ini | 5 + .../2d.imageData.put.dirty.rect2.html.ini | 5 + .../2d.imageData.put.unchanged.html.ini | 4 +- .../2d.transformation.scale.large.html.ini | 4 +- ...2d.layer.globalCompositeOperation.html.ini | 3 +- tests/wpt/vello_canvas_subsuite.json | 8 + 49 files changed, 1779 insertions(+), 165 deletions(-) create mode 100644 components/canvas/vello_backend.rs create mode 100644 tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/layers/2d.layer.globalCompositeOperation.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/line-styles/2d.line.cross.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/line-styles/2d.line.miter.acute.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/manual/text/canvas.2d.lang.dynamic.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.1.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/path-objects/2d.path.clip.intersect.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/path-objects/2d.path.rect.selfintersect.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/path-objects/2d.path.stroke.scale2.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html.ini create mode 100644 tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html.ini create mode 100644 tests/wpt/vello_canvas_subsuite.json diff --git a/Cargo.lock b/Cargo.lock index d254968362b..e4047b627cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1071,16 +1071,20 @@ dependencies = [ "euclid", "font-kit", "fonts", + "futures-intrusive", "ipc-channel", "kurbo", "log", "net_traits", "pixels", + "pollster", "range", "raqote", "servo_arc", + "servo_config", "stylo", "unicode-script", + "vello", "webrender_api", ] @@ -1324,6 +1328,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "color" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ae467d04a8a8aea5d9a49018a6ade2e4221d92968e8ce55a48c0b1164e5f698" + [[package]] name = "color_quant" version = "1.1.0" @@ -2798,6 +2808,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -3480,6 +3501,16 @@ dependencies = [ "system-deps", ] +[[package]] +name = "guillotiere" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +dependencies = [ + "euclid", + "svg_fmt", +] + [[package]] name = "h2" version = "0.3.27" @@ -6181,6 +6212,17 @@ dependencies = [ "synstructure", ] +[[package]] +name = "peniko" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f9529efd019889b2a205193c14ffb6e2839b54ed9d2720674f10f4b04d87ac9" +dependencies = [ + "color", + "kurbo", + "smallvec", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -6386,6 +6428,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + [[package]] name = "polyval" version = "0.6.2" @@ -6821,6 +6869,12 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "renderdoc-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" + [[package]] name = "resvg" version = "0.45.1" @@ -7805,6 +7859,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +[[package]] +name = "skrifa" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbeb4ca4399663735553a09dd17ce7e49a0a0203f03b706b39628c4d913a8607" +dependencies = [ + "bytemuck", + "read-fonts", +] + [[package]] name = "slab" version = "0.4.10" @@ -9066,6 +9130,48 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +[[package]] +name = "vello" +version = "0.5.0" +source = "git+https://github.com/linebender/vello?rev=ecf6b282dba01e5dc50e9463b87b6baeccdb3094#ecf6b282dba01e5dc50e9463b87b6baeccdb3094" +dependencies = [ + "bytemuck", + "futures-intrusive", + "log", + "peniko", + "png", + "skrifa", + "static_assertions", + "thiserror 2.0.12", + "vello_encoding", + "vello_shaders", + "wgpu", +] + +[[package]] +name = "vello_encoding" +version = "0.5.0" +source = "git+https://github.com/linebender/vello?rev=ecf6b282dba01e5dc50e9463b87b6baeccdb3094#ecf6b282dba01e5dc50e9463b87b6baeccdb3094" +dependencies = [ + "bytemuck", + "guillotiere", + "peniko", + "skrifa", + "smallvec", +] + +[[package]] +name = "vello_shaders" +version = "0.5.0" +source = "git+https://github.com/linebender/vello?rev=ecf6b282dba01e5dc50e9463b87b6baeccdb3094#ecf6b282dba01e5dc50e9463b87b6baeccdb3094" +dependencies = [ + "bytemuck", + "log", + "naga", + "thiserror 2.0.12", + "vello_encoding", +] + [[package]] name = "version-compare" version = "0.2.0" @@ -9593,6 +9699,34 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" +[[package]] +name = "wgpu" +version = "25.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8fb398f119472be4d80bc3647339f56eb63b2a331f6a3d16e25d8144197dd9" +dependencies = [ + "arrayvec", + "bitflags 2.9.1", + "cfg_aliases", + "document-features", + "hashbrown", + "js-sys", + "log", + "naga", + "parking_lot", + "portable-atomic", + "profiling", + "raw-window-handle", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + [[package]] name = "wgpu-core" version = "25.0.1" @@ -9611,7 +9745,9 @@ dependencies = [ "naga", "once_cell", "parking_lot", + "portable-atomic", "profiling", + "raw-window-handle", "rustc-hash 1.1.0", "serde", "smallvec", @@ -9683,9 +9819,11 @@ dependencies = [ "objc", "ordered-float", "parking_lot", + "portable-atomic", "profiling", "range-alloc", "raw-window-handle", + "renderdoc-sys", "smallvec", "thiserror 2.0.12", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index a1c50c9cc52..6391d648670 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -166,6 +166,7 @@ unicode-segmentation = "1.12.0" url = "2.5" urlpattern = "0.3" uuid = { version = "1.12.1", features = ["v4"] } +vello = { git = "https://github.com/linebender/vello", rev = "ecf6b282dba01e5dc50e9463b87b6baeccdb3094" } webdriver = "0.53.0" webgpu_traits = { path = "components/shared/webgpu" } webpki-roots = "1.0" diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 81fadb26eb7..97b36e10f4b 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -11,6 +11,9 @@ rust-version.workspace = true name = "canvas" path = "lib.rs" +[features] +vello = ["dep:vello", "dep:pollster", "dep:futures-intrusive"] + [dependencies] app_units = { workspace = true } canvas_traits = { workspace = true } @@ -31,3 +34,7 @@ servo_arc = { workspace = true } stylo = { workspace = true } unicode-script = { workspace = true } webrender_api = { workspace = true } +servo_config = { path = "../config" } +vello = { workspace = true, optional = true } +pollster = { version = "0.4", optional = true } +futures-intrusive = { version = "0.5", optional = true } diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index 125d1f5f0ea..810ef196b9d 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -110,10 +110,9 @@ impl CanvasPaintThread { let canvas_id = self.next_canvas_id; self.next_canvas_id.0 += 1; - let canvas_data = - CanvasData::new(size, self.compositor_api.clone(), self.font_context.clone()); - let image_key = canvas_data.image_key(); - self.canvases.insert(canvas_id, Canvas::Raqote(canvas_data)); + let canvas = Canvas::new(size, self.compositor_api.clone(), self.font_context.clone()); + let image_key = canvas.image_key(); + self.canvases.insert(canvas_id, canvas); (canvas_id, image_key) } @@ -283,14 +282,39 @@ impl CanvasPaintThread { } } +#[allow(clippy::large_enum_variant)] enum Canvas { Raqote(CanvasData), + #[cfg(feature = "vello")] + Vello(CanvasData), } impl Canvas { + fn new( + size: Size2D, + compositor_api: CrossProcessCompositorApi, + font_context: Arc, + ) -> Self { + #[cfg(feature = "vello")] + if servo_config::pref!(dom_canvas_vello_enabled) { + return Self::Vello(CanvasData::new(size, compositor_api, font_context)); + } + Self::Raqote(CanvasData::new(size, compositor_api, font_context)) + } + + fn image_key(&self) -> ImageKey { + match self { + Canvas::Raqote(canvas_data) => canvas_data.image_key(), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.image_key(), + } + } + fn pop_clip(&mut self) { match self { Canvas::Raqote(canvas_data) => canvas_data.pop_clip(), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.pop_clip(), } } @@ -320,6 +344,19 @@ impl Canvas { composition_options, transform, ), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.fill_text( + text, + x, + y, + max_width, + is_rtl, + style, + text_options, + shadow_options, + composition_options, + transform, + ), } } @@ -335,6 +372,10 @@ impl Canvas { Canvas::Raqote(canvas_data) => { canvas_data.fill_rect(rect, style, shadow_options, composition_options, transform) }, + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => { + canvas_data.fill_rect(rect, style, shadow_options, composition_options, transform) + }, } } @@ -356,6 +397,15 @@ impl Canvas { composition_options, transform, ), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.stroke_rect( + rect, + style, + line_options, + shadow_options, + composition_options, + transform, + ), } } @@ -371,6 +421,10 @@ impl Canvas { Canvas::Raqote(canvas_data) => { canvas_data.fill_path(path, style, shadow_options, composition_options, transform) }, + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => { + canvas_data.fill_path(path, style, shadow_options, composition_options, transform) + }, } } @@ -392,12 +446,23 @@ impl Canvas { composition_options, transform, ), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.stroke_path( + path, + style, + line_options, + shadow_options, + composition_options, + transform, + ), } } fn clear_rect(&mut self, rect: &Rect, transform: Transform2D) { match self { Canvas::Raqote(canvas_data) => canvas_data.clear_rect(rect, transform), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.clear_rect(rect, transform), } } @@ -421,42 +486,64 @@ impl Canvas { composition_options, transform, ), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.draw_image( + snapshot, + dest_rect, + source_rect, + smoothing_enabled, + shadow_options, + composition_options, + transform, + ), } } fn read_pixels(&mut self, read_rect: Option>) -> Snapshot { match self { Canvas::Raqote(canvas_data) => canvas_data.read_pixels(read_rect), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.read_pixels(read_rect), } } fn measure_text(&mut self, text: String, text_options: TextOptions) -> TextMetrics { match self { Canvas::Raqote(canvas_data) => canvas_data.measure_text(text, text_options), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.measure_text(text, text_options), } } fn clip_path(&mut self, path: &Path, transform: Transform2D) { match self { Canvas::Raqote(canvas_data) => canvas_data.clip_path(path, transform), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.clip_path(path, transform), } } fn put_image_data(&mut self, snapshot: Snapshot, rect: Rect) { match self { Canvas::Raqote(canvas_data) => canvas_data.put_image_data(snapshot, rect), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.put_image_data(snapshot, rect), } } fn update_image_rendering(&mut self) { match self { Canvas::Raqote(canvas_data) => canvas_data.update_image_rendering(), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.update_image_rendering(), } } fn recreate(&mut self, size: Option>) { match self { Canvas::Raqote(canvas_data) => canvas_data.recreate(size), + #[cfg(feature = "vello")] + Canvas::Vello(canvas_data) => canvas_data.recreate(size), } } } diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs index 91ab58b0e8b..a0c47557474 100644 --- a/components/canvas/lib.rs +++ b/components/canvas/lib.rs @@ -6,6 +6,8 @@ mod backend; mod raqote_backend; +#[cfg(feature = "vello")] +mod vello_backend; pub mod canvas_data; pub mod canvas_paint_thread; diff --git a/components/canvas/vello_backend.rs b/components/canvas/vello_backend.rs new file mode 100644 index 00000000000..e78697b798c --- /dev/null +++ b/components/canvas/vello_backend.rs @@ -0,0 +1,752 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Vello implementation of 2D canvas backend. +//! +//! Vello only encodes commands for GPU, then runs rendering when +//! image is explicitly requested. This requires to copy image +//! from texture to buffer, then download buffer to CPU +//! (where we also need to un pad it). +//! +//! All Vello images are in no alpha premultiplied RGBA8 pixel format. + +use std::cell::RefCell; +use std::collections::HashMap; +use std::num::NonZeroUsize; +use std::rc::Rc; + +use canvas_traits::canvas::{ + BlendingStyle, CanvasGradientStop, CompositionOptions, CompositionOrBlending, CompositionStyle, + FillOrStrokeStyle, LineCapStyle, LineJoinStyle, LineOptions, Path, ShadowOptions, +}; +use compositing_traits::SerializableImageData; +use euclid::default::{Point2D, Rect, Size2D, Transform2D}; +use fonts::{ByteIndex, FontIdentifier, FontTemplateRefMethods as _}; +use ipc_channel::ipc::IpcSharedMemory; +use pixels::{Snapshot, SnapshotAlphaMode, SnapshotPixelFormat}; +use range::Range; +use style::color::AbsoluteColor; +use vello::wgpu::{ + BackendOptions, Backends, BufferDescriptor, BufferUsages, CommandEncoderDescriptor, Device, + Extent3d, Instance, InstanceDescriptor, InstanceFlags, MapMode, Queue, TexelCopyBufferInfo, + TexelCopyBufferLayout, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, + TextureViewDescriptor, +}; +use vello::{kurbo, peniko}; +use webrender_api::{ImageDescriptor, ImageDescriptorFlags}; + +use crate::backend::GenericDrawTarget; +use crate::canvas_data::{Filter, TextRun}; + +thread_local! { + /// The shared font cache used by all canvases that render on a thread. It would be nicer + /// to have a global cache, but it looks like font-kit uses a per-thread FreeType, so + /// in order to ensure that fonts are particular to a thread we have to make our own + /// cache thread local as well. + static SHARED_FONT_CACHE: RefCell> = RefCell::default(); +} + +pub(crate) struct VelloDrawTarget { + device: Device, + queue: Queue, + renderer: Rc>, + scene: vello::Scene, + size: Size2D, +} + +fn options() -> vello::RendererOptions { + vello::RendererOptions { + use_cpu: false, + num_init_threads: NonZeroUsize::new(1), + antialiasing_support: vello::AaSupport::area_only(), + pipeline_cache: None, + } +} + +impl VelloDrawTarget { + fn with_draw_options(&mut self, draw_options: &CompositionOptions, f: F) { + self.scene.push_layer( + draw_options.composition_operation.convert(), + 1.0, + kurbo::Affine::IDENTITY, + &kurbo::Rect::ZERO.with_size(self.size.cast()), + ); + f(self); + self.scene.pop_layer(); + } + + fn render_and_download(&self, f: F) -> R + where + F: FnOnce(u32, Option<&[u8]>) -> R, + { + let size = Extent3d { + width: self.size.width, + height: self.size.height, + depth_or_array_layers: 1, + }; + let target = self.device.create_texture(&TextureDescriptor { + label: Some("Target texture"), + size, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + usage: TextureUsages::STORAGE_BINDING | TextureUsages::COPY_SRC, + view_formats: &[], + }); + let view = target.create_view(&TextureViewDescriptor::default()); + self.renderer + .borrow_mut() + .render_to_texture( + &self.device, + &self.queue, + &self.scene, + &view, + &vello::RenderParams { + base_color: peniko::color::AlphaColor::TRANSPARENT, + width: self.size.width, + height: self.size.height, + antialiasing_method: vello::AaConfig::Area, + }, + ) + .unwrap(); + // TODO(perf): do a render pass that will multiply with alpha on GPU + let padded_byte_width = (self.size.width * 4).next_multiple_of(256); + let buffer_size = padded_byte_width as u64 * self.size.height as u64; + let buffer = self.device.create_buffer(&BufferDescriptor { + label: Some("val"), + size: buffer_size, + usage: BufferUsages::MAP_READ | BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + let mut encoder = self + .device + .create_command_encoder(&CommandEncoderDescriptor { + label: Some("Copy out buffer"), + }); + encoder.copy_texture_to_buffer( + target.as_image_copy(), + TexelCopyBufferInfo { + buffer: &buffer, + layout: TexelCopyBufferLayout { + offset: 0, + bytes_per_row: Some(padded_byte_width), + rows_per_image: None, + }, + }, + size, + ); + self.queue.submit([encoder.finish()]); + let result = { + let buf_slice = buffer.slice(..); + let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + buf_slice.map_async(MapMode::Read, move |v| sender.send(v).unwrap()); + if let Err(error) = + vello::util::block_on_wgpu(&self.device, receiver.receive()).unwrap() + { + log::warn!("VELLO WGPU MAP ASYNC ERROR {error}"); + return f(padded_byte_width, None); + } + let data = buf_slice.get_mapped_range(); + f(padded_byte_width, Some(&data)) + }; + buffer.unmap(); + result + } +} + +impl GenericDrawTarget for VelloDrawTarget { + type SourceSurface = Vec; // TODO: this should be texture + + fn new(size: Size2D) -> Self { + // TODO: we should read prefs instead of env + + // we forbid GL because it clashes with servo's GL usage + let backends = Backends::from_env().unwrap_or_default() - Backends::GL; + let flags = InstanceFlags::from_build_config().with_env(); + let backend_options = BackendOptions::from_env_or_default(); + let instance = Instance::new(&InstanceDescriptor { + backends, + flags, + backend_options, + }); + let mut context = vello::util::RenderContext { + instance, + devices: Vec::new(), + }; + let device_id = pollster::block_on(context.device(None)).unwrap(); + let device_handle = &mut context.devices[device_id]; + let device = device_handle.device.clone(); + let queue = device_handle.queue.clone(); + let renderer = vello::Renderer::new(&device, options()).unwrap(); + let scene = vello::Scene::new(); + device.on_uncaptured_error(Box::new(|error| { + log::error!("VELLO WGPU ERROR: {error}"); + })); + Self { + device, + queue, + renderer: Rc::new(RefCell::new(renderer)), + scene, + size, + } + } + + fn clear_rect(&mut self, rect: &Rect, transform: Transform2D) { + let rect: kurbo::Rect = rect.cast().into(); + let transform = transform.cast().into(); + self.scene + .push_layer(peniko::Compose::Clear, 0.0, transform, &rect); + self.scene.fill( + peniko::Fill::NonZero, + transform, + peniko::BrushRef::Solid(peniko::color::AlphaColor::TRANSPARENT), + None, + &rect, + ); + self.scene.pop_layer(); + } + + fn copy_surface(&mut self, surface: Vec, source: Rect, destination: Point2D) { + let destination: kurbo::Point = destination.cast::().into(); + let rect = kurbo::Rect::from_origin_size(destination, source.size.cast()); + + // TODO: ignore clip from prev layers + // this will require creating a stacks of applicable clips + // that will be popped and reinserted after + // or we could impl this in vello directly + + // then there is also this nasty vello bug where clipping does not work correctly: + // https://xi.zulipchat.com/#narrow/channel/197075-vello/topic/Servo.202D.20canvas.20backend/near/525153593 + + self.scene + .push_layer(peniko::Compose::Copy, 1.0, kurbo::Affine::IDENTITY, &rect); + + self.scene.fill( + peniko::Fill::NonZero, + kurbo::Affine::IDENTITY, + &peniko::Image { + data: peniko::Blob::from(surface), + format: peniko::ImageFormat::Rgba8, + width: source.size.width as u32, + height: source.size.height as u32, + x_extend: peniko::Extend::Pad, + y_extend: peniko::Extend::Pad, + quality: peniko::ImageQuality::Low, + alpha: 1.0, + }, + Some(kurbo::Affine::translate(destination.to_vec2())), + &rect, + ); + + self.scene.pop_layer(); + } + + fn create_similar_draw_target(&self, size: &Size2D) -> Self { + Self { + device: self.device.clone(), + queue: self.queue.clone(), + renderer: self.renderer.clone(), + scene: vello::Scene::new(), + size: size.cast(), + } + } + + fn draw_surface( + &mut self, + surface: Vec, + dest: Rect, + source: Rect, + filter: Filter, + composition_options: CompositionOptions, + transform: Transform2D, + ) { + let scale_up = dest.size.width > source.size.width || dest.size.height > source.size.height; + let shape: kurbo::Rect = dest.into(); + self.with_draw_options(&composition_options, move |self_| { + self_.scene.fill( + peniko::Fill::NonZero, + transform.cast().into(), + &peniko::Image { + data: peniko::Blob::from(surface), + format: peniko::ImageFormat::Rgba8, + width: source.size.width as u32, + height: source.size.height as u32, + x_extend: peniko::Extend::Pad, + y_extend: peniko::Extend::Pad, + // we should only do bicubic when scaling up + quality: if scale_up { + filter.convert() + } else { + peniko::ImageQuality::Low + }, + alpha: composition_options.alpha as f32, + }, + Some( + kurbo::Affine::translate((dest.origin.x, dest.origin.y)).pre_scale_non_uniform( + dest.size.width / source.size.width, + dest.size.height / source.size.height, + ), + ), + &shape, + ) + }) + } + + fn draw_surface_with_shadow( + &self, + _surface: Vec, + _dest: &Point2D, + _shadow_options: ShadowOptions, + _composition_options: CompositionOptions, + ) { + log::warn!("no support for drawing shadows"); + /* + We will need to do some changes to support drawing shadows with vello, as current abstraction is made for azure. + In vello we do not need new draw target (we will use layers) and we need to pass whole rect. + offsets will be applied to rect directly. shadow blur will be passed directly to let backend do transforms. + */ + //self_.scene.draw_blurred_rounded_rect(self_.transform, rect, color, 0.0, sigma); + } + + fn fill( + &mut self, + path: &Path, + style: FillOrStrokeStyle, + composition_options: CompositionOptions, + transform: Transform2D, + ) { + self.with_draw_options(&composition_options, |self_| { + self_.scene.fill( + peniko::Fill::NonZero, + transform.cast().into(), + &style + .convert() + .multiply_alpha(composition_options.alpha as f32), + None, + &path.0, + ); + }) + } + + fn fill_text( + &mut self, + text_runs: Vec, + start: Point2D, + style: FillOrStrokeStyle, + composition_options: CompositionOptions, + transform: Transform2D, + ) { + let pattern = style + .convert() + .multiply_alpha(composition_options.alpha as f32); + let transform = transform.cast().into(); + self.with_draw_options(&composition_options, |self_| { + let mut advance = 0.; + for run in text_runs.iter() { + let glyphs = &run.glyphs; + + let template = &run.font.template; + + SHARED_FONT_CACHE.with(|font_cache| { + let identifier = template.identifier(); + if !font_cache.borrow().contains_key(&identifier) { + font_cache.borrow_mut().insert( + identifier.clone(), + peniko::Font::new( + peniko::Blob::from(run.font.data().as_ref().to_vec()), + identifier.index(), + ), + ); + } + + let font_cache = font_cache.borrow(); + let Some(font) = font_cache.get(&identifier) else { + return; + }; + + self_ + .scene + .draw_glyphs(font) + .transform(transform) + .brush(&pattern) + .font_size(run.font.descriptor.pt_size.to_f32_px()) + .draw( + peniko::Fill::NonZero, + glyphs + .iter_glyphs_for_byte_range(&Range::new(ByteIndex(0), glyphs.len())) + .map(|glyph| { + let glyph_offset = glyph.offset().unwrap_or(Point2D::zero()); + let x = advance + start.x + glyph_offset.x.to_f32_px(); + let y = start.y + glyph_offset.y.to_f32_px(); + advance += glyph.advance().to_f32_px(); + vello::Glyph { + id: glyph.id(), + x, + y, + } + }), + ); + }); + } + }) + } + + fn fill_rect( + &mut self, + rect: &Rect, + style: FillOrStrokeStyle, + composition_options: CompositionOptions, + transform: Transform2D, + ) { + let pattern = style + .convert() + .multiply_alpha(composition_options.alpha as f32); + let transform = transform.cast().into(); + let rect: kurbo::Rect = rect.cast().into(); + self.with_draw_options(&composition_options, |self_| { + self_ + .scene + .fill(peniko::Fill::NonZero, transform, &pattern, None, &rect); + }) + } + + fn get_size(&self) -> Size2D { + self.size.cast() + } + + fn pop_clip(&mut self) { + self.scene.pop_layer(); + } + + fn push_clip(&mut self, path: &Path, transform: Transform2D) { + self.scene + .push_layer(peniko::Mix::Clip, 1.0, transform.cast().into(), &path.0); + } + + fn push_clip_rect(&mut self, rect: &Rect) { + let mut path = Path::new(); + let rect = rect.cast(); + path.rect( + rect.origin.x, + rect.origin.y, + rect.size.width, + rect.size.height, + ); + self.push_clip(&path, Transform2D::identity()); + } + + fn stroke( + &mut self, + path: &Path, + style: FillOrStrokeStyle, + line_options: LineOptions, + composition_options: CompositionOptions, + transform: Transform2D, + ) { + self.with_draw_options(&composition_options, |self_| { + self_.scene.stroke( + &line_options.convert(), + transform.cast().into(), + &style + .convert() + .multiply_alpha(composition_options.alpha as f32), + None, + &path.0, + ); + }) + } + + fn stroke_rect( + &mut self, + rect: &Rect, + style: FillOrStrokeStyle, + line_options: LineOptions, + composition_options: CompositionOptions, + transform: Transform2D, + ) { + let rect: kurbo::Rect = rect.cast().into(); + self.with_draw_options(&composition_options, |self_| { + self_.scene.stroke( + &line_options.convert(), + transform.cast().into(), + &style + .convert() + .multiply_alpha(composition_options.alpha as f32), + None, + &rect, + ); + }) + } + + fn image_descriptor_and_serializable_data( + &mut self, + ) -> (ImageDescriptor, SerializableImageData) { + let size = self.size; + self.render_and_download(|stride, data| { + let image_desc = ImageDescriptor { + format: webrender_api::ImageFormat::RGBA8, + size: size.cast().cast_unit(), + stride: data.map(|_| stride as i32), + offset: 0, + flags: ImageDescriptorFlags::empty(), + }; + let data = SerializableImageData::Raw(if let Some(data) = data { + let mut data = IpcSharedMemory::from_bytes(data); + #[allow(unsafe_code)] + unsafe { + pixels::generic_transform_inplace::<1, false, false>(data.deref_mut()); + }; + data + } else { + IpcSharedMemory::from_byte(0, size.area() as usize * 4) + }); + (image_desc, data) + }) + } + + fn snapshot(&mut self) -> pixels::Snapshot { + let size = self.size; + self.render_and_download(|padded_byte_width, data| { + let data = data + .map(|data| { + let mut result_unpadded = Vec::::with_capacity(size.area() as usize * 4); + for row in 0..self.size.height { + let start = (row * padded_byte_width).try_into().unwrap(); + result_unpadded + .extend(&data[start..start + (self.size.width * 4) as usize]); + } + result_unpadded + }) + .unwrap_or_else(|| vec![0; size.area() as usize * 4]); + Snapshot::from_vec( + size, + SnapshotPixelFormat::RGBA, + SnapshotAlphaMode::Transparent { + premultiplied: false, + }, + data, + ) + }) + } + + fn surface(&mut self) -> Vec { + self.snapshot().to_vec(None, None).0 + } + + fn create_source_surface_from_data(&self, data: Snapshot) -> Option> { + let (data, _, _) = data.to_vec( + Some(SnapshotAlphaMode::Transparent { + premultiplied: false, + }), + Some(SnapshotPixelFormat::RGBA), + ); + Some(data) + } +} + +/// A version of the `Into` trait from the standard library that can be used +/// to convert between two types that are not defined in the canvas crate. +pub(crate) trait Convert { + fn convert(self) -> T; +} + +impl Convert for LineJoinStyle { + fn convert(self) -> kurbo::Join { + match self { + LineJoinStyle::Round => kurbo::Join::Round, + LineJoinStyle::Bevel => kurbo::Join::Bevel, + LineJoinStyle::Miter => kurbo::Join::Miter, + } + } +} + +impl Convert for LineCapStyle { + fn convert(self) -> kurbo::Cap { + match self { + LineCapStyle::Butt => kurbo::Cap::Butt, + LineCapStyle::Round => kurbo::Cap::Round, + LineCapStyle::Square => kurbo::Cap::Square, + } + } +} + +impl Convert for AbsoluteColor { + fn convert(self) -> peniko::Color { + let srgb = self.into_srgb_legacy(); + peniko::Color::new([ + srgb.components.0, + srgb.components.1, + srgb.components.2, + srgb.alpha, + ]) + } +} + +impl Convert for CompositionOrBlending { + fn convert(self) -> peniko::BlendMode { + match self { + CompositionOrBlending::Composition(composition_style) => { + composition_style.convert().into() + }, + CompositionOrBlending::Blending(blending_style) => blending_style.convert().into(), + } + } +} + +impl Convert for CompositionStyle { + fn convert(self) -> peniko::Compose { + match self { + CompositionStyle::SourceIn => peniko::Compose::SrcIn, + CompositionStyle::SourceOut => peniko::Compose::SrcOut, + CompositionStyle::SourceOver => peniko::Compose::SrcOver, + CompositionStyle::SourceAtop => peniko::Compose::SrcAtop, + CompositionStyle::DestinationIn => peniko::Compose::DestIn, + CompositionStyle::DestinationOut => peniko::Compose::DestOut, + CompositionStyle::DestinationOver => peniko::Compose::DestOver, + CompositionStyle::DestinationAtop => peniko::Compose::DestAtop, + CompositionStyle::Copy => peniko::Compose::Copy, + CompositionStyle::Lighter => peniko::Compose::Plus, + CompositionStyle::Xor => peniko::Compose::Xor, + CompositionStyle::Clear => peniko::Compose::Clear, + } + } +} + +impl Convert for BlendingStyle { + fn convert(self) -> peniko::Mix { + match self { + BlendingStyle::Multiply => peniko::Mix::Multiply, + BlendingStyle::Screen => peniko::Mix::Screen, + BlendingStyle::Overlay => peniko::Mix::Overlay, + BlendingStyle::Darken => peniko::Mix::Darken, + BlendingStyle::Lighten => peniko::Mix::Lighten, + BlendingStyle::ColorDodge => peniko::Mix::ColorDodge, + BlendingStyle::ColorBurn => peniko::Mix::ColorBurn, + BlendingStyle::HardLight => peniko::Mix::HardLight, + BlendingStyle::SoftLight => peniko::Mix::SoftLight, + BlendingStyle::Difference => peniko::Mix::Difference, + BlendingStyle::Exclusion => peniko::Mix::Exclusion, + BlendingStyle::Hue => peniko::Mix::Hue, + BlendingStyle::Saturation => peniko::Mix::Saturation, + BlendingStyle::Color => peniko::Mix::Color, + BlendingStyle::Luminosity => peniko::Mix::Luminosity, + } + } +} + +impl Convert for LineOptions { + fn convert(self) -> kurbo::Stroke { + let LineOptions { + width, + cap_style, + join_style, + miter_limit, + dash, + dash_offset, + } = self; + kurbo::Stroke { + width, + join: join_style.convert(), + miter_limit, + start_cap: cap_style.convert(), + end_cap: cap_style.convert(), + dash_pattern: dash.iter().map(|x| *x as f64).collect(), + dash_offset, + } + } +} + +impl Convert for FillOrStrokeStyle { + fn convert(self) -> peniko::Brush { + use canvas_traits::canvas::FillOrStrokeStyle::*; + match self { + Color(absolute_color) => peniko::Brush::Solid(absolute_color.convert()), + LinearGradient(style) => { + let start = kurbo::Point::new(style.x0, style.y0); + let end = kurbo::Point::new(style.x1, style.y1); + let mut gradient = peniko::Gradient::new_linear(start, end); + gradient.stops = style.stops.convert(); + peniko::Brush::Gradient(gradient) + }, + RadialGradient(style) => { + let center1 = kurbo::Point::new(style.x0, style.y0); + let center2 = kurbo::Point::new(style.x1, style.y1); + let mut gradient = peniko::Gradient::new_two_point_radial( + center1, + style.r0 as f32, + center2, + style.r1 as f32, + ); + gradient.stops = style.stops.convert(); + peniko::Brush::Gradient(gradient) + }, + Surface(surface_style) => { + let data = surface_style + .surface_data + .to_owned() + .to_vec( + Some(SnapshotAlphaMode::Transparent { + premultiplied: false, + }), + Some(SnapshotPixelFormat::RGBA), + ) + .0; + peniko::Brush::Image(peniko::Image { + data: peniko::Blob::from(data), + format: peniko::ImageFormat::Rgba8, + width: surface_style.surface_size.width, + height: surface_style.surface_size.height, + x_extend: if surface_style.repeat_x { + peniko::Extend::Repeat + } else { + peniko::Extend::Pad + }, + y_extend: if surface_style.repeat_y { + peniko::Extend::Repeat + } else { + peniko::Extend::Pad + }, + quality: peniko::ImageQuality::Low, + alpha: 1.0, + }) + }, + } + } +} + +impl Convert for AbsoluteColor { + fn convert(self) -> peniko::color::DynamicColor { + peniko::color::DynamicColor::from_alpha_color(self.convert()) + } +} + +impl Convert for CanvasGradientStop { + fn convert(self) -> peniko::ColorStop { + peniko::ColorStop { + offset: self.offset as f32, + color: self.color.convert(), + } + } +} + +impl Convert for Vec { + fn convert(self) -> peniko::ColorStops { + let mut stops = peniko::ColorStops(self.into_iter().map(|item| item.convert()).collect()); + // https://www.w3.org/html/test/results/2dcontext/annotated-spec/canvas.html#testrefs.2d.gradient.interpolate.overlap + stops + .0 + .sort_by(|a, b| a.offset.partial_cmp(&b.offset).unwrap()); + stops + } +} + +impl Convert for Filter { + fn convert(self) -> peniko::ImageQuality { + match self { + Filter::Bilinear => peniko::ImageQuality::Medium, + Filter::Nearest => peniko::ImageQuality::Low, + } + } +} diff --git a/components/config/prefs.rs b/components/config/prefs.rs index 0e095ef58c0..0ce2d76eb5f 100644 --- a/components/config/prefs.rs +++ b/components/config/prefs.rs @@ -76,6 +76,8 @@ pub struct Preferences { pub dom_allow_scripts_to_close_windows: bool, pub dom_canvas_capture_enabled: bool, pub dom_canvas_text_enabled: bool, + /// Uses vello as canvas backend + pub dom_canvas_vello_enabled: bool, pub dom_clipboardevent_enabled: bool, pub dom_composition_event_enabled: bool, pub dom_cookiestore_enabled: bool, @@ -255,6 +257,7 @@ impl Preferences { dom_bluetooth_testing_enabled: false, dom_canvas_capture_enabled: false, dom_canvas_text_enabled: true, + dom_canvas_vello_enabled: false, dom_clipboardevent_enabled: true, dom_composition_event_enabled: false, dom_cookiestore_enabled: false, diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml index 9092a0eab1e..0a615f7479a 100644 --- a/components/constellation/Cargo.toml +++ b/components/constellation/Cargo.toml @@ -16,6 +16,7 @@ bluetooth = ["bluetooth_traits"] default = [] tracing = ["dep:tracing"] webgpu = ["script_traits/webgpu"] +vello = ["canvas/vello"] [dependencies] background_hang_monitor = { path = "../background_hang_monitor" } diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index ab7b977ad14..b7a07b58913 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -62,6 +62,7 @@ webgpu = [ "constellation/webgpu", "constellation_traits/webgpu", ] +vello = ["constellation/vello"] [dependencies] background_hang_monitor = { path = "../background_hang_monitor" } diff --git a/deny.toml b/deny.toml index 0fa11761ea1..fc10048734f 100644 --- a/deny.toml +++ b/deny.toml @@ -193,4 +193,4 @@ skip = [ # github.com organizations to allow git sources for [sources.allow-org] -github = ["pcwalton", "servo"] +github = ["pcwalton", "servo", "linebender"] diff --git a/ports/servoshell/Cargo.toml b/ports/servoshell/Cargo.toml index 9adf2654a00..9a6a42b7866 100644 --- a/ports/servoshell/Cargo.toml +++ b/ports/servoshell/Cargo.toml @@ -52,6 +52,7 @@ webdriver = ["libservo/webdriver"] webgl_backtrace = ["libservo/webgl_backtrace"] webgpu = ["libservo/webgpu"] webxr = ["libservo/webxr"] +vello = ["libservo/vello"] [dependencies] cfg-if = { workspace = true } diff --git a/python/servo/try_parser.py b/python/servo/try_parser.py index 72044cac47c..bbaf8fe2c6f 100644 --- a/python/servo/try_parser.py +++ b/python/servo/try_parser.py @@ -104,7 +104,7 @@ def handle_preset(s: str) -> Optional[JobConfig]: return JobConfig( "WebGPU CTS", Workflow.LINUX, - wpt=True, # reftests are mode for new layout + wpt=True, wpt_args="_webgpu", # run only webgpu cts profile="production", # WebGPU works to slow with debug assert unit_tests=False, @@ -125,6 +125,20 @@ def handle_preset(s: str) -> Optional[JobConfig]: unit_tests=False, number_of_wpt_chunks=2, ) + elif any(word in s for word in ["vello"]): + return JobConfig( + "Vello WPT", + Workflow.LINUX, + wpt=True, + wpt_args=" ".join( + [ + "--subsuite-file ./tests/wpt/vello_canvas_subsuite.json", + "--subsuite vello_canvas", + "--processes 1", + ] + ), + build_args="--features 'vello'", + ) elif any(word in s for word in ["lint", "tidy"]): return JobConfig("Lint", Workflow.LINT) else: diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini index a195925f726..168d0bad19d 100644 --- a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html.ini @@ -1,2 +1,3 @@ [2d.composite.grid.no_filter.no_shadow.drawImage.html] - expected: FAIL + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini index eb4b6f2408e..bebe58d5a73 100644 --- a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html.ini @@ -1,2 +1,3 @@ [2d.composite.grid.no_filter.no_shadow.fillRect.html] - expected: FAIL + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini index a6edb5e7c8e..3a0b1b360bd 100644 --- a/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini +++ b/tests/wpt/meta/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html.ini @@ -1,2 +1,3 @@ [2d.composite.grid.no_filter.no_shadow.pattern.html] - expected: FAIL + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html.ini b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html.ini new file mode 100644 index 00000000000..45482761b5d --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.coloralpha.html.ini @@ -0,0 +1,5 @@ +[2d.gradient.interpolate.coloralpha.html] + [Canvas test: 2d.gradient.interpolate.coloralpha] + bug: https://github.com/linebender/vello/issues/1056 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html.ini b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html.ini index d058f7852d3..20619106747 100644 --- a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html.ini +++ b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.behind.html.ini @@ -1,4 +1,4 @@ [2d.gradient.radial.cone.behind.html] [Canvas test: 2d.gradient.radial.cone.behind] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html.ini b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html.ini index 573e63a2f5d..7a14336f5fb 100644 --- a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html.ini +++ b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.cone.shape2.html.ini @@ -1,4 +1,4 @@ [2d.gradient.radial.cone.shape2.html] [Canvas test: 2d.gradient.radial.cone.shape2] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html.ini b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html.ini index 30ebbe345aa..2e0c31b1a35 100644 --- a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html.ini +++ b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside2.html.ini @@ -1,4 +1,4 @@ [2d.gradient.radial.outside2.html] [Canvas test: 2d.gradient.radial.outside2] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html.ini b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html.ini index 258881c8ebc..4786f083031 100644 --- a/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html.ini +++ b/tests/wpt/meta/html/canvas/element/fill-and-stroke-styles/2d.gradient.radial.outside3.html.ini @@ -1,4 +1,4 @@ [2d.gradient.radial.outside3.html] [Canvas test: 2d.gradient.radial.outside3] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/layers/2d.layer.globalCompositeOperation.html.ini b/tests/wpt/meta/html/canvas/element/layers/2d.layer.globalCompositeOperation.html.ini new file mode 100644 index 00000000000..2d7e8bd6569 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/layers/2d.layer.globalCompositeOperation.html.ini @@ -0,0 +1,4 @@ +[2d.layer.globalCompositeOperation.html] + expected: + if subsuite == "vello_canvas": TIMEOUT + PASS diff --git a/tests/wpt/meta/html/canvas/element/line-styles/2d.line.cross.html.ini b/tests/wpt/meta/html/canvas/element/line-styles/2d.line.cross.html.ini new file mode 100644 index 00000000000..9fc308d6baa --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/line-styles/2d.line.cross.html.ini @@ -0,0 +1,5 @@ +[2d.line.cross.html] + [Canvas test: 2d.line.cross] + bug: https://github.com/linebender/vello/issues/1063 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/line-styles/2d.line.miter.acute.html.ini b/tests/wpt/meta/html/canvas/element/line-styles/2d.line.miter.acute.html.ini new file mode 100644 index 00000000000..2c14b4c32d9 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/line-styles/2d.line.miter.acute.html.ini @@ -0,0 +1,5 @@ +[2d.line.miter.acute.html] + [Miter joins are drawn correctly with acute angles] + bug: https://github.com/linebender/vello/issues/1063 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini index 6bdff31111d..378a3fdca81 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-resize.html.ini @@ -1,3 +1,15 @@ [canvas-createImageBitmap-resize.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [createImageBitmap from a HTMLImageElement of svg with no specified size with resize option.] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL + + [createImageBitmap from an ImageBitmap with resize option.] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from an ImageData with resize option.] + expected: + if subsuite == "vello_canvas": NOTRUN diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini index cc44470b689..a72ad7f0066 100644 --- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-drawImage.html.ini @@ -1,4 +1,6 @@ [createImageBitmap-drawImage.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [createImageBitmap from a vector HTMLImageElement resized, and drawImage on the created ImageBitmap] expected: FAIL @@ -73,3 +75,39 @@ [createImageBitmap from a vector HTMLImageElement scaled up, and drawImage on the created ImageBitmap] expected: FAIL + + [createImageBitmap from an ImageBitmap scaled down, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": [PASS, TIMEOUT] + + [createImageBitmap from an ImageBitmap scaled up, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": [TIMEOUT, NOTRUN] + + [createImageBitmap from an ImageBitmap resized, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from an ImageBitmap with negative sw/sh, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from a Blob, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from a Blob scaled down, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from a Blob scaled up, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from a Blob resized, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN + + [createImageBitmap from a Blob with negative sw/sh, and drawImage on the created ImageBitmap] + expected: + if subsuite == "vello_canvas": NOTRUN diff --git a/tests/wpt/meta/html/canvas/element/manual/text/canvas.2d.lang.dynamic.html.ini b/tests/wpt/meta/html/canvas/element/manual/text/canvas.2d.lang.dynamic.html.ini new file mode 100644 index 00000000000..ac37526e3d7 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/manual/text/canvas.2d.lang.dynamic.html.ini @@ -0,0 +1,3 @@ +[canvas.2d.lang.dynamic.html] + expected: + if subsuite == "vello_canvas": [PASS, FAIL] diff --git a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html.ini b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html.ini index 9e5d8714550..540eeec1aed 100644 --- a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-Blob.html.ini @@ -1,4 +1,6 @@ [canvas-display-p3-drawImage-ImageBitmap-Blob.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [sRGB-FF0000FF.png, Context srgb, ImageData display-p3, cropSource=false] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html.ini b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html.ini new file mode 100644 index 00000000000..3a737b99f87 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html.ini @@ -0,0 +1,3 @@ +[canvas-display-p3-drawImage-ImageBitmap-ImageBitmap.html] + expected: + if subsuite == "vello_canvas": TIMEOUT diff --git a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini index ab3c16fa28a..c8c049b2d92 100644 --- a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-cloned.html.ini @@ -1,4 +1,6 @@ [canvas-display-p3-drawImage-ImageBitmap-cloned.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [sRGB-FF0000FF.png, Context srgb, ImageData display-p3, cropSource=false] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html.ini b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html.ini index efe9b435ae4..a5602296681 100644 --- a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-image.html.ini @@ -1,4 +1,6 @@ [canvas-display-p3-drawImage-ImageBitmap-image.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [sRGB-FF0000FF.png, Context srgb, ImageData display-p3, cropSource=false] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html.ini b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html.ini index 572339c302b..aadfa832b55 100644 --- a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage.https.html.ini @@ -1,4 +1,6 @@ [canvas-display-p3-drawImage.https.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [sRGB-FF0000FF.png, Context srgb, ImageData display-p3, scaleImage=false] expected: FAIL @@ -36,28 +38,44 @@ expected: FAIL [sRGB-BB0000CC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000CC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000CC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000CC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FF0000FF.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FF0000FF.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FF0000CC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FF0000CC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BB0000FF.png, Context srgb, ImageData srgb, scaleImage=false] expected: FAIL @@ -78,178 +96,294 @@ expected: FAIL [Display-P3-BB0000CC.png, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BB0000CC.png, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BB0000CC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BB0000CC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BB0000CC.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BB0000CC.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000FF.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000FF.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000FF.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000FF.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000FF.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000FF.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000CC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000CC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000CC.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000CC.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000CC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FF0000CC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000FF.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BB0000CC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-FF000000.jpg, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Generic-CMYK-BE000000.jpg, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000FFFF.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000FFFF.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FFFF00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BBBC00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=false] expected: FAIL @@ -264,64 +398,104 @@ expected: FAIL [sRGB-BBBC00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BBBC00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BBBC00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BBBC00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FFFF00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FFFF00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FFFF00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-FFFF00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000FFFF.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000FFFF.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-BBBC00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FFFF00000000FFFF.png, Context srgb, ImageData display-p3, scaleImage=false] expected: FAIL @@ -342,22 +516,34 @@ expected: FAIL [Adobe-RGB-FFFF00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FFFF00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FFFF00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FFFF00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FFFF00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-FFFF00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=false] expected: FAIL @@ -384,121 +570,409 @@ expected: FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Adobe-RGB-BBBC00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-FF0000.svg, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [sRGB-BB0000.svg, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-1-0-0.svg, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context srgb, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context srgb, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context srgb, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context srgb, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context display-p3, ImageData srgb, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context display-p3, ImageData srgb, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context display-p3, ImageData display-p3, scaleImage=false] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL [Display-P3-0.7333-0-0.svg, Context display-p3, ImageData display-p3, scaleImage=true] - expected: FAIL + expected: + if subsuite == "vello_canvas": TIMEOUT + FAIL + + [sRGB-BB0000CC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BB0000CC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BB0000CC.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BB0000CC.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000FF.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000FF.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000FF.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000FF.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000FF.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000FF.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000CC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000CC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000CC.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000CC.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000CC.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FF0000CC.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-BB0000CC.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-BB0000CC.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Adobe-RGB-FF0000FF.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Adobe-RGB-FF0000FF.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Adobe-RGB-FF0000CC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Adobe-RGB-FF0000CC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000FFFF.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000FFFF.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-FFFF00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BBBC00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BBBC00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BBBC00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [sRGB-BBBC00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000FFFF.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000FFFF.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000FFFF.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000FFFF.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000FFFF.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000CCCC.png, Context display-p3, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-FFFF00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-BBBC00000000FFFF.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-BBBC00000000FFFF.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-BBBC00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Display-P3-BBBC00000000CCCC.png, Context display-p3, ImageData display-p3, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Adobe-RGB-FFFF00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=false] + expected: + if subsuite == "vello_canvas": TIMEOUT + + [Adobe-RGB-FFFF00000000CCCC.png, Context srgb, ImageData srgb, scaleImage=true] + expected: + if subsuite == "vello_canvas": TIMEOUT diff --git a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html.ini b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html.ini index 3b0bcfdb710..eb14940288f 100644 --- a/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html.ini +++ b/tests/wpt/meta/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-pattern-image.html.ini @@ -1,4 +1,6 @@ [canvas-display-p3-pattern-image.html] + expected: + if subsuite == "vello_canvas": TIMEOUT [sRGB-FF0000FF.png, Context srgb, ImageData display-p3] expected: FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.1.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.1.html.ini new file mode 100644 index 00000000000..ed3b9b0e199 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.1.html.ini @@ -0,0 +1,4 @@ +[2d.path.arc.scale.1.html] + [Non-uniformly scaled arcs are the right shape] + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.2.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.2.html.ini index 72ac9cfb4dc..00c4bd612ef 100644 --- a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.2.html.ini +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.scale.2.html.ini @@ -1,4 +1,4 @@ [2d.path.arc.scale.2.html] [Highly scaled arcs are the right shape] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini index 7c1f22ff41c..7849962dc21 100644 --- a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html.ini @@ -1,4 +1,4 @@ [2d.path.arc.selfintersect.1.html] [arc() with lineWidth > 2*radius is drawn sensibly] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html.ini index a25bacaabed..4d597db07a9 100644 --- a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html.ini +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.selfintersect.2.html.ini @@ -1,4 +1,4 @@ [2d.path.arc.selfintersect.2.html] [arc() with lineWidth > 2*radius is drawn sensibly] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.3.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.3.html.ini index c285647918d..8180b697ed1 100644 --- a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.3.html.ini +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.3.html.ini @@ -1,4 +1,4 @@ [2d.path.arc.shape.3.html] [arc() from 0 to -pi/2 does not draw anything in the wrong quadrant] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.4.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.4.html.ini index c22e98e44d2..8845612c1ed 100644 --- a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.4.html.ini +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.arc.shape.4.html.ini @@ -1,4 +1,4 @@ [2d.path.arc.shape.4.html] [arc() from 0 to -pi/2 draws stuff in the right quadrant] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.clip.intersect.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.clip.intersect.html.ini new file mode 100644 index 00000000000..6f60ae6ac45 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.clip.intersect.html.ini @@ -0,0 +1,5 @@ +[2d.path.clip.intersect.html] + [Canvas test: 2d.path.clip.intersect] + bug: https://github.com/linebender/vello/issues/1061 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.rect.selfintersect.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.rect.selfintersect.html.ini new file mode 100644 index 00000000000..5ac5b9c8bcc --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.rect.selfintersect.html.ini @@ -0,0 +1,5 @@ +[2d.path.rect.selfintersect.html] + [Canvas test: 2d.path.rect.selfintersect] + bug: https://github.com/linebender/vello/issues/1063#issuecomment-2998084736 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/path-objects/2d.path.stroke.scale2.html.ini b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.stroke.scale2.html.ini new file mode 100644 index 00000000000..ecde0bfb25d --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/path-objects/2d.path.stroke.scale2.html.ini @@ -0,0 +1,4 @@ +[2d.path.stroke.scale2.html] + [Stroke line widths are scaled by the current transformation matrix] + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html.ini b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html.ini new file mode 100644 index 00000000000..2d7c071dd03 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.clip.html.ini @@ -0,0 +1,5 @@ +[2d.imageData.put.clip.html] + [putImageData() is not affected by clipping regions] + bug: https://github.com/linebender/vello/issues/1088 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html.ini b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html.ini new file mode 100644 index 00000000000..8c28489a5e4 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.negative.html.ini @@ -0,0 +1,5 @@ +[2d.imageData.put.dirty.negative.html] + [putImageData() handles negative-sized dirty rectangles correctly] + bug: https://github.com/linebender/vello/issues/1061 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html.ini b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html.ini new file mode 100644 index 00000000000..ed889d633a6 --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect1.html.ini @@ -0,0 +1,5 @@ +[2d.imageData.put.dirty.rect1.html] + [putImageData() only modifies areas inside the dirty rectangle, using width and height] + bug: https://github.com/linebender/vello/issues/1061 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html.ini b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html.ini new file mode 100644 index 00000000000..fc9cee7b19e --- /dev/null +++ b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.dirty.rect2.html.ini @@ -0,0 +1,5 @@ +[2d.imageData.put.dirty.rect2.html] + [putImageData() only modifies areas inside the dirty rectangle, using x and y] + bug: https://github.com/linebender/vello/issues/1061 + expected: + if subsuite == "vello_canvas": FAIL diff --git a/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html.ini b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html.ini index 2cec1487d8c..bcc95019e98 100644 --- a/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html.ini +++ b/tests/wpt/meta/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html.ini @@ -1,4 +1,4 @@ [2d.imageData.put.unchanged.html] [putImageData(getImageData(...), ...) has no effect] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/element/transformations/2d.transformation.scale.large.html.ini b/tests/wpt/meta/html/canvas/element/transformations/2d.transformation.scale.large.html.ini index a2f6ef4c2cb..a7a94438904 100644 --- a/tests/wpt/meta/html/canvas/element/transformations/2d.transformation.scale.large.html.ini +++ b/tests/wpt/meta/html/canvas/element/transformations/2d.transformation.scale.large.html.ini @@ -1,4 +1,4 @@ [2d.transformation.scale.large.html] [scale() with large scale factors works] - expected: FAIL - + expected: + if subsuite == "": FAIL diff --git a/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.globalCompositeOperation.html.ini b/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.globalCompositeOperation.html.ini index f50e1227588..000e46d2512 100644 --- a/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.globalCompositeOperation.html.ini +++ b/tests/wpt/meta/html/canvas/offscreen/layers/2d.layer.globalCompositeOperation.html.ini @@ -1,2 +1,3 @@ [2d.layer.globalCompositeOperation.html] - expected: FAIL + expected: + FAIL diff --git a/tests/wpt/vello_canvas_subsuite.json b/tests/wpt/vello_canvas_subsuite.json new file mode 100644 index 00000000000..799a0de2583 --- /dev/null +++ b/tests/wpt/vello_canvas_subsuite.json @@ -0,0 +1,8 @@ +{ + "vello_canvas": { + "config": { + "binary_args": ["--pref", "dom_canvas_vello_enabled"] + }, + "include": ["/html/canvas/element"] + } +}