Skip to content

Bound shape recording, mip and glyph cache accounting - #33

Merged
timzifer merged 1 commit into
mainfrom
fix/budgets-30-32
Oct 6, 2026
Merged

timzifer merged 1 commit into
mainfrom
fix/budgets-30-32

Conversation

@timzifer

@timzifer timzifer commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Fixes #30, #31, #32.

#30 Shape geometry budget

  • New Shape.MaxBytes (default DefaultShapeBytes, enough for DefaultMaxEdges edges) bounds each form's edges, strips and row bins. A stroke makes up to two forms, so at most 2× MaxBytes.
  • Budget is checked before each append; recording stops when full, before bins are built. addPath and the stroker (new Stroker.halt, checked between subpaths) stop early.
  • FillShape (fill and stroke) and FillUnion report ErrEdgeBudget for a truncated form.
  • The bound belongs to the shape, not the canvas, so canvases with different clips and MaxEdges get the same truncated form on concurrent first use.
  • Known gap: the stroker's own per-subpath scratch within one huge subpath stays unbounded, as with Canvas.Stroke.

#31 Texture.MipBytes

  • Sums the actual rounded level sizes instead of W*H/3, saturating on overflow.
  • Also counts wrap levels that are distinct from ordinary levels (aliased ones once). Hence 4096×1 now reports 32752 (levels + wrap levels), 256×256 stays 87380.
  • cera picks this up after bumping its stilus dependency.

#32 GlyphCache.MaxBytes

  • Entries count cap(Pix), so reused larger buffers are accounted correctly.
  • A mask larger than MaxBytes is drawn but not cached; it is recycled afterwards.
  • MaxBytes doc states what is not counted (scratch, map).

Tests

New budget_test.go: MipBytes vs. actual levels (RGBA/gray/alpha/indexed, thin/odd/NPOT), oversized glyph entry, large-to-small buffer reuse, budget reduction, shape fill/stroke/union truncation, concurrent first use. TestGlyphCacheEviction now enforces the budget strictly. go test ./... passes, new tests also under -race.

- Shape.MaxBytes (default DefaultShapeBytes) bounds each form's edges,
  strips and bins; recording and the stroker stop at the budget, and
  FillShape/FillUnion report ErrEdgeBudget. The bound is the shape's,
  so concurrent first use is deterministic. Fixes #30.
- Texture.MipBytes sums the rounded level sizes and the distinct wrap
  levels instead of W*H/3, saturating on overflow. Fixes #31.
- GlyphCache counts mask capacity, not length, and draws a mask larger
  than MaxBytes without keeping it. Fixes #32.
@timzifer
timzifer merged commit d93ccd5 into main Oct 6, 2026
13 checks passed
@timzifer
timzifer deleted the fix/budgets-30-32 branch October 6, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bound geometry recording for Shape before allocating edges, strips and row bins

1 participant