core: refactor and improve surface commit (#9805)

* make CHLBufferReference not a SP anymore

* copy over release and acquire points in CHLBufferReference

* use CHLBufferReference in screencopy and toplevel export

TODO: use CHLBufferReference in direct scanout properly
      the only problem is the scanout buffer release timing,
      specifically the onBackendRelease mechanism

* cleanup SSurfaceState and surface pending commit tracking

* move surface code from DRMSyncobj, and move acquire to SSurfaceState

* use queue for comitted pending surface states like proto says

"The content update is placed in a queue until it becomes active." - wl_surface::commit

* drop, not release, prev buffer if 2nd buffer wl_surface.attach is sent

"A wl_buffer that has been attached and then replaced by another attach instead of committed will not receive a release event, and is not used by the compositor." - wl_surface::attach
This commit is contained in:
Ikalco
2025-04-07 14:03:27 -05:00
committed by GitHub
parent 70ae99f521
commit da86db43d4
15 changed files with 285 additions and 223 deletions

View File

@@ -1348,13 +1348,13 @@ bool CMonitor::attemptDirectScanout() {
return false;
// we can't scanout shm buffers.
const auto params = PSURFACE->current.buffer->buffer->dmabuf();
const auto params = PSURFACE->current.buffer->dmabuf();
if (!params.success || !PSURFACE->current.texture->m_pEglImage /* dmabuf */)
return false;
Debug::log(TRACE, "attemptDirectScanout: surface {:x} passed, will attempt, buffer {}", (uintptr_t)PSURFACE.get(), (uintptr_t)PSURFACE->current.buffer->buffer.get());
Debug::log(TRACE, "attemptDirectScanout: surface {:x} passed, will attempt, buffer {}", (uintptr_t)PSURFACE.get(), (uintptr_t)PSURFACE->current.buffer.buffer.get());
auto PBUFFER = PSURFACE->current.buffer->buffer;
auto PBUFFER = PSURFACE->current.buffer.buffer;
if (PBUFFER == output->state->state().buffer) {
if (scanoutNeedsCursorUpdate) {
@@ -1407,10 +1407,10 @@ bool CMonitor::attemptDirectScanout() {
auto explicitOptions = g_pHyprRenderer->getExplicitSyncSettings(output);
bool DOEXPLICIT = PSURFACE->syncobj && PSURFACE->current.buffer && PSURFACE->current.buffer->acquire && explicitOptions.explicitKMSEnabled;
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.buffer->acquire->exportAsFD();
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());