config: use linear upscaling except on classic guests

The nearest-neighbour default (ba5f7f7f, #3371) was chosen for
low-resolution guests, where linear washes out already-chunky text. It is
the wrong choice everywhere else: a modern guest rarely upscales by an
integer ratio, so nearest duplicates source pixels unevenly and looks
blocky rather than sharp -- the complaint behind #6209 and #6572.

Default to linear and let the wizard select nearest for the guests the
original change was about: Classic Mac OS, Windows 7 and below, and any OS
configured for legacy hardware. Legacy hardware is checked on its own
rather than folded into the Windows case so that choosing a legacy machine
opts in under any OS, and because the summary page can enable it after the
Windows page has already latched isWindows10OrHigher.

Existing VMs are unaffected: upscalingFilter is a required coding key, so
a saved configuration always carries its own value. The UTM 2.x migration
path is likewise unchanged, since an absent displayUpscaler already
defaulted to linear.

Assisted-by: Claude:claude-opus-5
This commit is contained in:
osy
2026-09-01 13:35:08 -07:00
parent 0e147d0024
commit e2e37cf9b2
2 changed files with 17 additions and 1 deletions
@@ -28,7 +28,12 @@ struct UTMQemuConfigurationDisplay: Codable, Identifiable {
var isDynamicResolution: Bool = true
/// Filter to use when upscaling.
var upscalingFilter: QEMUScaler = .nearest
///
/// Nearest neighbour is only a good fit for low-resolution guests, where it keeps the image
/// sharp instead of washing it out (#3371); the wizard selects it for those. For a modern
/// guest the upscale is rarely an integer ratio, so nearest duplicates source pixels
/// unevenly and looks blocky rather than sharp.
var upscalingFilter: QEMUScaler = .linear
/// Filter to use when downscaling.
var downscalingFilter: QEMUScaler = .linear
+11
View File
@@ -475,6 +475,17 @@ struct AlertMessage: Identifiable {
config.displays[0].hardware = AnyQEMUConstant(rawValue: newCard)!
}
}
// Low-resolution guests upscale better with nearest neighbour: linear washes out
// their already-chunky text (#3371). Legacy hardware is checked on its own rather
// than folded into the Windows case so that picking a legacy machine opts in under
// any OS, and because the summary page can enable it after the Windows page has
// latched isWindows10OrHigher. Modern guests keep the linear default, where the
// upscale is a non-integer ratio and nearest looks blocky instead of sharp.
if operatingSystem == .ClassicMacOS || legacyHardware || (operatingSystem == .Windows && !isWindows10OrHigher) {
for i in config.displays.indices {
config.displays[i].upscalingFilter = .nearest
}
}
if operatingSystem == .Linux && !isDisplayEnabled {
config.displays = []
let newSerial = UTMQemuConfigurationSerial(forArchitecture: systemArchitecture, target: systemTarget)!