video_core: Fixed occasional launch crash on certain platforms due to unsafe SDL_Init
Some checks failed
citra-build / source (push) Has been cancelled
citra-build / linux (appimage) (push) Has been cancelled
citra-build / linux (fresh) (push) Has been cancelled
citra-build / macos (arm64) (push) Has been cancelled
citra-build / macos (x86_64) (push) Has been cancelled
citra-build / windows (msvc) (push) Has been cancelled
citra-build / windows (msys2) (push) Has been cancelled
citra-build / android (push) Has been cancelled
citra-format / clang-format (push) Has been cancelled
citra-transifex / transifex (push) Has been cancelled
citra-build / macos-universal (push) Has been cancelled

This commit is contained in:
OpenSauce04 2025-10-27 18:46:24 +00:00 committed by OpenSauce
parent 67f6735f02
commit 375c8c1910
2 changed files with 38 additions and 27 deletions

View File

@ -61,31 +61,6 @@ constexpr static std::array<vk::DescriptorSetLayoutBinding, 1> PRESENT_BINDINGS
namespace {
static bool IsLowRefreshRate() {
#if defined(__APPLE__) || defined(ENABLE_SDL2)
#ifdef __APPLE__ // Need a special implementation because MacOS kills itself in disgust if the
// input thread calls SDL_PumpEvents at the same time as we're in SDL_Init here.
const auto cur_refresh_rate = AppleUtils::GetRefreshRate();
#elif defined(ENABLE_SDL2)
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
LOG_ERROR(Render_Vulkan, "SDL video failed to initialize, unable to check refresh rate");
return false;
}
SDL_DisplayMode cur_display_mode;
SDL_GetCurrentDisplayMode(0, &cur_display_mode); // TODO: Multimonitor handling. -OS
const auto cur_refresh_rate = cur_display_mode.refresh_rate;
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#endif // __APPLE__
if (cur_refresh_rate < SCREEN_REFRESH_RATE) {
LOG_WARNING(Render_Vulkan,
"Detected refresh rate lower than the emulated 3DS screen: {}hz. FIFO will "
"be disabled",
cur_refresh_rate);
return true;
}
#endif // defined(__APPLE__) || defined(ENABLE_SDL2)
#ifdef __APPLE__
// Apple's low power mode sometimes limits applications to 30fps without changing the refresh
// rate, meaning the above code doesn't catch it.
@ -94,8 +69,34 @@ static bool IsLowRefreshRate() {
"framerate. FIFO will be disabled");
return true;
}
#endif
const auto cur_refresh_rate = AppleUtils::GetRefreshRate();
#elif defined(ENABLE_SDL2)
if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
LOG_ERROR(Render_Vulkan, "Attempted to check refresh rate via SDL, but failed because "
"SDL_INIT_VIDEO wasn't initialized");
return false;
}
SDL_DisplayMode cur_display_mode;
SDL_GetCurrentDisplayMode(0, &cur_display_mode); // TODO: Multimonitor handling. -OS
const auto cur_refresh_rate = cur_display_mode.refresh_rate;
#endif // ENABLE_SDL2
if (cur_refresh_rate < SCREEN_REFRESH_RATE) {
LOG_WARNING(Render_Vulkan,
"Detected refresh rate lower than the emulated 3DS screen: {}hz. FIFO will "
"be disabled",
cur_refresh_rate);
return true;
} else {
LOG_INFO(Render_Vulkan, "Refresh rate is above emulated 3DS screen: {}hz. Good.",
cur_refresh_rate);
}
#endif // defined(__APPLE__) || defined(ENABLE_SDL2)
// We have no available method of checking refresh rate. Just assume that everything is fine :)
return false;
}
} // Anonymous namespace

View File

@ -1,4 +1,4 @@
// Copyright 2014 Citra Emulator Project
// Copyright Citra Emulator Project / Azahar Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -16,6 +16,10 @@
#endif
#include "video_core/video_core.h"
#ifdef ENABLE_SDL2
#include <SDL.h>
#endif
namespace VideoCore {
std::unique_ptr<RendererBase> CreateRenderer(Frontend::EmuWindow& emu_window,
@ -29,6 +33,12 @@ std::unique_ptr<RendererBase> CreateRenderer(Frontend::EmuWindow& emu_window,
#endif
#ifdef ENABLE_VULKAN
case Settings::GraphicsAPI::Vulkan:
#if defined(ENABLE_SDL2) && !defined(__APPLE__)
// TODO: When we migrate to SDL3, refactor so that we don't need to init here.
if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
SDL_Init(SDL_INIT_VIDEO);
}
#endif // ENABLE_SDL2
return std::make_unique<Vulkan::RendererVulkan>(system, pica, emu_window, secondary_window);
#endif
#ifdef ENABLE_OPENGL