Browse Source

[android] Replaced FramePacingMode path + Surface/EmuWindow added hints for FrameRate

vkexperiments1
CamilleLaVey 5 days ago
parent
commit
daf972b517
  1. 9
      src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
  2. 1
      src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
  3. 67
      src/android/app/src/main/jni/emu_window/emu_window.cpp
  4. 4
      src/android/app/src/main/jni/emu_window/emu_window.h
  5. 4
      src/video_core/renderer_vulkan/vk_swapchain.cpp

9
src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt

@ -647,15 +647,6 @@ abstract class SettingsItem(
valuesId = R.array.dmaAccuracyValues
)
)
put(
SingleChoiceSetting(
IntSetting.FRAME_PACING_MODE,
titleId = R.string.frame_pacing_mode,
descriptionId = R.string.frame_pacing_mode_description,
choicesId = R.array.framePacingModeNames,
valuesId = R.array.framePacingModeValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS,

1
src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt

@ -267,7 +267,6 @@ class SettingsFragmentPresenter(
add(IntSetting.RENDERER_ACCURACY.key)
add(IntSetting.DMA_ACCURACY.key)
add(IntSetting.FRAME_PACING_MODE.key)
add(IntSetting.MAX_ANISOTROPY.key)
add(IntSetting.RENDERER_VRAM_USAGE_MODE.key)
add(IntSetting.RENDERER_ASTC_DECODE_METHOD.key)

67
src/android/app/src/main/jni/emu_window/emu_window.cpp

@ -6,8 +6,14 @@
#include <android/native_window_jni.h>
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <dlfcn.h>
#include "common/android/id_cache.h"
#include "common/logging/log.h"
#include "common/settings.h"
#include "input_common/drivers/android.h"
#include "input_common/drivers/touch_screen.h"
#include "input_common/drivers/virtual_amiibo.h"
@ -22,6 +28,7 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
m_window_width = 0;
m_window_height = 0;
window_info.render_surface = nullptr;
m_last_frame_rate_hint = -1.0f;
return;
}
@ -32,6 +39,7 @@ void EmuWindow_Android::OnSurfaceChanged(ANativeWindow* surface) {
UpdateCurrentFramebufferLayout(m_window_width, m_window_height);
window_info.render_surface = reinterpret_cast<void*>(surface);
UpdateFrameRateHint();
}
void EmuWindow_Android::OnTouchPressed(int id, float x, float y) {
@ -51,6 +59,8 @@ void EmuWindow_Android::OnTouchReleased(int id) {
}
void EmuWindow_Android::OnFrameDisplayed() {
UpdateFrameRateHint();
if (!m_first_frame) {
Common::Android::RunJNIOnFiber<void>(
[&](JNIEnv* env) { EmulationSession::GetInstance().OnEmulationStarted(); });
@ -58,6 +68,63 @@ void EmuWindow_Android::OnFrameDisplayed() {
}
}
float EmuWindow_Android::GetFrameRateHint() const {
if (!Settings::values.use_speed_limit.GetValue()) {
return 0.0f;
}
const u16 speed_limit = Settings::SpeedLimit();
if (speed_limit == 0) {
return 0.0f;
}
if (speed_limit > 100) {
return 0.0f;
}
constexpr float NominalFrameRate = 60.0f;
const float desired_rate = NominalFrameRate * (static_cast<float>(speed_limit) / 100.0f);
if (desired_rate < 20.0f) {
return 0.0f;
}
return desired_rate;
}
void EmuWindow_Android::UpdateFrameRateHint() {
auto* const surface = reinterpret_cast<ANativeWindow*>(window_info.render_surface);
if (!surface) {
return;
}
const float frame_rate_hint = GetFrameRateHint();
if (std::fabs(frame_rate_hint - m_last_frame_rate_hint) < 0.01f) {
return;
}
using SetFrameRateWithChangeStrategyFn =
int32_t (*)(ANativeWindow*, float, int8_t, int8_t);
static const auto set_frame_rate_with_change_strategy =
reinterpret_cast<SetFrameRateWithChangeStrategyFn>(
dlsym(RTLD_DEFAULT, "ANativeWindow_setFrameRateWithChangeStrategy"));
if (!set_frame_rate_with_change_strategy) {
return;
}
const auto result = set_frame_rate_with_change_strategy(
surface, frame_rate_hint,
static_cast<int8_t>(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
static_cast<int8_t>(ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS));
if (result != 0) {
LOG_DEBUG(Frontend, "Failed to update Android surface frame rate hint: {}", result);
return;
}
m_last_frame_rate_hint = frame_rate_hint;
}
EmuWindow_Android::EmuWindow_Android(ANativeWindow* surface,
std::shared_ptr<Common::DynamicLibrary> driver_library)
: m_driver_library{driver_library} {

4
src/android/app/src/main/jni/emu_window/emu_window.h

@ -50,10 +50,14 @@ public:
};
private:
void UpdateFrameRateHint();
[[nodiscard]] float GetFrameRateHint() const;
float m_window_width{};
float m_window_height{};
std::shared_ptr<Common::DynamicLibrary> m_driver_library;
bool m_first_frame = false;
float m_last_frame_rate_hint = -1.0f;
};

4
src/video_core/renderer_vulkan/vk_swapchain.cpp

@ -170,6 +170,9 @@ bool Swapchain::AcquireNextImage() {
break;
}
#ifdef __ANDROID__
scheduler.Wait(resource_ticks[image_index]);
#else
switch (Settings::values.frame_pacing_mode.GetValue()) {
case Settings::FramePacingMode::Target_Auto:
scheduler.Wait(resource_ticks[image_index]);
@ -187,6 +190,7 @@ bool Swapchain::AcquireNextImage() {
scheduler.Wait(resource_ticks[image_index], 120.0);
break;
}
#endif
resource_ticks[image_index] = scheduler.CurrentTick();

Loading…
Cancel
Save