Kelebek1 пре 4 година
родитељ
комит
9d3b190465
2 измењених фајлова са 30 додато и 17 уклоњено
  1. 26 16
      src/core/hle/service/nvflinger/nvflinger.cpp
  2. 4 1
      src/core/hle/service/nvflinger/nvflinger.h

+ 26 - 16
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::SetCurrentThreadName(name.c_str());
     Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
     Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
-    s64 delay = 0;
+
     while (!stop_token.stop_requested()) {
     while (!stop_token.stop_requested()) {
+        vsync_signal.wait(false);
+        vsync_signal.store(false);
+
         guard->lock();
         guard->lock();
-        const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count();
+
         Compose();
         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();
         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>();
     guard = std::make_shared<std::mutex>();
 
 
     // Schedule the screen composition events
     // 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",
         "ScreenComposition",
         [this](std::uintptr_t, s64 time,
         [this](std::uintptr_t, s64 time,
                std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
                std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
             const auto lock_guard = Lock();
             const auto lock_guard = Lock();
             Compose();
             Compose();
 
 
-            return std::max(std::chrono::nanoseconds::zero(),
-                            std::chrono::nanoseconds(GetNextTicks()) - ns_late);
+            return std::chrono::nanoseconds(GetNextTicks());
         });
         });
 
 
     if (system.IsMulticore()) {
     if (system.IsMulticore()) {
+        system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, multi_composition_event);
         vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
         vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
     } else {
     } else {
-        system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, composition_event);
+        system.CoreTiming().ScheduleLoopingEvent(frame_ns, frame_ns, single_composition_event);
     }
     }
 }
 }
 
 
 NVFlinger::~NVFlinger() {
 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) {
     for (auto& display : displays) {

+ 4 - 1
src/core/hle/service/nvflinger/nvflinger.h

@@ -126,12 +126,15 @@ private:
     u32 swap_interval = 1;
     u32 swap_interval = 1;
 
 
     /// Event that handles screen composition.
     /// 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;
     std::shared_ptr<std::mutex> guard;
 
 
     Core::System& system;
     Core::System& system;
 
 
+    std::atomic<bool> vsync_signal;
+
     std::jthread vsync_thread;
     std::jthread vsync_thread;
 
 
     KernelHelpers::ServiceContext service_context;
     KernelHelpers::ServiceContext service_context;