mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-01-21 05:51:39 +00:00
videoout: Make present thread realtime on macOS. (#990)
This commit is contained in:
parent
03ba49a3e0
commit
770cbf14e9
|
@ -9,6 +9,7 @@
|
|||
#include "common/thread.h"
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <pthread.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <windows.h>
|
||||
|
@ -31,6 +32,48 @@
|
|||
|
||||
namespace Common {
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
void SetCurrentThreadRealtime(const std::chrono::nanoseconds period_ns) {
|
||||
// CPU time to grant.
|
||||
const std::chrono::nanoseconds computation_ns = period_ns / 2;
|
||||
|
||||
// Determine the timebase for converting time to ticks.
|
||||
struct mach_timebase_info timebase {};
|
||||
mach_timebase_info(&timebase);
|
||||
const auto ticks_per_ns =
|
||||
static_cast<double>(timebase.denom) / static_cast<double>(timebase.numer);
|
||||
|
||||
const auto period_ticks =
|
||||
static_cast<u32>(static_cast<double>(period_ns.count()) * ticks_per_ns);
|
||||
const auto computation_ticks =
|
||||
static_cast<u32>(static_cast<double>(computation_ns.count()) * ticks_per_ns);
|
||||
|
||||
thread_time_constraint_policy policy = {
|
||||
.period = period_ticks,
|
||||
.computation = computation_ticks,
|
||||
// Should not matter since preemptible is false, but needs to be >= computation regardless.
|
||||
.constraint = computation_ticks,
|
||||
.preemptible = false,
|
||||
};
|
||||
|
||||
int ret = thread_policy_set(
|
||||
pthread_mach_thread_np(pthread_self()), THREAD_TIME_CONSTRAINT_POLICY,
|
||||
reinterpret_cast<thread_policy_t>(&policy), THREAD_TIME_CONSTRAINT_POLICY_COUNT);
|
||||
if (ret != KERN_SUCCESS) {
|
||||
LOG_ERROR(Common, "Could not set thread to real-time with period {} ns: {}",
|
||||
period_ns.count(), ret);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void SetCurrentThreadRealtime(const std::chrono::nanoseconds period_ns) {
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void SetCurrentThreadPriority(ThreadPriority new_priority) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Common {
|
||||
|
@ -16,6 +17,8 @@ enum class ThreadPriority : u32 {
|
|||
Critical = 4,
|
||||
};
|
||||
|
||||
void SetCurrentThreadRealtime(std::chrono::nanoseconds period_ns);
|
||||
|
||||
void SetCurrentThreadPriority(ThreadPriority new_priority);
|
||||
|
||||
void SetCurrentThreadName(const char* name);
|
||||
|
|
|
@ -261,8 +261,11 @@ void VideoOutDriver::SubmitFlipInternal(VideoOutPort* port, s32 index, s64 flip_
|
|||
}
|
||||
|
||||
void VideoOutDriver::PresentThread(std::stop_token token) {
|
||||
static constexpr std::chrono::milliseconds VblankPeriod{16};
|
||||
static constexpr std::chrono::nanoseconds VblankPeriod{16666667};
|
||||
const auto vblank_period = VblankPeriod / Config::vblankDiv();
|
||||
|
||||
Common::SetCurrentThreadName("PresentThread");
|
||||
Common::SetCurrentThreadRealtime(vblank_period);
|
||||
|
||||
const auto receive_request = [this] -> Request {
|
||||
std::scoped_lock lk{mutex};
|
||||
|
@ -274,7 +277,6 @@ void VideoOutDriver::PresentThread(std::stop_token token) {
|
|||
return {};
|
||||
};
|
||||
|
||||
auto vblank_period = VblankPeriod / Config::vblankDiv();
|
||||
auto delay = std::chrono::microseconds{0};
|
||||
while (!token.stop_requested()) {
|
||||
// Sleep for most of the vblank duration.
|
||||
|
|
Loading…
Reference in a new issue