True HiDPI past the scaled-backing cap via a mirrored virtual display - #68
Draft
didriksg wants to merge 5 commits into
Draft
True HiDPI past the scaled-backing cap via a mirrored virtual display#68didriksg wants to merge 5 commits into
didriksg wants to merge 5 commits into
Conversation
Three findings baked in: alloc/init ownership must stay Unmanaged (claiming both over-releases), the looks-like HiDPI mode only materializes when both the 2x backing and the half-size pixel mode are declared, and a bare CLI's CG display-info cache never refreshes (create first, query after). Verified end to end on a 2560x1440 external: hardware mirror set, 165Hz preserved.
…lay (#65) Lazy lifecycle: first apply creates a hidden virtual display (stable per-monitor identity, MIRR serial marker, backing-only mode ladder for every beyond-cap stop), drives it to the looks-like HiDPI mode and hardware-mirrors the physical panel onto it; later applies just switch the virtual's mode. restore() unmirrors first, then destroys. Quit teardown unmirrors synchronously before the virtual displays die.
Synthetic stops (negative ids, same 16px grid) fill the gap between the enumerable HiDPI ladder top and native on capped panels. switchTo routes them to MirroredModeService and unmirrors before applying any real mode, so every entry point (slider, resolution row, refresh row) handles the mirror lifecycle through the one serialized path. Readback needs no new code: while mirrored the physical reports the virtual's looks-like mode, which matches the synthetic stop by size.
Unplugging a mirrored panel or losing the virtual master drops the bookkeeping (and orphan virtual) via refreshDisplays; a stray mirror virtual from a crashed session gets its panel unmirrored on every refresh (MIRR serial marker identifies it); wake's saved-mode reapply skips mirrored displays so it cannot fight the mirror; and a re-apply re-arms a mirror that a wake or WindowServer reset silently dropped.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #65, and delivers the HiDPI half asked for in #66.
On 5K2K ultrawides WindowServer refuses scaled backings wider than about 6720px, so the smooth-scaling ladder tops out around "looks like 3360x945" and the sizes between that and native only exist as plain 1x modes. This gets them as real HiDPI: slider stops past the ladder top now create a hidden virtual display that carries the 2x backing (rendered, not scanned out, so the cap doesn't apply), set it to the wanted looks-like size, and hardware-mirror the panel onto it. The scanout engine does the downscale.
How it holds together:
Verified so far, on a 2560x1440 AOC with scripts/mirror-hidpi-probe.swift: virtual display creation, the looks-like HiDPI mode enumerating and applying, hardware mirroring (hwMirrorSet true), 165Hz surviving the whole chain, clean restore. The probe encodes the three findings the implementation rests on: backing-only mode declarations (applySettings rejects the whole set somewhere above ~360 objects), create-before-query ordering in a CLI (CG's display cache never refreshes there), and unmirror before destroy.
Not verified yet, and why this stays a draft: whether a virtual framebuffer actually escapes the cap. I don't have an ultrawide until Thursday; the probe answers that in two minutes there (
swift scripts/mirror-hidpi-probe.swift 3840x1080), then a live pass with the app. Extra Brightness while mirrored also needs a look on real hardware.Not in tonight's release; this ships in the next one once the Thursday run confirms it.