core: wait for dmabuf readiness (#9806)

* add doOnReadable to event loop manager

* move syncTimeline addWaiter to doOnReadable

* wait on dmabuf buffers to be readable

* don't over synchronize in scanout, also give present feedback on same buffer commit
This commit is contained in:
Ikalco
2025-04-15 18:02:31 -05:00
committed by GitHub
parent ffd6cf65e4
commit 0e521788bc
8 changed files with 147 additions and 116 deletions

View File

@@ -1377,6 +1377,10 @@ bool CMonitor::attemptDirectScanout() {
auto PBUFFER = PSURFACE->current.buffer.buffer;
if (PBUFFER == output->state->state().buffer) {
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
PSURFACE->presentFeedback(&now, self.lock());
if (scanoutNeedsCursorUpdate) {
if (!state.test()) {
Debug::log(TRACE, "attemptDirectScanout: failed basic test");
@@ -1423,32 +1427,10 @@ bool CMonitor::attemptDirectScanout() {
output->state->addDamage(PSURFACE->current.accumulateBufferDamage());
output->state->resetExplicitFences();
auto cleanup = CScopeGuard([this]() { output->state->resetExplicitFences(); });
auto explicitOptions = g_pHyprRenderer->getExplicitSyncSettings(output);
bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->current.buffer && PSURFACE->current.acquire && explicitOptions.explicitKMSEnabled;
if (DOEXPLICIT) {
// wait for surface's explicit fence if present
inFence = PSURFACE->current.acquire.exportAsFD();
if (inFence.isValid()) {
Debug::log(TRACE, "attemptDirectScanout: setting IN_FENCE for aq to {}", inFence.get());
output->state->setExplicitInFence(inFence.get());
} else {
Debug::log(TRACE, "attemptDirectScanout: failed to acquire an sync file fd for aq IN_FENCE");
DOEXPLICIT = false;
}
}
// no need to do explicit sync here as surface current can only ever be ready to read
bool ok = output->commit();
if (!ok && DOEXPLICIT) {
Debug::log(TRACE, "attemptDirectScanout: EXPLICIT SYNC FAILED: commit() returned false. Resetting fences and retrying, might result in glitches.");
output->state->resetExplicitFences();
ok = output->commit();
}
if (!ok) {
Debug::log(TRACE, "attemptDirectScanout: failed to scanout surface");
lastScanout.reset();