linebender / linebender/vello

Issue with flattening of a stroked cubic around a near-cusp

Open
#581 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
4.3k
Forks
300
Avg merge
2d 13h
Merged PRs (30d)
61

Description

On Apple hardware, the following near-cusp test case from the `tricky_strokes` test scene has this artifact at certain scale factors:



This specifically only seems to happen with the near-cusp defined as `[(0., 0.01), (128., 127.999), (128., 0.01), (0., 127.99)]`. The bug itself is in the `flatten` stage, specifically the cubic-to-es subdivision loop in `flatten_euler`. I debugged this over a couple days and here are my findings so far:

- For that specific cubic, the issue is only present for a (uniform) scale factor within the range `5.3332` and `113.5797`. Scale factors outside that range do not exhibit the issue. This can be verified by hard-coding a scale factor right before testing the scaled error estimate against the error tolerance:
```
...
scale = 5.3332;
if cubic_params.err * scale <= tol || dt <= SUBDIV_LIMIT {
...
```
- The issue is not present when fastmath is disabled. The Metal compiler [enables optimizations](https://developer.apple.com/documentation/metal/mtlcompileoptions/1515914-fastmathenabled?language=objc) on floating-point arithmetic (which may violate the IEEE-754 standard) by default. I verified this by setting `fastMathEnabled = NO` on `MTLCompilerOptions` directly on Skia-Graphite's Metal backend (which uses the shaders directly and doesn't use wgpu).
- The issue is not present on CPU shaders (which doesn't use fastmath).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start from the flatten_euler cubic-to-es subdivision loop and reproduce the near-cusp from the tricky_strokes test scene. Compare Apple Metal behavior with fastmath enabled against the CPU-shader and fastmath-disabled cases across the reported scale range. Done means the artifact is eliminated for the specified cubic and scale factors.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.