canvas: Use vello_cpu as default canvas backend (#38844)

We really want to remove font-kit from dep tree, so this is the first
step into removing raqote from servo. While vello_cpu is not perfect
replacement, I am confident that we will resolve all issues eventually:
https://github.com/servo/servo/issues/38345 (most important ones already
have PRs).

Reviewable per commit.

Testing: Existing WPT tests.
Try run: https://github.com/sagudev/servo/actions/runs/17138369290

---------

Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
Sam 2025-08-27 09:22:20 +02:00 committed by GitHub
parent e126f09b25
commit 3dc9184121
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
109 changed files with 193 additions and 202 deletions

View file

@ -313,6 +313,12 @@ impl Canvas {
.to_lowercase()
.as_str()
{
#[cfg(feature = "vello_cpu")]
"" | "auto" | "vello_cpu" => Some(Self::VelloCPU(CanvasData::new(
size,
compositor_api,
font_context,
))),
#[cfg(feature = "raqote")]
"" | "auto" | "raqote" => Some(Self::Raqote(CanvasData::new(
size,
@ -325,12 +331,6 @@ impl Canvas {
compositor_api,
font_context,
))),
#[cfg(feature = "vello_cpu")]
"" | "auto" | "vello_cpu" => Some(Self::VelloCPU(CanvasData::new(
size,
compositor_api,
font_context,
))),
s => {
warn!("Unknown 2D canvas backend: `{s}`");
None

View file

@ -21,7 +21,7 @@ bluetooth = [
"script/bluetooth",
"script_traits/bluetooth",
]
default = ["clipboard", "raqote"]
default = ["clipboard", "vello_cpu"]
clipboard = ["dep:arboard"]
crown = ["script/crown"]
debugmozjs = ["script/debugmozjs"]

View file

@ -125,19 +125,6 @@ def handle_preset(s: str) -> Optional[JobConfig]:
unit_tests=False,
number_of_wpt_chunks=2,
)
elif any(word in s for word in ["vello-cpu", "vello_cpu"]):
return JobConfig(
"Vello-CPU WPT",
Workflow.LINUX,
wpt=True,
wpt_args=" ".join(
[
"--subsuite-file ./tests/wpt/vello_cpu_canvas_subsuite.json",
"--subsuite vello_cpu_canvas",
]
),
build_args="--features 'vello_cpu'",
)
elif any(word in s for word in ["vello"]):
return JobConfig(
"Vello WPT",

View file

@ -54,3 +54,12 @@
[corner-shape-render-precise.html?corner-top-left-shape=superellipse(-4)&border-radius=40px]
expected: FAIL
[corner-shape-render-precise.html?corner-top-right-shape=bevel&border-width=10px]
expected: FAIL
[corner-shape-render-precise.html?corner-bottom-right-shape=bevel&corner-bottom-left-shape=bevel]
expected: FAIL
[corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px]
expected: FAIL

View file

@ -1,4 +1,6 @@
[2d.composite.clip.clear.html]
[fill() does not affect pixels outside the clip region.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.clip.copy.html]
[fill() does not affect pixels outside the clip region.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.clip.destination-atop.html]
[fill() does not affect pixels outside the clip region.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.clip.destination-in.html]
[fill() does not affect pixels outside the clip region.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.clip.source-in.html]
[fill() does not affect pixels outside the clip region.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.clip.source-out.html]
[fill() does not affect pixels outside the clip region.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,3 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.drawImage.html]
expected:
if subsuite == "": FAIL

View file

@ -1,3 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.fillRect.html]
expected:
if subsuite == "": FAIL

View file

@ -1,3 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.pattern.html]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.uncovered.pattern.copy.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.uncovered.pattern.destination-atop.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.uncovered.pattern.destination-in.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.uncovered.pattern.source-in.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.composite.uncovered.pattern.source-out.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.clearRect.clip.html]
[clearRect is affected by clipping regions]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.clearRect.shadow.html]
[clearRect does not draw shadows]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +1,5 @@
[2d.clearRect.zero.html]
[clearRect of zero pixels has no effect]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,6 +1,4 @@
[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
if subsuite == "vello_cpu_canvas": FAIL
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.cone.behind.html]
[Canvas test: 2d.gradient.radial.cone.behind]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.cone.shape2.html]
[Canvas test: 2d.gradient.radial.cone.shape2]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.outside2.html]
[Canvas test: 2d.gradient.radial.outside2]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.outside3.html]
[Canvas test: 2d.gradient.radial.outside3]
expected:
if subsuite == "": FAIL

View file

@ -1,6 +1,4 @@
[2d.line.cross.html]
[Canvas test: 2d.line.cross]
bug: https://github.com/linebender/vello/issues/1063
expected:
if subsuite == "vello_canvas": FAIL
if subsuite == "vello_cpu_canvas": FAIL
expected: FAIL

View file

@ -1,4 +1,4 @@
[colr-glyph-composition.html]
expected:
if subsuite == "": FAIL
if subsuite == "": PASS
if subsuite == "vello_canvas": FAIL

View file

@ -0,0 +1,6 @@
[imagesmoothing.html]
[Test that image smoothing is actually on by default and just the attribute value.]
expected: FAIL
[Test that image smoothing works when imageSmoothingEnabled is set to true]
expected: FAIL

View file

@ -1,5 +1,3 @@
[2d.path.arc.scale.1.html]
[Non-uniformly scaled arcs are the right shape]
expected:
if subsuite == "vello_canvas": FAIL
if subsuite == "vello_cpu_canvas": FAIL
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.scale.2.html]
[Highly scaled arcs are the right shape]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.selfintersect.1.html]
[arc() with lineWidth > 2*radius is drawn sensibly]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.selfintersect.2.html]
[arc() with lineWidth > 2*radius is drawn sensibly]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.shape.3.html]
[arc() from 0 to -pi/2 does not draw anything in the wrong quadrant]
expected:
if subsuite == "": FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.shape.4.html]
[arc() from 0 to -pi/2 draws stuff in the right quadrant]
expected:
if subsuite == "": FAIL

View file

@ -1,6 +1,4 @@
[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
if subsuite == "vello_cpu_canvas": FAIL
expected: FAIL

View file

@ -1,5 +1,3 @@
[2d.path.stroke.scale2.html]
[Stroke line widths are scaled by the current transformation matrix]
expected:
if subsuite == "vello_canvas": FAIL
if subsuite == "vello_cpu_canvas": FAIL
expected: FAIL

View file

@ -1,4 +1,5 @@
[2d.imageData.put.alpha.html]
[putImageData() puts non-solid image data correctly]
expected:
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,5 +1,5 @@
[2d.imageData.put.unchanged.html]
[putImageData(getImageData(...), ...) has no effect]
expected:
if subsuite == "": FAIL
if subsuite == "vello_cpu_canvas": FAIL
if subsuite == "vello_canvas": PASS
FAIL

View file

@ -1,4 +0,0 @@
[2d.transformation.scale.large.html]
[scale() with large scale factors works]
expected:
if subsuite == "": FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.clear.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.clear.worker.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.copy.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.copy.worker.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.destination-atop.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.destination-atop.worker.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.destination-in.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.destination-in.worker.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.source-in.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.source-in.worker.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.source-out.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.clip.source-out.worker.html]
[fill() does not affect pixels outside the clip region.]
expected: FAIL

View file

@ -1,2 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.drawImage.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.drawImage.w.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.fillRect.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.fillRect.w.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.pattern.html]
expected: FAIL

View file

@ -1,2 +0,0 @@
[2d.composite.grid.no_filter.no_shadow.pattern.w.html]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.copy.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.copy.worker.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.destination-atop.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.destination-atop.worker.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.destination-in.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.destination-in.worker.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.source-in.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.source-in.worker.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.source-out.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.composite.uncovered.pattern.source-out.worker.html]
[Pattern fill() draws pixels not covered by the source object as (0,0,0,0), and does not leave the pixels unchanged.]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.clearRect.clip.html]
[clearRect is affected by clipping regions]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.clearRect.clip.worker.html]
[clearRect is affected by clipping regions]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.clearRect.shadow.html]
[clearRect does not draw shadows]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.clearRect.shadow.worker.html]
[clearRect does not draw shadows]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.clearRect.zero.html]
[clearRect of zero pixels has no effect]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.clearRect.zero.worker.html]
[clearRect of zero pixels has no effect]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.gradient.interpolate.coloralpha.html]
[OffscreenCanvas test: 2d.gradient.interpolate.coloralpha]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.gradient.interpolate.coloralpha.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.cone.behind.html]
[OffscreenCanvas test: 2d.gradient.radial.cone.behind]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.cone.behind.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.cone.shape2.html]
[OffscreenCanvas test: 2d.gradient.radial.cone.shape2]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.cone.shape2.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.outside2.html]
[OffscreenCanvas test: 2d.gradient.radial.outside2]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.outside2.worker.html]
[2d]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.outside3.html]
[OffscreenCanvas test: 2d.gradient.radial.outside3]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.gradient.radial.outside3.worker.html]
[2d]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.line.cross.html]
[OffscreenCanvas test: 2d.line.cross]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.line.cross.worker.html]
[2d]
expected: FAIL

View file

@ -0,0 +1,6 @@
[image.smoothing.html]
[Test that image smoothing is actually on by default.]
expected: FAIL
[Test that image smoothing works when imageSmoothingEnabled is set to true]
expected: FAIL

View file

@ -0,0 +1,6 @@
[image.smoothing.worker.html]
[Test that image smoothing is actually on by default.]
expected: FAIL
[Test that image smoothing works when imageSmoothingEnabled is set to true]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.path.arc.scale.1.html]
[Non-uniformly scaled arcs are the right shape]
expected: FAIL

View file

@ -0,0 +1,3 @@
[2d.path.arc.scale.1.worker.html]
[Non-uniformly scaled arcs are the right shape]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.scale.2.html]
[Highly scaled arcs are the right shape]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.scale.2.worker.html]
[Highly scaled arcs are the right shape]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.selfintersect.1.html]
[arc() with lineWidth > 2*radius is drawn sensibly]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.selfintersect.1.worker.html]
[arc() with lineWidth > 2*radius is drawn sensibly]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.selfintersect.2.html]
[arc() with lineWidth > 2*radius is drawn sensibly]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.selfintersect.2.worker.html]
[arc() with lineWidth > 2*radius is drawn sensibly]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.shape.3.html]
[arc() from 0 to -pi/2 does not draw anything in the wrong quadrant]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.shape.3.worker.html]
[arc() from 0 to -pi/2 does not draw anything in the wrong quadrant]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.shape.4.html]
[arc() from 0 to -pi/2 draws stuff in the right quadrant]
expected: FAIL

View file

@ -1,4 +0,0 @@
[2d.path.arc.shape.4.worker.html]
[arc() from 0 to -pi/2 draws stuff in the right quadrant]
expected: FAIL

Some files were not shown because too many files have changed in this diff Show more