Skip to content

feat: stencil-based arbitrary path clipping (GPU-CLIP-002b) #205

@kolkov

Description

@kolkov

GPU-CLIP-002b: Stencil-based arbitrary path clipping

Summary

Use the existing stencil-then-cover pipeline to clip content to arbitrary paths. Write clip path to stencil buffer, set stencil test for subsequent draws.

Rationale

Analytic SDF (Phase 1, #203) only handles RRect. For arbitrary shapes (bezier paths, complex polygons, text-shaped clips), stencil buffer is the industry standard:

  • Skia Ganesh: stencil buffer for arbitrary SkPath clips
  • Flutter/Impeller: ClipContents with stencil
  • Cairo: alpha mask rasterization (CPU equivalent)

gg already has the stencil infrastructure (stencil_renderer.go, stencil_fill.wgsl, cover.wgsl). The Tier 2b stencil-then-cover renderer uses it for path rendering. We reuse it for clipping.

See: NON-RECTANGULAR-CLIPPING-ENTERPRISE-RESEARCH.md §1 (Skia), §4 (Flutter)

Architecture

dc.Clip() with non-rect path:
  → clipStack.PushPath() (existing)
  → GPU: write clip path to stencil buffer (reuse RecordPath)
  → Set stencil test (GL_EQUAL, ref=N) for subsequent draws
  → Each draw tests against stencil before writing color
  → On Pop(): restore stencil state

Key Challenges

  • Stencil value management: nested clips require incrementing stencil reference values
  • 8-bit stencil limit: max 255 clip levels (sufficient for most cases)
  • Integration with scissor groups: stencil state must be tracked per group
  • Stencil clear between frames: managed by BeginFrame

Dependencies

Blocks

  • Complex UI shapes (non-rectangular containers, SVG clip paths)
  • Creative coding use cases (arbitrary clip masks)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions