time: move to stl's clocks and move timer

This commit is contained in:
Vaxry
2025-04-16 01:37:48 +01:00
parent 0e521788bc
commit 877fb5b93a
43 changed files with 392 additions and 248 deletions

View File

@@ -1,7 +1,7 @@
#pragma once
#include "../defines.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/time/Timer.hpp"
#include "../render/Texture.hpp"
#include "../SharedDefs.hpp"

View File

@@ -417,10 +417,10 @@ void CWindow::moveToWorkspace(PHLWORKSPACE pWorkspace) {
if (TOKEN) {
if (*PINITIALWSTRACKING == 2) {
// persistent
SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->data);
SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->m_data);
if (token.primaryOwner == m_pSelf) {
token.workspace = pWorkspace->getConfigName();
TOKEN->data = token;
TOKEN->m_data = token;
}
}
}
@@ -507,7 +507,7 @@ void CWindow::onUnmap() {
if (TOKEN) {
if (*PINITIALWSTRACKING == 2) {
// persistent token, but the first window got removed so the token is gone
SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->data);
SInitialWorkspaceToken token = std::any_cast<SInitialWorkspaceToken>(TOKEN->m_data);
if (token.primaryOwner == m_pSelf)
g_pTokenManager->removeToken(TOKEN);
}

View File

@@ -85,7 +85,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
const auto TOKEN = g_pTokenManager->getToken(SZTOKEN);
if (TOKEN) {
// find workspace and use it
SInitialWorkspaceToken WS = std::any_cast<SInitialWorkspaceToken>(TOKEN->data);
SInitialWorkspaceToken WS = std::any_cast<SInitialWorkspaceToken>(TOKEN->m_data);
Debug::log(LOG, "HL_INITIAL_WORKSPACE_TOKEN {} -> {}", SZTOKEN, WS.workspace);
@@ -99,7 +99,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
else if (*PINITIALWSTRACKING == 2) { // persistent
if (WS.primaryOwner.expired()) {
WS.primaryOwner = PWINDOW;
TOKEN->data = WS;
TOKEN->m_data = WS;
}
PWINDOW->m_szInitialWorkspaceToken = SZTOKEN;

View File

@@ -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();

View File

@@ -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"

View File

@@ -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;
}

View File

@@ -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
View 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
View 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);
};

View 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;
}

View 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();
};

View File

@@ -264,7 +264,7 @@ void CHyprAnimationManager::scheduleTick() {
float refreshDelayMs = std::floor(1000.f / PMOSTHZ->refreshRate);
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - PMOSTHZ->lastPresentationTimer.chrono()).count() / 1000.f;
const float SINCEPRES = std::chrono::duration_cast<std::chrono::microseconds>(Time::steadyNow() - PMOSTHZ->lastPresentationTimer.chrono()).count() / 1000.F;
const auto TOPRES = std::clamp(refreshDelayMs - SINCEPRES, 1.1f, 1000.f); // we can't send 0, that will disarm it

View File

@@ -8,7 +8,7 @@
#include <xkbcommon/xkbcommon.h>
#include "../devices/IPointer.hpp"
#include "eventLoop/EventLoopTimer.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/time/Timer.hpp"
class CInputManager;
class CConfigManager;

View File

