explicit sync stuff

This commit is contained in:
Vaxry 2024-07-09 17:31:04 +02:00
parent 00128256ef
commit 75f6de6bef
2 changed files with 79 additions and 28 deletions

View File

@ -1431,31 +1431,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
pMonitor->output->state->setPresentationMode(shouldTear ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE :
Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC);
// apply timelines for explicit sync
bool anyExplicit = !explicitPresented.empty();
if (anyExplicit) {
pMonitor->output->state->setExplicitInFence(pMonitor->inTimeline->exportAsSyncFileFD(pMonitor->lastWaitPoint));
for (auto& e : explicitPresented) {
if (!e->syncobj || !e->syncobj->releaseTimeline)
continue;
e->syncobj->releaseTimeline->timeline->transfer(pMonitor->outTimeline, pMonitor->commitSeq, e->syncobj->releasePoint);
}
explicitPresented.clear();
pMonitor->output->state->setExplicitOutFence(pMonitor->outTimeline->exportAsSyncFileFD(pMonitor->commitSeq));
}
pMonitor->lastWaitPoint = 0;
pMonitor->commitSeq++;
if (!pMonitor->state.commit()) {
// rollback the buffer to avoid writing to the front buffer that is being
// displayed
pMonitor->output->swapchain->rollback();
pMonitor->damage.damageEntire();
return;
}
commitPendingAndDoExplicitSync(pMonitor);
if (shouldTear)
pMonitor->tearingState.busy = true;
@ -1478,6 +1454,46 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
}
}
bool CHyprRenderer::commitPendingAndDoExplicitSync(CMonitor* pMonitor) {
// apply timelines for explicit sync
bool anyExplicit = !explicitPresented.empty();
if (anyExplicit) {
pMonitor->output->state->setExplicitInFence(pMonitor->inTimeline->exportAsSyncFileFD(pMonitor->lastWaitPoint));
for (auto& e : explicitPresented) {
if (!e->syncobj || !e->syncobj->releaseTimeline)
continue;
e->syncobj->releaseTimeline->timeline->transfer(pMonitor->outTimeline, pMonitor->commitSeq, e->syncobj->releasePoint);
}
explicitPresented.clear();
pMonitor->output->state->setExplicitOutFence(pMonitor->outTimeline->exportAsSyncFileFD(pMonitor->commitSeq));
}
pMonitor->lastWaitPoint = 0;
const auto COMMITTED_OUT = pMonitor->output->state->state().explicitOutFence;
const auto COMMITTED_IN = pMonitor->output->state->state().explicitInFence;
if (!pMonitor->state.commit()) {
// rollback the buffer to avoid writing to the front buffer that is being
// displayed
pMonitor->output->swapchain->rollback();
pMonitor->damage.damageEntire();
return false;
}
if (COMMITTED_IN >= 0)
close(COMMITTED_IN);
if (COMMITTED_OUT >= 0) {
pMonitor->outTimeline->importFromSyncFileFD(pMonitor->commitSeq, COMMITTED_OUT);
close(COMMITTED_OUT);
}
return true;
}
void CHyprRenderer::renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) {
Vector2D translate = {geometry.x, geometry.y};
float scale = (float)geometry.width / pMonitor->vecPixelSize.x;
@ -2658,6 +2674,8 @@ void CHyprRenderer::endRender() {
const auto PMONITOR = g_pHyprOpenGL->m_RenderData.pMonitor;
static auto PNVIDIAANTIFLICKER = CConfigValue<Hyprlang::INT>("opengl:nvidia_anti_flicker");
PMONITOR->commitSeq++;
if (m_eRenderMode != RENDER_MODE_TO_BUFFER_READ_ONLY)
g_pHyprOpenGL->end();
else {
@ -2671,12 +2689,43 @@ void CHyprRenderer::endRender() {
if (isNvidia() && *PNVIDIAANTIFLICKER)
glFinish();
else
glFlush();
if (m_eRenderMode == RENDER_MODE_NORMAL)
if (m_eRenderMode == RENDER_MODE_NORMAL) {
PMONITOR->output->state->setBuffer(m_pCurrentBuffer);
if (PMONITOR->output->state->state().explicitOutFence >= 0) {
auto sync = g_pHyprOpenGL->createEGLSync(-1);
if (!sync) {
m_pCurrentRenderbuffer->unbind();
m_pCurrentRenderbuffer = nullptr;
m_pCurrentBuffer = nullptr;
Debug::log(ERR, "renderer: couldn't create an EGLSync for out in endRender");
return;
}
auto dupedfd = sync->dupFenceFD();
sync.reset();
if (dupedfd < 0) {
m_pCurrentRenderbuffer->unbind();
m_pCurrentRenderbuffer = nullptr;
m_pCurrentBuffer = nullptr;
Debug::log(ERR, "renderer: couldn't dup an EGLSync fence for out in endRender");
return;
}
bool ok = PMONITOR->outTimeline->importFromSyncFileFD(PMONITOR->commitSeq, dupedfd);
close(dupedfd);
if (!ok) {
m_pCurrentRenderbuffer->unbind();
m_pCurrentRenderbuffer = nullptr;
m_pCurrentBuffer = nullptr;
Debug::log(ERR, "renderer: couldn't import from sync file fd in endRender");
return;
}
} else
glFlush();
}
m_pCurrentRenderbuffer->unbind();
m_pCurrentRenderbuffer = nullptr;

View File

@ -121,6 +121,8 @@ class CHyprRenderer {
void sendFrameEventsToWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now); // sends frame displayed events but doesn't actually render anything
void renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f);
bool commitPendingAndDoExplicitSync(CMonitor* pMonitor);
bool m_bCursorHidden = false;
bool m_bCursorHasSurface = false;
SP<CRenderbuffer> m_pCurrentRenderbuffer = nullptr;