This commit is contained in:
Vaxry 2024-03-18 22:15:02 +00:00
parent a8dc0d3824
commit 2f19e5be0f
7 changed files with 43 additions and 48 deletions

View file

@ -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) {

View file

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

View file

@ -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) {

View file

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

View file

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

View file

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

View file

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