Repository navigation
Conversation
Quest-Claim: 903e184462767cb6
…rade each canvas Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # README.md # rs/moq-studio/src/ui.rs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…adcast writes it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 56 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit 5ce216b. No actionable findings. Shared/independent switchers fit linked canvases, a single movable recording line avoids redundant encoder ladders, and preview gating appropriately reduces unseen GPU work.
Verification: GitHub-only static review of implementation, tests and relevant rendering/recording lifecycle paths. I did not run builds, tests, UI, GPU, relay, or performance execution.
There was a problem hiding this comment.
Reviewed changes
- Unlinked canvases (
moq-scene): preview, program, keyframe clocks, and the in-flight transition move into aSwitcher; linked canvases share the main one, and a canvas withExtra::transitiongets its own switcher cloned from the main one.rename,retain, andon_aircover every switcher, and relinking cuts the canvas to the main program. - Preview gating:
Compositor::set_previewednames the canvases that draw a preview; every other output draws its program alone, and the overlay painter and keyframe clocks skip unseen previews. The UI previews only the canvas it shows and advances the picker once that preview has been drawn. - Per-canvas recording: recording becomes its own
Line(Encoders::recording) fed whichever canvasExtra::recordednames, falling back to the main canvas, and reprobing when the canvas size changes.Stats::recordingreports its encoder, andDraft::set_recordedmoves the pick and falls back on removal. - Per-canvas health: each further canvas solicits viewer feedback beneath its own path and is graded by
health::Canvases; the uplink is graded across every canvas's tracks, encoder/viewer problems name the canvas, and readers run on the main runtime. - UI, docs, and tests: the canvas picker drives Scenes/Program/Items and marks unlinked canvases, the Program panel gains Linked, the Output panel gains a recording Canvas picker and encoder row, and Health is per canvas; README, scene-file docs, and tests are updated, and the
multi-canvasquest is marked complete.
✅ No new issues found.
big-pickle (free) | 𝕏
|
Closing: the maintainer is replacing canvases with published scenes (each scene has a size and a Publish checkbox, a scene source draws another scene or the program, and mixes become audio scenes). The parts that survive (Health per published broadcast, a recording picking its scene, skipping an unseen preview) carry into the new quest plan. (Written by Claude Opus 5.5) |

Problem
moq-dev/studio#42 drew further canvases, but every canvas switched scenes together, only the main canvas recorded, the Health panel graded only the main broadcast, and every canvas drew its preview each frame whether anyone looked or not. Multiple canvases asks for the rest.
Approach
moq-scene): preview, program, keyframe clocks, and the transition under way move fromCompositorinto aSwitcher. The main canvas has one, which every linked canvas shares; a canvas whoseExtra::transitionis set is unlinked and gets its own, cloned from the main one's so it keeps showing what it showed.Compositor::switcher(canvas)/switcher_mut(canvas)return the one that drives a canvas;rename,retain, andon_aircover every switcher, so a scene on air on any canvas cannot be removed. Relinking cuts the canvas to the main canvas's program.Draft::set_extra_transitionunlinks, relinks, or sets the unlinked canvas's own transition;Collection::takes(canvas)says which transition a canvas uses.Compositor::set_previewed(&[canvas])names the canvases that draw a preview; every other draws its program alone, and the overlay painter and keyframe clocks skip what no preview shows.Output::previewed()says whether the last render drew it. The UI previews only the canvas it shows, and switches the picker's canvas once that canvas's preview has been drawn, so it never flashes a stale one.Lineof its own (Encoders::recording) fed whichever canvasExtra::recordednames, or the main one; a canvas of another size reprobes, as any line does, so the recorder goes on in a new file.record.rsis untouched.Draft::set_recordedmoves the pick; removing the recorded canvas sends recordings back to the main one.Stats::recordingreports its encoder.health::Canvasesgrades each one beside the mainhealth::Broadcast, with its viewers, the relays' watch count, and its tracks. The uplink is graded on every canvas's tracks together (each further canvas's under itsname/prefix, as its grants already are). Encoder and viewer problems on a further canvas name it ("On canvastall, ..."). Readers run on the main runtime, not the program clock's, and a canvas removed and added back keeps its grading.Measurements
compositor::bench::sources_against_canvases, release, Apple M-series GPU (Metal); 1080p main canvas plus 1080x1920 further canvases, each item a quarter canvas at half opacity, GPU waited on per frame. "all" draws every canvas's preview (as before this PR), "main" only the main canvas's, as when the studio shows the main canvas:Skipping the previews nobody sees saves a third of the frame time with four dense canvases (14.6 ms to 9.3 ms at 64 sources), and a sparse canvas still costs about the same however many sources the collection has. One canvas is unchanged within noise (the 4-source, 1-canvas "every preview" cell is a warm-up outlier). A second run while other agents loaded the GPU was 2 to 5 times slower throughout and is not shown.
GPU copies and encoder load: unchanged per canvas. The recording still costs one encode session and one copy of the recorded canvas's program per frame while recording, and none otherwise; it no longer needs to be the main canvas.
Impact
[canvases.<name>] transition = {...}unlinks a canvas, which then switches scenes on its own by that transition;recorded = truehas recordings hold that canvas, on one canvas at most. Additive: existing files load unchanged.<broadcast>/<name>/viewers/. A recording can hold any canvas.moq-scene):SwitcherandOutputexported;Compositor::{preview_scene, program_scene, preview_since, set_preview, cut, transition, transitioning}move toSwitcher, reached byCompositor::switcher{,_mut}; newCompositor::set_previewed,Output::previewed,Extra::{transition, recorded},Collection::{recorded, takes},Draft::{set_extra_transition, set_recorded}. A compositor previews only its main canvas until told otherwise. No wire changes beyond the new feedback solicitation.README.mdupdated (Panels, Canvases, scene file, encoder sessions, Recording, Health).Choices made without asking
Decisions
Settled by the maintainer on 2026-11-05:
[canvases.<name>] transition = {...}unlinks a canvas, andrecorded = truepicks it for recordings, on one canvas at most. (Rejected:linked = falsebeside a transition ignored while linked; a top-levelrecording = "<canvas>"or a[recording]table holding canvas and mix.)Alternatives
Recorder's API; one recording line fed the picked canvas does neither.recording = "<canvas>"beside[mixes] recording, or a[recording]table holding canvas and mix: see Waiting.Follow-ups
None.
Validation
On macOS (Apple GPU, Metal):
just cipasses at 5ce216b (lint, both clippy feature sets, every test).--run-ignored allwithopenh264: everycompositor::tests::*, including the newan_unlinked_canvas_switches_on_its_ownandonly_a_previewed_canvas_draws_its_preview;engine::tests::the_program_records_without_a_relay, now recording a further canvas of another size into a new file;engine::tests::the_program_of_a_further_canvas_has_its_own_broadcast, now checking its catalog solicits feedback and Health grades it, then forgets it once removed;engine::tests::the_program_reaches_a_relay;setup::tests::times_every_canvas.collection::tests::a_further_canvas_unlinks_and_records,edit::tests::the_recorded_canvas_moves_and_falls_back,health::tests::{the_encoder_falling_behind_is_named, tracks_are_graded_by_canvas_and_source, viewer_feedback_times_each_track}.Review
Codex (
quest review), gpt-6.1-sol, medium effort.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code