github RamazanKara/nightjar v3.0.0
Nightjar 3.0.0

3 hours ago

Nightjar 3.0, for PCs running Rubylight 3.0.
It also works with Sunshine, Apollo and Vibepollo, and with other Moonlight-compatible hosts.

What you need. Home, a game's page, the Session and graphics menu and the Radeon panel use Rubylight's native API, so they need a Rubylight 3.0 host (the Radeon panel needs 3.0.0-alpha.2 or newer). Beam racing needs a Rubylight 3.0 host too, because it asks the host for PyroWave row order. Everything else works with the hosts you already use, and Sunshine, Apollo and Vibepollo keep the classic PC and game grid. Nightjar 0.8.0 offers this update in the app.

What's new

The console UI

  • Home. Favourites, Continue playing, a Library across your PCs and your PCs, with a shell bar (Home, PCs, Settings) under the top bar. A newly paired Rubylight 3.0 PC lands on Home.
  • PCs. The Hosts list is now PCs. Each PC has one options list: Open library or Pair, Resume, Quit, Wake, PC settings, Rename (a name kept on this device), Unpair and Remove PC. A failed pairing, unpair or wake says why.
  • Settings shell. Two panes on a TV and on wide screens, a Search settings row, and one focus rule on every sub-page. New under App: interface size, high contrast and reduce motion.
  • Game page. Pick a game to see the PC, the stream settings it will use and where they come from, then Play or Resume. Per-game presets (Competitive, Smoothness, Quality) set only the values they name.

On-screen PC keyboard

  • A full PC keyboard over the stream for keys a phone lacks (F-keys, Ctrl combinations, Win). Open it from the stream menu, with Ctrl+Alt+Shift+K, or with a three or four finger tap. It works with touch, controller and remote, and has US and German layouts, a size and an opacity.

Rust engine as default

  • The new streaming engine is on by default, PyroWave and remote monitor sessions included. Turn it off in Settings > Advanced > Diagnostics to use the classic engine. If you had it off, it is switched on once; turning it off again is kept. It now reports the same round trip time as the classic engine and fills the clock columns of the latency CSV.

Decoder flags

  • Decoder tuning keys from Artemis and moonlight-noir: Tegra and MediaTek keys, low-latency on every Android version, Snapdragon frame-drop.enable, and more reference frame invalidation entries. A decoder that rejects configure() gets the next try with fewer keys, and the applied and dropped keys are in the log and the problem report. Comparison.
  • MediaTek, NVIDIA Tegra and Amlogic changes are Experimental: they follow the forks and are covered by unit tests, but we have no such device.

Link, timing and PyroWave

  • Link-rate notices. Android sends the wired link speed for every codec, and with the Rust engine the overlay says when the host lowered the bitrate for the network.
  • Timing record. The latency CSV carries the host's timing record (nine columns) and the present scheduler's columns, so a run joins to the host's record. Automatic bitrate has a minimum and a maximum and cuts for loss and a growing queue, not for jitter bitrate does not cause.
  • Stream presets. Competitive, Smoothness and Quality per game, as above.
  • PyroWave. Runs on the Rust engine on Android, carries HDR through the window dataspace on Android 13 and 14, and decodes on the GPU on the desktop client (default on Windows and Linux). Early decode (off by default) decodes PyroWave blocks while a frame is still arriving.

Desktop client for Windows and Linux (Experimental)

  • The same engine on the desktop with hardware decoding, VRR pacing, audio, keyboard, mouse and controllers, Home, PCs and Settings, the Session and graphics page and Radeon panel, German and a UI zoom. Downloads: nightjar-desktop-3.0.0-windows-x86_64.zip and nightjar-desktop-3.0.0-linux-x86_64.tar.gz. The desktop client is Experimental and its packages are not signed.

Beam racing (opt-in, desktop)

  • Decodes a PyroWave picture in slices while the rest of it is still arriving, and draws the top before the bottom has left the network. Off by default (beam_race), labelled Experimental, and it needs a Rubylight 3.0 host. It missed its default-on gate on loopback, so nothing recommends it yet. Beam racing.

