Muryan

Using Metal in macOS Screen Savers

Posted on 2018-11-17 at 18:58

In my last post I was glowing in my praise for Apple’s Metal technology. Since then my love affair with Metal has cooled just a little. The underlying technology is great, but I just couldn’t get the recommended way of handling Metal graphics (MTKView) to play nice in a screen saver. It works fine in normal apps such the test harness I use for Ephemeral development, but there’s something about living inside a screen saver that makes it exhibit some odd behaviour, primarily visual glitches on start up.

So I ended up dropping down one level in the technology stack, getting rid of MTKView in favour of using CAMetalLayer and CVDisplayLink. Now I have a Metal screen saver that is free of glitches, and works exactly the way I want it to. Despite the switch in technology the bulk of my code didn’t need to change, which was a relief. And for a bonus I’m now using the new timer to run the OpenGL/OpenCL variant of Ephemeral, which is now drawing more smoothly than ever before.

There’s one more issue with Metal that’s cost me a huge amount of time, which is a rare problem which causes visual corruptions. The symptom is that every second frame of animation is garbled, but only ever when running from System Preferences in preview mode. I tried everything I could think of to fix it, but just couldn’t get it to go away.

And then I had the idea of looking at Metal screen savers written by other developers. I found three, and managed to get all of them to draw with the same style of corruption. So I think I can put this down to a problem with macOS: it seems very unlikely to me that all these Metal–based screen savers, independently created by different developers and using different methods for drawing, contain the exact same bug. Coupled with occasional visual corruptions I see on the macOS lock screen and desktop, and I feel even more certain that macOS that’s at fault.

With all that out of the way, the new Metal version of Ephemeral is almost ready to go…