@@ -15,6 +15,7 @@
#include "../render/Renderer.hpp"
#include "../render/OpenGL.hpp"
#include "SeatManager.hpp"
#include "../helpers/time/Time.hpp"
#include <cstring>
#include <gbm.h>
#include <cairo/cairo.h>
@@ -160,9 +161,7 @@ void CPointerManager::setCursorSurface(SP<CWLSurface> surf, const Vector2D& hots
if (surf->resource()->current.texture) {
currentCursorImage.size = surf->resource()->current.bufferSize;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
surf->resource()->frame(&now);
surf->resource()->frame(Time::steadyNow());
}
}
@@ -592,7 +591,7 @@ SP<Aquamarine::IBuffer> CPointerManager::renderHWCursorBuffer(SP<CPointerManager
return buf;
}
void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
void CPointerManager::renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage, std::optional<Vector2D> overridePos) {
if (!hasCursor())
return;

View File

@@ -6,6 +6,7 @@
#include "../helpers/math/Math.hpp"
#include "../desktop/WLSurface.hpp"
#include "../helpers/sync/SyncTimeline.hpp"
#include "../helpers/time/Time.hpp"
#include <tuple>
class CMonitor;
@@ -48,7 +49,7 @@ class CPointerManager {
void unlockSoftwareAll();
bool softwareLockedFor(PHLMONITOR pMonitor);
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, timespec* now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */);
void renderSoftwareCursorsFor(PHLMONITOR pMonitor, const Time::steady_tp& now, CRegion& damage /* logical */, std::optional<Vector2D> overridePos = {} /* monitor-local */);
// this is needed e.g. during screensharing where
// the software cursors aren't locked during the cursor move, but they

View File

@@ -1,7 +1,7 @@
#pragma once
#include "../defines.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/time/Timer.hpp"
#include "../helpers/signal/Signal.hpp"
#include <cstdint>
#include <unordered_map>

View File

@@ -2,12 +2,12 @@
#include <uuid/uuid.h>
#include <algorithm>
CUUIDToken::CUUIDToken(const std::string& uuid_, std::any data_, std::chrono::steady_clock::duration expires) : data(data_), uuid(uuid_) {
expiresAt = std::chrono::steady_clock::now() + expires;
CUUIDToken::CUUIDToken(const std::string& uuid_, std::any data_, Time::steady_dur expires) : m_data(data_), m_uuid(uuid_) {
m_expiresAt = Time::steadyNow() + expires;
}
std::string CUUIDToken::getUUID() {
return uuid;
return m_uuid;
}
std::string CTokenManager::getRandomUUID() {
@@ -23,7 +23,7 @@ std::string CTokenManager::getRandomUUID() {
return uuid;
}
std::string CTokenManager::registerNewToken(std::any data, std::chrono::steady_clock::duration expires) {
std::string CTokenManager::registerNewToken(std::any data, Time::steady_dur expires) {
std::string uuid = getRandomUUID();
m_mTokens[uuid] = makeShared<CUUIDToken>(uuid, data, expires);
@@ -33,8 +33,8 @@ std::string CTokenManager::registerNewToken(std::any data, std::chrono::steady_c
SP<CUUIDToken> CTokenManager::getToken(const std::string& uuid) {
// cleanup expired tokens
const auto NOW = std::chrono::steady_clock::now();
std::erase_if(m_mTokens, [&NOW](const auto& el) { return el.second->expiresAt < NOW; });
const auto NOW = Time::steadyNow();
std::erase_if(m_mTokens, [&NOW](const auto& el) { return el.second->m_expiresAt < NOW; });
if (!m_mTokens.contains(uuid))
return {};
@@ -45,5 +45,5 @@ SP<CUUIDToken> CTokenManager::getToken(const std::string& uuid) {
void CTokenManager::removeToken(SP<CUUIDToken> token) {
if (!token)
return;
m_mTokens.erase(token->uuid);
m_mTokens.erase(token->m_uuid);
}

View File

@@ -1,24 +1,23 @@
#pragma once
#include <chrono>
#include <any>
#include <unordered_map>
#include <string>
#include "../helpers/memory/Memory.hpp"
#include "../helpers/time/Time.hpp"
class CUUIDToken {
public:
CUUIDToken(const std::string& uuid_, std::any data_, std::chrono::steady_clock::duration expires);
CUUIDToken(const std::string& uuid_, std::any data_, Time::steady_dur expires);
std::string getUUID();
std::any data;
std::any m_data;
private:
std::string uuid;
std::chrono::steady_clock::time_point expiresAt;
std::string m_uuid;
Time::steady_tp m_expiresAt;
friend class CTokenManager;
};

View File

@@ -1,3 +1,9 @@
#define Time XTime__
extern "C" {
#include <X11/Xcursor/Xcursor.h>
}
#undef Time
#include <algorithm>
#include <cstring>
#include <dirent.h>
@@ -176,8 +182,9 @@ SP<SXCursors> CXCursorManager::getShape(std::string const& shape, int size, floa
return defaultCursor;
}
SP<SXCursors> CXCursorManager::createCursor(std::string const& shape, XcursorImages* xImages) {
auto xcursor = makeShared<SXCursors>();
SP<SXCursors> CXCursorManager::createCursor(std::string const& shape, void* ximages) {
auto xcursor = makeShared<SXCursors>();
XcursorImages* xImages = (XcursorImages*)ximages;
for (int i = 0; i < xImages->nimage; i++) {
auto xImage = xImages->images[i];

View File

@@ -7,10 +7,6 @@
#include <hyprutils/math/Vector2D.hpp>
#include "helpers/memory/Memory.hpp"
extern "C" {
#include <X11/Xcursor/Xcursor.h>
}
// gangsta bootleg XCursor impl. adidas balkanized
struct SXCursorImage {
Hyprutils::Math::Vector2D size;
@@ -34,7 +30,7 @@ class CXCursorManager {
void syncGsettings();
private:
SP<SXCursors> createCursor(std::string const& shape, XcursorImages* xImages);
SP<SXCursors> createCursor(std::string const& shape, void* /* XcursorImages* */ xImages);
std::set<std::string> themePaths(std::string const& theme);
std::string getLegacyShapeName(std::string const& shape);
std::vector<SP<SXCursors>> loadStandardCursors(std::string const& name, int size);

View File

@@ -1,55 +1,55 @@
#include "EventLoopTimer.hpp"
#include <limits>
#include "EventLoopManager.hpp"
#include "../../helpers/time/Time.hpp"
CEventLoopTimer::CEventLoopTimer(std::optional<std::chrono::steady_clock::duration> timeout, std::function<void(SP<CEventLoopTimer> self, void* data)> cb_, void* data_) :
cb(cb_), data(data_) {
CEventLoopTimer::CEventLoopTimer(std::optional<Time::steady_dur> timeout, std::function<void(SP<CEventLoopTimer> self, void* data)> cb_, void* data_) : m_cb(cb_), m_data(data_) {
if (!timeout.has_value())
expires.reset();
m_expires.reset();
else
expires = std::chrono::steady_clock::now() + *timeout;
m_expires = Time::steadyNow() + *timeout;
}
void CEventLoopTimer::updateTimeout(std::optional<std::chrono::steady_clock::duration> timeout) {
void CEventLoopTimer::updateTimeout(std::optional<Time::steady_dur> timeout) {
if (!timeout.has_value()) {
expires.reset();
m_expires.reset();
g_pEventLoopManager->nudgeTimers();
return;
}
expires = std::chrono::steady_clock::now() + *timeout;
m_expires = Time::steadyNow() + *timeout;
g_pEventLoopManager->nudgeTimers();
}
bool CEventLoopTimer::passed() {
if (!expires.has_value())
if (!m_expires.has_value())
return false;
return std::chrono::steady_clock::now() > *expires;
return Time::steadyNow() > *m_expires;
}
void CEventLoopTimer::cancel() {
wasCancelled = true;
expires.reset();
m_wasCancelled = true;
m_expires.reset();
}
bool CEventLoopTimer::cancelled() {
return wasCancelled;
return m_wasCancelled;
}
void CEventLoopTimer::call(SP<CEventLoopTimer> self) {
expires.reset();
cb(self, data);
m_expires.reset();
m_cb(self, m_data);
}
float CEventLoopTimer::leftUs() {
if (!expires.has_value())
if (!m_expires.has_value())
return std::numeric_limits<float>::max();
return std::chrono::duration_cast<std::chrono::microseconds>(*expires - std::chrono::steady_clock::now()).count();
return std::chrono::duration_cast<std::chrono::microseconds>(*m_expires - Time::steadyNow()).count();
}
bool CEventLoopTimer::armed() {
return expires.has_value();
return m_expires.has_value();
}

View File

@@ -5,14 +5,15 @@
#include <optional>
#include "../../helpers/memory/Memory.hpp"
#include "../../helpers/time/Time.hpp"
class CEventLoopTimer {
public:
CEventLoopTimer(std::optional<std::chrono::steady_clock::duration> timeout, std::function<void(SP<CEventLoopTimer> self, void* data)> cb_, void* data_);
CEventLoopTimer(std::optional<Time::steady_dur> timeout, std::function<void(SP<CEventLoopTimer> self, void* data)> cb_, void* data_);
// if not specified, disarms.
// if specified, arms.
void updateTimeout(std::optional<std::chrono::steady_clock::duration> timeout);
void updateTimeout(std::optional<Time::steady_dur> timeout);
void cancel();
bool passed();
@@ -25,8 +26,8 @@ class CEventLoopTimer {
void call(SP<CEventLoopTimer> self);
private:
std::function<void(SP<CEventLoopTimer> self, void* data)> cb;
void* data = nullptr;
std::optional<std::chrono::steady_clock::time_point> expires;
bool wasCancelled = false;
std::function<void(SP<CEventLoopTimer> self, void* data)> m_cb;
void* m_data = nullptr;
std::optional<Time::steady_tp> m_expires;
bool m_wasCancelled = false;
};

View File

@@ -36,6 +36,8 @@
#include "../../managers/EventManager.hpp"
#include "../../managers/LayoutManager.hpp"
#include "../../helpers/time/Time.hpp"
#include <aquamarine/input/Input.hpp>
CInputManager::CInputManager() {
@@ -142,10 +144,8 @@ void CInputManager::onMouseWarp(IPointer::SMotionAbsoluteEvent e) {
}
void CInputManager::simulateMouseMovement() {
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
m_vLastCursorPosFloored = m_vLastCursorPosFloored - Vector2D(1, 1); // hack: force the mouseMoveUnified to report without making this a refocus.
mouseMoveUnified(now.tv_sec * 1000 + now.tv_nsec / 10000000);
mouseMoveUnified(Time::millis(Time::steadyNow()));
}
void CInputManager::sendMotionEventsToFocused() {
@@ -156,9 +156,6 @@ void CInputManager::sendMotionEventsToFocused() {
const auto PWINDOW = g_pCompositor->getWindowFromSurface(g_pCompositor->m_pLastFocus.lock());
const auto PLS = g_pCompositor->getLayerSurfaceFromSurface(g_pCompositor->m_pLastFocus.lock());
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
const auto LOCAL = getMouseCoordsInternal() - (PWINDOW ? PWINDOW->m_vRealPosition->goal() : (PLS ? Vector2D{PLS->geometry.x, PLS->geometry.y} : Vector2D{}));
m_bEmptyFocusCursorSet = false;
@@ -1746,11 +1743,8 @@ void CInputManager::releaseAllMouseButtons() {
if (PROTO::data->dndActive())
return;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
for (auto const& mb : buttonsCopy) {
g_pSeatManager->sendPointerButton(now.tv_sec * 1000 + now.tv_nsec / 1000000, mb, WL_POINTER_BUTTON_STATE_RELEASED);
g_pSeatManager->sendPointerButton(Time::millis(Time::steadyNow()), mb, WL_POINTER_BUTTON_STATE_RELEASED);
}
m_lCurrentlyHeldButtons.clear();

View File

@@ -4,7 +4,7 @@
#include <list>
#include <any>
#include "../../helpers/WLClasses.hpp"
#include "../../helpers/Timer.hpp"
#include "../../helpers/time/Timer.hpp"
#include "InputMethodRelay.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../devices/IPointer.hpp"

View File

@@ -1,4 +1,5 @@
#include "GlobalShortcuts.hpp"
#include "../helpers/time/Time.hpp"
CShortcutClient::CShortcutClient(SP<CHyprlandGlobalShortcutsManagerV1> resource_) : resource(resource_) {
if UNLIKELY (!good())
@@ -68,14 +69,13 @@ void CGlobalShortcutsProtocol::sendGlobalShortcutEvent(std::string appid, std::s
for (auto const& c : m_vClients) {
for (auto const& sh : c->shortcuts) {
if (sh->appid == appid && sh->id == trigger) {
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
uint32_t tvSecHi = (sizeof(now.tv_sec) > 4) ? now.tv_sec >> 32 : 0;
uint32_t tvSecLo = now.tv_sec & 0xFFFFFFFF;
const auto [sec, nsec] = Time::secNsec(Time::steadyNow());
uint32_t tvSecHi = (sizeof(sec) > 4) ? sec >> 32 : 0;
uint32_t tvSecLo = sec & 0xFFFFFFFF;
if (pressed)
sh->resource->sendPressed(tvSecHi, tvSecLo, now.tv_nsec);
sh->resource->sendPressed(tvSecHi, tvSecLo, nsec);
else
sh->resource->sendReleased(tvSecHi, tvSecLo, now.tv_nsec);
sh->resource->sendReleased(tvSecHi, tvSecLo, nsec);
}
}
}

View File

@@ -40,7 +40,7 @@ bool CPresentationFeedback::good() {
return resource->resource();
}
void CPresentationFeedback::sendQueued(SP<CQueuedPresentationData> data, timespec* when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
void CPresentationFeedback::sendQueued(SP<CQueuedPresentationData> data, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
auto client = resource->client();
if LIKELY (PROTO::outputs.contains(data->pMonitor->szName)) {
@@ -58,12 +58,14 @@ void CPresentationFeedback::sendQueued(SP<CQueuedPresentationData> data, timespe
if (reportedFlags & Aquamarine::IOutput::AQ_OUTPUT_PRESENT_HW_COMPLETION)
flags |= WP_PRESENTATION_FEEDBACK_KIND_HW_COMPLETION;
time_t tv_sec = 0;
const auto TIMESPEC = Time::toTimespec(when);
time_t tv_sec = 0;
if (sizeof(time_t) > 4)
tv_sec = when->tv_sec >> 32;
tv_sec = TIMESPEC.tv_sec >> 32;
if (data->wasPresented)
resource->sendPresented((uint32_t)tv_sec, (uint32_t)(when->tv_sec & 0xFFFFFFFF), (uint32_t)(when->tv_nsec), untilRefreshNs, (uint32_t)(seq >> 32),
resource->sendPresented((uint32_t)tv_sec, (uint32_t)(TIMESPEC.tv_sec & 0xFFFFFFFF), (uint32_t)(TIMESPEC.tv_nsec), untilRefreshNs, (uint32_t)(seq >> 32),
(uint32_t)(seq & 0xFFFFFFFF), (wpPresentationFeedbackKind)flags);
else
resource->sendDiscarded();
@@ -107,15 +109,7 @@ void CPresentationProtocol::onGetFeedback(CWpPresentation* pMgr, wl_resource* su
}
}
void CPresentationProtocol::onPresented(PHLMONITOR pMonitor, timespec* when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
timespec now;
timespec* presentedAt = when;
if (!presentedAt) {
// just put the current time, we don't have anything better
clock_gettime(CLOCK_MONOTONIC, &now);
when = &now;
}
void CPresentationProtocol::onPresented(PHLMONITOR pMonitor, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags) {
for (auto const& feedback : m_vFeedbacks) {
if (!feedback->surface)
continue;

View File

@@ -4,6 +4,7 @@
#include <cstdint>
#include "WaylandProtocol.hpp"
#include "presentation-time.hpp"
#include "../helpers/time/Time.hpp"
class CMonitor;
class CWLSurfaceResource;
@@ -36,7 +37,7 @@ class CPresentationFeedback {
bool good();
void sendQueued(SP<CQueuedPresentationData> data, timespec* when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
void sendQueued(SP<CQueuedPresentationData> data, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
private:
SP<CWpPresentationFeedback> resource;
@@ -52,7 +53,7 @@ class CPresentationProtocol : public IWaylandProtocol {
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
void onPresented(PHLMONITOR pMonitor, timespec* when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
void onPresented(PHLMONITOR pMonitor, const Time::steady_tp& when, uint32_t untilRefreshNs, uint64_t seq, uint32_t reportedFlags);
void queueData(SP<CQueuedPresentationData> data);
private:

View File

@@ -11,6 +11,7 @@
#include "types/WLBuffer.hpp"
#include "types/Buffer.hpp"
#include "../helpers/Format.hpp"
#include "../helpers/time/Time.hpp"
#include <algorithm>
#include <functional>
@@ -166,10 +167,9 @@ void CScreencopyFrame::share() {
if (!buffer || !pMonitor)
return;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
const auto NOW = Time::steadyNow();
auto callback = [this, now, weak = self](bool success) {
auto callback = [this, NOW, weak = self](bool success) {
if (weak.expired())
return;
@@ -185,9 +185,11 @@ void CScreencopyFrame::share() {
resource->sendDamage(0, 0, buffer->size.x, buffer->size.y);
}
uint32_t tvSecHi = (sizeof(now.tv_sec) > 4) ? now.tv_sec >> 32 : 0;
uint32_t tvSecLo = now.tv_sec & 0xFFFFFFFF;
resource->sendReady(tvSecHi, tvSecLo, now.tv_nsec);
const auto [sec, nsec] = Time::secNsec(NOW);
uint32_t tvSecHi = (sizeof(sec) > 4) ? sec >> 32 : 0;
uint32_t tvSecLo = sec & 0xFFFFFFFF;
resource->sendReady(tvSecHi, tvSecLo, nsec);
};
if (bufferDMA)

View File

@@ -8,7 +8,8 @@
#include <list>
#include <vector>
#include "../managers/HookSystemManager.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/time/Timer.hpp"
#include "../helpers/time/Time.hpp"
#include "../managers/eventLoop/EventLoopTimer.hpp"
#include <aquamarine/buffer/Buffer.hpp>
@@ -102,7 +103,7 @@ class CScreencopyProtocol : public IWaylandProtocol {
void shareFrame(CScreencopyFrame* frame);
void sendFrameDamage(CScreencopyFrame* frame);
bool copyFrameDmabuf(CScreencopyFrame* frame);
bool copyFrameShm(CScreencopyFrame* frame, timespec* now);
bool copyFrameShm(CScreencopyFrame* frame, const Time::steady_tp& now);
friend class CScreencopyFrame;
friend class CScreencopyClient;

View File

@@ -3,6 +3,7 @@
#include "../Compositor.hpp"
#include "../managers/SeatManager.hpp"
#include "../managers/input/InputManager.hpp"
#include "../helpers/time/Time.hpp"
#include "core/Seat.hpp"
#include "core/Compositor.hpp"
#include <algorithm>
@@ -222,9 +223,7 @@ void CTabletToolV2Resource::sendFrame(bool removeSource) {
if (!current)
return;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
resource->sendFrame(now.tv_sec * 1000 + now.tv_nsec / 1000000);
resource->sendFrame(Time::millis(Time::steadyNow()));
}
CTabletSeat::CTabletSeat(SP<CZwpTabletSeatV2> resource_) : resource(resource_) {

View File

@@ -205,16 +205,13 @@ void CToplevelExportFrame::share() {
if (!buffer || !validMapped(pWindow))
return;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
if (bufferDMA) {
if (!copyDmabuf(&now)) {
if (!copyDmabuf(Time::steadyNow())) {
resource->sendFailed();
return;
}
} else {
if (!copyShm(&now)) {
if (!copyShm(Time::steadyNow())) {
resource->sendFailed();
return;
}
@@ -222,16 +219,17 @@ void CToplevelExportFrame::share() {
resource->sendFlags((hyprlandToplevelExportFrameV1Flags)0);
if (!m_ignoreDamage) {
if (!m_ignoreDamage)
resource->sendDamage(0, 0, box.width, box.height);
}
uint32_t tvSecHi = (sizeof(now.tv_sec) > 4) ? now.tv_sec >> 32 : 0;
uint32_t tvSecLo = now.tv_sec & 0xFFFFFFFF;
resource->sendReady(tvSecHi, tvSecLo, now.tv_nsec);
const auto [sec, nsec] = Time::secNsec(Time::steadyNow());
uint32_t tvSecHi = (sizeof(sec) > 4) ? sec >> 32 : 0;
uint32_t tvSecLo = sec & 0xFFFFFFFF;
resource->sendReady(tvSecHi, tvSecLo, nsec);
}
bool CToplevelExportFrame::copyShm(timespec* now) {
bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(resource->client(), PERMISSION_TYPE_SCREENCOPY);
auto shm = buffer->shm();
auto [pixelData, fmt, bufLen] = buffer->beginDataPtr(0); // no need for end, cuz it's shm
@@ -329,7 +327,7 @@ bool CToplevelExportFrame::copyShm(timespec* now) {
return true;
}
bool CToplevelExportFrame::copyDmabuf(timespec* now) {
bool CToplevelExportFrame::copyDmabuf(const Time::steady_tp& now) {
const auto PERM = g_pDynamicPermissionManager->clientPermissionMode(resource->client(), PERMISSION_TYPE_SCREENCOPY);
const auto PMONITOR = pWindow->m_pMonitor.lock();

View File

@@ -4,6 +4,7 @@
#include "hyprland-toplevel-export-v1.hpp"
#include "WaylandProtocol.hpp"
#include "Screencopy.hpp"
#include "../helpers/time/Time.hpp"
#include <vector>
@@ -62,8 +63,8 @@ class CToplevelExportFrame {
CBox box = {};
void copy(CHyprlandToplevelExportFrameV1* pFrame, wl_resource* buffer, int32_t ignoreDamage);
bool copyDmabuf(timespec* now);
bool copyShm(timespec* now);
bool copyDmabuf(const Time::steady_tp& now);
bool copyShm(const Time::steady_tp& now);
void share();
bool shouldOverlayCursor() const;
@@ -87,8 +88,8 @@ class CToplevelExportProtocol : IWaylandProtocol {
std::vector<WP<CToplevelExportFrame>> m_vFramesAwaitingWrite;
void shareFrame(CToplevelExportFrame* frame);
bool copyFrameDmabuf(CToplevelExportFrame* frame, timespec* now);
bool copyFrameShm(CToplevelExportFrame* frame, timespec* now);
bool copyFrameDmabuf(CToplevelExportFrame* frame, const Time::steady_tp& now);
bool copyFrameShm(CToplevelExportFrame* frame, const Time::steady_tp& now);
void sendDamage(CToplevelExportFrame* frame);
friend class CToplevelExportClient;

View File

@@ -1,6 +1,7 @@
#include "VirtualKeyboard.hpp"
#include <sys/mman.h>
#include "../devices/IKeyboard.hpp"
#include "../helpers/time/Time.hpp"
using namespace Hyprutils::OS;
CVirtualKeyboardV1Resource::CVirtualKeyboardV1Resource(SP<CZwpVirtualKeyboardV1> resource_) : resource(resource_) {
@@ -103,12 +104,9 @@ wl_client* CVirtualKeyboardV1Resource::client() {
}
void CVirtualKeyboardV1Resource::releasePressed() {
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
for (auto const& p : pressed) {
events.key.emit(IKeyboard::SKeyEvent{
.timeMs = now.tv_sec * 1000 + now.tv_nsec / 1000000,
.timeMs = Time::millis(Time::steadyNow()),
.keycode = p,
.state = WL_KEYBOARD_KEY_STATE_RELEASED,
});

View File

@@ -33,8 +33,8 @@ bool CWLCallbackResource::good() {
return resource->resource();
}
void CWLCallbackResource::send(timespec* now) {
resource->sendDone(now->tv_sec * 1000 + now->tv_nsec / 1000000);
void CWLCallbackResource::send(const Time::steady_tp& now) {
resource->sendDone(Time::millis(now));
}
CWLRegionResource::CWLRegionResource(SP<CWlRegion> resource_) : resource(resource_) {
@@ -323,7 +323,7 @@ void CWLSurfaceResource::sendPreferredScale(int32_t scale) {
resource->sendPreferredBufferScale(scale);
}
void CWLSurfaceResource::frame(timespec* now) {
void CWLSurfaceResource::frame(const Time::steady_tp& now) {
if (callbacks.empty())
return;
@@ -436,9 +436,7 @@ void CWLSurfaceResource::map() {
mapped = true;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
frame(&now);
frame(Time::steadyNow());
current.bufferDamage = CBox{{}, {INT32_MAX, INT32_MAX}};
pending.bufferDamage = CBox{{}, {INT32_MAX, INT32_MAX}};
@@ -565,7 +563,7 @@ void CWLSurfaceResource::updateCursorShm(CRegion damage) {
}
}
void CWLSurfaceResource::presentFeedback(timespec* when, PHLMONITOR pMonitor, bool discarded) {
void CWLSurfaceResource::presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded) {
frame(when);
auto FEEDBACK = makeShared<CQueuedPresentationData>(self.lock());
FEEDBACK->attachMonitor(pMonitor);

View File

@@ -16,6 +16,7 @@
#include "wayland.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../../helpers/time/Time.hpp"
#include "../types/Buffer.hpp"
#include "../types/SurfaceRole.hpp"
#include "../types/SurfaceState.hpp"
@@ -36,7 +37,7 @@ class CWLCallbackResource {
CWLCallbackResource(SP<CWlCallback> resource_);
bool good();
void send(timespec* now);
void send(const Time::steady_tp& now);
private:
SP<CWlCallback> resource;
@@ -69,7 +70,7 @@ class CWLSurfaceResource {
void leave(PHLMONITOR monitor);
void sendPreferredTransform(wl_output_transform t);
void sendPreferredScale(int32_t scale);
void frame(timespec* now);
void frame(const Time::steady_tp& now);
uint32_t id();
void map();
void unmap();
@@ -104,7 +105,7 @@ class CWLSurfaceResource {
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
void presentFeedback(timespec* when, PHLMONITOR pMonitor, bool discarded = false);
void presentFeedback(const Time::steady_tp& when, PHLMONITOR pMonitor, bool discarded = false);
void commitState(SSurfaceState& state);
// returns a pair: found surface (null if not found) and surface local coords.

View File

@@ -604,10 +604,7 @@ void CWLDataDeviceProtocol::initiateDrag(WP<CWLDataSourceResource> currentSource
if (!box.has_value())
return;
timespec timeNow;
clock_gettime(CLOCK_MONOTONIC, &timeNow);
dnd.focusedDevice->sendMotion(timeNow.tv_sec * 1000 + timeNow.tv_nsec / 1000000, V - box->pos());
dnd.focusedDevice->sendMotion(Time::millis(Time::steadyNow()), V - box->pos());
LOGM(LOG, "Drag motion {}", V - box->pos());
}
});
@@ -802,7 +799,7 @@ void CWLDataDeviceProtocol::abortDrag() {
g_pSeatManager->resendEnterEvents();
}
void CWLDataDeviceProtocol::renderDND(PHLMONITOR pMonitor, timespec* when) {
void CWLDataDeviceProtocol::renderDND(PHLMONITOR pMonitor, const Time::steady_tp& when) {
if (!dnd.dndSurface || !dnd.dndSurface->current.texture)
return;

View File

@@ -15,6 +15,7 @@
#include "wayland.hpp"
#include "../../helpers/signal/Signal.hpp"
#include "../../helpers/math/Math.hpp"
#include "../../helpers/time/Time.hpp"
#include "../types/DataDevice.hpp"
#include <hyprutils/os/FileDescriptor.hpp>
@@ -138,7 +139,7 @@ class CWLDataDeviceProtocol : public IWaylandProtocol {
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
// renders and damages the dnd icon, if present
void renderDND(PHLMONITOR pMonitor, timespec* when);
void renderDND(PHLMONITOR pMonitor, const Time::steady_tp& when);
// for inputmgr to force refocus
// TODO: move handling to seatmgr
bool dndActive();

View File

@@ -4,6 +4,7 @@
#include "../../devices/IKeyboard.hpp"
#include "../../devices/IHID.hpp"
#include "../../managers/SeatManager.hpp"
#include "../../helpers/time/Time.hpp"
#include "../../config/ConfigValue.hpp"
#include <algorithm>
@@ -174,10 +175,8 @@ void CWLPointerResource::sendLeave() {
// release all buttons unless we have a dnd going on in which case
// the events shall be lost.
if (!PROTO::data->dndActive()) {
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
for (auto const& b : pressedButtons) {
sendButton(now.tv_sec * 1000 + now.tv_nsec / 1000000, b, WL_POINTER_BUTTON_STATE_RELEASED);
sendButton(Time::millis(Time::steadyNow()), b, WL_POINTER_BUTTON_STATE_RELEASED);
}
}

View File

@@ -3,7 +3,7 @@
#include "../defines.hpp"
#include "../helpers/Monitor.hpp"
#include "../helpers/Color.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/time/Timer.hpp"
#include "../helpers/math/Math.hpp"
#include "../helpers/Format.hpp"
#include "../helpers/sync/SyncTimeline.hpp"

View File

@@ -135,9 +135,6 @@ CHyprRenderer::CHyprRenderer() {
if (m_vRenderUnfocused.empty())
return;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
bool dirty = false;
for (auto& w : m_vRenderUnfocused) {
if (!w) {
@@ -148,7 +145,7 @@ CHyprRenderer::CHyprRenderer() {
if (!w->m_pWLSurface || !w->m_pWLSurface->resource() || shouldRenderWindow(w.lock()))
continue;
w->m_pWLSurface->resource()->frame(&now);
w->m_pWLSurface->resource()->frame(Time::steadyNow());
auto FEEDBACK = makeShared<CQueuedPresentationData>(w->m_pWLSurface->resource());
FEEDBACK->attachMonitor(g_pCompositor->m_pLastMonitor.lock());
FEEDBACK->discarded();
@@ -265,7 +262,7 @@ bool CHyprRenderer::shouldRenderWindow(PHLWINDOW pWindow) {
return false;
}
void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* time) {
void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& time) {
PHLWINDOW pWorkspaceWindow = nullptr;
EMIT_HOOK_EVENT("render", RENDER_PRE_WINDOWS);
@@ -356,7 +353,7 @@ void CHyprRenderer::renderWorkspaceWindowsFullscreen(PHLMONITOR pMonitor, PHLWOR
}
}
void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* time) {
void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& time) {
PHLWINDOW lastWindow;
EMIT_HOOK_EVENT("render", RENDER_PRE_WINDOWS);
@@ -454,7 +451,7 @@ void CHyprRenderer::renderWorkspaceWindows(PHLMONITOR pMonitor, PHLWORKSPACE pWo
}
}
void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespec* time, bool decorate, eRenderPassMode mode, bool ignorePosition, bool standalone) {
void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, const Time::steady_tp& time, bool decorate, eRenderPassMode mode, bool ignorePosition, bool standalone) {
if (pWindow->isHidden() && !standalone)
return;
@@ -692,7 +689,7 @@ void CHyprRenderer::renderWindow(PHLWINDOW pWindow, PHLMONITOR pMonitor, timespe
g_pHyprOpenGL->m_RenderData.currentWindow.reset();
}
void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* time, bool popups) {
void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, const Time::steady_tp& time, bool popups) {
if (!pLayer)
return;
@@ -770,7 +767,7 @@ void CHyprRenderer::renderLayer(PHLLS pLayer, PHLMONITOR pMonitor, timespec* tim
}
}
void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, timespec* time) {
void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, const Time::steady_tp& time) {
const auto POS = pPopup->globalBox().pos();
CSurfacePassElement::SRenderData renderdata = {pMonitor, time, POS};
@@ -804,7 +801,7 @@ void CHyprRenderer::renderIMEPopup(CInputPopup* pPopup, PHLMONITOR pMonitor, tim
&renderdata);
}
void CHyprRenderer::renderSessionLockSurface(WP<SSessionLockSurface> pSurface, PHLMONITOR pMonitor, timespec* time) {
void CHyprRenderer::renderSessionLockSurface(WP<SSessionLockSurface> pSurface, PHLMONITOR pMonitor, const Time::steady_tp& time) {
CSurfacePassElement::SRenderData renderdata = {pMonitor, time, pMonitor->vecPosition, pMonitor->vecPosition};
renderdata.blur = false;
@@ -825,7 +822,7 @@ void CHyprRenderer::renderSessionLockSurface(WP<SSessionLockSurface> pSurface, P
&renderdata);
}
void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* time, const Vector2D& translate, const float& scale) {
void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& time, const Vector2D& translate, const float& scale) {
static auto PDIMSPECIAL = CConfigValue<Hyprlang::FLOAT>("decoration:dim_special");
static auto PBLURSPECIAL = CConfigValue<Hyprlang::INT>("decoration:blur:special");
static auto PBLUR = CConfigValue<Hyprlang::INT>("decoration:blur:enabled");
@@ -988,7 +985,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPA
//g_pHyprOpenGL->restoreMatrix();
}
void CHyprRenderer::renderLockscreen(PHLMONITOR pMonitor, timespec* now, const CBox& geometry) {
void CHyprRenderer::renderLockscreen(PHLMONITOR pMonitor, const Time::steady_tp& now, const CBox& geometry) {
TRACY_GPU_ZONE("RenderLockscreen");
if (g_pSessionLockManager->isSessionLocked()) {
@@ -1246,8 +1243,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) {
EMIT_HOOK_EVENT("preRender", pMonitor);
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
const auto NOW = Time::steadyNow();
// check the damage
bool hasChanged = pMonitor->output->needsFrame || pMonitor->damage.hasChanged();
@@ -1328,9 +1324,9 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) {
renderCursor = false;
} else {
CBox renderBox = {0, 0, (int)pMonitor->vecPixelSize.x, (int)pMonitor->vecPixelSize.y};
renderWorkspace(pMonitor, pMonitor->activeWorkspace, &now, renderBox);
renderWorkspace(pMonitor, pMonitor->activeWorkspace, NOW, renderBox);
renderLockscreen(pMonitor, &now, renderBox);
renderLockscreen(pMonitor, NOW, renderBox);
if (pMonitor == g_pCompositor->m_pLastMonitor) {
g_pHyprNotificationOverlay->draw(pMonitor);
@@ -1357,18 +1353,18 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) {
}
}
} else
renderWindow(pMonitor->solitaryClient.lock(), pMonitor, &now, false, RENDER_PASS_MAIN /* solitary = no popups */);
renderWindow(pMonitor->solitaryClient.lock(), pMonitor, NOW, false, RENDER_PASS_MAIN /* solitary = no popups */);
} else if (!pMonitor->isMirror()) {
sendFrameEventsToWorkspace(pMonitor, pMonitor->activeWorkspace, &now);
sendFrameEventsToWorkspace(pMonitor, pMonitor->activeWorkspace, NOW);
if (pMonitor->activeSpecialWorkspace)
sendFrameEventsToWorkspace(pMonitor, pMonitor->activeSpecialWorkspace, &now);
sendFrameEventsToWorkspace(pMonitor, pMonitor->activeSpecialWorkspace, NOW);
}
renderCursor = renderCursor && shouldRenderCursor();
if (renderCursor) {
TRACY_GPU_ZONE("RenderCursor");
g_pPointerManager->renderSoftwareCursorsFor(pMonitor->self.lock(), &now, g_pHyprOpenGL->m_RenderData.damage);
g_pPointerManager->renderSoftwareCursorsFor(pMonitor->self.lock(), NOW, g_pHyprOpenGL->m_RenderData.damage);
}
EMIT_HOOK_EVENT("render", RENDER_LAST_MOMENT);
@@ -1578,7 +1574,7 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
return ok;
}
void CHyprRenderer::renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) {
void CHyprRenderer::renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const CBox& geometry) {
Vector2D translate = {geometry.x, geometry.y};
float scale = (float)geometry.width / pMonitor->vecPixelSize.x;
@@ -1593,7 +1589,7 @@ void CHyprRenderer::renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace
renderAllClientsForWorkspace(pMonitor, pWorkspace, now, translate, scale);
}
void CHyprRenderer::sendFrameEventsToWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now) {
void CHyprRenderer::sendFrameEventsToWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now) {
for (auto const& w : g_pCompositor->m_vWindows) {
if (w->isHidden() || !w->m_bIsMapped || w->m_bFadingOut || !w->m_pWLSurface->resource())
continue;
@@ -1962,7 +1958,7 @@ void CHyprRenderer::damageMirrorsWith(PHLMONITOR pMonitor, const CRegion& pRegio
}
}
void CHyprRenderer::renderDragIcon(PHLMONITOR pMonitor, timespec* time) {
void CHyprRenderer::renderDragIcon(PHLMONITOR pMonitor, const Time::steady_tp& time) {
PROTO::data->renderDND(pMonitor, time);
}
@@ -2426,9 +2422,6 @@ void CHyprRenderer::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFram
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
// this is a hack but it works :P
// we need to disable blur or else we will get a black background, as the shader
// will try to copy the bg to apply blur.
@@ -2445,7 +2438,7 @@ void CHyprRenderer::makeRawWindowSnapshot(PHLWINDOW pWindow, CFramebuffer* pFram
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
renderWindow(pWindow, PMONITOR, &now, false, RENDER_PASS_ALL, true);
renderWindow(pWindow, PMONITOR, Time::steadyNow(), false, RENDER_PASS_ALL, true);
**PBLUR = BLURVAL;
@@ -2481,9 +2474,6 @@ void CHyprRenderer::makeWindowSnapshot(PHLWINDOW pWindow) {
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
// this is a hack but it works :P
// we need to disable blur or else we will get a black background, as the shader
// will try to copy the bg to apply blur.
@@ -2495,7 +2485,7 @@ void CHyprRenderer::makeWindowSnapshot(PHLWINDOW pWindow) {
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
renderWindow(pWindow, PMONITOR, Time::steadyNow(), !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL);
**PBLUR = BLURVAL;
@@ -2528,14 +2518,11 @@ void CHyprRenderer::makeLayerSnapshot(PHLLS pLayer) {
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0)); // JIC
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
const auto BLURLSSTATUS = pLayer->forceBlur;
pLayer->forceBlur = false;
// draw the layer
renderLayer(pLayer, PMONITOR, &now);
renderLayer(pLayer, PMONITOR, Time::steadyNow());
pLayer->forceBlur = BLURLSSTATUS;

View File

@@ -6,8 +6,9 @@
#include "../desktop/LayerSurface.hpp"
#include "OpenGL.hpp"
#include "Renderbuffer.hpp"
#include "../helpers/Timer.hpp"
#include "../helpers/time/Timer.hpp"
#include "../helpers/math/Math.hpp"
#include "../helpers/time/Time.hpp"
struct SMonitorRule;
class CWorkspace;
@@ -66,7 +67,7 @@ class CHyprRenderer {
void calculateUVForSurface(PHLWINDOW, SP<CWLSurfaceResource>, PHLMONITOR pMonitor, bool main = false, const Vector2D& projSize = {}, const Vector2D& projSizeUnscaled = {},
bool fixMisalignedFSV1 = false);
std::tuple<float, float, float> getRenderTimes(PHLMONITOR pMonitor); // avg max min
void renderLockscreen(PHLMONITOR pMonitor, timespec* now, const CBox& geometry);
void renderLockscreen(PHLMONITOR pMonitor, const Time::steady_tp& now, const CBox& geometry);
void recheckSolitaryForMonitor(PHLMONITOR pMonitor);
void setCursorSurface(SP<CWLSurface> surf, int hotspotX, int hotspotY, bool force = false);
void setCursorFromName(const std::string& name, bool force = false);
@@ -115,27 +116,27 @@ class CHyprRenderer {
CRenderPass m_sRenderPass = {};
private:
void arrangeLayerArray(PHLMONITOR, const std::vector<PHLLSREF>&, bool, CBox*);
void renderWorkspaceWindowsFullscreen(PHLMONITOR, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special)
void renderWorkspaceWindows(PHLMONITOR, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special)
void renderWindow(PHLWINDOW, PHLMONITOR, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool standalone = false);
void renderLayer(PHLLS, PHLMONITOR, timespec*, bool popups = false);
void renderSessionLockSurface(WP<SSessionLockSurface>, PHLMONITOR, timespec*);
void renderDragIcon(PHLMONITOR, timespec*);
void renderIMEPopup(CInputPopup*, PHLMONITOR, timespec*);
void renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry);
void sendFrameEventsToWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now); // sends frame displayed events but doesn't actually render anything
void renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
void renderSessionLockMissing(PHLMONITOR pMonitor);
void arrangeLayerArray(PHLMONITOR, const std::vector<PHLLSREF>&, bool, CBox*);
void renderWorkspaceWindowsFullscreen(PHLMONITOR, PHLWORKSPACE, const Time::steady_tp&); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special)
void renderWorkspaceWindows(PHLMONITOR, PHLWORKSPACE, const Time::steady_tp&); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special)
void renderWindow(PHLWINDOW, PHLMONITOR, const Time::steady_tp&, bool, eRenderPassMode, bool ignorePosition = false, bool standalone = false);
void renderLayer(PHLLS, PHLMONITOR, const Time::steady_tp&, bool popups = false);
void renderSessionLockSurface(WP<SSessionLockSurface>, PHLMONITOR, const Time::steady_tp&);
void renderDragIcon(PHLMONITOR, const Time::steady_tp&);
void renderIMEPopup(CInputPopup*, PHLMONITOR, const Time::steady_tp&);
void renderWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const CBox& geometry);
void sendFrameEventsToWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now); // sends frame displayed events but doesn't actually render anything
void renderAllClientsForWorkspace(PHLMONITOR pMonitor, PHLWORKSPACE pWorkspace, const Time::steady_tp& now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
void renderSessionLockMissing(PHLMONITOR pMonitor);
bool commitPendingAndDoExplicitSync(PHLMONITOR pMonitor);
bool commitPendingAndDoExplicitSync(PHLMONITOR pMonitor);
bool m_bCursorHidden = false;
bool m_bCursorHasSurface = false;
SP<CRenderbuffer> m_pCurrentRenderbuffer = nullptr;
SP<Aquamarine::IBuffer> m_pCurrentBuffer = nullptr;
eRenderMode m_eRenderMode = RENDER_MODE_NORMAL;
bool m_bNvidia = false;
bool m_bCursorHidden = false;
bool m_bCursorHasSurface = false;
SP<CRenderbuffer> m_pCurrentRenderbuffer = nullptr;
SP<Aquamarine::IBuffer> m_pCurrentBuffer = nullptr;
eRenderMode m_eRenderMode = RENDER_MODE_NORMAL;
bool m_bNvidia = false;
struct {
bool hiddenOnTouch = false;

View File

@@ -1,6 +1,7 @@
#pragma once
#include "PassElement.hpp"
#include <optional>
#include "../../helpers/time/Time.hpp"
class CWLSurfaceResource;
class CTexture;
@@ -10,7 +11,7 @@ class CSurfacePassElement : public IPassElement {
public:
struct SRenderData {
PHLMONITORREF pMonitor;
timespec* when = nullptr;
Time::steady_tp when = Time::steadyNow();
Vector2D pos, localPos;
void* data = nullptr;

View File

@@ -3,6 +3,7 @@
#include "../protocols/XWaylandShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../managers/ANRManager.hpp"
#include "../helpers/time/Time.hpp"
#ifndef NO_XWAYLAND
@@ -253,12 +254,9 @@ void CXWaylandSurface::ping() {
return;
}
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
xcb_client_message_data_t msg = {};
msg.data32[0] = HYPRATOMS["_NET_WM_PING"];
msg.data32[1] = now.tv_sec * 1000 + now.tv_nsec / 1000000;
msg.data32[1] = Time::millis(Time::steadyNow());
msg.data32[2] = xID;
lastPingSeq = msg.data32[1];