Fixes

  • #21: when this device's decoder rejects the stream, the message now says so instead of blaming the host.
  • #20: automatic bitrate minimum and maximum, and fixes to when it cuts and how fast it steps back.
  • #15: the audio report shows the output route, the native rate and dropped buffers.
  • #17 and #19: OpenGL rendering for frame-generation overlays, and negative stick deadzone values.
  • Input: a pad's D-pad moves menu focus and the PC keyboard once; a lone modifier tap is broken when a Ctrl+Alt+Shift shortcut fires.
  • A 3.0 alpha, beta or rc host version parses in the host capabilities, so its PyroWave records and timing are used.
  • Host processing counts on every path and keeps its own label (the frame header's value, as in Artemis).

Tested. Our own runs, on our hardware:

  • Rust engine against the classic engine, Retroid Pocket 6, Wi-Fi (about -41 dBm), isolated Rubylight host on an RX 7900 XT. HEVC 1080p60 at 40 Mbps, four 75 s runs per engine: median picture age 7.04 ms (classic) and 6.92 ms (Rust), decode 0.92 ms on both. PyroWave 1080p60 at 400 Mbps, one run each: 36.19 and 34.99 ms. At 1% and 5% injected loss neither showed corruption. A 30 minute Rust soak held about 59.3 fps with flat memory and no errors.
  • Decoder keys, Retroid Pocket 6 (Snapdragon 8 Gen 2). HEVC 1080p60 through c2.qti.hevc.decoder.low_latency, about 88 s per run: median decode 1.49 ms before and 1.43 ms with every key ported. We do not claim a gain. picture-order.enable = 0 was left out because that decoder accepted it and then produced no output.
  • GPU PyroWave decode, desktop client, loopback on the RX 7900 XT. Median receive to present at 1080p60, 133 Mbps: 20.53 ms on the CPU decoder, 8.80 ms on the GPU decoder. At 4K60, 167 Mbps the CPU decoder showed 32.6 fps and the GPU decoder 60.1. On the Linux NUC (Core i5-8259U, 1 GbE, offscreen window with no real display) at 1080p60, 133 Mbps: 23.73 ms and 13.45 ms.
  • Beam racing, loopback on the RX 7900 XT, 5120x1440 at 240 Hz, 1080p60 PyroWave at 399 Mbps. The first of four slices is decoded 1.65 ms after the frame's first packet; a whole frame takes 6.5 ms on the wire. The picture's middle row is 5.32 ms old without racing and 3.93 ms with it. The 95th percentile gains little, and at a higher pace receive to present got worse. The wired NUC runs have not been done.
  • The PCs and Settings screens were checked by D-pad on an Android 14 TV emulator, normal and high contrast, and the update check has unit tests for 3.0.0 against 0.8.0.

The standard and root APKs and the Android App Bundle are signed with the Nightjar release key. The desktop packages (Windows zip, Linux tar.gz) are not signed. SHA-256 hashes of everything are in SHA256SUMS-3.0.0.txt.

All 329 commits since v0.8.0 are included in v3.0.0:

  • f4395b68 feat(protocol): extended host timing report with absolute capture and convert stamps
  • 9dee5f2b feat(timing): cap extended 0x5536 reports at 17 records (616 bytes)
  • 45d8890c feat(timing): keep the host timing extension in the Rust engine listener
  • cb6e0f25 feat(timing): MoonBridge.presentClockOffset for both engines
  • a8a99653 feat(timing): read the host timing extension in HostTimingReport
  • ef0b3580 feat(timing): host timing record columns in the latency CSV
  • 384b0fa4 feat(timing): nightjar-cli writes the host timing record columns
  • 1bcd80b2 build(protocol): rebuild the prebuilt archives with rp_present_clock_offset
  • 10c9d455 docs(timing): the latency CSV carries the host timing record columns
  • 99401e4d fix(timing): one record without an extension keeps the others in the Rust engine
  • e6c74b5d fix(timing): probe the clock only for hosts that announced clock sync
  • d38268fb feat(desktop): read the native library and session, keep libraries on disk
  • 8ac4bd0e feat(desktop): Home and game screens with controller-first navigation
  • a0c04db7 feat(desktop): Session and graphics page in the stream menu
  • 865e55b0 feat(desktop): Recently played on Home
  • 8b6ce666 feat(desktop): document the Session page, Radeon panel and Recently played
  • c4227eca fix(desktop): drop native reads that land after an unpair or an action
  • 9eb9feb6 fix(desktop): keep the Session page while an exit runs, offer nothing before permissions
  • 593f9df3 fix(desktop): use checked arithmetic for Radeon integer steps
  • ab19e907 fix(desktop): prune older cover versions when a new one is saved
  • dc4edf37 fix(desktop): an empty install id matches no game
  • 38d82f80 refactor(client): move the timing record join into nightjar-core
  • 826b7619 feat(desktop): write the client timing CSV when NIGHTJAR_TIMING_CSV is set
  • 60cf18bd feat(desktop): package the Windows build with a decode-only FFmpeg
  • cc12adc0 fix(input): allow negative stick deadzone values (#19)
  • afc8422b feat(video): render through OpenGL for frame-generation overlays (#17)
  • ed606b83 fix(video): guard stop for OpenGL rendering and tighten setting texts (#17, #19)
  • c7eb0179 test(video): reassemble the host's streamed-frame packets byte for byte
  • 6441f933 test(video): a streamed frame cut off after an early block is dropped
  • 51ecb2f0 feat(input): add the PC keyboard model and its tests
  • 862e335f feat(input): on-screen PC keyboard overlay with touch, controller and remote
  • 75094ade docs(input): document the PC keyboard, its controller mapping and settings
  • eca31d61 feat(demo): show the PC keyboard in the debug stream demo
  • 9f7dc225 fix(input): PC keyboard pad capture, stale keys, Win/Alt, layout and device checks
  • dad7ece3 fix(i18n): call the Android keyboard "System keyboard" everywhere
  • 10f088b1 fix(input): PC keyboard releases a USB pad that is unplugged, resyncs the stick, maps Menu
  • 5e64e5b3 feat(bitrate): minimum and maximum for automatic bitrate (#20)
  • dd1f4a1a fix(audio): report output route, native rate and dropped buffers (#15)
  • 2fa36ffa fix(audio): mark the AudioTrack report as API 24 and up (#15)
  • af54ccda test(bitrate): give the encoder budget retry test a preference config (#20)
  • 6ae51f26 fix(bitrate): leave a host rounded bitrate alone when the maximum is higher (#20)
  • e1c30ca8 fix(bitrate): describe the limits as encoder bitrate (#20)
  • 3c7b3660 test(bitrate): the game hands the minimum and maximum over in order (#20)
  • fadc29cf fix(audio): cache the native rate, report the routed output, count AAudio drops (#15)
  • 91dc5a86 feat(rust): remote monitor, unbatched input and stream priority in the session
  • 5300f0f6 feat(android): run PyroWave and remote monitor on the Rust engine
  • 735001e6 feat(diagnostics): show the streaming engine in overlays and problem reports
  • a5b044dd docs: Rust engine parity table and device comparison steps
  • b43f8922 fix(rust): match the C engine socket QoS and thread priorities
  • d39fff52 test(android): check JNI types per parameter and every C native
  • 7127be23 feat(diagnostics): translate the Debug overlay engine label
  • 5cf483b8 docs: correct the Rust engine QoS rows and note remote monitor traffic
  • 6456da5d fix(rust): keep watching the control marking and set IP_TOS on IPv6
  • 6c957c33 feat(desktop): a device-local PC name and Android's pairing texts
  • 519833f5 feat(desktop): Home, PCs and Settings destinations and one list of PC options
  • 46f57848 docs(console): the desktop client's destinations and PC options
  • a8e1156f fix(desktop): keep a PC's chosen name when two records of it merge
  • 05a72c92 fix(desktop): pass F10 to the launcher so Shift+F10 opens the options
  • 2b61e41f fix(desktop): show the chosen PC name on the stream screens
  • 60da16b9 fix(desktop): keep the pairing until the PC has unpaired the device
  • af124aa1 fix(desktop): keep the card focused when Remove is cancelled
  • 80badb3c fix(desktop): start the rename empty for a PC that never reported a name
  • f0753faa fix(desktop): removing a PC also clears its covers and recent games
  • caa2c4be fix(desktop): Tab walks the header left to right
  • b5a500b9 feat(desktop): Resume and Pairing help in the PC options, Wake before the PC answers
  • 4c4d46e5 test(desktop): rename and remove go through the save path they use in the app
  • 17235d88 test(desktop): a cancelled pairing never shows an error
  • 8a06bf01 test(desktop): check the settings sections as drawn, not as written in the source
  • 76c455ab fix(desktop): Start from a library or game page returns to it
  • 397b7118 feat(home): favourites on Home and the game page
  • 8c7996d7 test(library): a saved cover shows with the host offline
  • f278fde9 feat(settings): Competitive, Smoothness and Quality presets for one game
  • 1bb314b3 docs(home): describe the Favourites row
  • a4c4d894 feat(library): offer Resume when another game already runs
  • 2097f951 feat(desktop): favourites on Home and the game page
  • 66ed1fba fix(settings): presets set only their own values and Quality ignores the network profile
  • 6bbc7e8b fix(library): match favourites on the host install id and harden their storage
  • f81fafbf fix(library): close the running game natively before starting another, and recheck it
  • 21e732b8 fix(library): keep Home focus steady around favourites and add the Menu key toggle
  • 34022bdd test(library): wait for the cover test executors instead of sleeping
  • 5e881b5e fix(desktop): replace prompt, favourites storage and unstar action
  • d3a6843c fix(desktop): removing a PC also forgets its favourites
  • e9694d85 feat(desktop): German, UI zoom, high contrast and reduced motion
  • 39e61b67 docs(console): language, zoom, contrast and motion on the desktop client
  • 474d9d33 fix(desktop): turn off egui's own Ctrl+=/- zoom
  • 5f08d2ac feat(desktop): translate toasts and Radeon names, tighten the string checks
  • f897adde fix(desktop): ignore unknown ReduceMotion and Language values
  • a23ed140 fix(desktop): keep window ids stable across languages
  • b9bc5755 fix(desktop): keep zoom keys out of text fields, isolate test palettes
  • 794db122 test(desktop): add an ignored benchmark of the open session menu frame
  • c814796f feat(pyrowave): take records packet by packet while a frame arrives
  • 3128dae7 feat(video): hand PyroWave record packets to the decoder as they arrive
  • 37a35acb feat(desktop): early decode of PyroWave records behind a setting
  • 04a845f1 docs: early decode design, cost model and A8 measurement plan
  • 5804bde6 fix(stream): early chunk queue counts drops, forwards without rescans, batches buffers
  • 6d265d9f fix(stream): make early decode visible and count a missed start as a fallback
  • d314e06d fix(stream): log the early-decode and queue counters at session end
  • 6c26e405 docs(early-decode): add the loopback decode-load numbers
  • 92dde60f fix(stream): translate the early decode overlay line and keep tests after the production code
  • dbc7af68 feat(shell): add the shell bar and the PCs destination
  • eac1e4ee docs: describe the shell bar and update the string count
  • 44c850aa test(shell): cover shell navigation and every existing entry intent
  • 6281ae84 fix(shell): tint the shell menu icons like every other menu
  • 6d062f09 fix(shell): keep the shell bar scroller from taking focus
  • 7829aa9f fix(shell): Settings Back and restart rules, search focus link
  • 19b638f5 fix(shell): Home joins the bar when the first library is seeded, first PC takes focus
  • c057d5d7 test(shell): cover Settings Back, root change, focus and Help by D-pad
  • 1085b885 test(smoke): use the shell bar and the Help route in emulator-smoke.py
  • d66f22e9 docs: fix the string count and note the Home stacking issue for N5
  • e2bbb08f docs: update the string count after the rebase
  • 5fd0261c test(smoke): use the PC and System keyboard labels, wait for the OTP dialog to close
  • 04badbc1 docs(parity): Rust engine against the C engine on a phone (B8)
  • 39588a10 fix(engine): the Rust engine runs the clock sync for the timing CSV
  • 16a95c00 fix(engine): the control stream round trip reads what the C engine reads
  • b67905fe feat(settings): the new streaming engine is on by default
  • 8cf19889 docs: the new streaming engine default, the classic opt-out and the release note
  • 5f9e9112 fix(engine): an interrupted start leaves no host messages, tighter RTT test, vendor notes
  • 38bf91b0 fix(overlay): show host processing and send apart when the host reports its timing
  • 4475b581 build(pyrowave): build the pinned decode SDK for the desktop client
  • c80b8e41 feat(pyrowave): bind the SDK's GPU decoder and probe it
  • c243b6a5 build(desktop): package the pinned PyroWave SDK on request
  • 87271dc7 test(pyrowave): measure the GPU decode, the D3D11 handoff and the handles per life
  • 0c61068a docs(pyrowave): the GPU decode route, its packaging and its measurements
  • 36e33713 fix(pyrowave): hold a decode back until D3D11 has read the plane set it overwrites
  • adfdec1c build(pyrowave): ship the winpthreads and GCC runtime notices with the SDK DLL
  • dc1d6443 docs(pyrowave): the presenter contract, the GPU column named, the upper bound measured
  • 2f3e471c fix(overlay): one statisticsText signature, send label in the stream doctor only with host reports
  • 162dd027 fix(desktop): keep a launch while the app list is read again
  • 82955a51 docs(pyrowave): skipping to the newest frame measured and not shipped
  • 5224b2f4 fix(pyrowave): say why PyroWave HDR falls back to AV1 or HEVC HDR
  • 3251073d fix(pyrowave): carry HDR through the window dataspace on Android 13 and 14
  • 345c005b docs(pyrowave): HDR on the Android 13 and 14 loader goes through the window dataspace
  • 598d2ec8 fix(bitrate): stop cutting for jitter that bitrate does not cause, step back fast, floor by resolution (#20)
  • cf6ea232 docs(bitrate): describe the checked cuts, fast recovery and resolution-aware floor (#20)
  • d39696b8 fix(bitrate): keep cutting for a growing queue, keep step-back state across suspend, reset stale holds, let loss cut under a raised floor (#20)
  • f0170a1f test(desktop): start and end a stream without the GUI for measurement
  • 78c9194d perf(pyrowave): time the decode and present stages and dump real frames
  • a5495104 test(scripts): summarize timing CSV legs with the keep rule
  • 20962e11 test(scripts): add the PyroWave loopback measurement run
  • 1d3c619c test(scripts): quote the host assets path in the loopback run
  • f8a738f2 test(scripts): read the host log and exit codes right in the loopback run
  • 11928814 perf(pyrowave): keep the presenter stage timers when the texture is destroyed
  • 65e1beba test(desktop): start the autostream launch again when the launcher drops it
  • 5d5b787d perf(pyrowave): upload the reconstruction frame to one texture instead of two
  • 92635cea perf(pyrowave): submit the eleven reconstruction passes as one command list
  • e2f03488 test(scripts): derive shown fps from the render stamps when the CSV column is empty
  • f9c7d32a test(scripts): pool shown fps per leg and keep on decode_to_present_ms in the loopback run
  • e5f1d886 Revert "perf(pyrowave): submit the eleven reconstruction passes as one command list"
  • 800c5036 perf(present): show the first sixteen pictures at once and keep them out of the delay
  • 0dc4b56e Revert "test(desktop): start the autostream launch again when the launcher drops it"
  • afe7b75f test(scripts): look at the host again once the GPU lock is taken, poll the lock twice a second
  • fbca1871 docs(pyrowave): decode stage split, the two presenter fixes and the present clock start
  • ef5f901c perf(present): let the delay fall by a share of the gap, cap it, warm up in host time
  • 9821798c fix(scripts): shown fps per leg from the render stamps, stalls included
  • 0b2299a0 feat(desktop): fill shown_fps in the timing CSV from the last second of presents
  • cda3edbb perf(desktop): keep PyroWave stage times in a fixed-size histogram
  • 0a90b6f1 test(desktop): poison the second wavelet texture before the single-upload draws
  • 9eff2202 fix(desktop): show why a launch could not start when the app list failed
  • 0086027e test(scripts): atomic GPU lock, exit 4 for an unanswering host, hang scan before exit 2, -Codec
  • 39d8fb39 test(desktop): keep the window out of screen capture when NIGHTJAR_EXCLUDE_FROM_CAPTURE=1
  • 11f9a080 fix(scripts): doc name after the rebase
  • 3120cea1 test(scripts): keep the client window out of the host capture in the loopback run
  • 45a59bb4 fix(scripts): compile the scripted content on PowerShell 7.4, fail the run when it does not start
  • 26ba66fc docs(pyrowave): the new present clock rule, the repeat ABBA, HEVC check and harness changes
  • ba8d411b feat(hosts): keep a PC alias on this device
  • 24e38ba3 feat(hosts): strings for rename, unpair and Remove PC in 15 languages
  • b95fd097 feat(hosts): HostActions, options for every input, rename, unpair and error dialogs
  • ce1772b5 docs(console): PCs on Android
  • 56d404c3 fix(hosts): restore the ellipsis in a PcView comment as UTF-8
  • 9fde9c59 fix(hosts): open options on right-click from the grid, not the cards
  • 0e90edc2 test(smoke): Remove PC wording and scroll to the game settings layer text
  • 4c9c221a fix(hosts): a rediscovered PC keeps its name from the first update
  • ba0f47f4 fix(hosts): show the PC name on stream titles, shortcuts and the TV channel
  • 21b75f75 fix(hosts): unpair drops the cached state, and the hint stops resizing the list
  • 36102fcf test(smoke): take the shared find_text from the settings branch
  • 635b5342 docs(console): names on shortcuts, X in a library and the open rename issues
  • 27611e2a feat(settings): one focus rule on the settings sub-pages
  • 4719528c feat(settings): two panes, a Search settings row and open(section, focusKey)
  • f04d474c docs(settings): the two panes and open(section, focusKey); smoke handles both panes
  • 15937117 fix(settings): keep the Search row and the right section across a recreation
  • 5df4cfa2 docs(settings): open() falls back to the section of the setting
  • 784b9501 test(pyrowave): one band of lookahead is enough for the row order
  • 73102af1 feat(a11y): interface size, high contrast and reduced motion
  • f0a8dd57 test(a11y): focus visibility on PCs and Settings, and 150 % fit
  • b2a4cc23 fix(a11y): a focus ring on Material buttons, and a focus test that needs a ring
  • b2011bef docs(a11y): the Accessibility section for Android
  • c57d0f31 feat(link): send the wired link speed for every codec
  • 5adb8a8f feat(link): Android sends the wired link speed for every codec
  • bbac305a feat(present): vsync-grid scheduling and content rate in the present clock (B1 N1 interface)
  • 1f790f80 feat(present): native side of the grid schedule and content rate (B1 N1)
  • 1536bbe7 docs(present): the vsync grid schedule and content rate interface (B1 N1)
  • 39aa3f77 feat(video): follow the content rate with setFrameRate (B1 N3)
  • 1a01a50a fix(framerate): drop the content rate when the game stops holding one
  • 9240f45d fix(framerate): withdraw the content vote, gate the tracker, poll only when on
  • e3503aaa perf(pyrowave): GPU decode path in the desktop stream behind pyrowave_decoder
  • ff012ac9 perf(pyrowave): GPU decoder failures are typed, tests for the GPU path
  • 3ef2d62b test(scripts): loopback harness takes the decoder per leg, the resolution and the host port
  • dfcda362 perf(pyrowave): GPU decode is the default on Windows, with the ABBA in the docs
  • 427e10eb docs(pyrowave): the laptop leg, the GPU decoder's stage line and the harness options
  • ac00a8c4 fix(pyrowave): review fixes for the GPU decode path
  • a864fa5a feat(desktop): timing CSV columns for the wait between decoded and shown
  • 7230c679 test(scripts): breakdown of the wait between decoded and shown, loopback settings per variant
  • 79e1efb0 test(scripts): loopback harness takes per-variant settings and an already held lock
  • 624aef67 docs(pyrowave): the wait between decoded and shown, the CPU fence wait trial, review fixes
  • 9bc4c0b1 test(pyrowave): bound the signed mean on real 8-bit frames at 0.4 code
  • 2107341e feat(desktop): VRR displays present immediately by default, host frame times are opt-in
  • cfda64b3 feat(video): residency governor and in-flight cap policies
  • deed5f98 feat(video): scheduler columns at the end of the latency CSV
  • 694342f0 feat(video): deadline present scheduler, queue bound and late drop behind hostFrameTimes
  • 0b89a047 fix(video): scheduler releases at once, plans from fresh time, counts its own queue
  • afa96a36 feat(cli): BUTTERPOLLO_TEST_LINK_MBPS sets the wired link hint
  • b839e5cd feat(console): Hosts becomes PCs in Home and the shell
  • 1bb6c3c3 fix(console): Home shows the name given with Rename
  • 608987d2 test(console): a rename changes Home's reload signature
  • d767896c refactor(computers): HostMenu holds a PC's option list for both screens
  • 714dfd78 feat(console): Home gets the shell bar and options on its PC cards
  • 47eb3048 feat(console): a game page gets the shell bar
  • 4921c705 feat(settings): a PC's settings page shows its name and manages the PC
  • 5023da11 fix(settings): the display picker names the PC the way the page does
  • 45a77579 feat(console): a newly paired native host lands on Home
  • adc9b198 test(console): focus order on Home and a game page on television
  • f9894df1 chore(demo): states pair and options for the debug harness
  • 5c163417 docs(console): the shell bar on Home and a game page, PC options everywhere
  • 1f5ae14f test(console): a host card's long press opens the PC options
  • 6e092cad fix(console): the host card's right-click needs API 23
  • e2018e14 chore(build): -PdebugIdSuffix installs a side-by-side debug copy
  • 66cedd9c chore(demo): the options state scrolls to the PCs row on a short screen
  • 4e9e9156 fix(theme): a tonal button has an outline at rest in high contrast
  • 2eb46e68 fix(pcs): a PC removed on its settings page leaves the PC list and Home
  • 98a56b74 fix(theme): a disabled tonal button's outline fades like its label
  • 6dd1465b chore(demo): the demo home has its own task affinity and opens the options sheet once
  • 12930a16 chore(strings): drop the unused console_menu_hosts
  • 4740ab81 test(shell): PCs from a game page goes Back to Home when Home is the root
  • 880e5dd8 feat(protocol): shared PyroWave row-order step table and tracker
  • 942f487e fix(http): a 3.0 beta host's version parses, so its PyroWave records are used
  • 211130a1 feat(client): ask the host for row order (pyrowaveRowOrder)
  • 59c38aef chore(clippy): drop two redundant conversions clippy 1.98 flags
  • 3707076e feat(desktop): beam race, slice decodes while a row-ordered PyroWave frame arrives
  • ba211a62 fix(desktop): the final decode after slice decodes skips the SDK ready gate
  • 63a6f074 docs(settings): usage advice for three keys, settings.md regenerated
  • 6a87acdb feat(desktop): PyroWave GPU decoding on Linux
  • 2443ba34 build(desktop): Linux package and PyroWave SDK build scripts
  • 646c7610 test(desktop): CPU against GPU PyroWave legs for a Linux client
  • 8d04f58c docs(desktop): PyroWave GPU decoding on Linux
  • da70d644 fix(desktop): the Linux PyroWave decode has the same 2 s deadline as Windows
  • 9e8203c2 feat(desktop): PyroWave decodes on the GPU by default on Linux too
  • 3969d628 test(desktop): environment-dependent ignored tests skip with a reason
  • f10caa50 fix(desktop): the timing CSV carries Android's seven scheduler columns, empty
  • 7de115fa fix(pyrowave): the row tracker follows each packet's lowest step, not each record
  • 84eac989 feat(desktop): NIGHTJAR_STREAM_LOCATION picks the stream's link class for measurement
  • 28ca35e0 fix(desktop): PyroWave Linux decode runs submit and complete under the watchdog
  • 7ec8bd23 docs(desktop): beam racing, the row tracker follows the packet cursor, loopback numbers
  • 93137f13 fix(pyrowave): a lost packet makes a frame unordered, clippy clean on all targets
  • dcee3363 fix(desktop): beam race asks for row order only with the GPU decoder, and says why not
  • e7863a20 fix(desktop): slices of a frame that left the row order are not marked exact
  • 5abb4a97 docs: beam race loopback numbers in early-decode and pyrowave-decode
  • c4843a82 fix(overlay): Host processing is the frame header's average again, host reports get their own line
  • 32acd5a1 Merge main into b10-step4
  • 29cdf944 fix(stats): count host processing on every path, Artemis window and precision, report values under their own label
  • 04a9bec5 fix(input): a pad's D-pad moves menu focus and the PC keyboard once
  • a7f9bf41 docs(input): USB and Bluetooth pads in menus and the PC keyboard, expected
  • f7288261 fix(input): review fixes for pad navigation
  • 4799d46d fix(http): host version pre-releases rank alpha, beta, rc, release
  • 01b7d4cb fix(pyrowave): a late record after a decoded slice drops the frame's slices
  • 7e313336 Merge main into b10-step4
  • 8ee16d09 feat(video): name why the refresh switch and HDR10 do not happen (untested on hardware)
  • af6fe1a0 docs: Expected (untested on hardware) notes for refresh switching and HDR10
  • 8c720395 fix(video): review fixes for the refresh switch and HDR10 notes
  • 7eb6188f fix(http): a 3.0 alpha or beta host's version parses in HostCapabilities
  • d9ec1b7f feat(protocol): link notice control message 0x5538
  • 40efc47a feat(protocol): ask for and print the host's link notice (0x5538)
  • e51eca8f feat(overlay): say when the host lowered the bitrate for the network
  • f31e2157 test(video): pin the scheduler's target vsync with the Retroid's presentation deadlines
  • fbf566fb docs(video): host frame times measured at the compositor's present times
  • 0318f9a1 fix(desktop): scroll the stream menu to the focused row
  • 79d2d815 feat(present): lower late-frame percentile on a vsync grid and round to the nearest vsync
  • 8ab3fe22 feat(desktop): read the scan line, calibrate the scan, and say why the beam race is on or off
  • 908b5f28 feat(scripts): capture the client's presents with PresentMon in the loopback harness
  • 15aba014 feat(desktop): restart check tuned on hardware, windowed is composed, delay summary
  • 3f04ed95 feat(desktop): count PresentMon modes and race verdicts per leg, document the probe
  • d5989b55 fix(desktop): name the restart check failure for what it measures
  • db44603b fix(desktop): test the restart check only when the display idles, window from the delay data
  • 942faa02 fix(desktop): clippy const assertion in the window test
  • 330f5531 fix(scripts): PresentMon check after the hang check, stop it and stale sessions
  • 02b68a56 fix(desktop): beam race probe review fixes
  • f4873545 fix(desktop): the restart delay summary counts presents that began a scan
  • a2504ec9 fix(present): a dropped frame no longer lifts the grid's delay back to the 97th percentile
  • 5b987f2d fix(desktop): gate the scanline probe code and fix the Linux and focus-test CI failures
  • b828c890 feat(desktop): scheduler for the raced presenter
  • 11bcc985 feat(desktop): hand finished slices to the presenter and draw rows of them
  • 9dee7c58 feat(desktop): raced presenter, slices go to the screen ahead of the beam
  • 12d88450 feat(desktop): learn the present call from whole pictures, count why frames were not raced
  • b891d569 fix(desktop): keep the raced presenter clean on the Linux build
  • 419c3ff2 perf(desktop): the raced presenter draws consecutive slices in one pass and lets a finished picture go first
  • 76b9a408 feat(stream): one request for the beam race, label the setting experimental
  • 1cc6a797 docs(beam-racing): measured, opt-in; the gate table and the untested wired legs
  • da8561a6 fix(race): review fixes for the opt-in beam race
  • 9acb49b7 fix(race): keep held slices on a re-decode, number frames across decoders, drop the margin-sweep claim
  • 343978ab ci(release): build and sign the release in Actions when a v* tag is pushed
  • 1094bfef fix(release): read the certificate digest in the runner's apksigner format
  • 08d15031 docs: 3.0 README and docs for the console, Rust engine and desktop client
  • 1c215ff5 docs(readme): name the desktop client Experimental, add measurement conditions, qualify Rubylight-only features
  • a397ab60 fix(input): the PC keyboard acts on the first controller press after touch
  • b30ac553 fix(input): break the lone modifier tap when a Ctrl+Alt+Shift shortcut fires
  • ca87615b fix(desktop): Up and Down leave number fields; Left and Right step them
  • 85006c65 test(ui): the stream menu text follows the system font scale
  • cdc193c8 fix(desktop): round the PyroWave wavelet stores so the CPU path stops running 0.28 code bright
  • 23457725 fix(desktop): a Left or Right step on a number field reports a change
  • eaa0495b test(input): the first A press after touch types the touched Q
  • 5d201df0 fix(video): say when this device's decoder rejected the stream, not the host (#21)
  • d52517e0 test(video): pin which text the stream dialog shows for a failed stage (#21)
  • f40616c1 feat(decoder): add Artemis's Tegra and MediaTek decoder keys, report applied and dropped keys
  • ca6c51fd fix(decoder): keep HDR null key and diagnostics from failing configure
  • 0389f0c1 feat(decoder): port moonlight-noir MediaTek, Snapdragon and RFI decoder settings
  • 22c06f6d docs(decoder): compare Nightjar's decoder flags with Artemis and moonlight-noir
  • aa79f2c6 fix(decoder): keep MediaTek RFI detection off the AV1 whitelist, gate rate and priority on performance hints
  • c554f563 fix(decoder): send Tegra and MediaTek the operating rate only, never the real-time priority
  • 4b787b43 docs(readme): sell Nightjar with screenshots of the console, stream and desktop client
  • 28acdeb0 docs(readme): retake the desktop client shot unpatched against a real host
  • 5154c40b docs(readme): match the desktop shot's alt text to what it shows
  • e752681c ci(release): publish the Windows and Linux desktop client with the APKs
  • dcb0a13c ci(release): bundle the PyroWave SDK in the desktop packages
  • 876e5402 ci(release): harden the desktop release jobs after review
  • 89ffd5d7 fix(release): start the MSYS2 FFmpeg build in the workspace
  • a75c33db fix(release): check out the Windows desktop job with LF endings
  • ed26b18f fix(release): install gcc-libs for the runtime licence the SDK bundles
  • ec0caf95 fix(release): find the GCC runtime licence after the gcc 16.2 package split
  • b3c42e9f Update README.md
  • bc416a94 chore(release): 3.0.0-rc.1

Full changelog: v0.8.0...v3.0.0-rc.1

Don't miss a new nightjar release

NewReleases is sending notifications on new releases.