feat(apple): stage-2 default + pixel-perfect, decode robustness, UI/rumble polish
Stream reliability - Default to the stage-2 presenter (VTDecompressionSession + CAMetalLayer): it detects and recovers a wedged decoder, where stage-1's AVSampleBufferDisplayLayer freezes hard on a lost HEVC reference frame with no app-side recovery (confirmed Apple limitation). Stage 1 is now a DEBUG-only presenter toggle, plus the automatic no-Metal fallback. - Stage-2 pixel-perfect: render the drawable at the decoded size (shader stays 1:1 = identity) and let the layer's contentsGravity scale via the system compositor — the same path stage-1's videoGravity used — instead of scaling in-shader. - Loss recovery in both pumps is now a persistent awaitingIDR want, retried until an IDR actually lands, so a keyframe request swallowed by the throttle can't strand a frozen frame; 100 ms keyframe throttle to match the Android path. - Fix "Publishing changes from within view updates": defer the HostStore writes out of the .onChange(of: model.phase) callback. - Move AVAudioSession setActive/setCategory off the main thread (async on a shared serial queue) to stop the UI-stall warning. Controllers - Rumble: capped-exponential backoff when the gamecontrollerd.haptics XPC breaks (-4811) so a transient server interruption self-heals instead of cascading; playsHapticsOnly so a controller engine doesn't join the always-active streaming audio session. - Host cards: iPad pointer "magnet" hover effect; iPhone press scale + light haptic. UI / design - Ship Geist (SIL OFL 1.1) as the app font (bundled OTFs + registration), with the license surfaced in Acknowledgements. - Restructure iOS/iPadOS Settings into a category NavigationSplitView; resolution wheel with custom-resolution entry; 10-bit HDR toggle in Display. - Industrial host-card redesign (left-aligned, bold, brand monogram tiles). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,17 @@ public enum Licenses {
|
||||
+ apache
|
||||
}
|
||||
|
||||
/// The bundled brand typeface (Geist Sans + Geist Mono) — SIL Open Font License 1.1. The
|
||||
/// license file ships alongside the OTFs in `Resources/Fonts/`, satisfying the OFL's
|
||||
/// distribution requirement; this surfaces it in the Acknowledgements screen too.
|
||||
public static var fontLicense: String {
|
||||
guard let url = Bundle.module.url(
|
||||
forResource: "Geist-OFL", withExtension: "txt", subdirectory: "Fonts"),
|
||||
let text = try? String(contentsOf: url, encoding: .utf8)
|
||||
else { return "" }
|
||||
return text
|
||||
}
|
||||
|
||||
/// Third-party software notices for the linked Rust crates (generated by
|
||||
/// `scripts/gen-third-party-notices.sh`).
|
||||
public static var thirdPartyNotices: String {
|
||||
|
||||
Reference in New Issue
Block a user