mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-07 23:45:58 +01:00
work
This commit is contained in:
parent
a8dc0d3824
commit
2f19e5be0f
7 changed files with 43 additions and 48 deletions
|
@ -2383,7 +2383,7 @@ void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor) {
|
||||||
if (!pMonitor->frameNeededSource)
|
if (!pMonitor->frameNeededSource)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wl_event_source_timer_update(pMonitor->frameNeededSource, 1);
|
pMonitor->scheduleFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
|
CWindow* CCompositor::getWindowByRegex(const std::string& regexp) {
|
||||||
|
|
|
@ -340,8 +340,6 @@ CConfigManager::CConfigManager() {
|
||||||
m_pConfig->addConfigValue("misc:no_direct_scanout", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:no_direct_scanout", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("misc:hide_cursor_on_touch", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:hide_cursor_on_touch", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("misc:mouse_move_focuses_monitor", Hyprlang::INT{1});
|
m_pConfig->addConfigValue("misc:mouse_move_focuses_monitor", Hyprlang::INT{1});
|
||||||
m_pConfig->addConfigValue("misc:render_ahead_of_time", Hyprlang::INT{0});
|
|
||||||
m_pConfig->addConfigValue("misc:render_ahead_safezone", Hyprlang::INT{1});
|
|
||||||
m_pConfig->addConfigValue("misc:cursor_zoom_factor", {1.f});
|
m_pConfig->addConfigValue("misc:cursor_zoom_factor", {1.f});
|
||||||
m_pConfig->addConfigValue("misc:cursor_zoom_rigid", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("misc:cursor_zoom_rigid", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("misc:allow_session_lock_restore", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("misc:allow_session_lock_restore", Hyprlang::INT{0});
|
||||||
|
|
|
@ -127,40 +127,7 @@ void Events::listener_monitorFrame(void* owner, void* data) {
|
||||||
|
|
||||||
CMonitor* const PMONITOR = (CMonitor*)owner;
|
CMonitor* const PMONITOR = (CMonitor*)owner;
|
||||||
|
|
||||||
return; // TODO: remove completely
|
g_pFrameSchedulingManager->onFrame(PMONITOR);
|
||||||
|
|
||||||
static auto PENABLERAT = CConfigValue<Hyprlang::INT>("misc:render_ahead_of_time");
|
|
||||||
static auto PRATSAFE = CConfigValue<Hyprlang::INT>("misc:render_ahead_safezone");
|
|
||||||
|
|
||||||
PMONITOR->lastPresentationTimer.reset();
|
|
||||||
|
|
||||||
if (*PENABLERAT && !PMONITOR->tearingState.nextRenderTorn) {
|
|
||||||
if (!PMONITOR->RATScheduled) {
|
|
||||||
// render
|
|
||||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
PMONITOR->RATScheduled = false;
|
|
||||||
|
|
||||||
const auto& [avg, max, min] = g_pHyprRenderer->getRenderTimes(PMONITOR);
|
|
||||||
|
|
||||||
if (max + *PRATSAFE > 1000.0 / PMONITOR->refreshRate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto MSLEFT = 1000.0 / PMONITOR->refreshRate - PMONITOR->lastPresentationTimer.getMillis();
|
|
||||||
|
|
||||||
PMONITOR->RATScheduled = true;
|
|
||||||
|
|
||||||
const auto ESTRENDERTIME = std::ceil(avg + *PRATSAFE);
|
|
||||||
const auto TIMETOSLEEP = std::floor(MSLEFT - ESTRENDERTIME);
|
|
||||||
|
|
||||||
if (MSLEFT < 1 || MSLEFT < ESTRENDERTIME || TIMETOSLEEP < 1)
|
|
||||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
||||||
else
|
|
||||||
wl_event_source_timer_update(PMONITOR->renderTimer, TIMETOSLEEP);
|
|
||||||
} else {
|
|
||||||
g_pHyprRenderer->renderMonitor(PMONITOR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Events::listener_monitorDestroy(void* owner, void* data) {
|
void Events::listener_monitorDestroy(void* owner, void* data) {
|
||||||
|
|
|
@ -16,8 +16,6 @@ static int ratHandler(void* data) {
|
||||||
static int wlFrameCallback(void* data) {
|
static int wlFrameCallback(void* data) {
|
||||||
const auto PMONITOR = (CMonitor*)data;
|
const auto PMONITOR = (CMonitor*)data;
|
||||||
|
|
||||||
Debug::log(LOG, "wlFrameCallback");
|
|
||||||
|
|
||||||
g_pFrameSchedulingManager->onFrameNeeded(PMONITOR);
|
g_pFrameSchedulingManager->onFrameNeeded(PMONITOR);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -761,10 +759,18 @@ void CMonitor::updateMatrix() {
|
||||||
int64_t CMonitor::activeWorkspaceID() {
|
int64_t CMonitor::activeWorkspaceID() {
|
||||||
return activeWorkspace ? activeWorkspace->m_iID : 0;
|
return activeWorkspace ? activeWorkspace->m_iID : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t CMonitor::activeSpecialWorkspaceID() {
|
int64_t CMonitor::activeSpecialWorkspaceID() {
|
||||||
return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0;
|
return activeSpecialWorkspace ? activeSpecialWorkspace->m_iID : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMonitor::scheduleFrame() {
|
||||||
|
if (!g_pFrameSchedulingManager->isMonitorUsingLegacyScheduler(this))
|
||||||
|
wl_event_source_timer_update(frameNeededSource, 1);
|
||||||
|
else
|
||||||
|
wlr_output_schedule_frame(output);
|
||||||
|
}
|
||||||
|
|
||||||
CMonitorState::CMonitorState(CMonitor* owner) {
|
CMonitorState::CMonitorState(CMonitor* owner) {
|
||||||
m_pOwner = owner;
|
m_pOwner = owner;
|
||||||
wlr_output_state_init(&m_state);
|
wlr_output_state_init(&m_state);
|
||||||
|
|
|
@ -151,6 +151,7 @@ class CMonitor {
|
||||||
void updateMatrix();
|
void updateMatrix();
|
||||||
int64_t activeWorkspaceID();
|
int64_t activeWorkspaceID();
|
||||||
int64_t activeSpecialWorkspaceID();
|
int64_t activeSpecialWorkspaceID();
|
||||||
|
void scheduleFrame();
|
||||||
|
|
||||||
bool m_bEnabled = false;
|
bool m_bEnabled = false;
|
||||||
bool m_bRenderingInitPassed = false;
|
bool m_bRenderingInitPassed = false;
|
||||||
|
|
|
@ -14,6 +14,8 @@ void CFrameSchedulingManager::registerMonitor(CMonitor* pMonitor) {
|
||||||
|
|
||||||
SSchedulingData* DATA = &m_vSchedulingData.emplace_back(SSchedulingData{pMonitor});
|
SSchedulingData* DATA = &m_vSchedulingData.emplace_back(SSchedulingData{pMonitor});
|
||||||
DATA->event = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, onPresentTimer, DATA);
|
DATA->event = wl_event_loop_add_timer(g_pCompositor->m_sWLEventLoop, onPresentTimer, DATA);
|
||||||
|
|
||||||
|
DATA->legacyScheduler = !wlr_backend_is_drm(pMonitor->output->backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrameSchedulingManager::unregisterMonitor(CMonitor* pMonitor) {
|
void CFrameSchedulingManager::unregisterMonitor(CMonitor* pMonitor) {
|
||||||
|
@ -25,7 +27,7 @@ void CFrameSchedulingManager::onFrameNeeded(CMonitor* pMonitor) {
|
||||||
|
|
||||||
RASSERT(DATA, "No data in onFrameNeeded");
|
RASSERT(DATA, "No data in onFrameNeeded");
|
||||||
|
|
||||||
if (pMonitor->tearingState.activelyTearing)
|
if (pMonitor->tearingState.activelyTearing || DATA->legacyScheduler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (DATA->activelyPushing && DATA->lastPresent.getMillis() < 100) {
|
if (DATA->activelyPushing && DATA->lastPresent.getMillis() < 100) {
|
||||||
|
@ -34,8 +36,6 @@ void CFrameSchedulingManager::onFrameNeeded(CMonitor* pMonitor) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "onFrameNeeded");
|
|
||||||
|
|
||||||
DATA->noVblankTimer = true;
|
DATA->noVblankTimer = true;
|
||||||
onPresent(pMonitor, nullptr);
|
onPresent(pMonitor, nullptr);
|
||||||
}
|
}
|
||||||
|
@ -72,12 +72,23 @@ void CFrameSchedulingManager::dropBuffer(wlr_buffer* pBuffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CFrameSchedulingManager::onFrame(CMonitor* pMonitor) {
|
||||||
|
const auto DATA = dataFor(pMonitor);
|
||||||
|
|
||||||
|
RASSERT(DATA, "No data in onFrame");
|
||||||
|
|
||||||
|
if (!DATA->legacyScheduler)
|
||||||
|
return;
|
||||||
|
|
||||||
|
renderMonitor(DATA);
|
||||||
|
}
|
||||||
|
|
||||||
void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_present* presentationData) {
|
void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_present* presentationData) {
|
||||||
const auto DATA = dataFor(pMonitor);
|
const auto DATA = dataFor(pMonitor);
|
||||||
|
|
||||||
RASSERT(DATA, "No data in onPresent");
|
RASSERT(DATA, "No data in onPresent");
|
||||||
|
|
||||||
if (pMonitor->tearingState.activelyTearing) {
|
if (pMonitor->tearingState.activelyTearing || DATA->legacyScheduler) {
|
||||||
DATA->activelyPushing = false;
|
DATA->activelyPushing = false;
|
||||||
return; // don't render
|
return; // don't render
|
||||||
}
|
}
|
||||||
|
@ -88,8 +99,6 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "onPresent");
|
|
||||||
|
|
||||||
int forceFrames = DATA->forceFrames + pMonitor->forceFullFrames;
|
int forceFrames = DATA->forceFrames + pMonitor->forceFullFrames;
|
||||||
|
|
||||||
DATA->lastPresent.reset();
|
DATA->lastPresent.reset();
|
||||||
|
@ -115,8 +124,6 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "remder!");
|
|
||||||
|
|
||||||
// we can't do this on wayland
|
// we can't do this on wayland
|
||||||
if (!wlr_backend_is_wl(pMonitor->output->backend) && !DATA->noVblankTimer && presentationData) {
|
if (!wlr_backend_is_wl(pMonitor->output->backend) && !DATA->noVblankTimer && presentationData) {
|
||||||
const std::chrono::system_clock::time_point LASTVBLANK{std::chrono::duration_cast<std::chrono::system_clock::duration>(
|
const std::chrono::system_clock::time_point LASTVBLANK{std::chrono::duration_cast<std::chrono::system_clock::duration>(
|
||||||
|
@ -204,3 +211,12 @@ int CFrameSchedulingManager::onVblankTimer(void* data) {
|
||||||
Debug::log(ERR, "Vblank timer fired without a frame????");
|
Debug::log(ERR, "Vblank timer fired without a frame????");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CFrameSchedulingManager::isMonitorUsingLegacyScheduler(CMonitor* pMonitor) {
|
||||||
|
const auto DATA = dataFor(pMonitor);
|
||||||
|
|
||||||
|
if (!DATA)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return DATA->legacyScheduler;
|
||||||
|
}
|
||||||
|
|
|
@ -20,9 +20,12 @@ class CFrameSchedulingManager {
|
||||||
void onFrameNeeded(CMonitor* pMonitor);
|
void onFrameNeeded(CMonitor* pMonitor);
|
||||||
|
|
||||||
void onPresent(CMonitor* pMonitor, wlr_output_event_present* presentationData);
|
void onPresent(CMonitor* pMonitor, wlr_output_event_present* presentationData);
|
||||||
|
void onFrame(CMonitor* pMonitor);
|
||||||
|
|
||||||
int onVblankTimer(void* data);
|
int onVblankTimer(void* data);
|
||||||
|
|
||||||
|
bool isMonitorUsingLegacyScheduler(CMonitor* pMonitor);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SSchedulingData {
|
struct SSchedulingData {
|
||||||
CMonitor* pMonitor = nullptr;
|
CMonitor* pMonitor = nullptr;
|
||||||
|
@ -57,6 +60,10 @@ class CFrameSchedulingManager {
|
||||||
|
|
||||||
// whether we're actively pushing frames
|
// whether we're actively pushing frames
|
||||||
bool activelyPushing = false;
|
bool activelyPushing = false;
|
||||||
|
|
||||||
|
// legacy scheduler: for backends that do not send us reliable present events
|
||||||
|
// these rely on onFrame
|
||||||
|
bool legacyScheduler = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<SSchedulingData> m_vSchedulingData;
|
std::vector<SSchedulingData> m_vSchedulingData;
|
||||||
|
|
Loading…
Reference in a new issue