time: move to stl's clocks and move timer
This commit is contained in:
parent
0e521788bc
commit
877fb5b93a
43 changed files with 392 additions and 248 deletions
|
|
@ -24,6 +24,7 @@
|
|||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "sync/SyncTimeline.hpp"
|
||||
#include "time/Time.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include <aquamarine/output/Output.hpp>
|
||||
#include "debug/Log.hpp"
|
||||
|
|
@ -32,6 +33,7 @@
|
|||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
#include <cstring>
|
||||
#include <ranges>
|
||||
|
||||
using namespace Hyprutils::String;
|
||||
using namespace Hyprutils::Utils;
|
||||
using namespace Hyprutils::OS;
|
||||
|
|
@ -72,8 +74,15 @@ void CMonitor::onConnect(bool noRule) {
|
|||
output->events.needsFrame.registerListener([this](std::any d) { g_pCompositor->scheduleFrameForMonitor(self.lock(), Aquamarine::IOutput::AQ_SCHEDULE_NEEDS_FRAME); });
|
||||
|
||||
listeners.presented = output->events.present.registerListener([this](std::any d) {
|
||||
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
|
||||
PROTO::presentation->onPresented(self.lock(), E.when, E.refresh, E.seq, E.flags);
|
||||
auto E = std::any_cast<Aquamarine::IOutput::SPresentEvent>(d);
|
||||
|
||||
timespec* ts = E.when;
|
||||
if (!ts) {
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
PROTO::presentation->onPresented(self.lock(), Time::fromTimespec(&now), E.refresh, E.seq, E.flags);
|
||||
} else
|
||||
PROTO::presentation->onPresented(self.lock(), Time::fromTimespec(E.when), E.refresh, E.seq, E.flags);
|
||||
});
|
||||
|
||||
listeners.destroy = output->events.destroy.registerListener([this](std::any d) {
|
||||
|
|
@ -1377,9 +1386,7 @@ bool CMonitor::attemptDirectScanout() {
|
|||
auto PBUFFER = PSURFACE->current.buffer.buffer;
|
||||
|
||||
if (PBUFFER == output->state->state().buffer) {
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
PSURFACE->presentFeedback(&now, self.lock());
|
||||
PSURFACE->presentFeedback(Time::steadyNow(), self.lock());
|
||||
|
||||
if (scanoutNeedsCursorUpdate) {
|
||||
if (!state.test()) {
|
||||
|
|
@ -1420,9 +1427,7 @@ bool CMonitor::attemptDirectScanout() {
|
|||
return false;
|
||||
}
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
PSURFACE->presentFeedback(&now, self.lock());
|
||||
PSURFACE->presentFeedback(Time::steadyNow(), self.lock());
|
||||
|
||||
output->state->addDamage(PSURFACE->current.accumulateBufferDamage());
|
||||
output->state->resetExplicitFences();
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include <array>
|
||||
|
||||
#include <xf86drmMode.h>
|
||||
#include "Timer.hpp"
|
||||
#include "time/Timer.hpp"
|
||||
#include "math/Math.hpp"
|
||||
#include <optional>
|
||||
#include "../protocols/types/ColorManagement.hpp"
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
#include "Timer.hpp"
|
||||
#include <chrono>
|
||||
|
||||
void CTimer::reset() {
|
||||
m_tpLastReset = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::duration CTimer::getDuration() {
|
||||
return std::chrono::steady_clock::now() - m_tpLastReset;
|
||||
}
|
||||
|
||||
float CTimer::getMillis() {
|
||||
return std::chrono::duration_cast<std::chrono::microseconds>(getDuration()).count() / 1000.f;
|
||||
}
|
||||
|
||||
float CTimer::getSeconds() {
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(getDuration()).count() / 1000.f;
|
||||
}
|
||||
|
||||
const std::chrono::steady_clock::time_point& CTimer::chrono() const {
|
||||
return m_tpLastReset;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
class CTimer {
|
||||
public:
|
||||
void reset();
|
||||
float getSeconds();
|
||||
float getMillis();
|
||||
const std::chrono::steady_clock::time_point& chrono() const;
|
||||
|
||||
private:
|
||||
std::chrono::steady_clock::time_point m_tpLastReset;
|
||||
|
||||
std::chrono::steady_clock::duration getDuration();
|
||||
};
|
||||
139
src/helpers/time/Time.cpp
Normal file
139
src/helpers/time/Time.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#include "Time.hpp"
|
||||
|
||||
#define chr std::chrono
|
||||
#define TIMESPEC_NSEC_PER_SEC 1000000000L
|
||||
|
||||
using s_ns = std::pair<uint64_t, uint64_t>;
|
||||
|
||||
// HAS to be a > b
|
||||
static s_ns timediff(const s_ns& a, const s_ns& b) {
|
||||
s_ns d;
|
||||
|
||||
d.first = a.first - b.first;
|
||||
if (a.second >= b.second)
|
||||
d.second = a.second - b.second;
|
||||
else {
|
||||
d.second = b.second - a.second;
|
||||
d.first -= 1;
|
||||
}
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static s_ns timeadd(const s_ns& a, const s_ns& b) {
|
||||
s_ns d;
|
||||
|
||||
d.first = a.first + b.first;
|
||||
if (a.second + b.second >= TIMESPEC_NSEC_PER_SEC) {
|
||||
d.second = a.second + b.second - TIMESPEC_NSEC_PER_SEC;
|
||||
d.first += 1;
|
||||
} else
|
||||
d.second = a.second + b.second;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
Time::steady_tp Time::steadyNow() {
|
||||
return chr::steady_clock::now();
|
||||
}
|
||||
|
||||
Time::system_tp Time::systemNow() {
|
||||
return chr::system_clock::now();
|
||||
}
|
||||
|
||||
uint64_t Time::millis(const steady_tp& tp) {
|
||||
return chr::duration_cast<chr::milliseconds>(tp.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
s_ns Time::secNsec(const steady_tp& tp) {
|
||||
const uint64_t sec = chr::duration_cast<chr::seconds>(tp.time_since_epoch()).count();
|
||||
const chr::steady_clock::duration nsecdur = tp - chr::steady_clock::time_point(chr::seconds(sec));
|
||||
return std::make_pair<>(sec, chr::duration_cast<chr::nanoseconds>(nsecdur).count());
|
||||
}
|
||||
|
||||
uint64_t Time::millis(const system_tp& tp) {
|
||||
return chr::duration_cast<chr::milliseconds>(tp.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
s_ns Time::secNsec(const system_tp& tp) {
|
||||
const uint64_t sec = chr::duration_cast<chr::seconds>(tp.time_since_epoch()).count();
|
||||
const chr::steady_clock::duration nsecdur = tp - chr::system_clock::time_point(chr::seconds(sec));
|
||||
return std::make_pair<>(sec, chr::duration_cast<chr::nanoseconds>(nsecdur).count());
|
||||
}
|
||||
|
||||
// TODO: this is a mess, but C++ doesn't define what steady_clock is.
|
||||
// At least on Linux, system_clock == CLOCK_REALTIME
|
||||
// and steady_clock == CLOCK_MONOTONIC,
|
||||
// or at least it seems so with gcc and gcc's stl.
|
||||
// but, since we can't *ever* be sure, we have to guess.
|
||||
// In general, this may shift the time around by a couple hundred ns. Doesn't matter, realistically.
|
||||
|
||||
Time::steady_tp Time::fromTimespec(const timespec* ts) {
|
||||
struct timespec mono, real;
|
||||
clock_gettime(CLOCK_MONOTONIC, &mono);
|
||||
clock_gettime(CLOCK_REALTIME, &real);
|
||||
Time::steady_tp now = Time::steadyNow();
|
||||
Time::system_tp nowSys = Time::systemNow();
|
||||
s_ns stdSteady, stdReal;
|
||||
stdSteady = Time::secNsec(now);
|
||||
stdReal = Time::secNsec(nowSys);
|
||||
|
||||
// timespec difference, REAL - MONO
|
||||
s_ns diff;
|
||||
diff.first = real.tv_sec - mono.tv_sec;
|
||||
if (real.tv_nsec >= mono.tv_nsec)
|
||||
diff.second = real.tv_nsec - mono.tv_nsec;
|
||||
else {
|
||||
diff.second = mono.tv_nsec - real.tv_nsec;
|
||||
diff.first -= 1;
|
||||
}
|
||||
|
||||
// STD difference, REAL - MONO
|
||||
s_ns diff2 = timediff(stdReal, stdSteady);
|
||||
|
||||
s_ns diffFinal;
|
||||
s_ns monotime = {ts->tv_sec, ts->tv_nsec};
|
||||
|
||||
if (diff.first >= diff2.first || (diff.first == diff2.first && diff.second >= diff2.second))
|
||||
diffFinal = timediff(diff, diff2);
|
||||
else
|
||||
diffFinal = timediff(diff2, diff);
|
||||
|
||||
auto sum = timeadd(monotime, diffFinal);
|
||||
return chr::steady_clock::time_point(std::chrono::seconds(sum.first)) + chr::nanoseconds(sum.second);
|
||||
}
|
||||
|
||||
struct timespec Time::toTimespec(const steady_tp& tp) {
|
||||
struct timespec mono, real;
|
||||
clock_gettime(CLOCK_MONOTONIC, &mono);
|
||||
clock_gettime(CLOCK_REALTIME, &real);
|
||||
Time::steady_tp now = Time::steadyNow();
|
||||
Time::system_tp nowSys = Time::systemNow();
|
||||
s_ns stdSteady, stdReal;
|
||||
stdSteady = Time::secNsec(now);
|
||||
stdReal = Time::secNsec(nowSys);
|
||||
|
||||
// timespec difference, REAL - MONO
|
||||
s_ns diff;
|
||||
diff.first = real.tv_sec - mono.tv_sec;
|
||||
if (real.tv_nsec >= mono.tv_nsec)
|
||||
diff.second = real.tv_nsec - mono.tv_nsec;
|
||||
else {
|
||||
diff.second = mono.tv_nsec - real.tv_nsec;
|
||||
diff.first -= 1;
|
||||
}
|
||||
|
||||
// STD difference, REAL - MONO
|
||||
s_ns diff2 = timediff(stdReal, stdSteady);
|
||||
|
||||
s_ns diffFinal;
|
||||
s_ns tpTime = secNsec(tp);
|
||||
|
||||
if (diff.first >= diff2.first || (diff.first == diff2.first && diff.second >= diff2.second))
|
||||
diffFinal = timediff(diff, diff2);
|
||||
else
|
||||
diffFinal = timediff(diff2, diff);
|
||||
|
||||
auto sum = timeadd(tpTime, diffFinal);
|
||||
return timespec{.tv_sec = sum.first, .tv_nsec = sum.second};
|
||||
}
|
||||
25
src/helpers/time/Time.hpp
Normal file
25
src/helpers/time/Time.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <ctime>
|
||||
|
||||
//NOLINTNEXTLINE
|
||||
namespace Time {
|
||||
using steady_tp = std::chrono::steady_clock::time_point;
|
||||
using system_tp = std::chrono::system_clock::time_point;
|
||||
using steady_dur = std::chrono::steady_clock::duration;
|
||||
using system_dur = std::chrono::system_clock::duration;
|
||||
|
||||
steady_tp steadyNow();
|
||||
system_tp systemNow();
|
||||
|
||||
steady_tp fromTimespec(const timespec*);
|
||||
struct timespec toTimespec(const steady_tp& tp);
|
||||
|
||||
uint64_t millis(const steady_tp& tp);
|
||||
uint64_t millis(const system_tp& tp);
|
||||
std::pair<uint64_t, uint64_t> secNsec(const steady_tp& tp);
|
||||
std::pair<uint64_t, uint64_t> secNsec(const system_tp& tp);
|
||||
};
|
||||
23
src/helpers/time/Timer.cpp
Normal file
23
src/helpers/time/Timer.cpp
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#include "Timer.hpp"
|
||||
|
||||
#define chr std::chrono
|
||||
|
||||
void CTimer::reset() {
|
||||
m_lastReset = Time::steadyNow();
|
||||
}
|
||||
|
||||
Time::steady_dur CTimer::getDuration() {
|
||||
return Time::steadyNow() - m_lastReset;
|
||||
}
|
||||
|
||||
float CTimer::getMillis() {
|
||||
return chr::duration_cast<chr::microseconds>(getDuration()).count() / 1000.F;
|
||||
}
|
||||
|
||||
float CTimer::getSeconds() {
|
||||
return chr::duration_cast<chr::milliseconds>(getDuration()).count() / 1000.F;
|
||||
}
|
||||
|
||||
const Time::steady_tp& CTimer::chrono() const {
|
||||
return m_lastReset;
|
||||
}
|
||||
16
src/helpers/time/Timer.hpp
Normal file
16
src/helpers/time/Timer.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include "Time.hpp"
|
||||
|
||||
class CTimer {
|
||||
public:
|
||||
void reset();
|
||||
float getSeconds();
|
||||
float getMillis();
|
||||
const Time::steady_tp& chrono() const;
|
||||
|
||||
private:
|
||||
Time::steady_tp m_lastReset;
|
||||
|
||||
Time::steady_dur getDuration();
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue