Skip to content

Implement a Native Renderer for Compiled Language Bindings - #85

Draft
parkernilson wants to merge 151 commits into
elemaudio:mainfrom
parkernilson:parkernilson/native-renderer
Draft

parkernilson wants to merge 151 commits into
elemaudio:mainfrom
parkernilson:parkernilson/native-renderer

Conversation

@parkernilson

@parkernilson parkernilson commented Sep 3, 2026 •

Copy link
Copy Markdown

Fixes: #84

Summary

This PR carries changes in the c++ layer that:

  1. Implement struct elem::NodeRepr which corresponds to NodeRepr.res
  2. Implement class elem::Renderer<FloatType> which corresponds to the Renderer in index.ts and can render graphs of std::shared_ptr<elem::NodeRepr> and apply instructions to elem::Runtime<FloatType>
  3. Implement the suite of stdlib node functions corresponding to js lib functions

Additionally, it:

  1. Adds an elemcli-native executable that shows a basic use case of the native renderer (and adds a compilable target that helps with IDE intellisense of header-only library)
  2. Adds functionality to the elembench tool so that it can benchmark the performance of JS and native renderers (i.e. how long does it take to build an audio graph representation and how long does it take to render those changes to the runtime)
  3. Bumps the miniaudio.h version to support newer versions of macOS
  4. Adds googletest as a submodule dependency for c++ tests
  5. Adds tests for the native renderer equivalent to js/packages/core/tests
  6. Adds c++ test utils for snapshots
  7. Modifies some existing types to support Renderer functionality, including GraphNode.h, Runtime.h, and Value.h

Updates to the Docs if Accepted

If these changes are accepted, I have also created a PR here with the related changes to the docs on the Elementary Website.

Proof of Concept with Swift

I put together a PoC with Swift. The basic pieces are there for end-to-end integration with Elementary, however development is still on-going.

Verification

Added automated tests for the new c++ features, and included them in the CI workflows as a new "Test" step that runs the native tests. These tests cover all the applicable test cases that the current JS renderer is subject to.

Also added benchmark testing for the JS and Native renderers. Both are extremely fast, and well within the limits of reasonable requirements. The following are the results of rendering a cycle(440.0 + i) for i in [0..10000) with no keyed constants (i.e. the entire graph is re-rendered on each pass). us = microseconds:

$ ./build/cli/elembench renderer js cli/examples/dist/renderer/00_BenchmarkSineNoKey.js
[Running Renderer JS, cli/examples/dist/renderer/00_BenchmarkSineNoKey.js]:
Build graph total: 181000us, average: 18.1us
Render graph total: 434000us, average: 43.4us
Done

$ ./build/cli/elembench renderer native sine_no_key
[Running Renderer Native, sine_no_key]:
Build graph total: 10158us, average: 1.0158us
Render graph total: 41867us, average: 4.1867us
Done

I plan on adding another benchmark for rendering a very large graph like 1,000 and 10,000 sine waves where each modulates the frequency of the next. I'll also include variants with keyed constants at the leaf nodes for comparison.

Parker Nilson added 30 commits August 12, 2026 18:11
Documents the algorithm for Renderer::renderGraph: on-demand structural
hashing folded into a single post-order recursive pass, ordered
instruction batching threaded through the call stack instead of stored
as Renderer member state, and root-node wrapping semantics mirroring
the JS core reconciler.
Breaks the reconciliation-algorithm design spec into four tasks: data
model change, test scaffolding (plain-assertion harness, no new test
framework dependency), the renderGraph implementation itself, and
behavior tests covering create/update/dedup/multi-root scenarios.
@parkernilson

Copy link
Copy Markdown
Author

This is still a draft PR because there are a couple of final touches I need to finish

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.

Add a Native Renderer Implementation for Better Language Binding Support

1 participant