Skip to content

Tesselated Text Cache improvements #47

Description

@vade

Current TesselatedTextGeometry already has a local cache:

var geometryCache: [Character: GeometryData]
var characterPathsCache: [Character: [Polyline2D]]

That helps a bit, but it is weak because:

  • Character is not enough. Same character can map to different glyphs depending on font, style, ligature shaping, fallback font, etc.
  • It is per geometry instance, so multiple text nodes do not share work.
  • fontSize changes clear the cache, even though glyph outlines could be cached in normalized font units and scaled later.
  • It still recombines/copies glyph geometry into one large mesh every update.
  • CoreText layout still runs per text update.

A cleaner model:

  1. Global or context-level glyph outline/mesh cache
    Key by something like:

    • font PostScript name / CTFont identity
    • glyph id (CGGlyph)
    • tessellation settings: angleLimit, curve tolerance, winding/triangulation mode
    • maybe variable font axes if relevant
  2. Cache glyph geometry in font units
    Store the triangulated/path geometry once in normalized units. Then font size becomes a transform/scale, not a reason to re-triangulate.

  3. Separate layout from glyph mesh generation
    CoreText still computes glyph IDs and positions for the string. But once layout gives you:

    • glyph id
    • font/run
    • position
      then mesh assembly should mostly be “append cached glyph mesh with offset/scale.”
  4. Avoid rebuilding one huge CPU mesh when possible
    The even more scalable version is an instanced glyph renderer:

    • one cached glyph mesh per glyph
    • per-character instance data contains offset, scale, maybe color/index
    • draw grouped by glyph/material
      This avoids copying all glyph vertices every time text positions change.

For your Instruments result, the immediate win is likely: move from Character cache to glyph+font+tessellation cache, ideally shared across TesselatedTextGeometry instances. The bigger architectural win is treating text as layout records + cached
glyph meshes, not regenerating a monolithic mesh every update.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions