Busy desktop windows ran at ~50 copies/s because WindowServer, holding at most two swaps, got one refresh per frame while the kext completed each swap a tick after its copy, and the kext's per-IB cache maintenance (3.4 ms over ~98 MiB) sat on WindowServer's path. The GPU is not the limit: 94% of the time at 1700 MHz, ~7% busy. ADRENO_PRESENT_EARLY_DONE (--present-early-done, adaptive mode 2) completes a layer-0 swap at its scanout copy after a late frame; the desktop-early-done profile adds it to the coherent backlight build so --gpu-coherent can drop the maintenance. Replay: busy 49.8 -> 56.3 copies/s, 57.9 with coherent.
The quiet desktop's sporadic heavy frames (next2c: 3 IBs a second,
57.9 copies/s) with b12v23's coherent maintenance: the kext time per
IB falls from 13 ms to 6.5-8.5 ms (the preparation stays), and the
model then delivers every refresh (59.5 copies/s) in every mode, so
the adaptive mode never engages there.
tools/summarize-present-pacing.py reduces a console's AdrenoDisplay
perf windows to busy and quiet groups: copies per second, the copy
interval buckets, ready / missed / true-miss ticks, per-IB GPU,
submission, cache and preparation time, the copy, tick lateness and
q, the perf done line's early completions and arrival histograms,
and with --report the GPU's time per clock (DVFSREP1). Its host test
runs it on a synthetic console.
tools/test-adreno-early-done.c unit-tests AdrenoDisplayEarlyDone.h
(modes, arrival bins, late frames and what is not one, adaptive
engagement, renewal and expiry, windows, the perf done line at its
caps). tools/test-present-early-done.py runs it, requires it to fail
on eight mutants of the header, checks that the kext touches the
feature only under ADRENO_PRESENT_EARLY_DONE, that desktop-early-done
differs from desktop-backlight only in AdrenoDisplay.o, the cycle
flags, refusals and AuxKC choice, and the replay (earlier outputs
unchanged by the define, no failure or cost failure in
early-done.json).
--present-early-done MODE (needs --edp-backlight and its chain) adds
the guest boot-arg adreno_present_early_done=MODE and
--present-early-hold-ms (mode 2 only) adreno_present_early_hold_ms;
both are refused with --present-hold on. --edp-backlight with
--present-early-done or --gpu-coherent now takes the collection
pinned as INPUT_AUXKC_DESKTOP_EARLY_DONE (SnapAdreno
desktop-early-done: the coherent desktop kext with the backlight
service and early completion) instead of the nocoherent
INPUT_AUXKC_DESKTOP_BACKLIGHT, and is refused until that collection
is linked and pinned. Without the new flags the boot arguments, the
AuxKC and the monitor are unchanged: the next3 argument list still
builds monitor 97be2b80 (459,904 bytes).
With -DADRENO_PRESENT_EARLY_DONE=1 the presentation replay mirrors
AdrenoDisplayEarlyDone.h step for step (the completion at the copy
in l_present, arrivals in l_swap_begin, the tick state in l_tick) and
runs early_done_scenarios (early-done.json): the 2026-10-24 busy
desktop (org2's 117 windows: 49.8 copies/s with a SLOT WindowServer
of 5-9 ms frames, 20% of them 14-30 ms), the same with b12v23's
coherent maintenance, a FREE WindowServer, a quiet cursor desktop and
next2c's sporadic heavy frames, each with the mode off, always and
adaptive, under the deployed switches (relatch, urgent polling,
EP1/EP2, no EP3 assist).
Every earlier output (beam, damage, latency, pacing, pipeline,
presentation, presentsync, relatch, vsync .json) is byte for byte the
define-off build's, and the define-off build's equal the previous
tree's. Busy SLOT: 49.8 -> 56.3 copies/s (coherent 51.8 -> 57.9),
input latency mean +7 ms; quiet: unchanged in adaptive mode, +14 ms
always; sporadic: 56.5 -> 58.1 adaptive, 59.4 always.
SnapAdreno a2d43d0: ADRENO_PRESENT_EARLY_DONE in AdrenoDisplay
(src/AdrenoDisplayEarlyDone.h, boot-arg adreno_present_early_done)
and the desktop-early-done profile (desktop-backlight plus the
define). Define off, the desktop-next profile still builds the
deployed swap-path-20261024 AdrenoX2 section for section.
swap-path-20261024 (9e916a41), built by the backlight-path work from 8f9eeb5 / SnapAdreno e1cf072 / SnapI2CHID f0b7984 with KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys: AdrenoBacklight takes the brightness from the swap record instead of a brightness-nits write WindowServer's sandbox refuses. next2-20261024 (cc07dfd3) stays as the rollback.
The on-device CoreImage pixel test (tools/run-icon-pixels.py, compare-icon-pixels.py, SnapMetal harness/icon-pixels) and SnapMetal 8fe64cb's ADRENO_CS_TABLES=1 build (SP_CS_CONFIG NTEX equal to NSAMP, as Mesa programs every stage), trusted and deployable as metal-stage-iconfix-20261024 (AdrenoMetal ba3a3fd6, CDHash 11d5ff9a; the icon-pixels tool 25f07e86). next1/next1b showed partial System Settings icons with no plug-in or kext refusal.
next2c showed WindowServer bind the panel to AdrenoBacklight but its sandbox refuse every brightness-nits write (iokit-set-properties is allowed only on AppleARMBacklight). The brightness now comes from the swap record IOMobileFramebufferSwapSetBrightness fills (+0x354 present, +0x35e nits as a double): AdrenoDisplay overrides swap_submit and hands the value to AdrenoBacklight as source swap, at most one monitor call per 33 ms. force-brightness-control is no longer published (SnapAdreno e1cf072).
RUNNING.md no longer says BrightnessControl writes brightness-nits to
the service (WindowServer's sandbox refuses that): the service lets
WindowServer bind the panel's framebuffer, CoreBrightness's nits
arrive in the swaps as on a DCP Mac, and the kext logs "SET <level>
from swap".
test-edp-backlight.py follows the kext's move from BrightnessControl
writes to the swap record:
- Wiring: AdrenoDisplay overrides swap_submit, reads the record at the
expected offsets through edp_bl_double_to_q16, returns the family's
answer and hands the value on as source "swap" from
swap_begin_gated, all under ADRENO_BACKLIGHT; the service no longer
publishes force-brightness-control.
- UserspaceContract (26A428 host with ipsw, else SKIP): besides the
BrightnessControl names the IOMFB bind needs, IOMobileFramebuffer
exports IOMobileFramebufferSwapSetBrightness, QuartzCore has
IOMFBDisplay::swap_brightness, and the framework's setter and swap
submit still use the kext's record offsets and size.
- Kext (--kext-reference): both backlight profiles override
swap_submit, the default kext does not.
check-iomfb-vtable.py's help names the new override.
SnapAdreno e1cf072 (branch backlight-path, not pushed): AdrenoDisplay
overrides swap_submit and hands the brightness each swap carries to
AdrenoBacklight as source "swap"; AdrenoBacklight no longer publishes
force-brightness-control, whose writes WindowServer's sandbox refused
in run next2c. The default kext is section for section unchanged.
The A16 kext now takes the panel brightness from the swap record
IOMobileFramebufferSwapSetBrightness fills: an IEEE double in nits,
unaligned, straight from a client. edp_bl_double_to_q16 turns its bits
into 16.16 nits in integer arithmetic, rounded to nearest and capped,
refuses NaN, infinities and negative values (which name no
brightness), and maps zero and subnormals to 0 (the darkest request).
The model test checks it bit-exact against the host's double
arithmetic for chosen values and for every exponent with a spread of
mantissas, and four mutations (NaN or negative accepted, truncation,
no cap) must fail it. Header-only and unused by the monitor: the
SNAP_EDP_BACKLIGHT monitors built with run next1b's flags, with and
without the define, are byte-identical to org next's.
The next installed run boots with the settings-icons executable
378ff525 installed and replaces it from single-user mode with SnapMetal
icon-pixels-next built the same way (lenient, ADRENO_PIPELINE,
ADRENO_SETTINGS_ICONS, runtime v7) plus ADRENO_CS_TABLES=1: AdrenoMetal
ba3a3fd6, CDHash 11d5ff9a. CoreImage's compute kernels then get
SP_CS_CONFIG NTEX = NSAMP = their T#/S# count and NUAV = their UAV
count; a process started with ADRENO_CS_TABLES=0 keeps the
settings-icons counts, so icon-pixels can compare both in one boot.
installed_fresh: the trust additions become the iconfix set's (the
settings-icons set's 47 rows plus 11d5ff9a and the icon-pixels probe
25f07e86: 501a90b6, payload 7857aabc); the settings-icons set stays as
ADDITIONS_SETTINGSICONS for rollback, and every earlier CDHash stays
trusted, so --restore (back to 378ff525) still boots. deploy-guest-
plugin: the executable's base is the settings-icons 378ff525 and its
payload the 27,627-byte AdrenoMetal-378ff525.bsdiff; the runtime and
CodeResources are already the installed ones and are skipped.
The probe's row: the guest's TXM service reports the code-signing
monitor disabled and answers only static trust-cache lookups
(compat/txm.h), so code outside the cache is left to in-kernel AMFI,
whose ad-hoc handling has never been observed in the guest; every
executable of ours that ran there (metal-triangle-probe,
metal-clear-probe) had its CDHash in the trust additions. The row costs
nothing and follows that pattern.
The set, build/current-assets/metal-stage-iconfix-20261024, is a local
(ignored) input: AdrenoMetal, AdrenoMetal-378ff525.bsdiff,
trust-additions.json, trustcache.payload and SET.json.
Evidence: the prepare-time trust check (configure_guest, then
trust_cache_spec(ADDITIONS).load(FIRMWARE) against TRUST_PAYLOAD and
TRUST_SHA) passes for the installed, -input and -input-touchpad
profiles, for this set and the settings-icons rollback; the payload
holds 11d5ff9a, 25f07e86, c76a4677 and runtime v7's ab4ccbd4;
tools/test-deploy-guest-plugin.py PASS 21 checks (install, again,
restore, refuse) over the console stand-in with 3% loss.
The --cs-tables expectations of test-adreno-settings-ci-encoding.py,
and SnapMetal at icon-pixels-next (8fe64cb): ADRENO_CS_TABLES (51d07a1,
ef0c80a) merged with the icon-pixels probe (713dab1, 263dd47).
icon-pixels (SnapMetal harness/icon-pixels*.m) and the tools that
build it, run it in the guest over the console and compare its lines
with this Mac's reference; docs/RUNNING.md describes the check.
next2-20261024 (cc07dfd3), built from fbed1ca with KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys: AdrenoX2 d88a2620 now publishes force-brightness-control and maps nits proportionally (SnapAdreno 9cc1e92). SnapI2CHID's code sections are identical to next-20261024's. next-20261024 (57965a84) stays as the rollback.
BrightnessControl writes brightness-nits only to a backlight service that carries force-brightness-control; AdrenoBacklight now publishes it (SnapAdreno 9cc1e92), so CoreBrightness's slider and keys reach the panel instead of dimming in software (next1b: RequestsNits 0). The floor drops from 10% to 2% (level 41 of 2047) and nits map proportionally onto levels.
The synth-ab step runs the synthetic cases again with one VAR=VALUE in
the tool's environment, into synth-ab.txt, compared with the same
reference. With a plug-in that has a per-process switch installed (the
ADRENO_CS_TABLES candidate honours ADRENO_CS_TABLES=0), one boot then
measures both encodings on the GPU. test-icon-pixels.py runs it over
the console stand-in (55 checks pass).
RUNNING.md now gives the 2% floor, how CoreBrightness's nits reach
AdrenoBacklight (WindowServer's BrightnessControl, enabled by the
service's force-brightness-control) and the two boot-args that move
the nits-to-level curve. It no longer names the pinned collection's
folder, which the next pin will change.
SnapMetal ef0c80a lets a process started with ADRENO_CS_TABLES=0 keep the
old compute counts, so icon-pixels can compare both encodings in one
boot with the candidate installed.
test-edp-backlight.py gains three checks for the path SnapAdreno's
AdrenoBacklight.h describes:
- Wiring: the service publishes force-brightness-control as data with
a nonzero first byte, backlight-control and IODisplayParameters,
takes brightness-nits, and maps every request through the one curve
with the configured minimum.
- UserspaceContract: on a 26A428 host (the guest's userspace) with
ipsw, the dyld cache's BrightnessControl and IOMobileFramebuffer
still carry the names the path relies on; SKIP elsewhere.
- Kext (--kext-reference): desktop-next builds too, both backlight
profiles carry force-brightness-control, the default kext does not.
SnapAdreno 9cc1e92 (branch backlight-path, not pushed): AdrenoBacklight
maps nits proportionally onto levels with the compat helpers of the
previous commit, publishes force-brightness-control so WindowServer's
BrightnessControl writes brightness-nits to it, and publishes its
DPCD700 diagnostic as 64 bits. The default kext is section for section
the base commit's.
The monitor's floor was 10% of full scale (level 205 of 2047) and the
kext's helpers mapped [min_nits, max_nits] affinely onto [floor, max].
If the panel's DPCD level is linear in luminance, the darkest macOS
request was ~50 nits: ten times the 5-nit minimum the A16's panel
table gives Windows (BrightnessRangeLevel0 5000..500000 millinits,
BrightnessRangeLowOffset 10000).
EDP_BL_FLOOR_PERMILLE is now 20: level 41, ~10 nits under the linear
model (the table's low offset), very dark but never off if the TCON
applied a 2.2 power law instead. Nothing has measured the panel's
curve; the header says so and the hardware run must check the bottom
of the slider. The helpers now model luminance proportional to level
(edp_bl_nits_to_level/edp_bl_level_to_nits with the top level at
max_nits) and edp_bl_min_nits_q16 raises the darkest request to the
floor's luminance; the slider helpers take 16.16 bounds.
The SNAP_EDP_BACKLIGHT=1 monitor built with run next1b's flags differs
from next1b's qualified one in one byte (same size, 200 bytes of code
budget left); without the define the monitor is byte-identical. The
model test checks the floor and the curve, and four new mutations (no
floor change back to 10%, an affine curve, a top short of max, a
minimum below the floor) must fail it.
The SnapAdreno kext with ADRENO_BACKLIGHT uses the new signatures; it
builds once the submodule pointer moves (next commit). The default
kext does not include this header.
test-adreno-settings-ci-encoding.py pins the single and two-input
packages' T#/sampler units, TSIZE and SP_CS_CONFIG NTEX/NSAMP/NUAV.
--cs-tables expects a plug-in built with ADRENO_CS_TABLES: NTEX 2 /
NSAMP 2 / NUAV 1 for the single shape, 3 / 3 / 1 and a zero third
sampler entry for the two-input one; units and TSIZE are unchanged.
ADRENO_CS_TABLES build: PASS 352 checks (production and CS-sampler
validators). Unchanged build with --cs-tables --expect-before: fails
27 checks, as it must. Unchanged build without the flag: PASS 351.
SnapMetal 51d07a1 adds ADRENO_CS_TABLES (default off): CoreImage's
compute kernels get SP_CS_CONFIG NTEX = NSAMP = their T#/S# count and
NUAV = their UAV count, as Mesa programs every stage. A candidate for
the partial Settings icons, to be decided by the icon-pixels check.
The A16 showed partial System Settings icons while neither the plug-in
nor the kext refused anything, so the GPU ran the icon kernels and some
produced wrong or empty pixels; the encoding tests cannot see that.
build-icon-pixels.py builds and ad-hoc signs SnapMetal's icon-pixels
for arm64e and records its size, SHA-256 and CDHash (and the trust
row the guest would need if its AMFI refused an ad-hoc executable).
run-icon-pixels.py runs it in the guest from the root console shell:
pushes it with deploy-guest-plugin.py's checked chunk transfer, checks
that it executes, runs the synthetic CoreImage cases as root and the
system icons both in-process (root) and through NSWorkspace as the
console user (launchctl asuser + sudo -u), fetches every output file
three CRC-checked lines per command, optionally renames the icon
caches aside and restarts iconservicesd, iconservicesagent, the Dock
and System Settings (multi-user), collects the plug-in's per-process
and unified-log diagnostics, and compares. Offline it refuses the
steps that would act on this Mac's own processes.
compare-icon-pixels.py compares the guest's lines with this Mac's
within a tolerance and names the first matching explanation per case:
unwritten or partial output, readback or repeat differences, black or
transparent output, swapped red/blue, an extra or missing sRGB decode,
the missing or foreign input of a multi-input kernel (with its Metal
texture index), a broken blend band, otherwise the channels and tiles
that are off; for icons empty, black, partial, wrong colour or shape.
--census-only compares the dispatched kernels and formats of an
intercepted plug-in run.
icon-pixels-reference-synth.txt is this Mac's synthetic reference
(generated inputs only; M3 Max, 26A428, capabilities answered like the
deployed plug-in 378ff525). The icons reference summarises Apple's
icons and is not committed.
test-icon-pixels.py: the reference reproduces exactly on this Mac;
the plug-in device (commits intercepted) dispatches the same kernels
and formats with 8 CS sampler units and drops the multi-input ones
without; 20 injected faults are each diagnosed and a within-tolerance
perturbation passes; the whole console procedure runs over the
console stand-in with loss and noise and fetches lines identical to a
direct run.
--watchdog SECONDS sets the run's watchdog from 1800 (the default, unchanged) to 7200 s; above 1800 the boot
preflight requires the A16 on AC. --session (with --console) leaves the guest trigger out of SNAP_EARLY_STOP, so the
kext never requests its first-present stop and a desktop session lasts until the watchdog, the thermal guard or
tools/request-stop.py. --early-stop-delay is checked against the run's watchdog. tools/test-session-watchdog.py
covers the default, the bounds, the delay check and the session's triggers.
A 256-table kernel view pool with lazy reclaim of copies that no longer hold a protected leaf, behind --view-reclaim (SNAP_VIEW_RECLAIM); CODE_AT moves down 16 KiB so the monitor keeps 15 KiB of headroom with --edp-backlight; the pool's count, high-water mark and reclaims are reported as VIEWRCL1. next1 stopped at 1104 s when the 128-table pool was full (exit 7, ROZONE RETYPE refused).
tools/test-view-reclaim.c drives a monitor-shaped kernel tree (one root,
one level 1, four level 2, 512 level 3) the way the retypes do: prepare,
detach, commit, refresh, with kernel_views_quiesce's steps as the
quiesce. After every step, independently of the library: each CPU's
walk of all 16,384 leaves gives the canonical descriptor or, for
selector2/4, its translation under that CPU's PPERM; no reachable page
holds an unpublished store; copies are distinct and never sources; no
store reaches a retired page before the TLBI after its unlinking.
Scenarios: fill to 256, a full pool and a one-slot-short path refuse
with no change, release and reclaim (TXM import, the level-2 ancestor),
reuse of the retired pages before any allocation, reclaim down to the
root, the restart of a two-frame change, read failure, nothing to
retire, unconfigured views and a failed quiesce. A quiesce without its
TLBI and a dropped protected table are caught (harness self-checks).
tools/test-view-reclaim.py runs it, nine weakened sprr-view.c copies
(each must fail: all do), test-kernel-pperm-variants.c with and without
the define, the wiring (default off, guarded uses, cycle, report place
and decoder) and, with --build, the monitor identities.
test-kernel-pperm-variants.c gains reclaim steps under the define:
positions move under the reuse snapshot, publication rows and variant
columns while both machines keep agreeing.
Tests that hard-coded the 128-table shape now derive it from
SPRR_VIEW_TABLES / USER_PUBLISH_MAX (test-tpro-view.c's RAM,
test-user-prepare-fused.c, test-user-fused-compare.c,
test-user-publish.c, test-user-tree-memo.c); define-off they check
exactly what they did.
Results on this tree (host, ASan/UBSan):
python3 tools/test-view-reclaim.py PASS (model 20,578
checks; 9/9 mutants caught; consumers; wiring)
python3 tools/test-view-reclaim.py --build --qualification
.../installed-fresh-desktop-20261024-next1/qualification.json
PASS (absent == =0 ==
86bb02ea9e03...; =1 459,904 bytes, 15,232 headroom)
the 26 C suites linking sprr-view.c, with and without
-DSNAP_VIEW_RECLAIM=1 PASS (define-off check
counts equal the base commit's)
Hardware: not run.
installed-fresh --view-reclaim appends -DSNAP_VIEW_RECLAIM=1 after every
other monitor define. It is a monitor define only: no AuxKC, boot-arg
or loader change. docs/RUNNING.md describes it.
tools/test-edp-backlight.py's "appended last" check now lets this newer
define follow its own.
With next1's qualification flags plus the define the monitor is 459,904
bytes, 15,232 under the 464 KiB reservation; without it the monitor is
byte-identical to next1's (458,552 bytes, 16,584 under).
Hardware: not run.
With SNAP_VIEW_RECLAIM the report carries, behind "VIEWRCL1" and a word
of value bytes << 32, the kernel views' count, its high-water mark, the
reclaims that retired tables and how many, the refusals that found
nothing to retire, and the capacity. The record sits at a fixed place
just below the IB async slot (used or not); every chained record is
asserted to end before it. tools/perf_counters.py decode_view_reclaim
reads it (refusing a record whose counts disagree), decode_report adds
it as view_reclaim, the speed/installed-fresh summary keeps it, and
probes/run.py prints one line. 88 bytes of monitor code.
Hardware: not run.
probes/run.py's reservation note now gives the reclaim's exact cost with
this record: 1,352 bytes.
With --edp-backlight the next1 monitor left 200 bytes of the 448 KiB
reservation, and SNAP_VIEW_RECLAIM adds about 1.3 KiB.
OUT_AT cannot rise: the report ends exactly at heap+0x480000, where the
stopped-probe scratch begins (tools/probe-a16-cpus.py, code at 0x480000,
output at 0x490000), and tools/secondary-runtime.py collect runs that
probe after the monitor returns and before probes/run.py reads the
report, so a higher report would lose its tail (the thermal and DVFS
records). CODE_AT moves down 16 KiB instead. Nothing in q1n1's heap
below CODE_AT is used during a run; the only other user of that range
is tools/qualify-txm-image4-native.py (heap+0x100000, 3 MiB), which
requires a fresh stage. q1n1 does not know these offsets, every tool
reads run.CODE_AT, and the monitor is position independent.
tools/test-monitor-reservation.py checks the new order (code, report,
stopped-probe scratch, SMP page, work locator), that the two stopped
probes use the scratch after the report, and the fresh-stage tool's
workspace. tools/test-reuse-match-mapped.py's budget follows.
Hardware: not run.
installed-fresh-desktop-20261024-next1 stopped after 1,104 s with exit
7: a RETYPE to ROZONE was refused because sprr_views_prepare found the
kernel views at SPRR_VIEW_TABLES (128). Its context.bin shows that 114
of the 118 level-3 copies still held selector2 leaves (122 ROZONE
protects, 3 releases): each RO-zone frame lands in its own 2 MiB table,
so the live set itself reached the pool. In the 86 preserved runs of
6 minutes or more, releases stayed at 2 to 8.
SNAP_VIEW_RECLAIM (opt-in, default 0):
- SPRR_VIEW_TABLES becomes 256. struct sprr_views grows by 8,192 bytes
and 65 of them precede pauth_bank, so PAUTH_BANK_CONTEXT moves under
the define (still asserted). The publication rows, the row-empty
checks (sprr_publish_row_empty) and USER_PUBLISH_MAX follow the
capacity. Context +1.0 MiB, root_ext +1.5 MiB of the arena.
- sprr_views_reclaim retires every copied table no CPU needs: a level-3
table without a valid selector2/4/9 leaf, an upper table none of
whose entries leads to a needed copy, never the root. It reads every
source before changing anything, compacts the metadata (kept tables
in order, retired sets parked past count at SPRR_VIEW_RETIRED), then
calls quiesce. kernel_views_quiesce drops the reuse snapshot and the
publication rows, and shadow_tlb_sync syncs all six views (a retired
table's parent entry names its canonical source again, an identical
translation), publishes them and runs TLBI ALLE1IS. Only after that
may add() reuse the six pages at that position; after a failed
quiesce they stay unusable.
The trigger is lazy: kernel_views_prepare_change, used by the ROZONE
and TXM-default retypes, reclaims only when a prepare is refused with
fewer than three free slots, then prepares the whole change again,
because the reclaim also retires paths an earlier leaf of the change
prepared (not protected until the commit). prepare_path refuses a path
that does not fit before adding any of it. Nothing runs before the pool
is full: the refresh, PPERM and sync paths are unchanged.
Off, the monitor is byte-identical: next1's flags give 458,552 bytes,
sha256 86bb02ea9e03...; so does the build without SNAP_EDP_BACKLIGHT
and the define-free one. On, the code grows by about 1.3 KiB, which
needs the code reservation of the next commit. kernel_sync_view's
frame grows from 2,336 to 4,528 bytes (64 KiB EL2 stacks; worst
direct-call chain 13.2 KiB, unchanged).
The mirrored multipage_close in tools/test-multipage-fast.c and the
source check in tools/test-kernel-ops-perf-source.py follow the row
helper. Hardware: not run.
INPUT_AUXKC_DESKTOP_BACKLIGHT, the collection --edp-backlight selects
(the only route the next1 run's flags reach), becomes next-20261024:
KEXT_PROFILE=desktop-next I2C_PROFILE=desktop-fnkeys
tools/build-auxkc-desktop.sh at umbrella 78920c5, SnapAdreno b5bfcb4,
SnapI2CHID f0b7984 (sources.txt, no uncommitted changes).
adreno-input.kc 57965a84916986eed68988b174d699eba06050207945af742c6dd57f616cbd82
adreno-input.raw.kc 444b0cd1c732071075ca19668a16ca800cd0b752f6c84d072739251eb7e99f40
AdrenoX2 3202fd6f (desktop-next)
SnapI2CHID 4a81f74e (desktop-fnkeys)
The brightness branch named this pin for a PROFILE=desktop-backlight
AdrenoX2, which adds the service to desktop (coherent maintenance
skipping, for --gpu-coherent). The run has no --gpu-coherent, so the
pin holds desktop-next instead: desktop-nocoherent plus the service,
with the head rule, the IOMFB trace and the CS sampler opt-in. The
SnapI2CHID in it carries the Fn-key layer, so --input-fnkeys needs no
pin of its own. Both kexts are section-identical (12 of 12) to
separate builds of those profiles from the same tree.
Runs without --edp-backlight keep the latch collection
org-desktop-nocoherent-20261023 (ccf0c8f4, 353756d), which is also
the rollback. docs/RUNNING.md says which profile the pin holds.
tools/test-edp-backlight.py test_cycle now takes its pinned branch
and passes.
The fn-keys branch added installed-fresh --input-fnkeys and the
desktop-fnkeys SnapI2CHID profile but left docs/RUNNING.md without
them. List the flag in the Input row and say what it adds, which
SnapI2CHID build reads it, what its bits do and which test covers it.
SnapAdreno f54b9ec..b5bfcb4 (next):
adreno-kext: add the desktop-next build profile
(desktop-nocoherent plus ADRENO_BACKLIGHT in AdrenoDisplay.o, the
kext of an --edp-backlight run without --gpu-coherent)
SnapMetal 936d51b..7bc40ef (next): the --no-ff merge of
feature/settings-icons onto migrate-private 40a1864 (same tree as
936d51b)
SnapI2CHID 816aad8..f0b7984 (next): the merge of feature/fn-keys
(abaa501 Fn-key layer, 7c0a059 desktop-fnkeys profile). fn-keys made
no pointer commit, so this is the first one that carries it; the
umbrella's tests and build-auxkc-desktop.sh I2C_PROFILE need it.
Default builds stay section-identical to migrate-private
(tools/macho-sections.py, ZERO_AR_DATE=1): AdrenoX2 default 12 of 12,
SnapI2CHID default and desktop 12 of 12 each.
Both options already add their guest boot-args; the tests only called
boot_addition with hand-built namespaces. Parse real command lines
with cycle.py's parser and check the addition:
- test-edp-backlight.py test_cycle: no adreno_backlight=1 without the
flag, adreno_backlight=1 with --edp-backlight (and no mode word),
and both words, in order, with --edp-backlight-mode;
- test-input-fnkeys.py: --input-fnkeys 0x3, 3, 0x13 and 0b111 each
give exactly one snap_i2c_fnkeys=<decimal value>, none without it.
For the next1 run's arguments (org2's plus --single-user,
--edp-backlight, --input-fnkeys 0x3, --adreno-cs-samplers) the
addition carries adreno_cs_samplers=1, adreno_backlight=1 and
snap_i2c_fnkeys=3.
installed-fresh --adreno-cs-samplers appends the guest boot-arg
adreno_cs_samplers=1, the run-time half of SnapAdreno's
ADRENO_IB_CS_SAMPLERS: the IB validator admits CS sampler loads of up
to 8 units and AdrenoX2 publishes AdrenoIBComputeSamplers, so the
ADRENO_SETTINGS_ICONS plug-in encodes CoreImage's multi-input kernels.
An AdrenoX2 built without the define ignores the boot-arg. Without the
option the boot-argument addition is unchanged.
tools/test-adreno-cs-samplers.py: the default addition is unchanged,
the flag adds the boot-arg once (also beside --edp-backlight,
--input-fnkeys and --single-user), cycle.py's parser reaches the
namespace, AdrenoX2 reads exactly this name under the define, and the
desktop, desktop-nocoherent, desktop-backlight and desktop-next
profiles build AdrenoX2 and adreno-ib-command with it. A misspelt
boot-arg in installed_fresh.py fails it. docs/RUNNING.md lists the
flag and drops "no option yet".
Merge feature/settings-icons (b9c12cb..22aad4b). docs/RUNNING.md and
tools/cycle_lib/installed_fresh.py merge without conflict: the
settings-icons trust set (ADDITIONS/TRUST_PAYLOAD, mirror-slab kept as
ADDITIONS_MIRRORSLAB for rollback) sits beside the brightness and
fn-keys options.
gpu/adreno-kext/kext: SnapAdreno next f54b9ec, the merge of all three
SnapAdreno feature branches; gpu/adreno-kext/plugin: SnapMetal 936d51b
(feature/settings-icons).
Merge feature/brightness (7da9adf..f189da7) onto the display-modes
merge.
tools/check-iomfb-vtable.py: both branches added an AdrenoDisplay
define option (display-modes --display-define, applied to
AdrenoDisplay.cpp only; brightness --define, applied to every .cpp).
Keep one implementation: --display-define, with --define as an alias
of the same list, compiles AdrenoDisplay.cpp alone with the defines,
which is what both branches' help text promises and what
test-adreno-display-trace.py passes.
gpu/adreno-kext/kext: SnapAdreno next 53c0054, the merge of
feature/display-modes and feature/brightness.
BUILDING.md: the plug-in's ADRENO_PIPELINE and ADRENO_SETTINGS_ICONS
build switches (0 or 1; unset or 0 leaves the build unchanged) and the
suites that test the latter. RUNNING.md: a plug-in that changes icon
rendering needs IconServices' store, the user icon caches and the
Dock's icon cache renamed aside from the single-user shell before the
boot continues, and the order that does it with deploy-guest-plugin.py
and guest-console.py under one owner; ADRENO_IB_CS_SAMPLERS stays off
without the boot-arg adreno_cs_samplers=1, which cycle.py cannot add
yet.
SnapMetal 40a1864..936d51b (branch feature/settings-icons):
adreno-metal: let build.sh pass ADRENO_PIPELINE
adreno-metal: encode the CoreImage kernels of Settings pane icons
adreno-metal: add the Settings pane icon harnesses
SnapAdreno 79de60e..e7b1d3c (branch feature/settings-icons):
adreno-kext: opt in to multi-unit CS sampler loads (adreno_cs_samplers)
adreno-kext: build the desktop profiles with ADRENO_IB_CS_SAMPLERS
Both features stay behind their defines. With ADRENO_SETTINGS_ICONS
unset or 0 the plug-in builds byte for byte as at 40a1864 (strict,
lenient, and with ADRENO_PIPELINE); without ADRENO_IB_CS_SAMPLERS the
default and desktop-profile kexts are byte-identical to 79de60e's. The
profiles now carry ADRENO_IB_CS_SAMPLERS, inert unless the guest boots
with adreno_cs_samplers=1. SnapAdreno's AdrenoX2 calls this
repository's adreno_ib_set_cs_sampler_units (compat, b9c12cb).
The next installed run boots with the mirror-slab executable 758535d9
installed and must replace it with SnapMetal's ADRENO_SETTINGS_ICONS
build (lenient, ADRENO_PIPELINE, runtime v7: AdrenoMetal 378ff525,
CDHash c76a4677) from single-user mode.
installed_fresh: the trust additions become the settings-icons set's
(the mirror-slab set's 46 rows plus c76a4677: cdc784df, payload
247598bc); the mirror-slab set stays as ADDITIONS_MIRRORSLAB for
rollback, and every earlier CDHash stays trusted, so --restore still
boots. deploy-guest-plugin: the executable's base is the mirror-slab
758535d9 and its payload the 36,670-byte AdrenoMetal-758535d9.bsdiff;
the runtime and CodeResources are already the installed (wsabort) ones
and are skipped.
The set, build/current-assets/metal-stage-settingsicons-20261024, is a
local (ignored) input: AdrenoMetal, AdrenoMetal-758535d9.bsdiff,
trust-additions.json, trustcache.payload and SET.json.
Evidence: the prepare-time trust check (configure_guest, then
trust_cache_spec(ADDITIONS).load(FIRMWARE) against TRUST_PAYLOAD and
TRUST_SHA) passes for the installed, -input and -input-touchpad
profiles, for this set and the mirror-slab rollback;
tools/test-deploy-guest-plugin.py PASS 21 checks (install, again,
restore, refuse) over the console stand-in with 3% loss.