Opened 18 months ago

Closed 18 months ago

Last modified 10 months ago

#11430 closed defect (fixed)

macOS: blurry content on Retina displays

Reported by: dwatteau Owned by: criezy
Priority: normal Component: Port: Mac OS X
Version: Keywords: retina, dark mode, blurry
Cc: Game:

Description (last modified by dwatteau)

(Following some discussion with criezy on Discord.)

On macOS Mojave 10.14.6 (18G4032), on a 2017 27-inch 5K Retina iMac (iMac18,3), official ScummVM 2.1.2's whole display is blurry (the games, and the GUI in itself), compared to earlier releases.

It's quite easy (and quick) to see if you just launch ScummVM with the old green/black builtin interface on a macOS Retina display with Mojave (possibly Catalina). The attached screenshot shows the difference.

The blurriness disappears if I remove the following content from /Applications/ScummVM.app/Contents/Info.plist:

   <key>NSRequiresAquaSystemAppearance</key>
   <false/>

NSRequiresAquaSystemAppearance was introduced in the the following commit, so that macOS Dark Mode (which appeared in Mojave) could be applied to ScummVM, while continuing building official releases with older macOS SDKs:

https://github.com/scummvm/scummvm/commit/485e8bee17230ed

This blurriness also appears if I build ScummVM with Xcode 11 on Mojave without any NSRequiresAquaSystemAppearance, but with a 10.14+ SDK.

It's possible that this is a bug with macOS Dark Mode in itself. It looks like VMWare Fusion and VLC had similar issues:

https://communities.vmware.com/thread/618831
https://code.videolan.org/videolan/VLCKit/issues/82#note_30971

Similar issues may have been reported to Apple's Radar in early Mojave betas:

https://openradar.appspot.com/45895864

but I'm not sure Apple is going to fix that.

I've also reported this problem to SDL2 Bugzilla:

https://bugzilla.libsdl.org/show_bug.cgi?id=5087

I'm not aware of any proper fix for this problem yet.

The only workaround which seems to work is to:

  • continue building official ScummVM releases on an earlier macOS release (possibly any pre-10.14 SDK?)
  • stop setting any NSRequiresAquaSystemAppearance value in Info.plist.

Hence, 485e8bee17230ed may need to be reverted (results to be confirmed on various macOS setups, maybe?).

