diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 12 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 12 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.h | 2 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 4 | ||||
-rw-r--r-- | src/core/hle/service/service.h | 2 |
5 files changed, 25 insertions, 7 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index eed2dc9f3..fdc774e30 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -48,8 +48,8 @@ namespace Kernel { struct KernelCore::Impl { explicit Impl(Core::System& system_, KernelCore& kernel_) - : time_manager{system_}, - service_threads_manager{1, "ServiceThreadsManager"}, system{system_} {} + : time_manager{system_}, service_threads_manager{1, "ServiceThreadsManager"}, + service_thread_barrier{2}, system{system_} {} void SetMulticore(bool is_multi) { is_multicore = is_multi; @@ -737,7 +737,12 @@ struct KernelCore::Impl { } void ClearServiceThreads() { - service_threads_manager.QueueWork([this]() { service_threads.clear(); }); + service_threads_manager.QueueWork([this] { + service_threads.clear(); + default_service_thread.reset(); + service_thread_barrier.Sync(); + }); + service_thread_barrier.Sync(); } std::mutex server_objects_lock; @@ -802,6 +807,7 @@ struct KernelCore::Impl { std::unordered_set<std::shared_ptr<ServiceThread>> service_threads; std::weak_ptr<ServiceThread> default_service_thread; Common::ThreadWorker service_threads_manager; + Common::Barrier service_thread_barrier; std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index aa14d2cbc..dad93b38e 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -102,15 +102,19 @@ NVFlinger::~NVFlinger() { system.CoreTiming().UnscheduleEvent(single_composition_event, {}); } + ShutdownLayers(); + + if (nvdrv) { + nvdrv->Close(disp_fd); + } +} + +void NVFlinger::ShutdownLayers() { for (auto& display : displays) { for (size_t layer = 0; layer < display.GetNumLayers(); ++layer) { display.GetLayer(layer).Core().NotifyShutdown(); } } - - if (nvdrv) { - nvdrv->Close(disp_fd); - } } void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 99509bc5b..b8191c595 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -48,6 +48,8 @@ public: explicit NVFlinger(Core::System& system_, HosBinderDriverServer& hos_binder_driver_server_); ~NVFlinger(); + void ShutdownLayers(); + /// Sets the NVDrv module instance to use to send buffers to the GPU. void SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index dadaf897f..5db6588e4 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -303,4 +303,8 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system Services::~Services() = default; +void Services::KillNVNFlinger() { + nv_flinger->ShutdownLayers(); +} + } // namespace Service diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 5bf197c51..ec9deeee4 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -238,6 +238,8 @@ public: explicit Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system); ~Services(); + void KillNVNFlinger(); + private: std::unique_ptr<NVFlinger::HosBinderDriverServer> hos_binder_driver_server; std::unique_ptr<NVFlinger::NVFlinger> nv_flinger; |