diff --git a/aurora-main/lib/dolphin/vi/vi.cpp b/aurora-main/lib/dolphin/vi/vi.cpp index d036b86..37f49d6 100644 --- a/aurora-main/lib/dolphin/vi/vi.cpp +++ b/aurora-main/lib/dolphin/vi/vi.cpp @@ -7,11 +7,13 @@ #include #include #include +#include namespace aurora::vi { std::optional g_renderMode; namespace { std::atomic g_presentAspectCorrection{1.f}; +std::mutex g_renderModeMutex; float calculate_present_aspect_correction(const GXRenderModeObj& rm) noexcept { if (rm.viWidth == 0 || rm.viHeight == 0) { @@ -29,9 +31,8 @@ float calculate_present_aspect_correction(const GXRenderModeObj& rm) noexcept { const float verticalFill = static_cast(rm.viHeight) / nominalActiveHeight; return horizontalFill / verticalFill; } -} // namespace -Vec2 render_mode_size() noexcept { +Vec2 render_mode_size_locked() noexcept { if (!g_renderMode) { return {640, 528}; } @@ -40,18 +41,31 @@ Vec2 render_mode_size() noexcept { return {std::max(g_renderMode->fbWidth, 640), std::max(g_renderMode->efbHeight, 528)}; } +} // namespace + +Vec2 render_mode_size() noexcept { + std::lock_guard lock(g_renderModeMutex); + return render_mode_size_locked(); +} + void configure(const GXRenderModeObj* rm) noexcept { - const auto oldSize = render_mode_size(); - if (rm == nullptr) { - g_renderMode.reset(); - } else { - g_renderMode = *rm; - g_presentAspectCorrection.store(calculate_present_aspect_correction(*rm), std::memory_order_release); + bool sizeChanged = false; + { + std::lock_guard lock(g_renderModeMutex); + const auto oldSize = render_mode_size_locked(); + if (rm == nullptr) { + g_renderMode.reset(); + } else { + g_renderMode = *rm; + g_presentAspectCorrection.store(calculate_present_aspect_correction(*rm), std::memory_order_release); + } + if (rm == nullptr) { + g_presentAspectCorrection.store(1.f, std::memory_order_release); + } + sizeChanged = render_mode_size_locked() != oldSize; } - if (rm == nullptr) { - g_presentAspectCorrection.store(1.f, std::memory_order_release); - } - if (render_mode_size() != oldSize) { + // Never hold the mode lock across a resize request or a renderer callback. + if (sizeChanged) { window::request_frame_buffer_resize(); } } @@ -61,6 +75,7 @@ Vec2 configured_fb_size() noexcept { } Vec2 visible_fb_size() noexcept { + std::lock_guard lock(g_renderModeMutex); if (!g_renderMode) { return {640, 528}; }