Dark Mode will be lost but, in my opinion, proper output of the interface and the games is more important than having a dark titlebar and a dark file choosing dialog (official VLC still doesn't enable Dark Mode on Mojave, for instance).

Attachments (1)

sdl2-blurry-retina.png (72.8 KB ) - added by dwatteau 18 months ago.

Download all attachments as: .zip

Change History (18)

by dwatteau, 18 months ago

Attachment: sdl2-blurry-retina.png added

comment:1 by dwatteau, 18 months ago

Description: modified (diff)

comment:2 by criezy, 18 months ago

Thank you for he report and all the details it contains!
From what I remember of our discussion on Discord, you also said that the issue was not happening when using the OpenGL graphics mode, and only happened with the other graphics mode. Do you confirm?

comment:3 by dwatteau, 18 months ago

No problem, I've been such a happy user of ScummVM for many many years and years!

Unfortunately, my OpenGL test was wrong (it was harder to spot in games, but it's evident with the old builtin UI). Official ScummVM 2.1.2, without any NSRequiresAquaSystemAppearance removal, but with OpenGL, is blurry as well.

I think that OpenGL is also "expected" to be broken, because that's where VLC also had problems, and SDL2 devs spoke about the NSOpenGLView layer in SDL, which is already full of various workarounds for various macOS releases, it seems. It looks like it's pretty fragile.

I'll try opening a Radar report to Apple, but it could take a lot of time, and I'm not really sure we'll see an upstream fix soon.

comment:4 by criezy, 18 months ago

Owner: set to criezy
Resolution: fixed
Status: newclosed

I have now merged your pull request to remove the NSRequiresAquaSystemAppearance key from the Info.plist file, so this issue should be fixed now.

I have also reopened bug #11305 and I think I can close this one now. I think this should not prevent you from adding more information if needed or if the SDL guys find a magic fix for the issue that would allow us to add back the support for the dark mode. Otherwise you can comment on bug #11305.

comment:5 by criezy, 18 months ago

Resolution: fixed
Status: closednew

I am reopening this as the issue still exists when building with the SDK 10.14 or 10.15. Explicitly opting out of dark mode support in the Info.plist (with NSRequiresAquaSystemAppearance = YES) does not fix the issue.

LibreOffice also had a similar bug: https://bugs.documentfoundation.org/show_bug.cgi?id=122218
They tracked down the issue was resulting from building with SDK 10.14 or above. Just changing the two bytes for the LC_VERSION_MIN_MACOSX sdk value in the resulting executable fixes the blurring. So this confirms that macOS does something different depending on the SDK value.

They didn't track or fix the root cause of the issue, but added a workaround when building with Xcode 11 and the 10.14 or 10.15 SDK to set the SDK value to n/a in the executable: https://git.libreoffice.org/core/+/645fe53be0dc36535dba0ed684e21ca4cda80d70%5E%21

The fix uses the -platform_version linker flag, which does not exist for older version of the linker so a check needs to be added if we want to use it (see for example https://git.libreoffice.org/core/+/b7fd89100d8653dc73955780358fe31d38b68ebf%5E%21). And this also means that building with Xcode 10 and the 10.14 SDK will result in the blurring. But this should at least fix the blurring in most cases (using SDK 10.13 or below, or using Xcode 11 or above). This might not work when using cross-compilation though (e.g. on buildbot).

comment:6 by criezy, 18 months ago

Resolution: fixed
Status: newclosed

I have now adapted the workaround that LibreOffice is using to scummvm and committed the change in commit 70f79d3. When using configure it is automatically used when possible. When using create_project it is disabled by default and it needs to be enabled manually by editing a line in the devtools/create_project/xcode.cpp file. I have updated the build instructions in the wiki to mention this.

The issue still exists in some cases:

  • When building with Xcode 10 and the 10.14 SDK or above.
  • With cross-compilation that use the 10.14 SDK or above.

But I have no idea how those cases could be fixed.
Since I don't think there is much more that can be done, I am closing this now.

comment:7 by dwatteau, 13 months ago

FWIW, the problem is back with the new 2.2.0 release.

I'm not 100% sure it has been built with the prereqs mentioned in commit 70f79d3df8b4a9d4c6d1b69838ff5a722c51b61e. Looking at "otool -l" output, it looks like it has been built with an older Xcode, but the current workaround needs Xcode 11, it seems.

(I can test some new test builds if this helps.)

comment:8 by dwatteau, 13 months ago

Summary: macOS Dark Mode compatibility makes content blurry on Retina displaysmacOS: blurry content on Retina displays

comment:9 by dwatteau, 13 months ago

Hi,

Actually, ScummVM 2.2.0 doesn't have that blurriness problem on Mojave 10.14.6 iff you launch the official binary this way:

SDL_RENDER_DRIVER=opengl /Applications/ScummVM.app/Contents/MacOS/scummvm

I can't find any explanation for this behaviour, though.

comment:10 by dwatteau, 13 months ago

Alright, so SDL2 now tries to use Metal before OpenGL (but their documentation still mentions the opposite order…):

https://hg.libsdl.org/SDL/rev/1acae5590352

(this was already included in SDL2 2.0.10)

Maybe SDL2 should be built with --disable-render-metal --disable-video-metal for the official macOS builds, for now (if this fixes it). I haven't checked it on macOS Big Sur, but for what we're doing, OpenGL may be a safer choice, for now?

EDIT: or SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl") could be used somewhere if we're on the macOS target. That one works, here.

Last edited 13 months ago by dwatteau (previous) (diff)

comment:11 by criezy, 13 months ago

Thanks a lot for looking into that!

The SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl") seems like the easiest solution for now.

An alternative (so that it can be changed without recompiling) could be to add the following to the Info.plist:

    <key>LSEnvironment</key>
    <dict>
        <key>SDL_RENDER_DRIVER</key>
        <string>opengl</string>
    </dict>

Could you also confirm that the display is not blurry if you use the OpenGL graphics mode (instead of for example HQ2X) in ScummVM without any of those changes? Or does it somehow still go through Metal at some point?

I also found a bit of information that could be useful. A similar bug was reported for Dota2 where on Retina screen the display would be blurry with the Metal version but not the OpenGL one. And they found a fix: https://github.com/ValveSoftware/Dota-2-Vulkan/issues/258#issuecomment-400393846

It turned out the issue is that the default value for CALayer.magnificationFilter is linear and we needed to set it to nearest sampling.

This is maybe something that SDL could do.

comment:12 by dwatteau, 13 months ago

Yes, the Info.plist trick works, I didn't know about that one, nice, thanks!

I did have to rename the app in /Applications so that the Info.plist cache got removed, though (but it seems that making and distributing a new build will be enough for end users).

I confirm that OpenGL graphics mode is OK too (I was using 3x before that). No regression with that Info.plist change on Leopard PPC either.

I'll update my SDL bug report with that new information, thanks.

Could this change be part of a 2.2.1 release, if it happens? Do you want me to do the PR on Github?

comment:13 by dwatteau, 13 months ago

Ah, however the Info.plist trick has not effect if the scummvm binary is run from the Terminal:

https://stackoverflow.com/a/16189257

I'm not sure if this matters. Otherwise, the SDL_SetHint() line would be more definitive.

comment:14 by criezy, 13 months ago

I don't think it really matters. When starting it from the Terminal you can easily define your own environment variable.

However since environment variables take precedence over SDL_SetHint, I think adding SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl") to the code might be the best way to go. And if a user still wants to use the Metal renderer he can use the SDL_RENDER_DRIVER environment variable to override it.

Do you want me to do the PR on Github?

This would be welcome yes.

comment:15 by dwatteau, 13 months ago

OK, so I've submitted PR 2494 which has been merged (thanks!), so let's hope that these workarounds continue working for a while :)

comment:16 by criezy, 13 months ago

And thank you for the pull request.

In the long term it would be nice to support high-DPI rendering (not just on mac, but any platform with a high-DPI screen). But I can't really start working on that without any computer or device to test it. So we will either have to wait for another developer to work on this, or for me to get a new computer. This is related to bug #10944.

comment:17 by dwatteau, 10 months ago

Hi,

For what it's worth, It looks like the following content can be put back in Info.plist:

<key>NSRequiresAquaSystemAppearance</key>
<false/>

if:

  • you keep the current SDL_HINT_RENDER_DRIVER OpenGL workaround (as per merged PR 2494)
  • and build with a 11.0 SDK (while still targeting older macOS versions).

This way, you obtain a macOS app with no blurry effect on Retina screens, but Dark Mode works again.

As tested on macOS 11.0.1 (20B29).

I'm also thinking of this, since you might want to upgrade to the 11.0 SDK (and associated Xcode) to make a Universal x86_64/arm64 build, at some point.

Note: See TracTickets for help on using tickets.