diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp index 196f4075..7a0363ca 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp @@ -29,7 +29,9 @@ namespace skyline::gpu { presentationTrack{static_cast(trace::TrackIds::Presentation), perfetto::ProcessTrack::Current()}, vsyncEvent{std::make_shared(state, true)}, choreographerThread{&PresentationEngine::ChoreographerThread, this}, - presentationThread{&PresentationEngine::PresentationThread, this} { + presentationThread{&PresentationEngine::PresentationThread, this}, + forceTripleBuffering{*state.settings->forceTripleBuffering}, + disableFrameThrottling{*state.settings->disableFrameThrottling} { auto desc{presentationTrack.Serialize()}; desc.set_name("Presentation"); perfetto::TrackEvent::SetTrackDescriptor(presentationTrack, desc); @@ -203,7 +205,7 @@ namespace skyline::gpu { }); // We don't care about suboptimal images as they are caused by not respecting the transform hint, we handle transformations externally } - timestamp = (timestamp && !*state.settings->disableFrameThrottling) ? timestamp : getMonotonicNsNow(); // We tie FPS to the submission time rather than presentation timestamp, if we don't have the presentation timestamp available or if frame throttling is disabled as we want the maximum measured FPS to not be restricted to the refresh rate + timestamp = (timestamp && !disableFrameThrottling) ? timestamp : getMonotonicNsNow(); // We tie FPS to the submission time rather than presentation timestamp, if we don't have the presentation timestamp available or if frame throttling is disabled as we want the maximum measured FPS to not be restricted to the refresh rate if (frameTimestamp) { i64 sampleWeight{Fps ? Fps : 1}; //!< The weight of each sample in calculating the average, we want to roughly average the past second @@ -281,7 +283,7 @@ namespace skyline::gpu { } void PresentationEngine::UpdateSwapchain(texture::Format format, texture::Dimensions extent) { - auto minImageCount{std::max(vkSurfaceCapabilities.minImageCount, *state.settings->forceTripleBuffering ? 3U : 2U)}; + auto minImageCount{std::max(vkSurfaceCapabilities.minImageCount, forceTripleBuffering ? 3U : 2U)}; if (minImageCount > MaxSwapchainImageCount) throw exception("Requesting swapchain with higher image count ({}) than maximum slot count ({})", minImageCount, MaxSwapchainImageCount); @@ -305,7 +307,7 @@ namespace skyline::gpu { if ((capabilities.supportedUsageFlags & presentUsage) != presentUsage) throw exception("Swapchain doesn't support image usage '{}': {}", vk::to_string(presentUsage), vk::to_string(capabilities.supportedUsageFlags)); - auto requestedMode{*state.settings->disableFrameThrottling ? vk::PresentModeKHR::eMailbox : vk::PresentModeKHR::eFifo}; + auto requestedMode{disableFrameThrottling ? vk::PresentModeKHR::eMailbox : vk::PresentModeKHR::eFifo}; auto modes{gpu.vkPhysicalDevice.getSurfacePresentModesKHR(**vkSurface)}; if (std::find(modes.begin(), modes.end(), requestedMode) == modes.end()) throw exception("Swapchain doesn't support present mode: {}", vk::to_string(requestedMode)); @@ -342,9 +344,11 @@ namespace skyline::gpu { swapchainImageCount = vkImages.size(); } - void PresentationEngine::OnDisableFrameThrottlingChanged(const bool &value) { + void PresentationEngine::OnDisableFrameThrottlingChanged(const bool value) { std::scoped_lock guard{mutex}; + disableFrameThrottling = value; + if (vkSurface && swapchainExtent && swapchainFormat) UpdateSwapchain(swapchainFormat, swapchainExtent); } diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.h b/app/src/main/cpp/skyline/gpu/presentation_engine.h index 19ac6bc2..16f56f09 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.h +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.h @@ -46,6 +46,9 @@ namespace skyline::gpu { size_t frameIndex{}; //!< The index of the next semaphore/fence to be used for acquiring swapchain images size_t swapchainImageCount{}; //!< The number of images in the current swapchain + bool forceTripleBuffering{}; //!< If the presentation engine should always triple buffer even if the swapchain supports double buffering + bool disableFrameThrottling{}; //!< Allow the guest to submit frames without any blocking calls + i64 frameTimestamp{}; //!< The timestamp of the last frame being shown in nanoseconds i64 averageFrametimeNs{}; //!< The average time between frames in nanoseconds i64 averageFrametimeDeviationNs{}; //!< The average deviation of frametimes in nanoseconds @@ -108,7 +111,7 @@ namespace skyline::gpu { /** * @brief Handles DisableFrameThrottling setting changed event */ - void OnDisableFrameThrottlingChanged(const bool &value); + void OnDisableFrameThrottlingChanged(const bool value); public: PresentationEngine(const DeviceState &state, GPU &gpu);