PrismCore / API reference / Display

Enumeration

DisplayCriteriaLogic

enum DisplayCriteriaLogic

Declared in Sources/PrismCore/Display/DisplayCriteriaController.swift · PrismCore 3.5.4

The pure decisions DisplayCriteriaController acts on, split out so they compile — and test — on every platform, while the controller itself only exists where AVDisplayManager does (tvOS).

Type methods

static func writeIsRedundant(previous: WrittenCriteria?, next: WrittenCriteria) -> Bool

Skip the write when the previously-written criteria are still active and identical. previous is nil after a reset (or before the first write), and then the write always happens.

static func panelPresentsHDR(headroomIsRaised: Bool, wroteHDRCriteria: Bool, panelHasProvenHDR: Bool) -> Bool

Will the panel present this session in HDR?

UIScreen.currentEDRHeadroom is not a readout of the panel's HDMI mode — it rises around a dynamic-range transition and decays back to 1.0 while the panel keeps presenting HDR. So a raised headroom is trusted as a positive, and its absence is answered by history: once a criteria write has demonstrably driven this display into HDR, an HDR write that ended quietly means "already there", not "refused". A panel that never proved itself (Match Dynamic Range off, genuinely SDR display) keeps the conservative answer and is never offered a PQ master it would reject.

static func settleBounds(wantsHDRPanel: Bool) -> (startGrace: Duration, settleCap: Duration)

How long waitForSwitch may spend on each stage, by what the last write asked of the panel.

A dynamic-range switch is a real HDMI renegotiation — HDCP re-auth, mode engage, often through an AVR — and on living-room chains it routinely takes 2–5 s to end, and over a second to visibly start. The old flat 1 s + 2 s bounds lost that race often enough to matter: the master loaded against the panel's old mode, tvOS refused the DV claim (-11868), and the rejection fallback silently replayed the title as HDR10 — a different HDMI mode with the TV's other picture preset. One play engaged Dolby Vision, the next didn't, and which one a viewer got was a coin flip (found on an Apple TV 4K driving a real panel, 2026-08-07).

Both waits exit on the first positive signal (mode-switch-end, raised headroom, in-progress flag clearing), so generous caps cost nothing on panels that report their switches; the caps only bind where the switch is genuinely still running or unobservable. Rate-only writes keep the old bounds — a refresh-rate switch has no range claim to lose a race for, and stretching every SDR load would be pure dead time.

Structure

DisplayCriteriaLogic.SettleReport

struct SettleReport

What one waitForSwitch actually did, with real elapsed times — the telemetry that turns settle budgets from bets into measurements.

The elapsed fields are wall-clock readings, deliberately not derived from tick counts times tick length: a budget-derived number reports the budget, and a settle that exits early then looks exactly like one that ran to its cap. Hosts are expected to log summary (Aether's Log screen shows it under its prismcore category), so slow chains show their real handshake times and the bounds in settleBounds(wantsHDRPanel:) can be tuned from evidence.

Initializers

init(outcome: Outcome, switchStartedAfterMilliseconds: Int? = nil, clearedAfterMilliseconds: Int? = nil, totalMilliseconds: Int)

No documentation comment in the source.

Instance properties

let outcome: Outcome

No documentation comment in the source.

let switchStartedAfterMilliseconds: Int?

When stage 1 saw the switch start; nil when none ever did.

let clearedAfterMilliseconds: Int?

When the in-progress flag cleared without an HDR signal; only set for .clearedWithoutHDRSignal.

let totalMilliseconds: Int

No documentation comment in the source.

var summary: String { get }

One log-ready line, e.g. settled via modeSwitchEnd in 2140ms (switch started at 380ms).

Enumeration

DisplayCriteriaLogic.SettleReport.Outcome

enum Outcome

No documentation comment in the source.

Cases

case matchingDisabled

Match Content is fully off — tvOS ignored the write, nothing can switch, nothing was waited for.

case alreadyPresentingHDR

An HDR write met a panel already presenting HDR — no wait.

case noSwitchStarted

Nothing visibly started within the grace: the panel already satisfied the criteria (or its switch is unobservable).

case modeSwitchEnd

The mode-switch-end notification arrived.

case headroomRaised

The EDR headroom rose — the HDR engage is visible.

case inProgressCleared

The in-progress flag cleared without an end notification — terminal only for rate-only writes, where there is no range engage left to confirm.

case clearedWithoutHDRSignal

HDR targets only: the in-progress flag cleared, the rest of the cap was spent watching for an HDR signal (end notification, raised headroom), and none came. The clear was ambiguous — a panel that finished quietly looks exactly like one that ABORTED the switch and stayed SDR — so the wait doesn't end on it; but a cap's worth of silence afterwards means the master this session serves may well be about to meet an SDR panel (-11868, and the rejection fallback takes it from there). Found on a panel that takes HDR10 fine when parked there, yet cleared its runtime switch at ~2.9 s with the mode never engaging.

case capExpired

The settle cap expired with the switch still reporting in-progress — the unobservable-switch case the cap exists for.

Structure

DisplayCriteriaLogic.WrittenCriteria

struct WrittenCriteria

What a criteria write asked the panel for, reduced to the fields whose equality means "the panel is already there". Re-writing identical criteria is not a no-op: it starts a redundant HDMI mode switch, and on panels whose Dolby Vision switch is unobservable that redundant switch makes every settle wait run to its cap.

Initializers

init(target: DisplayCriteriaChoice.Target, refreshRate: Float)

No documentation comment in the source.

Instance properties

let target: DisplayCriteriaChoice.Target

No documentation comment in the source.

let refreshRate: Float

No documentation comment in the source.

Generated from the public symbols of PrismCore 3.5.4. All types