Skip to content

Off-isolate frame worklets (setFrameWorklet) — 0.1.0 - #5

Merged
JenteJan merged 2 commits into
mainfrom
feat/off-isolate-worklets
Jun 27, 2026
Merged

Off-isolate frame worklets (setFrameWorklet) — 0.1.0#5
JenteJan merged 2 commits into
mainfrom
feat/off-isolate-worklets

Conversation

@JenteJan

Copy link
Copy Markdown
Owner

The headline differentiator's last gap. setFrameWorklet(entry, args:) runs heavy per-frame work (ML/CV) on a background isolate with the main thread untouched; results stream via frameResults.

Mechanism (device-proven on Pixel 8): the NativeCallable.listener is created on the worker isolate, so the native camera thread delivers frames there — frames cross as the same zero-copy FFI pointers. The entry is a top-level function (Dart can't ship closures across isolates); model bytes come via args (a worker can't read rootBundle).

Example: the Object Detector now runs EfficientDet-Lite0 fully off-isolate, with a live main-isolate UI-tick counter proving the main thread stays free. Both platforms build; 14 tests pass; setFrameProcessor stays for light work.

JenteJan added 2 commits June 28, 2026 01:21
Run heavy per-frame work (ML/CV) on a background isolate, main thread untouched:
- setFrameWorklet(entry, args:) spawns a worker; the NativeCallable.listener is
  created ON the worker, so the native camera thread delivers frames there (proven
  on-device). Frames cross as the same zero-copy FFI pointers.
- FrameWorklet context: onFrame / send / args. Results stream via frameResults.
- Entry is a top-level fn (Dart can't ship closures across isolates); a worker
  can't read rootBundle, so model bytes come via args.
- Race-free cross-isolate teardown; shared Frame.fromNative factory.
- setFrameProcessor (main isolate) stays for light work.
EfficientDet-Lite0 inference + YUV->RGB now run in a worklet on a worker isolate;
the UI isolate only maps boxes (previewRectFromFrame) and paints. A live
main-isolate UI-tick counter shows the main thread stays free under heavy load.
Model bytes are loaded on main and passed via args (Interpreter.fromBuffer).
@JenteJan
JenteJan merged commit c891abc into main Jun 27, 2026
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