feat(session): tile discard (freeze/thaw) + audio-mute + frame-cadence ops#27
Merged
Conversation
freeze() tears down one session's native browser — and, when it was the profile's last live browser, the whole cef_host process tree — while the FlutterTexture keeps serving the last painted frame (the consumer-held CVPixelBuffer retains the producer's IOSurface, a kernel object that survives the producer's exit). thaw() recreates a browser onto the SAME session/texture through the normal create pacer + establishment watchdogs, reusing the C2 re-home attach() path; the frozen frame shows until the new first paint adopts, so there is no flash. detachForFreeze() resets the establishment counters (firstPresentSeen / presentCount / lastPresentNs / livenessNudgedAt) so the thawed browser reads as a FRESH establishment to the pacer and first-present watchdog — a stale presentCount would pin the pacer slot until the timeout backstop and repeat-fire paintStalled. Side levers, policy left to the consumer: - setAudioMuted (kOpSetAudioMuted 0x3a): a hidden AND muted page regains Chromium's intensive wake-up throttling (audible pages are exempt). - setFrameInterval (kOpSetPumpInterval 0x3b): per-slot visible begin-frame cadence, clamped [8, 250]ms — 33ms halves an unengaged tile's paint/blit CPU. kCefHostProtocolVersion 4 -> 5 (new ops; the opReady handshake refuses skewed prebuilts). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The agent_ui discard path regenerates its document from host-side state, so thaw needs the same html->data-URL entry create/loadHtml have (html wins over url, mirroring create). Purely Dart-side: converts to a data: URL and rides the existing thawSession url param — no native change. Without this, a consumer that froze an authored-document session can only thaw by url, losing its live state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds session-level discard (freeze/thaw) to
flutter_cef, plus twolower-cost levers, so a host can reclaim a hidden tile's Chromium footprint
without losing its on-screen frame.
freeze()— tears down a session's browser (and, when it was theprofile's last live browser, the whole
cef_hostprocess tree) while theconsumer-held
CVPixelBufferkeeps serving the last painted frame (theIOSurface is a kernel object that survives the producer exit).
thaw({url, html})— recreates a browser onto the same session/texturethrough the normal create path, reusing the C2 re-home attach (with a fix for
its latent stale-
presentCountbug).setAudioMuted(bool)(op0x3a) andsetFrameInterval(op0x3b) —cheaper levers for tiles that should stay live but quiet/slow.
Wire protocol bumps v4 → v5.
Why
Each webview tile is its own renderer tree; a busy canvas of them is the memory
ceiling. Discard reclaims a hidden tile's RSS while the texture stays visually
intact, and thaw restores it on the next visible edge.
Validation
Consumed live from
work_canvas(co-dev path override). A board of webviews:baseline ~2.1 GB / 17 procs → after discard ~0.9 GB / 7 procs, whole host tree
exiting on the last freeze; switching back thaws cleanly. See the companion
work_canvas PR for the full harness + a
--assertregression guard.Landing note
Because this bumps the wire protocol, the consumer must
make pin-cefto thiscommit and
make publish-cef-hostso a content-hash-matched prebuilt existsbefore the pin flips — otherwise agent_ui/cefWebview tiles freeze/blank silently.
🤖 Generated with Claude Code