Skip to content

perf(transform): translate-only fast path for global transforms#13

Merged
chiefcll merged 1 commit into
mainfrom
perf/transform-fast-path
May 11, 2026
Merged

perf(transform): translate-only fast path for global transforms#13
chiefcll merged 1 commit into
mainfrom
perf/transform-fast-path

Conversation

@chiefcll
Copy link
Copy Markdown
Contributor

Summary

Three fixes covering the hot update path for x/y changes on simple nodes (no rotation/scale/mount). Targets CoreNode.update and Matrix3d.

  • update Global block (🐛 [BUG] - CanvasTextRenderer tints color-emoji glyphs with node.color, crushing native emoji colors #1, big win): when both the node is isSimple and the parent's global is translate-only, the resulting global is also translate-only and collapses to two adds on tx/ty. Bypasses the 6-field Matrix3d.copy + 2 mul-add translate. Tracked with a per-node _globalIsTranslate flag that propagates down the tree. RTT chains conservatively opt out.
  • updateLocalTransform simple path ([fix] [sdf] Sdf text alpha double multiplication #2): localTransform is guaranteed identity-shape (ta=1, tb=0, tc=0, td=1), so only tx/ty need to change between frames — skips 4 redundant field writes. _localIsTranslate tracks identity-shape so a non-simple → simple transition correctly restores the matrix.
  • updateBoundingRect ([fix] [subtexture] Update quad on subtexture node texture set #5, correctness bug): fix ||&& on the axis-aligned-fast-path check. With ||, a matrix with one zero shear component and the other non-zero (e.g. tb=0, tc=-0.5) wrongly took the diagonal fast path and produced incorrect bounds. Now matches calculateRenderCoords semantics.

Adds a setTranslate(x, y) helper on Matrix3d for the in-place tx/ty + mutation-flag write used by both the local and global fast paths.

Test plan

  • pnpm test — 120/120 passing
  • pnpm build — clean
  • Lint (prettier + eslint) clean on changed files
  • 12 new unit tests for setTranslate, simple-path reuse, non-simple → simple transitions, translate-only propagation through grandchildren, fast-path opt-out, and the bounding-rect axis check
  • Visual regression — recommend running locally before merge; no shader/rendering math changed but bounds change is observable for sheared matrices

🤖 Generated with Claude Code

Three changes covering the hot update path for x/y changes on simple
nodes (no rotation/scale/mount):

1. CoreNode.update Global block: when both the node is simple and the
   parent's global is translate-only, the resulting global is also
   translate-only and collapses to two adds on tx/ty — bypassing the
   6-field Matrix3d.copy + 2 mul-add translate. Tracked with a per-node
   _globalIsTranslate flag that propagates down the tree. RTT chains
   conservatively opt out.

2. updateLocalTransform simple path: localTransform is guaranteed to be
   identity-shape (ta=1, tb=0, tc=0, td=1), so only tx/ty need to change
   between frames. _localIsTranslate tracks whether the matrix is still
   in identity-shape so a non-simple -> simple transition correctly
   restores it.

3. updateBoundingRect: fix `||` -> `&&` on the axis-aligned-fast-path
   check. With `||`, a matrix with one zero shear component and the other
   non-zero (e.g. tb=0, tc=-0.5) wrongly took the diagonal fast path and
   produced incorrect bounds. Now matches calculateRenderCoords semantics.

Adds setTranslate() helper to Matrix3d for the in-place tx/ty + mutation
flag write used by both #1 and #2.

Adds 12 unit tests covering simple-path reuse, non-simple -> simple
transitions, translate-only propagation through grandchildren, fast-path
opt-out when parent has rotation, and the bounding-rect axis check.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@chiefcll chiefcll merged commit 27525f7 into main May 11, 2026
1 check passed
@chiefcll chiefcll deleted the perf/transform-fast-path branch May 11, 2026 14:05
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.

1 participant