From 59384de7773eb09b2c131debfc54c1975ab124c1 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Thu, 13 Aug 2026 20:42:49 -0400 Subject: [PATCH] Revert the Auto policy --- .../java/org/yuzu/yuzu_emu/NativeLibrary.kt | 6 -- .../yuzu_emu/activities/EmulationActivity.kt | 6 -- .../src/main/jni/emu_window/emu_window.cpp | 61 +------------------ .../app/src/main/jni/emu_window/emu_window.h | 4 -- src/android/app/src/main/jni/native.cpp | 5 -- .../app/src/main/res/values/arrays.xml | 2 - .../app/src/main/res/values/strings.xml | 3 +- src/common/settings.cpp | 29 +-------- src/common/settings.h | 10 +-- .../renderer_vulkan/present/frame_gen.cpp | 6 +- .../renderer_vulkan/vk_present_manager.cpp | 4 +- 11 files changed, 12 insertions(+), 124 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt index 9ac0cace2d..4610574f21 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt @@ -222,12 +222,6 @@ object NativeLibrary { external fun getDebugKnobAt(index: Int): Boolean - /** - * Publishes the refresh rate of the display the emulation surface lives on, in hertz. - * Frame generation uses it to cap the multiplier to what the display can actually present. - */ - external fun setDisplayRefreshRate(rate: Float) - /** * Set the current speed limit to the configured turbo speed. */ diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index 4575c4201f..716bdfeb7e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -245,7 +245,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager override fun onResume() { super.onResume() - publishDisplayRefreshRate() nfcReader.startScanning() startMotionSensorListener() InputHandler.updateControllerData() @@ -254,11 +253,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager buildPictureInPictureParams() } - private fun publishDisplayRefreshRate() { - val rate = display?.mode?.refreshRate ?: display?.refreshRate ?: 0f - NativeLibrary.setDisplayRefreshRate(rate) - } - override fun onPause() { nfcReader.stopScanning() stopMotionSensorListener() diff --git a/src/android/app/src/main/jni/emu_window/emu_window.cpp b/src/android/app/src/main/jni/emu_window/emu_window.cpp index d2020ce98d..8dfea40693 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.cpp +++ b/src/android/app/src/main/jni/emu_window/emu_window.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include "common/android/id_cache.h" @@ -34,12 +33,8 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) { m_pending_frame_rate_hint = -1.0f; m_pending_frame_rate_hint_votes = 0; m_smoothed_present_rate = 0.0f; - m_peak_guest_frame_rate = 0.0f; - m_published_guest_frame_rate = 0.0f; - Settings::values.guest_frame_rate = 0.0f; m_last_frame_display_time = {}; m_pending_frame_rate_since = {}; - m_guest_frame_rate_since = {}; return; } @@ -69,28 +64,8 @@ void EmuWindow_Android::OnTouchReleased(int id) { EmulationSession::GetInstance().GetInputSubsystem().GetTouchScreen()->TouchReleased(id); } -namespace { - -constexpr std::array GUEST_FRAME_RATE_LADDER{20.0f, 30.0f, 60.0f}; - -[[nodiscard]] float SnapToGuestFrameRateLadder(float rate) { - float snapped = GUEST_FRAME_RATE_LADDER.front(); - float best_distance = std::numeric_limits::max(); - for (const float step : GUEST_FRAME_RATE_LADDER) { - const float distance = std::fabs(step - rate); - if (distance <= best_distance) { - best_distance = distance; - snapped = step; - } - } - return snapped; -} - -} // Anonymous namespace - void EmuWindow_Android::OnFrameDisplayed() { UpdateObservedFrameRate(); - UpdateGuestFrameRate(); UpdateFrameRateHint(); if (!m_first_frame) { @@ -122,40 +97,6 @@ void EmuWindow_Android::UpdateObservedFrameRate() { m_last_frame_display_time = now; } -void EmuWindow_Android::UpdateGuestFrameRate() { - const float measured = GetFrameTimeVerifiedHint(); - if (measured <= 0.0f) { - return; - } - - constexpr float PeakDecayFactor = 0.0015f; - m_peak_guest_frame_rate = - measured > m_peak_guest_frame_rate - ? measured - : m_peak_guest_frame_rate + (measured - m_peak_guest_frame_rate) * PeakDecayFactor; - - const float candidate = SnapToGuestFrameRateLadder(m_peak_guest_frame_rate); - if (candidate == m_published_guest_frame_rate) { - m_guest_frame_rate_since = {}; - return; - } - - const auto now = Clock::now(); - if (m_guest_frame_rate_since.time_since_epoch().count() == 0) { - m_guest_frame_rate_since = now; - return; - } - - constexpr auto SettleDuration = std::chrono::seconds(3); - if (now - m_guest_frame_rate_since < SettleDuration) { - return; - } - - m_published_guest_frame_rate = candidate; - Settings::values.guest_frame_rate = candidate; - m_guest_frame_rate_since = {}; -} - float EmuWindow_Android::QuantizeFrameRateHint(float frame_rate) { if (!std::isfinite(frame_rate) || frame_rate <= 0.0f) { return 0.0f; @@ -187,7 +128,7 @@ float EmuWindow_Android::GetPresentedFrameMultiplier() { if (!Settings::values.frame_gen.GetValue()) { return 1.0f; } - return static_cast(Settings::FrameGenMultiplier()); + return static_cast(std::clamp(Settings::values.frame_gen_multiplier.GetValue(), 2, 4)); } float EmuWindow_Android::GetFrameRateHint() const { diff --git a/src/android/app/src/main/jni/emu_window/emu_window.h b/src/android/app/src/main/jni/emu_window/emu_window.h index 33b8f9ba83..fca83b91fa 100644 --- a/src/android/app/src/main/jni/emu_window/emu_window.h +++ b/src/android/app/src/main/jni/emu_window/emu_window.h @@ -59,7 +59,6 @@ private: void UpdateFrameRateHint(); void UpdateObservedFrameRate(); - void UpdateGuestFrameRate(); [[nodiscard]] float GetFrameRateHint() const; [[nodiscard]] float GetFrameTimeVerifiedHint() const; [[nodiscard]] static float GetPresentedFrameMultiplier(); @@ -74,10 +73,7 @@ private: float m_last_frame_rate_hint = -1.0f; float m_pending_frame_rate_hint = -1.0f; float m_smoothed_present_rate = 0.0f; - float m_peak_guest_frame_rate = 0.0f; - float m_published_guest_frame_rate = 0.0f; Clock::time_point m_last_frame_display_time{}; Clock::time_point m_pending_frame_rate_since{}; - Clock::time_point m_guest_frame_rate_since{}; std::uint32_t m_pending_frame_rate_hint_votes = 0; }; diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index 80b2991722..7173ccddd0 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -1229,11 +1229,6 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_getDebugKnobAt(JNIEnv* env, jobje return static_cast(Settings::getDebugKnobAt(static_cast(index))); } -void Java_org_yuzu_yuzu_1emu_NativeLibrary_setDisplayRefreshRate(JNIEnv* env, jobject jobj, - jfloat rate) { - Settings::values.display_refresh_rate = static_cast(rate); -} - void Java_org_yuzu_yuzu_1emu_NativeLibrary_setTurboSpeedLimit(JNIEnv *env, jobject jobj, jboolean enabled) { if (enabled) { Settings::values.use_speed_limit.SetValue(true); diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index d63435331d..d8ae109e97 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -163,14 +163,12 @@ - @string/frame_gen_multiplier_auto @string/frame_gen_multiplier_2x @string/frame_gen_multiplier_3x @string/frame_gen_multiplier_4x - 0 2 3 4 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index b1ba713f55..62e2f2eee5 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -302,8 +302,7 @@ Manage and configure frame generation Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled. Frame multiplier - How many frames to display for each rendered frame. Higher values cost proportionally more GPU time. Capped to what your display can present at the game\'s frame rate. - Auto + How many frames to display for each rendered frame. Higher values cost proportionally more GPU time. Asking for more than your display can present will slow emulation down. 2x 3x 4x diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 71fc0112d6..1f747c44b1 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -380,34 +380,9 @@ void UpdateRescalingInfo() { TranslateResolutionInfo(setup, info); } -u32 FrameGenMultiplierCeiling() { - const u32 configured = values.frame_gen_multiplier.GetValue(); - if (configured == AUTO_FRAME_GEN_MULTIPLIER) { - return MAX_FRAME_GEN_MULTIPLIER; - } - return std::clamp(configured, MIN_FRAME_GEN_MULTIPLIER, MAX_FRAME_GEN_MULTIPLIER); -} - u32 FrameGenMultiplier() { - const u32 ceiling = FrameGenMultiplierCeiling(); - - const float refresh = values.display_refresh_rate; - if (refresh <= 1.0f) { - return ceiling; - } - - constexpr float UNMEASURED_GUEST_FRAME_RATE = 60.0f; - float base = values.guest_frame_rate > 1.0f ? values.guest_frame_rate - : UNMEASURED_GUEST_FRAME_RATE; - if (values.use_speed_limit.GetValue()) { - const u16 limit = std::min(SpeedLimit(), 100); - if (limit > 0) { - base *= static_cast(limit) / 100.0f; - } - } - - const u32 presentable = static_cast(refresh / std::max(base, 1.0f)); - return std::min(ceiling, std::max(presentable, 1u)); + return std::clamp(values.frame_gen_multiplier.GetValue(), MIN_FRAME_GEN_MULTIPLIER, + MAX_FRAME_GEN_MULTIPLIER); } size_t FrameGenGenerations() { diff --git a/src/common/settings.h b/src/common/settings.h index 8513d5e8ea..b413cab9e4 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -392,8 +392,8 @@ struct Values { Specialization::Default, true, false}; SwitchableSetting frame_gen_multiplier{linkage, - 0, - 0, + 2, + 2, 4, "frame_gen_multiplier", Category::Renderer, @@ -914,19 +914,13 @@ struct Values { // Per-game overrides bool use_squashed_iterated_blend; - // Rates published by the frontend, in hertz. Zero means not measured yet. - float display_refresh_rate; - float guest_frame_rate; }; extern Values values; -constexpr u32 AUTO_FRAME_GEN_MULTIPLIER = 0; constexpr u32 MIN_FRAME_GEN_MULTIPLIER = 2; constexpr u32 MAX_FRAME_GEN_MULTIPLIER = 4; -[[nodiscard]] u32 FrameGenMultiplierCeiling(); - [[nodiscard]] u32 FrameGenMultiplier(); [[nodiscard]] size_t FrameGenGenerations(); diff --git a/src/video_core/renderer_vulkan/present/frame_gen.cpp b/src/video_core/renderer_vulkan/present/frame_gen.cpp index 76d9834b1b..3dfc34f282 100644 --- a/src/video_core/renderer_vulkan/present/frame_gen.cpp +++ b/src/video_core/renderer_vulkan/present/frame_gen.cpp @@ -183,7 +183,11 @@ FrameGen::~FrameGen() = default; void FrameGen::Process(const Device& device, Frame* frame, VkFormat format, bool generate) { generated = false; - if (unavailable || !Settings::values.frame_gen.GetValue()) { + if (unavailable || ConfiguredGenerations() == 0) { + if (chain) { + scheduler.Finish(); + chain.reset(); + } return; } diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index a5f08698f8..8924241562 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -351,9 +351,7 @@ void PresentManager::SetImageCount() { // We cannot have more than 7 images in flight at any given time. // FRAMES_IN_FLIGHT is 8, and the cache TICKS_TO_DESTROY is 8. // Mali drivers will give us 6. - const size_t generations = Settings::values.frame_gen.GetValue() - ? Settings::FrameGenMultiplierCeiling() - 1 - : 0; + const size_t generations = Settings::FrameGenGenerations(); const size_t queued_composites = Settings::values.frame_gen_queue_target.GetValue() + 1; image_count = std::clamp((generations + 1) * queued_composites, swapchain.GetImageCount(),