mirror of https://github.com/hyprwm/Hyprland
explicit sync stuff
This commit is contained in:
parent
37a96c6110
commit
13af7fb2fb
|
@ -1431,31 +1431,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||||
pMonitor->output->state->setPresentationMode(shouldTear ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE :
|
pMonitor->output->state->setPresentationMode(shouldTear ? Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_IMMEDIATE :
|
||||||
Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC);
|
Aquamarine::eOutputPresentationMode::AQ_OUTPUT_PRESENTATION_VSYNC);
|
||||||
|
|
||||||
// apply timelines for explicit sync
|
commitPendingAndDoExplicitSync(pMonitor);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldTear)
|
if (shouldTear)
|
||||||
pMonitor->tearingState.busy = true;
|
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) {
|
void CHyprRenderer::renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry) {
|
||||||
Vector2D translate = {geometry.x, geometry.y};
|
Vector2D translate = {geometry.x, geometry.y};
|
||||||
float scale = (float)geometry.width / pMonitor->vecPixelSize.x;
|
float scale = (float)geometry.width / pMonitor->vecPixelSize.x;
|
||||||
|
@ -2658,6 +2674,8 @@ void CHyprRenderer::endRender() {
|
||||||
const auto PMONITOR = g_pHyprOpenGL->m_RenderData.pMonitor;
|
const auto PMONITOR = g_pHyprOpenGL->m_RenderData.pMonitor;
|
||||||
static auto PNVIDIAANTIFLICKER = CConfigValue<Hyprlang::INT>("opengl:nvidia_anti_flicker");
|
static auto PNVIDIAANTIFLICKER = CConfigValue<Hyprlang::INT>("opengl:nvidia_anti_flicker");
|
||||||
|
|
||||||
|
PMONITOR->commitSeq++;
|
||||||
|
|
||||||
if (m_eRenderMode != RENDER_MODE_TO_BUFFER_READ_ONLY)
|
if (m_eRenderMode != RENDER_MODE_TO_BUFFER_READ_ONLY)
|
||||||
g_pHyprOpenGL->end();
|
g_pHyprOpenGL->end();
|
||||||
else {
|
else {
|
||||||
|
@ -2671,12 +2689,43 @@ void CHyprRenderer::endRender() {
|
||||||
|
|
||||||
if (isNvidia() && *PNVIDIAANTIFLICKER)
|
if (isNvidia() && *PNVIDIAANTIFLICKER)
|
||||||
glFinish();
|
glFinish();
|
||||||
else
|
|
||||||
glFlush();
|
|
||||||
|
|
||||||
if (m_eRenderMode == RENDER_MODE_NORMAL)
|
if (m_eRenderMode == RENDER_MODE_NORMAL) {
|
||||||
PMONITOR->output->state->setBuffer(m_pCurrentBuffer);
|
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->unbind();
|
||||||
|
|
||||||
m_pCurrentRenderbuffer = nullptr;
|
m_pCurrentRenderbuffer = nullptr;
|
||||||
|
|
|
@ -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 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);
|
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_bCursorHidden = false;
|
||||||
bool m_bCursorHasSurface = false;
|
bool m_bCursorHasSurface = false;
|
||||||
SP<CRenderbuffer> m_pCurrentRenderbuffer = nullptr;
|
SP<CRenderbuffer> m_pCurrentRenderbuffer = nullptr;
|
||||||
|
|
Loading…
Reference in New Issue