From 2f19e5be0f0250dc1a4540c832769119d57cb092 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 18 Mar 2024 22:15:02 +0000 Subject: [PATCH] work --- src/Compositor.cpp | 2 +- src/config/ConfigManager.cpp | 2 -- src/events/Monitors.cpp | 35 +------------------------ src/helpers/Monitor.cpp | 10 +++++-- src/helpers/Monitor.hpp | 1 + src/managers/FrameSchedulingManager.cpp | 34 +++++++++++++++++------- src/managers/FrameSchedulingManager.hpp | 7 +++++ 7 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/Compositor.cpp b/src/Compositor.cpp index 009e846d..19891ea3 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -2383,7 +2383,7 @@ void CCompositor::scheduleFrameForMonitor(CMonitor* pMonitor) { if (!pMonitor->frameNeededSource) return; - wl_event_source_timer_update(pMonitor->frameNeededSource, 1); + pMonitor->scheduleFrame(); } CWindow* CCompositor::getWindowByRegex(const std::string& regexp) { diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 2eafc892..1b662dd5 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -340,8 +340,6 @@ CConfigManager::CConfigManager() { 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: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_rigid", Hyprlang::INT{0}); m_pConfig->addConfigValue("misc:allow_session_lock_restore", Hyprlang::INT{0}); diff --git a/src/events/Monitors.cpp b/src/events/Monitors.cpp index 96059f50..6a7a28ec 100644 --- a/src/events/Monitors.cpp +++ b/src/events/Monitors.cpp @@ -127,40 +127,7 @@ void Events::listener_monitorFrame(void* owner, void* data) { CMonitor* const PMONITOR = (CMonitor*)owner; - return; // TODO: remove completely - - static auto PENABLERAT = CConfigValue("misc:render_ahead_of_time"); - static auto PRATSAFE = CConfigValue("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); - } + g_pFrameSchedulingManager->onFrame(PMONITOR); } void Events::listener_monitorDestroy(void* owner, void* data) { diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 8fcfa02d..058da621 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -16,8 +16,6 @@ static int ratHandler(void* data) { static int wlFrameCallback(void* data) { const auto PMONITOR = (CMonitor*)data; - Debug::log(LOG, "wlFrameCallback"); - g_pFrameSchedulingManager->onFrameNeeded(PMONITOR); return 1; @@ -761,10 +759,18 @@ void CMonitor::updateMatrix() { int64_t CMonitor::activeWorkspaceID() { return activeWorkspace ? activeWorkspace->m_iID : 0; } + int64_t CMonitor::activeSpecialWorkspaceID() { 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) { m_pOwner = owner; wlr_output_state_init(&m_state); diff --git a/src/helpers/Monitor.hpp b/src/helpers/Monitor.hpp index d0c0b136..1f862dad 100644 --- a/src/helpers/Monitor.hpp +++ b/src/helpers/Monitor.hpp @@ -151,6 +151,7 @@ class CMonitor { void updateMatrix(); int64_t activeWorkspaceID(); int64_t activeSpecialWorkspaceID(); + void scheduleFrame(); bool m_bEnabled = false; bool m_bRenderingInitPassed = false; diff --git a/src/managers/FrameSchedulingManager.cpp b/src/managers/FrameSchedulingManager.cpp index 992a65be..5b2e4b6d 100644 --- a/src/managers/FrameSchedulingManager.cpp +++ b/src/managers/FrameSchedulingManager.cpp @@ -14,6 +14,8 @@ void CFrameSchedulingManager::registerMonitor(CMonitor* pMonitor) { SSchedulingData* DATA = &m_vSchedulingData.emplace_back(SSchedulingData{pMonitor}); 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) { @@ -25,7 +27,7 @@ void CFrameSchedulingManager::onFrameNeeded(CMonitor* pMonitor) { RASSERT(DATA, "No data in onFrameNeeded"); - if (pMonitor->tearingState.activelyTearing) + if (pMonitor->tearingState.activelyTearing || DATA->legacyScheduler) return; if (DATA->activelyPushing && DATA->lastPresent.getMillis() < 100) { @@ -34,8 +36,6 @@ void CFrameSchedulingManager::onFrameNeeded(CMonitor* pMonitor) { return; } - Debug::log(LOG, "onFrameNeeded"); - DATA->noVblankTimer = true; 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) { const auto DATA = dataFor(pMonitor); RASSERT(DATA, "No data in onPresent"); - if (pMonitor->tearingState.activelyTearing) { + if (pMonitor->tearingState.activelyTearing || DATA->legacyScheduler) { DATA->activelyPushing = false; return; // don't render } @@ -88,8 +99,6 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre return; } - Debug::log(LOG, "onPresent"); - int forceFrames = DATA->forceFrames + pMonitor->forceFullFrames; DATA->lastPresent.reset(); @@ -115,8 +124,6 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre return; } - Debug::log(LOG, "remder!"); - // we can't do this on wayland if (!wlr_backend_is_wl(pMonitor->output->backend) && !DATA->noVblankTimer && presentationData) { const std::chrono::system_clock::time_point LASTVBLANK{std::chrono::duration_cast( @@ -203,4 +210,13 @@ int CFrameSchedulingManager::onVblankTimer(void* data) { // what the fuck? Debug::log(ERR, "Vblank timer fired without a frame????"); return 0; -} \ No newline at end of file +} + +bool CFrameSchedulingManager::isMonitorUsingLegacyScheduler(CMonitor* pMonitor) { + const auto DATA = dataFor(pMonitor); + + if (!DATA) + return true; + + return DATA->legacyScheduler; +} diff --git a/src/managers/FrameSchedulingManager.hpp b/src/managers/FrameSchedulingManager.hpp index 80c2c507..a26aadd4 100644 --- a/src/managers/FrameSchedulingManager.hpp +++ b/src/managers/FrameSchedulingManager.hpp @@ -20,9 +20,12 @@ class CFrameSchedulingManager { void onFrameNeeded(CMonitor* pMonitor); void onPresent(CMonitor* pMonitor, wlr_output_event_present* presentationData); + void onFrame(CMonitor* pMonitor); int onVblankTimer(void* data); + bool isMonitorUsingLegacyScheduler(CMonitor* pMonitor); + private: struct SSchedulingData { CMonitor* pMonitor = nullptr; @@ -57,6 +60,10 @@ class CFrameSchedulingManager { // whether we're actively pushing frames bool activelyPushing = false; + + // legacy scheduler: for backends that do not send us reliable present events + // these rely on onFrame + bool legacyScheduler = false; }; std::vector m_vSchedulingData;