Repository: hyprwm/Hyprland
File: src/protocols/DRMSyncobj.cpp (C++)

Code before:

    listeners.surfacePrecommit = surface->events.precommit.registerListener([this](std::any d) {
        if (!surface->pending.buffer && surface->pending.newBuffer && !surface->pending.texture) {
            removeAllWaiters();
            surface->commitPendingState(surface->pending);
            return; // null buffer attached.
        }

        if (!surface->pending.buffer && !surface->pending.newBuffer && surface->current.buffer) {
            surface->current.bufferDamage.clear();
            surface->current.damage.clear();
            surface->commitPendingState(surface->current);
            return; // no new buffer, but we still have current around and a commit happend, commit current again.
        }

        if (!surface->pending.buffer && !surface->pending.newBuffer && !surface->current.buffer) {
            surface->commitPendingState(surface->pending); // no pending buffer, no current buffer. probably first commit
            return;
        }

        if (!pendingAcquire.timeline().expired()) {
            surface->pending.buffer->acquire = makeUnique<CDRMSyncPointState>(std::move(pendingAcquire));
            pendingAcquire                   = {};
        }

        if (!pendingRelease.timeline().expired()) {
            surface->pending.buffer->release = makeUnique<CDRMSyncPointState>(std::move(pendingRelease));
            pendingRelease                   = {};
        }

        if (protocolError())
            return;

        const auto& state = pendingStates.emplace_back(makeShared<SSurfaceState>(surface->pending));
        surface->pending.damage.clear();
        surface->pending.bufferDamage.clear();
        surface->pending.newBuffer = false;
        surface->pending.buffer.reset();

        state->buffer->buffer->syncReleaser = state->buffer->release->createSyncRelease();
        state->buffer->acquire->addWaiter([this, surf = surface, wp = CWeakPointer<SSurfaceState>(*std::prev(pendingStates.end()))] {
            if (!surf)
                return;

            surf->commitPendingState(*wp.lock());
            std::erase(pendingStates, wp);
        });
    });
}

void CDRMSyncobjSurfaceResource::removeAllWaiters() {

Review comment (suggestion):
I think this can just be a null check now. The timeline method should return an SP instead of a WP. Other than that, this change looks great to me and makes the lifetimes a lot more understandable I think.

Code after:

    listeners.surfacePrecommit = surface->events.precommit.registerListener([this](std::any d) {
        if (!surface->pending.buffer && surface->pending.newBuffer && !surface->pending.texture) {
            removeAllWaiters();
            surface->commitPendingState(surface->pending);
            return; // null buffer attached.
        }

        if (!surface->pending.buffer && !surface->pending.newBuffer && surface->current.buffer) {
            surface->current.bufferDamage.clear();
            surface->current.damage.clear();
            surface->commitPendingState(surface->current);
            return; // no new buffer, but we still have current around and a commit happend, commit current again.
        }

        if (!surface->pending.buffer && !surface->pending.newBuffer && !surface->current.buffer) {
            surface->commitPendingState(surface->pending); // no pending buffer, no current buffer. probably first commit
            return;
        }

        if (pendingAcquire.timeline()) {
            surface->pending.buffer->acquire = makeUnique<CDRMSyncPointState>(std::move(pendingAcquire));
            pendingAcquire                   = {};
        }

        if (pendingRelease.timeline()) {
            surface->pending.buffer->release = makeUnique<CDRMSyncPointState>(std::move(pendingRelease));
            pendingRelease                   = {};
        }

        if (protocolError())
            return;

        const auto& state = pendingStates.emplace_back(makeShared<SSurfaceState>(surface->pending));
        surface->pending.damage.clear();
        surface->pending.bufferDamage.clear();
        surface->pending.newBuffer = false;
        surface->pending.buffer.reset();

        state->buffer->buffer->syncReleaser = state->buffer->release->createSyncRelease();
        state->buffer->acquire->addWaiter([this, surf = surface, wp = CWeakPointer<SSurfaceState>(*std::prev(pendingStates.end()))] {
            if (!surf)
                return;

            surf->commitPendingState(*wp.lock());
            std::erase(pendingStates, wp);
        });
    });
}

void CDRMSyncobjSurfaceResource::removeAllWaiters() {