Skip to content

chore: repin all 4 samples to plugin v2.12.1 + cap the avatar speech-bubble refresh (DisplayXR/displayxr-unity#254) - #11

Merged
dfattal merged 2 commits into
mainfrom
chore/repin-v2.12.1-bubble-cap
Aug 19, 2026
Merged

dfattal merged 2 commits into
mainfrom
chore/repin-v2.12.1-bubble-cap

Conversation

@dfattal

@dfattal dfattal commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Two upstream ports from the plugin's v2.12.1 release and the downstream avatar app.

1. Repin all 4 samples to plugin #upm/v2.12.1

Plugin release v2.12.1 (DisplayXR/displayxr-unity#254 via its PR #255) fixes the
transparent-overlay click-through hit test: it no longer CPU-skins and ray-scans renderers
that are disabled or sitting on inactive GameObjects. A consumer with several avatars wired
but only one visible was paying the full bake + scan for all of them every frame. The
release also drops a per-frame mesh.triangles full-array allocation, adds a bounds
pre-check before the triangle scan, and declares the plugin's previously-undeclared
com.unity.inputsystem dependency.

Packages/manifest.json moves v2.12.0 → v2.12.1 in all four samples. The
com.displayxr.unity entry in each Packages/packages-lock.json is deleted rather than
hash-refreshed, so Unity re-resolves the git dependency from scratch on next open — the lock
caches the pinned commit SHA (this repo's documented gotcha: leave it and the bump silently
doesn't take), and the plugin's dependency set changed in this release, so a hand-edited hash
would leave a stale dependency block behind. All eight JSON files re-validated after editing.

2. desktop-avatar: cap the speech-bubble Local2D refresh at 4 Hz

Assets/TigerSpeechBubble.cs builds its speech bubble as a DisplayXRLocal2D layer that
re-rendered every frame — an enabled offscreen camera plus the provider's full-RT bridge
copy, all to redraw identical pixels. The bubble is a static panel of text.

  • m_BubbleL2D.maxRefreshHz = 4f; — 4 Hz caps the worst case for an unannounced content
    change at 250 ms while dropping ~93% of those renders at 60 fps.
  • New MarkBubbleDirty() helper (null-guarded SetDirty()), called at the end of BuildUI()
    and at the end of SetLayoutMode(bool) — both branches of the Ctrl+Shift+L layout-mode
    toggle rewrite the title/body text.
  • The component itself force-refreshes when its pixel rect moves, which already covers the
    split drag and window resizes.

Ported from the verified downstream avatar app (which has been running this since the
maxRefreshHz API landed).

Static-bubble verification (required before this port is safe): TigerSpeechBubble is the
only writer of the bubble's Text components in this sample — they are set at build
(BuildBubble) and in SetLayoutMode, nowhere else — and it is the sample's only
DisplayXRLocal2D user (no scene or prefab references one either). TigerTuningHUD writes its
own texts but lives on a separate DisplayXRWindowSpaceUI canvas, so it is unaffected. There is
no streaming/animated content path into the bubble.

Coupling: maxRefreshHz / SetDirty() require plugin ≥ v2.11.0 (DisplayXR/displayxr-unity#244).
Satisfied by change 1's repin to v2.12.1 — the two changes must land together.

Not done here

No Unity builds were run (this repo's CI is lint-only; player builds are manual). The
file-encoding invariant was preserved: TigerSpeechBubble.cs stays UTF-8 without BOM
with CRLF line endings (538/538 lines CRLF, verified), and the diff is +19 lines with no
unrelated churn.

🤖 Generated with Claude Code

dfattal and others added 2 commits August 19, 2026 02:22
…/displayxr-unity#254)

v2.12.0 -> v2.12.1 (transparent-overlay click-through hit test no longer
CPU-skins and ray-scans renderers that are disabled or on inactive
GameObjects; drops a per-frame mesh.triangles allocation; adds a bounds
pre-check before the triangle scan; declares the previously-undeclared
com.unity.inputsystem dependency).

The com.displayxr.unity packages-lock.json entries are DELETED rather than
hash-refreshed, so Unity re-resolves the git dependency from scratch on next
open — the lock caches the pinned commit SHA, and the plugin's dependency set
changed in this release (inputsystem is now declared), so a hand-edited hash
would leave a stale dependency block behind.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…yXR/displayxr-unity#244)

The bubble is a static panel of text, but its Local2D layer re-rendered every
frame: an enabled offscreen camera plus the provider's full-RT bridge copy, all
to redraw identical pixels. Set maxRefreshHz = 4f and announce the two content
changes explicitly via a MarkBubbleDirty() helper (build, and the Ctrl+Shift+L
layout-mode toggle, whose both branches rewrite the title/body text). The
component itself force-refreshes when the pixel rect moves, which already covers
the split drag and window resizes.

Verified static: TigerSpeechBubble is the only writer of the bubble's Text
components in this sample, and the only DisplayXRLocal2D user — the tuning HUD
is a separate DisplayXRWindowSpaceUI canvas, unaffected.

maxRefreshHz / SetDirty need plugin >= v2.11.0; satisfied by the v2.12.1 pin in
the preceding commit. Ported from the verified downstream avatar app.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dfattal
dfattal merged commit 6f2b1a5 into main Aug 19, 2026
1 check passed
@dfattal
dfattal deleted the chore/repin-v2.12.1-bubble-cap branch August 19, 2026 09:27
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