Repository navigation
Conversation
Every `MpRunView` started a 125 Hz interval when it was created, whether or not a child process was attached. The timer's `Event::Timer` went through the whole app on every pass of the event loop — the hosted AppCard module's widget tree included — and on the phone, which hosts no child processes, it was the most frequent event the app handled (about 94 per second, idle or animating, against 60 next-frames). The interval now starts in `set_target` when a process attaches and stops when it detaches; the tick's work (bootstrap resends, `StudioToApp::Tick`) already did nothing without a target. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aa21709 on top of f1db9eb (OctoSense-org/makepad#6): - a worker's UI wake no longer paints on Android: `SignalToUI` sent the Choreographer's own `RenderLoop` message, so every worker signal drew and swapped an extra frame between vsync beats (one per animation frame here); - Android retires draw storage without raising the UI signal, which reached the whole app, the hosted AppCard included, once or twice per frame; - `AppIconDraw` keeps tessellated icons per device-size bucket instead of re-tessellating an icon drawn at two sizes on every draw; - the render thread runs at nice -10 on the fast cluster. Same routing as the previous pin: every crate of the OctoSense-org/makepad URL resolves through the www host alias at this rev, so `octos-app`'s ad8f372 manifest and the workspace share one makepad lineage (one makepad-widgets in Cargo.lock, no ad8f372 left). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The drawer is an opaque full-screen sheet with no slide, so the wallpaper under it is never visible, yet the scene plan drew it on every frame, and with glass up (a home swipe that starts on the drawer blurs it into Recents) a second time into the backdrop scene. The wallpaper is the most expensive full-screen fill the phone draws: a Recents hold over the drawer presented at 39 fps (GPU-ready p50 43 ms) against 55 fps (13 ms) over Home on the OnePlus 6T, and the harness reaches Recents from the drawer after its page swipe. The plan leaves the wallpaper out on Android's drawer. The iOS App Library is translucent and keeps it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The shade asked the backdrop compositor for a mid-scene checkpoint after all scene content. That opened a second segment whose only content was a full-screen copy of the first: one more full-resolution scene pass plus a copy on every frame of the pull. The sheet samples the finished scene, which is what `finish`'s final glass snapshots with no copy; the upside-down GL snapshot that kept the shade off it was fixed in the fork (f1db9eb). With the keyboard up (its own final glass) the shade keeps the checkpoint. The census during a pull goes from two `gauss_scene` passes to one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lyphs An A/B of the shade's parts on the OnePlus 6T (monitor off, two pulls each) put the cost in fill rate, not in draw calls: CPU `draw` stayed at 4-5 ms in every variant while the swap wait fell from 7-21 ms to 1.5 ms with the sheet glass, dim and content removed (60 fps). The sheet glass was the largest single part. - The sheet was a glass at the overview tint plus a 55-62 % tint rect over it: two full-width blends. The tint is now folded into a dedicated `shade_glass`, exactly: mix(mix(T, g, 0.2), c, a) = mix(T, g', 1 - 0.8 (1 - a)), with the rim and inner shadow scaled by (1 - a) as the tint layer covered them. - The full-screen dim is drawn only below the sheet: the sheet's glass fills at alpha 1 from a snapshot taken before the overlay, so dim under it never reached the screen. - The first pull after launch spent ~30 ms of a 55 ms frame packing glyphs into the atlas under `draw_overlay`. Both pages are now drawn once from a seeded copy of the shade, off-screen and transparent, on the first idle frame; the live shade still seeds its fixtures on its first real open. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two fork commits on top of aa21709: - the render thread's boost runs after `Event::Startup`, whose task-pool warm set it back to nice 0; - an integer glass blur level reads one mip level and the compositor builds ceil(level) mips (the shade and a settled Recents sit at 3.0). Same www-alias routing: one makepad lineage in Cargo.lock, no ad8f372. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
With the drawer open the phone scene drew a full-screen flat fill (the system-bar colour, standing in for the wallpaper) under the drawer's own full-screen sheet, both through the SDF chrome quad. A home swipe that starts on the drawer composes both into Recents' blur, and the frame missed its vsync: an A/B on the OnePlus 6T (Recents hold from the drawer, monitor off, two runs each) ran 38-40 fps with both, 42-44 without either one, 48-49 without both (GPU-ready p50 42 -> 33 ms); the drawer's icons, labels and search pill moved nothing. The scene now fills only the strips outside the safe area when the Android drawer covers the rest, and the drawer's sheet is a flat fill rather than the chrome quad. The look is unchanged: the drawer is opaque. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
simpleperf call graphs and atrace per transition on the OnePlus 6T: the render thread's hotspots (icon re-tessellation, the hosted AppCard handling a worker signal and a 125 Hz timer per frame), its scheduling (nice 0, a quarter of its time on the little cores), the shade A/B that puts the remaining cost in GPU fill rate rather than GL driver overhead, the Recents hold's dependence on starting from the drawer, the fixes with their files, before/after SurfaceFlinger tables (two fresh launches per build, monitor off), the attribution run, and what is still short of 55 fps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
One fork commit on top of e596207: the script VM's probe lookups (`+:` and a shader's scope-object field) pass NoTrap, so their expected misses no longer build a "Did you mean" edit-distance list (part of a hosted AppCard's first open). Same www-alias routing: one makepad lineage, no ad8f372. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ymote
force-pushed
the
perf/android-idle-repaint
branch
from
September 19, 2026 23:56
cab4e59 to
f9e254c
Compare
ymote
force-pushed
the
perf/transition-main-thread
branch
from
September 19, 2026 23:56
efc153c to
344655f
Compare
Contributor
Author
|
Closing as superseded: every commit in this stack (#22–#28) is already on OctoSense-ROM 🤖 Generated with Claude Code |
This was referenced Sep 27, 2026
Closed
Closed
chrislearn
pushed a commit
to chrislearn/OctoSense
that referenced
this pull request
Sep 29, 2026
OctosMap: a maps app for the phone shell
chrislearn
pushed a commit
to chrislearn/OctoSense
that referenced
this pull request
Sep 29, 2026
…e993d4c Home: App Hub 3e993d4c, System-Apps c0f2199c (octos main)
chrislearn
pushed a commit
to chrislearn/OctoSense
that referenced
this pull request
Sep 29, 2026
OctoSense-System-Apps c0f2199c and App Hub 3e993d4c (pinned by OctoSense-org#28) carry the AI providers app, octosense-llm-service and octosense-llm-config, and the `llm` capability; the Mail and llm services name Home's App Hub rev, so the graph keeps one App Hub. Home links the llm crates under `app-hub`, and system-apps.json selects ai-providers. src/llm_host.rs registers `llm` at startup with the AppCard kernel's octos home as the core dir and, on Android, a camera QR scanner over cx.show_qr_scanner() (NativeQrScanned / NativeQrCancelled routed from Home's events; a scan the service did not ask for, such as AppCard's composer's, is left alone) and an image picker: QrImagePickActivity, an invisible activity in a task of its own that runs the system picker and hands the bytes over in a private cache file on the qr.image.result packet. With AppCard linked (--features app-appcard, opt-in since OctoSense-org#27), a change to the provider set restarts the AppCard core; without it no change hook is registered. System-Apps' AppCard now takes octos from octos main, which no longer vendors nix; Home's nix patch stays at the 18fcd3f1 copy octos-app itself patches in, and the comment and READMEs say so. Co-Authored-By: Claude Opus 5.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.
Draft: the OnePlus 6 (Android 15) numbers are still to come; see the placeholders below.
Phone-shell transition performance on the OnePlus 6T (Snapdragon 845 / Adreno 630, Android 11, 1080×2340 @ 60 Hz), profiled with root
simpleperf --call-graph dwarfandatrace. Stacked on #27 (perf/android-idle-repaint). The makepad pin moves to OctoSense-org/makepad#7 (perf/android-main-thread).What the profile found
Render-thread samples on PR #27's build, OnePlus 6T, Android 11:
draw_phone_sceneAppIconDraw→render_svgrender_viewThe hosted AppCard's share. It came from
Event::SignalandEvent::Timer: a worker signal once per animation frame, plus a 125 Hz run-view timer. Each event ran the AppCard'supdate_connection_indicatorscript eval.After the fixes (same phone):
AppIconDraw0.8–1.8 %render_svg≤ 0.6 %glTexImage2D0 %Scheduling:
eglSwapBuffers/queueBuffertook 22–73 ms in slow frames, which is GPU back-pressure.The shade A/B. CPU
drawstays at 4–5.5 ms in every variant. The swapwaitfalls from 7–21 ms to 1.5–3.7 ms once the stacked full-screen blends are removed, and that variant reaches 60 fps. The remaining cost is fill rate, not GL driver overhead, so a Vulkan path would not remove it.Commits
wm: a run view ticks its child only while a process is attached. A 125 Hz timer ran through the whole app, the hosted AppCard included, on a phone with no child processes.deps: makepad pin toperf/android-main-thread, samewwwalias routing (one makepad lineage, no ad8f372).mobile: the Android app drawer hides the wallpaper, including under glass.mobile: the shade's sheet is the compositor's final glass. This removes a second full-screen scene segment on every frame of the pull.mobile: the shade is one glass layer. Its tint is folded in exactly, the dim is drawn only below the sheet, and its glyphs are warmed once before the first pull.mobile: under Android's drawer only the system-bar strips are filled.docs: the fourth column indocs/perf-mobile-shell.md.The pin commits track the fork head: aa21709, then e596207, then 73dfc62. The last adds the script VM's probe lookups passing
NoTrap(OctoSense-org/makepad#7).Before / after (SurfaceFlinger, monitor off, two fresh launches per build)
Cells: burst fps · p95 ms · intervals > 33 ms / burst intervals · worst first frame (ms).
OnePlus 6T, Android 11 (
bf0a4730)OnePlus 6, Android 15 (
cfb7c9e3)These numbers come from a different phone than the 6T tables above and are not comparable with them. It has the same Snapdragon 845 / Adreno 630, but a 1080×2280 screen, density 450, and gesture navigation. Before is PR #27's build and after is this branch, on the same phone, monitor off, with harness coordinates recalibrated to its screen.
OP6_TABLE
First frame on a fresh launch: OP6_FIRST. Attribution run with the monitor on: OP6_MON.
Shade
waitwith the monitor on: OnePlus 6T: mean 7–21 ms (worst 57–85) before the shade fixes; 4.9–16 ms (worst 36–47) after; 1.5–3.7 ms with the sheet glass, dim and content switched off. CPUdrawstays at 4–5.5 ms throughout, so this is GPU fill rate, not GL driver overhead. OnePlus 6: OP6_WAIT.Attribution run with the monitor on: see Table 6 in the doc.
Not met
aapt add), or preload them off the main thread;Tests
cargo test: 265 passed.cargo test --features mobile-only: 262 passed.--test-action capture).Not for merge until reviewed.
🤖 Generated with Claude Code