diff --git a/src/common/macos.h b/src/common/macos.h index 297c8f116..a9fdf407d 100644 --- a/src/common/macos.h +++ b/src/common/macos.h @@ -49,6 +49,12 @@ std::string checkDropEvents(); **/ void requestAttention(bool continuous); +/** + * Sets whether vsync is enabled for the given CAMetalLayer + **/ +void setMetalLayerVSync(void *metallayer, bool vsync); +bool getMetalLayerVSync(void *metallayer); + } // macos } // love diff --git a/src/common/macos.mm b/src/common/macos.mm index 06edf8a37..87051874a 100644 --- a/src/common/macos.mm +++ b/src/common/macos.mm @@ -24,6 +24,7 @@ #import #import +#import #ifdef LOVE_MACOSX_SDL_DIRECT_INCLUDE # include @@ -85,6 +86,32 @@ void requestAttention(bool continuous) } } +void setMetalLayerVSync(void *metallayer, bool vsync) +{ + @autoreleasepool + { + if (@available(macOS 10.13, *)) + { + CAMetalLayer *layer = (__bridge CAMetalLayer *) metallayer; + layer.displaySyncEnabled = vsync; + } + } +} + +bool getMetalLayerVSync(void *metallayer) +{ + @autoreleasepool + { + if (@available(macOS 10.13, *)) + { + CAMetalLayer *layer = (__bridge CAMetalLayer *) metallayer; + return layer.displaySyncEnabled; + } + } + + return true; +} + } // osx } // love diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 5cedf9ea0..1f7a915f7 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -1070,20 +1070,43 @@ love::image::ImageData *Window::getIcon() void Window::setVSync(int vsync) { - if (glcontext == nullptr) - return; + if (glcontext != nullptr) + { + SDL_GL_SetSwapInterval(vsync); - SDL_GL_SetSwapInterval(vsync); + // Check if adaptive vsync was requested but not supported, and fall + // back to regular vsync if so. + if (vsync == -1 && SDL_GL_GetSwapInterval() != -1) + SDL_GL_SetSwapInterval(1); + } - // Check if adaptive vsync was requested but not supported, and fall back - // to regular vsync if so. - if (vsync == -1 && SDL_GL_GetSwapInterval() != -1) - SDL_GL_SetSwapInterval(1); +#if defined(LOVE_GRAPHICS_METAL) && defined(LOVE_MACOS) + if (metalView != nullptr) + { + void *metallayer = SDL_Metal_GetLayer(metalView); + love::macos::setMetalLayerVSync(metallayer, vsync != 0); + } +#endif } int Window::getVSync() const { - return glcontext != nullptr ? SDL_GL_GetSwapInterval() : 0; + if (glcontext != nullptr) + return SDL_GL_GetSwapInterval(); + +#if defined(LOVE_GRAPHICS_METAL) + if (metalView != nullptr) + { +#ifdef LOVE_MACOS + void *metallayer = SDL_Metal_GetLayer(metalView); + return love::macos::getMetalLayerVSync(metallayer) ? 1 : 0; +#else + return 1; +#endif + } +#endif + + return 0; } void Window::setDisplaySleepEnabled(bool enable)