diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/result.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/audio/audout_u.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | 7 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 42 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.h | 5 |
6 files changed, 41 insertions, 22 deletions
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 4de44cd06..47a1b829b 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -117,6 +117,7 @@ union Result { BitField<0, 9, ErrorModule> module; BitField<9, 13, u32> description; + Result() = default; constexpr explicit Result(u32 raw_) : raw(raw_) {} constexpr Result(ErrorModule module_, u32 description_) @@ -130,6 +131,7 @@ union Result { return !IsSuccess(); } }; +static_assert(std::is_trivial_v<Result>); [[nodiscard]] constexpr bool operator==(const Result& a, const Result& b) { return a.raw == b.raw; diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index a44dd842a..49c092301 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -246,9 +246,8 @@ void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) { const auto write_count = static_cast<u32>(ctx.GetWriteBufferSize() / sizeof(AudioDevice::AudioDeviceName)); std::vector<AudioDevice::AudioDeviceName> device_names{}; - std::string print_names{}; if (write_count > 0) { - device_names.push_back(AudioDevice::AudioDeviceName("DeviceOut")); + device_names.emplace_back("DeviceOut"); LOG_DEBUG(Service_Audio, "called. \nName=DeviceOut"); } else { LOG_DEBUG(Service_Audio, "called. Empty buffer passed in."); diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index bc69117c6..6fb07c37d 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -252,7 +252,7 @@ private: std::vector<AudioDevice::AudioDeviceName> out_names{}; - u32 out_count = impl->ListAudioDeviceName(out_names, in_count); + const u32 out_count = impl->ListAudioDeviceName(out_names, in_count); std::string out{}; for (u32 i = 0; i < out_count; i++) { @@ -365,7 +365,7 @@ private: std::vector<AudioDevice::AudioDeviceName> out_names{}; - u32 out_count = impl->ListAudioOutputDeviceName(out_names, in_count); + const u32 out_count = impl->ListAudioOutputDeviceName(out_names, in_count); std::string out{}; for (u32 i = 0; i < out_count; i++) { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 2a5128c60..a7385fce8 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "audio_core/audio_core.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" @@ -65,7 +66,10 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& return NvResult::NotImplemented; } -void nvhost_nvdec::OnOpen(DeviceFD fd) {} +void nvhost_nvdec::OnOpen(DeviceFD fd) { + LOG_INFO(Service_NVDRV, "NVDEC video stream started"); + system.AudioCore().SetNVDECActive(true); +} void nvhost_nvdec::OnClose(DeviceFD fd) { LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); @@ -73,6 +77,7 @@ void nvhost_nvdec::OnClose(DeviceFD fd) { if (iter != fd_to_id.end()) { system.GPU().ClearCdmaInstance(iter->second); } + system.AudioCore().SetNVDECActive(false); } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 5574269eb..9b382bf56 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -38,20 +38,16 @@ void NVFlinger::SplitVSync(std::stop_token stop_token) { Common::SetCurrentThreadName(name.c_str()); Common::SetCurrentThreadPriority(Common::ThreadPriority::High); - s64 delay = 0; + while (!stop_token.stop_requested()) { + vsync_signal.wait(false); + vsync_signal.store(false); + guard->lock(); - const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count(); + Compose(); - const auto ticks = GetNextTicks(); - const s64 time_end = system.CoreTiming().GetGlobalTimeNs().count(); - const s64 time_passed = time_end - time_start; - const s64 next_time = std::max<s64>(0, ticks - time_passed - delay); + guard->unlock(); - if (next_time > 0) { - std::this_thread::sleep_for(std::chrono::nanoseconds{next_time}); - } - delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time; } } @@ -66,27 +62,41 @@ NVFlinger::NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_dr guard = std::make_shared<std::mutex>(); // Schedule the screen composition events - composition_event = Core::Timing::CreateEvent( + multi_composition_event = Core::Timing::CreateEvent( + "ScreenComposition", + [this](std::uintptr_t, s64 time, + std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { + vsync_signal.store(true); + vsync_signal.notify_all(); + return std::chrono::nanoseconds(GetNextTicks()); + }); + + single_composition_event = Core::Timing::CreateEvent( "ScreenComposition", [this](std::uintptr_t, s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { const auto lock_guard = Lock(); Compose(); - return std::max(std::chrono::nanoseconds::zero(), - std::chrono::nanoseconds(GetNextTicks()) - ns_late); + return std::chrono::nanoseconds(GetNextTicks()); }); if (system.IsMulticore()) { + system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, multi_composition_event); vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); }); } else { - system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, composition_event); + system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, single_composition_event); } } NVFlinger::~NVFlinger() { - if (!system.IsMulticore()) { - system.CoreTiming().UnscheduleEvent(composition_event, 0); + if (system.IsMulticore()) { + system.CoreTiming().UnscheduleEvent(multi_composition_event, {}); + vsync_thread.request_stop(); + vsync_signal.store(true); + vsync_signal.notify_all(); + } else { + system.CoreTiming().UnscheduleEvent(single_composition_event, {}); } for (auto& display : displays) { diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 4775597cc..044ac6ac8 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -126,12 +126,15 @@ private: u32 swap_interval = 1; /// Event that handles screen composition. - std::shared_ptr<Core::Timing::EventType> composition_event; + std::shared_ptr<Core::Timing::EventType> multi_composition_event; + std::shared_ptr<Core::Timing::EventType> single_composition_event; std::shared_ptr<std::mutex> guard; Core::System& system; + std::atomic<bool> vsync_signal; + std::jthread vsync_thread; KernelHelpers::ServiceContext service_context; |