summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/nvflinger/nvflinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 2b2985a2d..5574269eb 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -67,21 +67,20 @@ NVFlinger::NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_dr
// Schedule the screen composition events
composition_event = Core::Timing::CreateEvent(
- "ScreenComposition", [this](std::uintptr_t, std::chrono::nanoseconds ns_late) {
+ "ScreenComposition",
+ [this](std::uintptr_t, s64 time,
+ std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto lock_guard = Lock();
Compose();
- const auto ticks = std::chrono::nanoseconds{GetNextTicks()};
- const auto ticks_delta = ticks - ns_late;
- const auto future_ns = std::max(std::chrono::nanoseconds::zero(), ticks_delta);
-
- this->system.CoreTiming().ScheduleEvent(future_ns, composition_event);
+ return std::max(std::chrono::nanoseconds::zero(),
+ std::chrono::nanoseconds(GetNextTicks()) - ns_late);
});
if (system.IsMulticore()) {
vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
} else {
- system.CoreTiming().ScheduleEvent(frame_ns, composition_event);
+ system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, composition_event);
}
}
@@ -288,9 +287,21 @@ s64 NVFlinger::GetNextTicks() const {
static constexpr s64 max_hertz = 120LL;
const auto& settings = Settings::values;
- const bool unlocked_fps = settings.disable_fps_limit.GetValue();
- const s64 fps_cap = unlocked_fps ? static_cast<s64>(settings.fps_cap.GetValue()) : 1;
- return (1000000000 * (1LL << swap_interval)) / (max_hertz * fps_cap);
+ auto speed_scale = 1.f;
+ if (settings.use_multi_core.GetValue()) {
+ if (settings.use_speed_limit.GetValue()) {
+ // Scales the speed based on speed_limit setting on MC. SC is handled by
+ // SpeedLimiter::DoSpeedLimiting.
+ speed_scale = 100.f / settings.speed_limit.GetValue();
+ } else {
+ // Run at unlocked framerate.
+ speed_scale = 0.01f;
+ }
+ }
+
+ const auto next_ticks = ((1000000000 * (1LL << swap_interval)) / max_hertz);
+
+ return static_cast<s64>(speed_scale * static_cast<float>(next_ticks));
}
} // namespace Service::NVFlinger