diff --git a/src/managers/FrameSchedulingManager.cpp b/src/managers/FrameSchedulingManager.cpp index d89a379b..367f6746 100644 --- a/src/managers/FrameSchedulingManager.cpp +++ b/src/managers/FrameSchedulingManager.cpp @@ -190,18 +190,12 @@ void CFrameSchedulingManager::onPresent(CMonitor* pMonitor, wlr_output_event_pre } else µsUntilVblank = std::chrono::duration_cast(DATA->nextVblank - std::chrono::system_clock::now()).count(); - if (µsUntilVblank > 100) - DATA->vblankTimer->updateTimeout(std::chrono::microseconds(µsUntilVblank / 2)); + if (µsUntilVblank > 500) + DATA->vblankTimer->updateTimeout(std::chrono::microseconds(µsUntilVblank - 500)); Debug::log(LOG, "until vblank {}µs", µsUntilVblank); renderMonitor(DATA); - -#ifndef GLES2 - g_pHyprRenderer->makeEGLCurrent(); - - DATA->fenceSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -#endif } CFrameSchedulingManager::SSchedulingData* CFrameSchedulingManager::dataFor(CMonitor* pMonitor) { @@ -254,7 +248,7 @@ void CFrameSchedulingManager::renderMonitor(SSchedulingData* data) { pMonitor->tearingState.frameScheduledWhileBusy = false; } - g_pHyprRenderer->renderMonitor(pMonitor); + data->fenceSync = g_pHyprRenderer->renderMonitor(pMonitor, !data->legacyScheduler); data->rendered = true; } @@ -263,6 +257,8 @@ void CFrameSchedulingManager::onVblankTimer(void* data) { #ifndef GLES2 + g_pHyprRenderer->makeEGLCurrent(); + GLint syncStatus = 0; glGetSynciv(DATA->fenceSync, GL_SYNC_STATUS, sizeof(GLint), nullptr, &syncStatus); bool GPUSignaled = syncStatus == GL_SIGNALED; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index fe0ae918..d4759560 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1062,7 +1062,7 @@ bool CHyprRenderer::attemptDirectScanout(CMonitor* pMonitor) { return true; } -void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { +GLsync CHyprRenderer::renderMonitor(CMonitor* pMonitor, bool withSync) { static std::chrono::high_resolution_clock::time_point renderStart = std::chrono::high_resolution_clock::now(); static std::chrono::high_resolution_clock::time_point renderStartOverlay = std::chrono::high_resolution_clock::now(); @@ -1122,7 +1122,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { if (pMonitor->framesToSkip > 10) pMonitor->framesToSkip = 0; - return; + return nullptr; } // checks // @@ -1150,7 +1150,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { if (!wlr_gamma_control_v1_apply(PGAMMACTRL, pMonitor->state.wlr())) { Debug::log(ERR, "Could not apply gamma control to {}", pMonitor->szName); - return; + return nullptr; } if (!wlr_output_test_state(pMonitor->output, pMonitor->state.wlr())) { @@ -1168,17 +1168,17 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { if (!*PTEARINGENABLED) { Debug::log(WARN, "Tearing commit requested but the master switch general:allow_tearing is off, ignoring"); - return; + return nullptr; } if (g_pHyprOpenGL->m_RenderData.mouseZoomFactor != 1.0) { Debug::log(WARN, "Tearing commit requested but scale factor is not 1, ignoring"); - return; + return nullptr; } if (!pMonitor->tearingState.canTear) { Debug::log(WARN, "Tearing commit requested but monitor doesn't support it, ignoring"); - return; + return nullptr; } if (pMonitor->solitaryClient) @@ -1187,7 +1187,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { if (!*PNODIRECTSCANOUT && !shouldTear) { if (attemptDirectScanout(pMonitor)) { - return; + return nullptr; } else if (m_pLastScanout) { Debug::log(LOG, "Left a direct scanout."); m_pLastScanout = nullptr; @@ -1208,11 +1208,11 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current); if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0) - return; + return nullptr; if (*PDAMAGETRACKINGMODE == -1) { Debug::log(CRIT, "Damage tracking mode -1 ????"); - return; + return nullptr; } EMIT_HOOK_EVENT("render", RENDER_PRE); @@ -1252,7 +1252,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { pMonitor->state.clear(); - return; + return nullptr; } // if we have no tracking or full tracking, invalidate the entire monitor @@ -1352,6 +1352,10 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { EMIT_HOOK_EVENT("render", RENDER_LAST_MOMENT); + GLsync sync = nullptr; + if (withSync) + sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + endRender(); TRACY_GPU_COLLECT; @@ -1384,7 +1388,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { wlr_damage_ring_add_whole(&pMonitor->damage); - return; + return sync; } if (shouldTear) @@ -1409,6 +1413,8 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { g_pDebugOverlay->renderDataNoOverlay(pMonitor, µs); } } + + return sync; } void CHyprRenderer::renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) { diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index d9a0a6e8..5f3b453d 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -38,11 +38,15 @@ class CToplevelExportProtocolManager; class CInputManager; struct SSessionLockSurface; +#ifdef GLES2 +#define GLsync void* +#endif + class CHyprRenderer { public: CHyprRenderer(); - void renderMonitor(CMonitor* pMonitor); + GLsync renderMonitor(CMonitor* pMonitor, bool withSync = false); void outputMgrApplyTest(wlr_output_configuration_v1*, bool); void arrangeLayersForMonitor(const int&); void damageSurface(wlr_surface*, double, double, double scale = 1.0);