From ccaca68570c0858caa64016854c88c0a0e57b342 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 23 Oct 2025 21:16:53 -0500 Subject: [PATCH] Don't use CAMetalDisplayLink on Intel Macs When in Direct mode, skipping a frame will cause the display to flash black on Tahoe. --- app/streaming/video/ffmpeg-renderers/vt.h | 2 ++ .../ffmpeg-renderers/vt_avsamplelayer.mm | 21 +------------------ .../video/ffmpeg-renderers/vt_base.mm | 20 ++++++++++++++++++ .../video/ffmpeg-renderers/vt_metal.mm | 2 +- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/app/streaming/video/ffmpeg-renderers/vt.h b/app/streaming/video/ffmpeg-renderers/vt.h index b608901c..d5b1b45e 100644 --- a/app/streaming/video/ffmpeg-renderers/vt.h +++ b/app/streaming/video/ffmpeg-renderers/vt.h @@ -12,6 +12,8 @@ public: void setHdrMode(bool enabled) override; protected: + bool isAppleSilicon(); + bool m_HdrMetadataChanged; // Manual reset CFDataRef m_MasteringDisplayColorVolume; CFDataRef m_ContentLightLevelInfo; diff --git a/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm b/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm index 067aeb99..857b7eca 100644 --- a/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm +++ b/app/streaming/video/ffmpeg-renderers/vt_avsamplelayer.mm @@ -10,8 +10,6 @@ #include #include -#include -#include #import #import #import @@ -325,23 +323,6 @@ public: return false; } - bool isAppleSilicon = false; - { - uint32_t cpuType; - size_t size = sizeof(cpuType); - - err = sysctlbyname("hw.cputype", &cpuType, &size, NULL, 0); - if (err == 0) { - // Apple Silicon Macs have CPU_ARCH_ABI64 set, so we need to mask that off. - // For some reason, 64-bit Intel Macs don't seem to have CPU_ARCH_ABI64 set. - isAppleSilicon = (cpuType & ~CPU_ARCH_MASK) == CPU_TYPE_ARM; - } - else { - SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, - "sysctlbyname(hw.cputype) failed: %d", err); - } - } - if (qgetenv("VT_FORCE_INDIRECT") == "1") { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Using indirect rendering due to environment variable"); @@ -385,7 +366,7 @@ public: // // https://github.com/moonlight-stream/moonlight-qt/issues/493 // https://github.com/moonlight-stream/moonlight-qt/issues/722 - if (isAppleSilicon && !(params->videoFormat & VIDEO_FORMAT_MASK_10BIT)) { + if (isAppleSilicon() && !(params->videoFormat & VIDEO_FORMAT_MASK_10BIT)) { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "Using layer rasterization workaround"); if (info.info.cocoa.window.screen != nullptr) { diff --git a/app/streaming/video/ffmpeg-renderers/vt_base.mm b/app/streaming/video/ffmpeg-renderers/vt_base.mm index cdf97f6f..2a4ca196 100644 --- a/app/streaming/video/ffmpeg-renderers/vt_base.mm +++ b/app/streaming/video/ffmpeg-renderers/vt_base.mm @@ -9,6 +9,9 @@ #import #import +#include +#include + VTBaseRenderer::VTBaseRenderer(IFFmpegRenderer::RendererType type) : IFFmpegRenderer(type), m_HdrMetadataChanged(false), @@ -27,6 +30,23 @@ VTBaseRenderer::~VTBaseRenderer() { } } +bool VTBaseRenderer::isAppleSilicon() { + static uint32_t cpuType = 0; + if (cpuType == 0) { + size_t size = sizeof(cpuType); + int err = sysctlbyname("hw.cputype", &cpuType, &size, NULL, 0); + if (err != 0) { + SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, + "sysctlbyname(hw.cputype) failed: %d", err); + return false; + } + } + + // Apple Silicon Macs have CPU_ARCH_ABI64 set, so we need to mask that off. + // For some reason, 64-bit Intel Macs don't seem to have CPU_ARCH_ABI64 set. + return (cpuType & ~CPU_ARCH_MASK) == CPU_TYPE_ARM; +} + bool VTBaseRenderer::checkDecoderCapabilities(id device, PDECODER_PARAMETERS params) { if (params->videoFormat & VIDEO_FORMAT_MASK_H264) { if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_H264)) { diff --git a/app/streaming/video/ffmpeg-renderers/vt_metal.mm b/app/streaming/video/ffmpeg-renderers/vt_metal.mm index 38fd4f39..5ff1e329 100644 --- a/app/streaming/video/ffmpeg-renderers/vt_metal.mm +++ b/app/streaming/video/ffmpeg-renderers/vt_metal.mm @@ -828,7 +828,7 @@ public: void startDisplayLink() { if (@available(macOS 14, *)) { - if (m_MetalDisplayLink != nullptr || !m_MetalLayer.displaySyncEnabled) { + if (m_MetalDisplayLink != nullptr || !m_MetalLayer.displaySyncEnabled || !isAppleSilicon()) { return; }