[TEST] Set on fps limiters with adfp

This commit is contained in:
CamilleLaVey
2026-08-06 02:42:53 -04:00
committed by crueter
parent ad854018df
commit 8476fbfcfe
5 changed files with 47 additions and 26 deletions
+17 -20
View File
@@ -101,8 +101,10 @@ struct SessionState {
std::mutex g_mutex;
std::array<SessionState, 2> g_sessions;
constexpr s64 MAX_REPORTED_TARGETS = 4;
std::atomic<s64> g_target_ns{DEFAULT_TARGET.count()};
thread_local std::chrono::steady_clock::time_point t_work_begin{};
thread_local std::chrono::steady_clock::time_point t_last_frame{};
SessionState& StateOf(Session session) {
return g_sessions[static_cast<size_t>(session)];
@@ -119,8 +121,6 @@ void CloseLocked(SessionState& state) {
}
}
// Builds a session for the given thread list without touching any existing one, so a refusal
// costs nothing.
AHintSession* CreateSessionFor(Session session, const std::vector<pid_t>& threads) {
const Api& api = Resolve();
const s64 target = session == Session::Render ? g_target_ns.load(std::memory_order_relaxed) : 0;
@@ -213,8 +213,6 @@ bool AddCurrentThread(Session session) {
state.threads.push_back(tid);
}
if (!SyncLocked(session, state)) {
// The session in use survived the refusal and still holds the list without this thread,
// so only the addition has to be undone.
if (added) {
std::erase(state.threads, tid);
}
@@ -252,26 +250,27 @@ void SetTargetWorkDuration(std::chrono::nanoseconds target) {
}
}
void BeginFrameWork() {
if (!Resolve().usable) {
return;
}
t_work_begin = std::chrono::steady_clock::now();
}
void EndFrameWork() {
void ReportFrameInterval() {
const Api& api = Resolve();
if (!api.usable || t_work_begin.time_since_epoch().count() == 0) {
if (!api.usable) {
return;
}
const auto elapsed = std::chrono::steady_clock::now() - t_work_begin;
t_work_begin = {};
const s64 actual = std::chrono::duration_cast<std::chrono::nanoseconds>(elapsed).count();
const auto now = std::chrono::steady_clock::now();
const auto previous = t_last_frame;
t_last_frame = now;
if (previous.time_since_epoch().count() == 0) {
return;
}
s64 actual = std::chrono::duration_cast<std::chrono::nanoseconds>(now - previous).count();
if (actual <= 0) {
return;
}
const s64 ceiling = g_target_ns.load(std::memory_order_relaxed) * MAX_REPORTED_TARGETS;
actual = (std::min)(actual, ceiling);
std::scoped_lock lock{g_mutex};
SessionState& state = StateOf(Session::Render);
if (state.handle != nullptr) {
@@ -309,9 +308,7 @@ void RemoveCurrentThread() {}
void SetTargetWorkDuration(std::chrono::nanoseconds) {}
void BeginFrameWork() {}
void EndFrameWork() {}
void ReportFrameInterval() {}
void Shutdown() {}
+2 -2
View File
@@ -18,8 +18,8 @@ bool AddCurrentThread(Session session);
void RemoveCurrentThread();
void SetTargetWorkDuration(std::chrono::nanoseconds target);
void BeginFrameWork();
void EndFrameWork();
void ReportFrameInterval();
void Shutdown();
@@ -87,7 +87,7 @@ void nvdisp_disp0::Composite(std::span<const Nvnflinger::HwcLayer> sorted_layers
}
system.GPU().RequestComposite(std::move(output_layers), std::move(output_fences));
Common::ADPF::EndFrameWork();
Common::ADPF::ReportFrameInterval();
system.SpeedLimiter().DoSpeedLimiting(system.CoreTiming().GetGlobalTimeUs());
system.GetPerfStats().EndSystemFrame();
system.GetPerfStats().BeginSystemFrame();
+26 -3
View File
@@ -4,6 +4,8 @@
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include "common/adpf.h"
#include "common/settings.h"
#include "common/thread.h"
@@ -16,6 +18,8 @@
constexpr auto FrameNs = std::chrono::nanoseconds{1000000000 / 60};
constexpr s64 UNLOCKED_TARGET_DIVISOR = 4;
namespace Service::VI {
Conductor::Conductor(Core::System& system, Container& container, DisplayList& displays)
@@ -70,10 +74,8 @@ void Conductor::UnlinkVsyncEvent(u64 display_id, Event* event) {
}
void Conductor::ProcessVsync() {
Common::ADPF::BeginFrameWork();
Common::PollThreadPolicies();
Common::ADPF::SetTargetWorkDuration(std::chrono::nanoseconds{this->GetNextTicks()});
Common::ADPF::SetTargetWorkDuration(std::chrono::nanoseconds{this->GetFramePeriodNs()});
for (auto& [display_id, manager] : m_vsync_managers) {
m_container.ComposeOnDisplay(&m_swap_interval, &m_compose_speed_scale, display_id);
@@ -123,4 +125,25 @@ s64 Conductor::GetNextTicks() const {
return static_cast<s64>(speed_scale * (1000000000.f / effective_fps));
}
s64 Conductor::GetFramePeriodNs() const {
const auto& settings = Settings::values;
f32 speed_scale = 1.f;
bool unlocked = false;
if (settings.use_multi_core.GetValue()) {
if (settings.use_speed_limit.GetValue()) {
speed_scale = 100.f / Settings::SpeedLimit();
} else {
unlocked = true;
}
}
speed_scale /= m_compose_speed_scale;
const f32 effective_fps = 60.f / static_cast<f32>(m_swap_interval);
s64 period = static_cast<s64>(speed_scale * (1000000000.f / effective_fps));
if (unlocked) {
period /= UNLOCKED_TARGET_DIVISOR;
}
return std::clamp<s64>(period, 1'000'000, 100'000'000);
}
} // namespace Service::VI
+1
View File
@@ -44,6 +44,7 @@ private:
void ProcessVsync();
void VsyncThread(std::stop_token token);
s64 GetNextTicks() const;
s64 GetFramePeriodNs() const;
private:
Core::System& m_system;