Skip to content

fix(razer): smooth wrapper colours between Chroma service updates - #296

Open
moeilijk wants to merge 1 commit into
Aurora-RGB:devfrom
moeilijk:fix/razer-wrapper-smoothing
Open

fix(razer): smooth wrapper colours between Chroma service updates#296
moeilijk wants to merge 1 commit into
Aurora-RGB:devfrom
moeilijk:fix/razer-wrapper-smoothing

Conversation

@moeilijk

@moeilijk moeilijk commented Jul 5, 2026

Copy link
Copy Markdown

List any issues that this PR fixes: none

This pull request proposes the following changes:

  • The Razer Chroma wrapper layer now eases each key toward the newest service colour per render tick (exponential smoothing, time constant 100 ms; new per-layer SmoothingEnabled property, default on, logic-overridable)
  • Removes the RzHelper.IsStale/_updatedLayers short-circuit: it was a plain HashSet cleared from the reader thread while the render thread Added, which corrupts the set (observed in the wild: InvalidOperationException: Operations that change non-concurrent collections must have exclusive access thrown from RazerLayerHandler.Render); smoothing needs per-tick rendering anyway

Why: measured on a live system (RazerSdkReader with no work in the hot path), RzSDKService republishes the emulator keyboard buffer at most ~10 Hz (inter-update intervals cluster at ~100 ms) with occasional 200-600 ms gaps followed by colour jumps. Mirrored raw, a classic Chroma game whose effect ramps colours (e.g. BG3's breathing menu) looks visibly stepped on the keyboard.

This ~10 Hz is not the reader being slow: Razer's own Chroma SDK FAQ states that "reducing the delay down below 100ms starts to really get out of sync and the keyboard seems to lose steady timing", while animation content is authored at 30 FPS (verified: the 007 catalog keyboard .chroma frames are a uniform 33 ms). So the pipeline delivers ~30 FPS content over a link that only reliably services ~10 Hz, and the documented pipeline has no interpolation step to bridge the two. This layer adds that step client-side: easing toward the latest buffer value each render tick reconstructs the intended motion instead of showing the raw ~10 Hz samples. It is opt-out via SmoothingEnabled.

Known issues/To do:

  • none known

RzSDKService writes the emulator buffers at ~10 Hz with multi-frame
gaps, so raw wrapper output steps visibly on the keyboard. Each key now
eases toward the newest service colour per render tick (tau 100 ms, new
per-layer SmoothingEnabled property, default on), turning steps into
fades.

This requires rendering every tick, so the IsStale/_updatedLayers
short-circuit is removed — it was also a plain HashSet cleared from the
reader thread while the render thread Add'ed, which corrupted the set
(InvalidOperationException in Render).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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