๐ก OnionPlus ships and updates itself over-the-air โ
ota_update.shchecksAmiga500/Onionreleases directly on-device, so every optimization and hardening pass below reaches installs without a manual re-flash. See ยง9 ยท Build, CI & release for the wiring.
| Section | |
|---|---|
| ๐ฏ | Why this document exists |
| ๐ผ๏ธ | 1 ยท Vectorized pixel paths (NEON) |
| โก | 2 ยท Algorithmic wins (O(nยฒ) โ O(n)) |
| ๐จ | 3 ยท Rendering & UI caches |
| ๐ | 4 ยท Power, battery & idle CPU |
| โ๏ธ | 5 ยท Process & syscall diet |
| ๐ก๏ธ | 6 ยท Security & memory hardening |
| ๐น๏ธ | 7 ยท AdvanceMENU frontend |
| ๐งช | 8 ยท Testing safety net |
| ๐๏ธ | 9 ยท Build, CI & release |
| ๐ | 10 ยท Grand totals |
| ๐ | 11 ยท Commit timeline |
| โ | Final word |
OnionPlus is measured against OnionUI/Onion:main
at merge-base 07505ea5 (4.4.0-beta).
That is the comparison that matters for this fork. Some NEON kernels and early hardening
were first written elsewhere; every percentage in this document is OnionPlus vs
OnionUI/Onion:main, not vs that sibling branch.
The integration branch is onionplus-compact:
the long OnionPlus history (97 commits to fa5bb007)
squashed into topic commits, then the @robcodedev ports of still-open
OnionUI/Onion PRs #1936โ#1946
(Amiga500 #217), and the 2026-09-09
review fixes (fbd26d06 list-cache
dimming + installer Flip detect; bf3deb8e
Flip 640 lock, fbmode before the FB driver, AXP percBat clamp).
git rev-list --count 07505ea5..HEAD on this branch is the compact count, not 97.
On top of 07505ea5 the tree still carries the power/CPU batch, security review, hot-path
passes, an AdvanceMENU frontend pass, a surgical Miyoo Mini Flip port from
OnionUI/Onion:v4.5-dev that does not merge that branch,
an OnionUI-parity review (charging-icon sentinel, RetroArch killall semantics,
path bounds, rumble GPIO retry), and the 2026-09-01 independent review (findings
AโG). Every pass reaches installs through the built-in
OTA updater (Amiga500/Onion, assets OnionPlus-vโฆ). Last code tip is
bf3deb8e. This document groups
everything shipped to date by category rather than by commit.
| Icon | Meaning |
|---|---|
| ๐ฅ | Order-of-magnitude win โ vectorized paths, quadratic โ linear, busy-wait removal |
| ๐ง | Structural win โ a syscall/shell-out/scan eliminated on a repeatable path |
| ๐จ | Incremental win โ smaller but still measurable saving |
| ๐ฆ | Robustness โ correctness / memory-safety fix, no performance claim |
| ๐ฉ | Quality floor โ tests, CI, tooling |
| ๐ | Speedup of the OnionPlus path vs the OnionUI/Onion:main equivalent |
| ๐ | Figure estimated analytically (algorithmic complexity / syscall count) |
| ๐งช | Verified by unit test in this repository |
| ๐ก๏ธ | Correctness/safety fix carrying no performance claim |
โ ๏ธ Percentages compare OnionPlus code vsOnionUI/Onion:main(07505ea5). They have not been re-timed on a physical Miyoo as part of this fork. ๐ = analytical (complexity / syscall count). See methodology.
๐ฅ The single biggest performance category โ whole scalar loops replaced by ARM NEON vector kernels, each with a scalar C fallback so non-NEON builds still work.
| Kernel | What it replaced | Speedup | Evidence |
|---|---|---|---|
๐ neon_rotate180_inplace |
rotozoom blit + extra surface alloc | ๐ +5000 % | ๐ |
๐จ neon_swap_rb_inplace |
scalar per-pixel loop | ๐ ~+800 % | ๐ |
๐จ neon_argb_to_rgba |
scalar per-pixel loop | ๐ ~+800 % | ๐ |
๐จ neon_rgb888_to_argb |
scalar per-pixel loop | ๐ ~+800 % | ๐ |
โช neon_gray8_to_argb |
scalar per-pixel loop | ๐ ~+600 % | ๐ |
โช neon_gray8a_to_argb |
scalar per-pixel loop | ๐ ~+500 % | ๐ |
๐จ neon_argb_to_rgba_alpha |
scalar per-pixel + branch | ๐ ~+600 % | ๐ |
๐ซ๏ธ surfaceSetAlpha (NEON intrinsics) |
float mul + SDL_GetRGBA |
๐ ~+400 % | ๐ |
- ๐ฆ 8 kernels total (7 hand-written ARM assembly + 1 NEON intrinsics), all guarded by
#ifdef __ARM_NEONwith a correct scalar tail loop for the remainder. - ๐งช Backed by
test_neon,test_neon_pixelandtest_alpha_scaleโ 109 tests / 67,353 assertions cross-checking NEON output against the scalar oracle. - ๐ฌ Every scalar fallback is exercised on the x86-64 host CI; a separate
neon-armjob cross-compiles the assembly and runs it underqemu-user.
๐ฅ๐ง String and path handling rewritten to drop a re-scan hidden inside a loop.
| Function | Before | After | Class | Evidence |
|---|---|---|---|---|
str_count_char |
strlen() re-evaluated every iteration |
single pointer walk | O(nยฒ)โO(n) ๐ โ90 % | ๐๐งช |
file_removeExtension |
strlen + strcpy rescans |
one scan + length-known memcpy |
โ50 % scans | ๐๐งช |
file_path_relative_to |
strcat loop rescanning from byte 0 |
explicit offset + memcpy |
O(nยฒ)โO(n) | ๐๐งช |
file_resolvePath |
strcat loop per path component |
bounds-checked memcpy at offset |
O(nยฒ)โO(n) | ๐๐งช |
file_read() |
fopen+fseekร2+ftell+buffered fread |
stat64 + one read() loop |
2 seeks removed | ๐๐งช |
๐น๏ธ move_Roms_Without_Preview.ps1 |
rescans the Snaps folder per ROM | Snaps folder read once into a lookup set | O(nยฒ)โO(n) | ๐ |
๐น๏ธ move_incompatible_Roms.ps1 |
linear XML scan per ROM | ROM names indexed into a hashtable | O(nยฒ)โO(n) | ๐ |
๐ Bonus fixes bundled in:
str_count_charalso closed a 1-byte over-read (i <= strlen); the path-assembly rewrites addPATH_MAXbounds checks the oldstrcatversions lacked; the PowerShell hashtable rewrite also fixes a crash on ROM names containing an apostrophe.
๐ฅ Redrawing the same pixels every frame is the classic "free win" โ cache it once, invalidate on change.
| Cache | Before | After | Impact |
|---|---|---|---|
| ๐ค TTF label / list / footer / header / dialog surfaces | TTF_RenderUTF8_Blended on every frame |
hash-invalidated cached SDL_Surface; hidden-row dim uses a SDL_ConvertSurface copy (_blit_cached_label) so surfaceSetAlpha never mutates the cache |
๐ 5โ15 ms/frame saved ๐ |
๐ผ๏ธ infoPanel drawImage() |
zoomSurface() + free on every redraw |
scaled surface cached per (source, w, h) | O(wยทh) scale eliminated on repeats ๐ |
| ๐ฎ playActivityUI page render | 4ร IMG_Load+SoftStretch+alloc per page flip |
4 surfaces cached, reloaded only on page change | page flips skip all image I/O ๐ |
๐ฅ๏ธ display_readOrWriteBuffer |
per-pixel loop on every row | memcpy fast path for contiguous rows |
row copy vectorized ๐ |
๐งน Every cache above ships with its own teardown:
list_free()releases the TTF slots,cleanImagesCache()frees the infoPanel scaled cache, andfree_resources()releases the playActivityUI page cache โ so this is a speed win without a new leak.
๐ฅ๐ง The category with the most direct battery-life relevance: fewer wake-ups, fewer forked subprocesses, fewer duplicate sysfs writes.
| Subsystem | Before | After | Impact |
|---|---|---|---|
| ๐ OSD volume/brightness bar thread | usleep(100) busy-wait (~10,000 loops/s) |
usleep(16000) (~60 fps) |
๐ idle CPU ~10 % โ <1 % ๐ |
| ๐ผ๏ธ OSD overlay draw loop | full-throttle spin for the overlay's duration | msleep(2) per iteration + demoted logging |
overlay CPU burn capped ๐ |
๐ battery_isCharging() (HAS_AXP() โ MM+ and Flip) |
fork+exec of axp_test every call (~5โ10 ms) |
2 s cached wrapper | ๐ ~โ99 % subprocess spawns ๐ |
๐ battery_hasChanged while charging |
OnionPlus used to overwrite the 500 charging sentinel from /tmp/percBat |
early-return like OnionUI/Onion:main (500 stays while plugged in) |
charging icon no longer drops after the first percBat tick ๐ก๏ธ |
๐ชซ getBatPercMMP() AXP percent |
axp_test garbage (e.g. 1735289191) and -1 written to /tmp/percBat |
last sane 0โ100 kept; out-of-range samples dropped | GS/keymon never read a bogus percent ๐ก๏ธ |
| ๐ชซ batmon low-battery thread | usleep(0x4000) (~16 ms) |
usleep(500000) (500 ms) |
๐ ~โ97 % wake-ups ๐ |
๐ก display_setBrightnessRaw |
sysfs write on every call | cached, duplicate writes skipped | โ100 % duplicate PWM writes ๐ |
| โฑ๏ธ batmon main loop | config_get("battery/warnAt") every tick |
read only at check timeout | โ100 % hot-loop config reads ๐ |
๐ณ rumble() GPIO init |
export+direction sysfs writes on every pulse |
one-time init + retry if gpio48 missing, value-only writes after |
โ2 sysfs writes/pulse ๐ |
| ๐ฎ GameSwitcher battery poll | stat() on /tmp/percBat every loop (~1 kHz) |
checked once/second (matches batmon's write rate) | ~99.9 % fewer stat calls ๐ |
| ๐ AdvanceMENU quick-switch (PWM) | backlight PWM always re-enabled on exit | re-enabled only when returning from a game (quick_switch) |
fewer redundant PWM writes ๐ |
๐ง Every
system()call forks a shell and the real binary โ two processes for one line of intent. These were replaced with direct syscalls orfork+exec.
| Call site | Before | After | Result |
|---|---|---|---|
mkdirs() |
system("mkdir -p โฆ") |
iterative mkdir() walk |
2 โ 0 processes |
file_copy() |
system("cp -f โฆ") |
open/read/write loop |
2 โ 0 processes, shell-injection surface closed |
config.h _config_prepare |
system("mkdir -p โฆ") |
direct mkdirs() |
2 โ 0 processes |
GS overlay playActivity |
system("โฆ &") |
double-fork + execl (async, no zombies) |
๐ โ80 % process overhead ๐ |
| GS overlay RetroArch kill/poll | killall / pidof shell-outs |
process_killall_signal / process_isRunning (all matching PIDs) |
โ100 % shell, killall semantics restored |
| playActivity DB ops | 2ร open/close per operation | 1ร open/exec/close | โ50 % DB I/O ๐ |
| Reset paths (tweaks/theme/RA overrides) | rm -rf via system() |
nftw()-based file_remove_recursive() |
shell-free recursive delete |
| ๐น๏ธ AdvanceMENU romscripts | temp file written CWD-relative | temp file next to advmenu.rc, PID-suffixed |
race condition + read-only-CWD failure fixed |
๐น๏ธ AdvanceMENU launch.sh |
no reentrancy guard | early exit if advmenu already running |
duplicate-instance guard |
๐ Net result across the 25-file hardening core:
system()call sites 3 โ 1 (the one survivor,process_start(), is confirmed dead code with no live caller).
๐ฆ No performance claim attached to anything in this section โ pure correctness and memory-safety.
| Category | Before โ After | Count |
|---|---|---|
๐ด Unbounded sprintf |
โ bounded snprintf |
23 โ 0 โ |
๐ด Unbounded strcpy + strcat |
โ bounded copies / memcpy |
37 โ 0 โ |
๐ด Non-reentrant strtok |
โ strtok_r with owned save-pointer |
4 โ 0 โ |
| ๐ข NULL-pointer / I/O guards added | new if (!ptr) / return-value checks |
+57 (25-file set) |
| ๐ข Leaked descriptors closed | fclose/close on error paths |
+18 |
| ๐ข Division-by-zero guards added | early return before % total_count |
+2 |
- ๐
hash.hFNV1A load โ removed a 7-byte out-of-bounds read, an unaligned 64-bit load (traps on ARMv7), and an oversized shift (x << 64, UB). Hashes stay bit-identical โ verified against 264 reference vectors at 5 optimization levels. - ๐ณ๏ธ
gs_popMenu.hsave thread โ used to run with an uninitialised 4 KB stack buffer as a path when path construction failed; now returns early instead of polling a garbage path for up to 30 s. - ๐ฏ
currentGame()NULL derefs โ 3 call sites now guard against an empty game list. - ๐งฎ Dead slot-bounds check โ the reject condition was
selected_slot < 0 && selected_slot >= slot_count, which can never be true for a single value, so out-of-range slots were never rejected; changed to||. - ๐
_isContentNameInInfoOOB read โ a match at offset 0 no longer reads one byte before the buffer. - ๐
includeCJK()UTF-8 validation โ all 3 continuation bytes checked, not just the first. - ๐พ File I/O consistency โ
fsync()before rename on key-value writes;file_remove_recursive()errors are now logged instead of swallowed. - ๐งฉ
const-correctness โfile_basename()no longer discardsconstvia a cast (-Wcast-qualclean). - ๐น๏ธ AdvanceMENU biosset false positive โ indexing only
//game[@name]so BIOS-set XML entries (which also carry anameattribute) no longer cause incompatible ROMs to be kept by mistake. - ๐
battery_hasChangedcharging icon โ OnionPlus no longer lets/tmp/percBatoverwrite the500sentinel while the cable is plugged in. MatchesOnionUI/Onion:mainearly-return. - ๐น๏ธ AdvanceMENU
advmenu.rcsafety โ the rewrite script only overwrites the live config if bothgrepandechosucceeded; otherwise the partial temp file is removed and the original is left untouched. - ๐
mp4_to_mng.ps1โ restored the official HTTPS ffmpeg download permalink (was an insecure/unreliable HTTP mirror), forced TLS 1.2 for old PowerShell, and scoped the ffmpeg search to the extraction directory. - ๐ฒ
randomGamePickerdivision-by-zero โ recents/favorites and single-system modes now bail out withERROR_CODE_NO_GAME_FOUNDinstead of computingrand() % total_games_countwhen the list is empty. - ๐ผ๏ธ
batteryMonitorUImissing assets & OOB graph write โ every blit is routed through asafeBlitSurface()helper that no-ops on a NULL surface (e.g. a failedIMG_Load), andcompute_graph()now stops processing a record set if a corrupt duration would index outside thegraphic[]array. - ๐จ
themeSwitcherNULL assets & theme-count overflow โ the samesafeBlitSurface()pattern plusSURF_W/SURF_Hmacros guard every icon blit against a missing PNG, andloadThemeDirectory()now stops scanning onceNUMBER_OF_THEMESis reached instead of overflowing the theme array. - ๐ฆ
packageManagerloading screen โIMG_Load("res/loading.png")result is now NULL-checked before blitting/flipping/freeing. - ๐งต
gs_romscreen.hformat-string bug โsprintf(currPicture, game->recentItem.imgpath)used the artwork path as a format string; changed tosprintf(currPicture, "%s", ...). - ๐ค List TTF cache dimming โ
surfaceSetAlphaon a cached label mutated the pixels; restoring with alpha 255 is a no-op. Hidden rows now dim aSDL_ConvertSurfacecopy (_blit_cached_label,fbd26d06). - ๐ชซ AXP
percBatgarbage โgetBatPercMMP()keeps the last sane 0โ100 instead of writing-1or timestamps to/tmp/percBat(bf3deb8e).
๐ The newest optimization/hardening pass on the branch โ a fully self-contained batch covering fonts, power handling, script robustness, and tooling.
| Area | Change | Kind |
|---|---|---|
| ๐ค Fonts | advmenu.rc now uses fonts bundled in BIOS/.advance instead of Onion core fonts |
๐จ UX/consistency |
| ๐ Backlight | PWM restored only on quick_switch return-from-game, not on every exit |
๐ power |
| ๐ฆ Single-instance | launch.sh skips launch (with a log message) if AdvanceMENU is already running |
๐ก๏ธ robustness |
| ๐ PS tooling | move_Roms_Without_Preview.ps1 / move_incompatible_Roms.ps1 rewritten from per-item rescans to lookup tables |
โก O(nยฒ)โO(n) |
| ๐ Romscripts | Temp files moved next to advmenu.rc with a PID suffix; only committed if the rewrite fully succeeded |
๐ก๏ธ atomicity |
| ๐ฌ Media tooling | mp4_to_mng.ps1 ffmpeg download hardened (HTTPS, TLS 1.2, scoped search, -Force) |
๐ก๏ธ reliability |
๐ This pass shipped in PR #210, with an explicit code-review follow-up round (
a25abb81) that fixed the BIOS-set false positive and improved the launch-guard log message.
๐ฉ Zero host unit tests existed at the OnionPlus base commit. All of the following was added during this branch.
| Metric | Value |
|---|---|
| ๐งช Active test suites | 68 |
| โ Tests | 1,419 |
| โ Assertions | 71,410 |
| โ Failures | 0 |
| โฑ๏ธ Suite runtime (prebuilt) | ~2.5 s |
| ๐ Security-focused suites | 10 suites ยท 219 tests ยท 960 assertions (15 % of all tests) |
- ๐๏ธ Runs entirely on the host โ no cross-toolchain, no SDL, no device โ via a single
make unit-testtarget, making it usable as a fast CI gate. - ๐งฌ A separate
neon-armCI job cross-compiles the NEON assembly and runs it underqemu-user; aunit-test-sanjob runs a sanitizer subset (ASan/UBSan). - ๐งฏ
test_hashalone grew from 12 tests/21 assertions to 15 tests / 350 assertions to lock in the hash bit-identity guarantee above. - ๐
test_device_modelnow coversMIYOO285and theHAS_AXP()/HAS_WIFI()/IS_MIYOO_PLUS_OR_FLIP()macros (13 tests / 23 assertions, host-run green). - ๐ค
test_alpha_scaleincludesscale_alpha_255_does_not_undo_dim(list-cache dimming). - ๐ชซ
test_batteryclamp contract:axp_percent_keeps_valid/rejects_negative/rejects_garbage/first_failure_is_zero.
| Change | Detail |
|---|---|
| ๐ฆ Release flags | -O2 -ffunction-sections -fdata-sections -Wl,--gc-sections โ ๐ โ5โ15 % binary size ๐ |
| ๐ฏ New build target | make unit-test โ host-only, zero device dependency |
| ๐ Opt-in profiling | src/common/utils/perf.h โ PERF_START/PERF_END compile to nothing unless -DPERF_ENABLED |
| ๐ท๏ธ Release naming | OnionPlus V4.4.0-beta-YYYYMMDD, zip OnionPlus-vโฆ-<sha>.zip โ real dated GitHub Releases, no more overwritten latest. Base remains 4.4.0-beta; Flip support is a port, not a rebase onto official v4.5-dev. |
| ๐ก OTA | ota_update.sh points at Amiga500/Onion, filters OnionPlus-v assets. Stable = /releases/latest. Beta installs only GitHub prereleases โ no fallback to releases[0] (finding D). Host CI (.github/workflows/test.yml) runs on push to onionplus-compact. |
| ๐ฑ Mini Flip | Device id 285, MainUI-285 binaries, lid-close Tweaks. Runtime probes AXP first (354 Mini+), then the hall-mh248 sysfs node (285 Flip). The installer probes hall first (Flip stays Flip if axp is not on PATH yet); axp / axp_test = Plus. /dev/input/event* is not a Flip signal. Installer preclears the framebuffer (fbmode if present, else dd + fbset 640x480/2) before check_device_model. Ported from OnionUI/Onion:v4.5-dev without merging that branch. Lid/Hall untested on a physical Flip. |
| ๐ฅ๏ธ Boot FB | Plus/Flip: a dmesg hint of 640x480 no longer skips the mi_fb0 poll (avoids locking a 752 panel at 640 for the boot). commit_mainui_fbmode() waits for the FB driver; on timeout it uses fbset, not fbmode with the driver still down. |
| ๐งต Signal handling | Shared signal_handler_quit() deduplicated across 6 apps; volatile sig_atomic_t used correctly for signal-shared state |
| Metric | Value |
|---|---|
๐ง Commits (07505ea5..HEAD) |
20 (git rev-list --count on onionplus-compact after this number audit; 18 through last code bf3deb8e. The long OnionPlus branch was 97.) |
| ๐ Files changed | 182 (88 added, 94 modified, 0 deleted) |
| โโ Lines | +30,487 / โ1,109 |
๐งฉ Production (src/ + static/ + CI/Makefile) |
101 files ยท +4,572 / โ1,080 (excludes .gitignore + SDL.h, 2 ยท +35 / โ0) |
๐งช Tests (test/) |
75 files ยท +23,327 / โ10 |
| ๐ Docs + README | 4 files ยท +2,548 / โ16 |
| โก NEON kernels | 8 (7 asm + 1 intrinsics) |
| ๐งช Test suites / tests / assertions | 68 / 1,419 / 71,410 โ all green โ |
๐ก๏ธ Unsafe sprintf/strcpy+strcat/strtok remaining (hardened set) |
0 / 0 / 0 |
| ๐ก๏ธ NULL-guards / closed descriptors added | +57 / +18 (25-file set) |
| ๐ Pre-existing upstream defects fixed | 6 |
| ๐น๏ธ AdvanceMENU scripts hardened/optimized | 7 files |
๐ For per-commit line counts, file-level diff stats, and independently reproducible
gitcommands, seeOnionPlus-vs-base.md.
A bird's-eye view of the branch's evolution, oldest first:
- ๐ผ๏ธ NEON foundation โ vector kernels vs OnionUI scalar pixel loops.
- ๐ก๏ธ Hardening wave โ crash/memory-safety port across the common layer.
- ๐งช Test harness โ 68-suite host unit-test scaffold added from scratch.
- ๐ Docs โ first optimization report published.
- ๐ Power/CPU batch โ OSD busy-wait, brightness cache, battery cache, batmon, SQLite, config, GS overlay fork+exec, infoPanel hardening.
- ๐ Defect fixes โ hash over-read, save-state uninitialised buffer,
constcast, plus two external PRs (#206, #207) merged in. - ๐ Review pass 1 โ
currentGame()NULL derefs, asyncplayActivityrestored, dead slot check, OSD overlay throttle. - ๐๏ธ Release/OTA โ dated GitHub Releases,
Amiga500/OnionOTA wiring,TARGET=OnionPlus. - ๐ฏ GameSwitcher fixes โ framebuffer stride and romscreen stretch corrections.
- ๐ Review pass 2 โ rumble caching, infoPanel image cache, GS battery-poll throttle, playActivityUI page cache, randomGamePicker dedup.
- ๐น๏ธ AdvanceMENU pass โ fonts, PWM handling, script speedups, race-condition and false-positive fixes (PR #210).
- ๐ Review pass 3 โ randomGamePicker division-by-zero guard, batteryMonitorUI/themeSwitcher NULL-asset & bounds hardening, packageManager NULL guard, gs_romscreen format-string fix.
- ๐ฑ Mini Flip port โ surgical carry of Miyoo Mini Flip + MainUI-285 from upstream
v4.5-dev(921155e8); OnionPlus battery cache /file_copyreset / settings bounds kept. - ๐ OnionUI-parity review โ restore
battery_hasChangedearly-return while charging;process_killallfor RetroArch;file_read("")parity; rumble GPIO retry; remainingsprintfbounds on GS/chargingState; TTF cache cleanup on exit. - ๐ฉน 2026-09-01 review (AโG) โ empty-file test contract; Flip
suspend_execlid-already-closed; AXP-then-hall detect; OTA beta without stable fallback; brightness write-through; infoPanel scale identity; theme TTF cleanup-before-free. On the long branch: duplicate tree (9ab47af/2f90bbe); CI push trigger (fa5bb007). Compact CI isonionplus-compact(22004cce). - ๐ฆ Compact history โ long
OnionPlus(97 commits tofa5bb007) squashed ontoonionplus-compact. - ๐ @robcodedev ports โ
OnionUI/OnionPRs #1936โ#1946 (still open upstream) via Amiga500 #217 (c7a1a7e9+587c35ec+ mergef87e7781): keymon SELECT refresh,lt.langJSON, ThemeSwitcher on-demand previews, GameSwitcher favorites + crash fixes,fbmodeframebuffer transitions,.forceKillRetroarch,romwinidxon SD, theme perSERIAL_NUMBER, recents cap 200, skip RA cfg patch, overlap launch. - ๐ค List cache + installer Flip โ
fbd26d06: dim a copy of cached TTF labels; installer hall-first (neverevent*); framebuffer preclear before device detect. - ๐ฅ๏ธ Boot FB + AXP percent โ
bf3deb8e: Plus/Flip keep pollingmi_fb0when dmesg says 640;commit_mainui_fbmodehonorswait_for_fb_driver;getBatPercMMPnever writes garbage to/tmp/percBat.
๐ Full SHA-by-SHA detail lives in ยง1 of the deep-dive report.
onionplus-compact is 21 commits ahead of upstream OnionUI/Onion:main (07505ea5 โ
this number audit; last code bf3deb8e. The long OnionPlus branch was 97). Same tree: 8 vectorized NEON kernels,
a dozen algorithmic O(nยฒ)โO(n) rewrites, five distinct render/UI caches (list dimming
no longer mutates the TTF cache), a power/battery batch (AXP percent clamped), a syscall
diet that removed every avoidable system() call from the hardened core, six
pre-existing upstream defects closed, a 68-suite / 1,419-test host test harness
that did not exist before this branch, a full AdvanceMENU hardening pass, a
Miyoo Mini Flip port from v4.5-dev that does not merge that branch, an
OnionUI-parity review, the 2026-09-01 AโG fixes, the @robcodedev ports of
OnionUI/Onion #1936โ#1946, and the 2026-09-09 installer / boot-FB fixes.
Base remains 4.4.0-beta. OTA stays on Amiga500/Onion. Flip lid/Hall and on-device
timings are still unconfirmed.
See ONIONPLUS_OPTIMIZATION.md.
Repository: Amiga500/Onion ยท Branch: onionplus-compact ยท
Base: 07505ea5 (OnionUI/Onion:main) โ last code bf3deb8e (20 including this number audit,
git rev-list --count) ยท Headline figures refreshed 2026-09-09 ยท Companion docs:
ONIONPLUS_OPTIMIZATION.md ยท
OnionPlus-vs-base.md