summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp29
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h11
2 files changed, 8 insertions, 32 deletions
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 3ead813b0..a22811ec1 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -13,28 +13,20 @@
13#include "common/thread.h" 13#include "common/thread.h"
14#include "core/core.h" 14#include "core/core.h"
15#include "core/core_timing.h" 15#include "core/core_timing.h"
16#include "core/core_timing_util.h"
17#include "core/hardware_properties.h"
18#include "core/hle/kernel/k_readable_event.h" 16#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/kernel/kernel.h"
20#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 17#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
21#include "core/hle/service/nvdrv/nvdrv.h" 18#include "core/hle/service/nvdrv/nvdrv.h"
22#include "core/hle/service/nvflinger/buffer_queue.h" 19#include "core/hle/service/nvflinger/buffer_queue.h"
23#include "core/hle/service/nvflinger/nvflinger.h" 20#include "core/hle/service/nvflinger/nvflinger.h"
24#include "core/hle/service/vi/display/vi_display.h" 21#include "core/hle/service/vi/display/vi_display.h"
25#include "core/hle/service/vi/layer/vi_layer.h" 22#include "core/hle/service/vi/layer/vi_layer.h"
26#include "core/perf_stats.h" 23#include "video_core/gpu.h"
27#include "video_core/renderer_base.h"
28 24
29namespace Service::NVFlinger { 25namespace Service::NVFlinger {
30 26
31constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60}; 27constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
32 28
33void NVFlinger::VSyncThread(NVFlinger& nv_flinger) { 29void NVFlinger::SplitVSync(std::stop_token stop_token) {
34 nv_flinger.SplitVSync();
35}
36
37void NVFlinger::SplitVSync() {
38 system.RegisterHostThread(); 30 system.RegisterHostThread();
39 std::string name = "yuzu:VSyncThread"; 31 std::string name = "yuzu:VSyncThread";
40 MicroProfileOnThreadCreate(name.c_str()); 32 MicroProfileOnThreadCreate(name.c_str());
@@ -45,7 +37,7 @@ void NVFlinger::SplitVSync() {
45 Common::SetCurrentThreadName(name.c_str()); 37 Common::SetCurrentThreadName(name.c_str());
46 Common::SetCurrentThreadPriority(Common::ThreadPriority::High); 38 Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
47 s64 delay = 0; 39 s64 delay = 0;
48 while (is_running) { 40 while (!stop_token.stop_requested()) {
49 guard->lock(); 41 guard->lock();
50 const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count(); 42 const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count();
51 Compose(); 43 Compose();
@@ -55,7 +47,7 @@ void NVFlinger::SplitVSync() {
55 const s64 next_time = std::max<s64>(0, ticks - time_passed - delay); 47 const s64 next_time = std::max<s64>(0, ticks - time_passed - delay);
56 guard->unlock(); 48 guard->unlock();
57 if (next_time > 0) { 49 if (next_time > 0) {
58 wait_event->WaitFor(std::chrono::nanoseconds{next_time}); 50 std::this_thread::sleep_for(std::chrono::nanoseconds{next_time});
59 } 51 }
60 delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time; 52 delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time;
61 } 53 }
@@ -84,9 +76,7 @@ NVFlinger::NVFlinger(Core::System& system_)
84 }); 76 });
85 77
86 if (system.IsMulticore()) { 78 if (system.IsMulticore()) {
87 is_running = true; 79 vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
88 wait_event = std::make_unique<Common::Event>();
89 vsync_thread = std::make_unique<std::thread>(VSyncThread, std::ref(*this));
90 } else { 80 } else {
91 system.CoreTiming().ScheduleEvent(frame_ns, composition_event); 81 system.CoreTiming().ScheduleEvent(frame_ns, composition_event);
92 } 82 }
@@ -96,14 +86,7 @@ NVFlinger::~NVFlinger() {
96 for (auto& buffer_queue : buffer_queues) { 86 for (auto& buffer_queue : buffer_queues) {
97 buffer_queue->Disconnect(); 87 buffer_queue->Disconnect();
98 } 88 }
99 89 if (!system.IsMulticore()) {
100 if (system.IsMulticore()) {
101 is_running = false;
102 wait_event->Set();
103 vsync_thread->join();
104 vsync_thread.reset();
105 wait_event.reset();
106 } else {
107 system.CoreTiming().UnscheduleEvent(composition_event, 0); 90 system.CoreTiming().UnscheduleEvent(composition_event, 0);
108 } 91 }
109} 92}
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 6d84cafb4..7935cf773 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -4,13 +4,10 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <atomic>
8#include <list> 7#include <list>
9#include <memory> 8#include <memory>
10#include <mutex> 9#include <mutex>
11#include <optional> 10#include <optional>
12#include <string>
13#include <string_view>
14#include <thread> 11#include <thread>
15#include <vector> 12#include <vector>
16 13
@@ -109,9 +106,7 @@ private:
109 /// Creates a layer with the specified layer ID in the desired display. 106 /// Creates a layer with the specified layer ID in the desired display.
110 void CreateLayerAtId(VI::Display& display, u64 layer_id); 107 void CreateLayerAtId(VI::Display& display, u64 layer_id);
111 108
112 static void VSyncThread(NVFlinger& nv_flinger); 109 void SplitVSync(std::stop_token stop_token);
113
114 void SplitVSync();
115 110
116 std::shared_ptr<Nvidia::Module> nvdrv; 111 std::shared_ptr<Nvidia::Module> nvdrv;
117 112
@@ -133,9 +128,7 @@ private:
133 128
134 Core::System& system; 129 Core::System& system;
135 130
136 std::unique_ptr<std::thread> vsync_thread; 131 std::jthread vsync_thread;
137 std::unique_ptr<Common::Event> wait_event;
138 std::atomic<bool> is_running{};
139 132
140 KernelHelpers::ServiceContext service_context; 133 KernelHelpers::ServiceContext service_context;
141}; 134};