diff options
| author | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2024-07-21 13:09:54 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-21 13:09:54 +0200 |
| commit | 016da234d0e852de3ef20eb2e89ac58d2a85f6e7 (patch) | |
| tree | 496085987176551b0794fffc069877d44943e2f1 /src/protocols/core/Compositor.cpp | |
| parent | f642fb97df5c69267a03452533de383ff8023570 (diff) | |
Core: Move to aquamarine (#6608)
Moves Hyprland from wlroots to aquamarine for the backend.
---------
Signed-off-by: Vaxry <vaxry@vaxry.net>
Co-authored-by: Mihai Fufezan <mihai@fufexan.net>
Co-authored-by: Jan Beich <jbeich@FreeBSD.org>
Co-authored-by: vaxerski <vaxerski@users.noreply.github.com>
Co-authored-by: UjinT34 <41110182+UjinT34@users.noreply.github.com>
Co-authored-by: Tom Englund <tomenglund26@gmail.com>
Co-authored-by: Ikalco <73481042+ikalco@users.noreply.github.com>
Co-authored-by: diniamo <diniamo53@gmail.com>
Diffstat (limited to 'src/protocols/core/Compositor.cpp')
| -rw-r--r-- | src/protocols/core/Compositor.cpp | 149 |
1 files changed, 99 insertions, 50 deletions
diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 691267b0..5cd6005a 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -6,6 +6,9 @@ #include "Subcompositor.hpp" #include "../Viewporter.hpp" #include "../../helpers/Monitor.hpp" +#include "../PresentationTime.hpp" +#include "../DRMSyncobj.hpp" +#include "../../render/Renderer.hpp" #define LOGM PROTO::compositor->protoLog @@ -102,58 +105,14 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> resource_) : resource(reso pending.size = tfs / pending.scale; } - if (viewportResource) - viewportResource->verify(); - pending.damage.intersect(CBox{{}, pending.size}); - auto previousBuffer = current.buffer; - CRegion previousBufferDamage = accumulateCurrentBufferDamage(); - - current = pending; - pending.damage.clear(); - pending.bufferDamage.clear(); - - if (current.buffer && !bufferReleased) { - // without previous dolphin et al are weird vvv - //CRegion surfaceDamage = - // current.damage.copy().scale(current.scale).transform(current.transform, current.size.x, current.size.y).add(current.bufferDamage).add(previousBufferDamage); - current.buffer->update(CBox{{}, {INT32_MAX, INT32_MAX}}); // FIXME: figure this out to not use this hack. QT apps are wonky without this. - - // release the buffer if it's synchronous as update() has done everything thats needed - // so we can let the app know we're done. - if (current.buffer->isSynchronous()) { - current.buffer->sendRelease(); - bufferReleased = true; - } - } - - // TODO: we should _accumulate_ and not replace above if sync - if (role->role() == SURFACE_ROLE_SUBSURFACE) { - auto subsurface = (CWLSubsurfaceResource*)role.get(); - if (subsurface->sync) - return; - - events.commit.emit(); - } else { - // send commit to all synced surfaces in this tree. - breadthfirst( - [](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { - if (surf->role->role() == SURFACE_ROLE_SUBSURFACE) { - auto subsurface = (CWLSubsurfaceResource*)surf->role.get(); - if (!subsurface->sync) - return; - } - surf->events.commit.emit(); - }, - nullptr); - } + events.precommit.emit(); + if (pending.rejected) + return; - // for async buffers, we can only release the buffer once we are unrefing it from current. - if (previousBuffer && !previousBuffer->isSynchronous() && !bufferReleased) { - previousBuffer->sendRelease(); - bufferReleased = true; - } + if (stateLocks <= 0) + commitPendingState(); }); resource->setDamage([this](CWlSurface* r, int32_t x, int32_t y, int32_t w, int32_t h) { pending.damage.add(CBox{x, y, w, h}); }); @@ -426,7 +385,97 @@ CRegion CWLSurfaceResource::accumulateCurrentBufferDamage() { Vector2D trc = current.transform % 2 == 1 ? Vector2D{current.buffer->size.y, current.buffer->size.x} : current.buffer->size; - return surfaceDamage.scale(current.scale).transform(wlTransformToHyprutils(wlr_output_transform_invert(current.transform)), trc.x, trc.y).add(current.bufferDamage); + return surfaceDamage.scale(current.scale).transform(wlTransformToHyprutils(invertTransform(current.transform)), trc.x, trc.y).add(current.bufferDamage); +} + +void CWLSurfaceResource::lockPendingState() { + stateLocks++; +} + +void CWLSurfaceResource::unlockPendingState() { + stateLocks--; + if (stateLocks <= 0) + commitPendingState(); +} + +void CWLSurfaceResource::commitPendingState() { + auto previousBuffer = current.buffer; + CRegion previousBufferDamage = accumulateCurrentBufferDamage(); + + current = pending; + pending.damage.clear(); + pending.bufferDamage.clear(); + + if (current.buffer && !bufferReleased) { + // without previous dolphin et al are weird vvv + //CRegion surfaceDamage = + // current.damage.copy().scale(current.scale).transform(current.transform, current.size.x, current.size.y).add(current.bufferDamage).add(previousBufferDamage); + current.buffer->update(CBox{{}, {INT32_MAX, INT32_MAX}}); // FIXME: figure this out to not use this hack. QT apps are wonky without this. + + // release the buffer if it's synchronous as update() has done everything thats needed + // so we can let the app know we're done. + if (current.buffer->isSynchronous()) { + current.buffer->sendReleaseWithSurface(self.lock()); + bufferReleased = true; + } + } + + // TODO: we should _accumulate_ and not replace above if sync + if (role->role() == SURFACE_ROLE_SUBSURFACE) { + auto subsurface = (CWLSubsurfaceResource*)role.get(); + if (subsurface->sync) + return; + + events.commit.emit(); + } else { + // send commit to all synced surfaces in this tree. + breadthfirst( + [](SP<CWLSurfaceResource> surf, const Vector2D& offset, void* data) { + if (surf->role->role() == SURFACE_ROLE_SUBSURFACE) { + auto subsurface = (CWLSubsurfaceResource*)surf->role.get(); + if (!subsurface->sync) + return; + } + surf->events.commit.emit(); + }, + nullptr); + } + + // for async buffers, we can only release the buffer once we are unrefing it from current. + if (previousBuffer && !previousBuffer->isSynchronous() && !bufferReleased) { + if (previousBuffer->lockedByBackend) { + previousBuffer->hlEvents.backendRelease = previousBuffer->events.backendRelease.registerListener([this, previousBuffer](std::any data) { + if (!self.expired()) // could be dead in the dtor + previousBuffer->sendReleaseWithSurface(self.lock()); + else + previousBuffer->sendRelease(); + previousBuffer->hlEvents.backendRelease.reset(); + bufferReleased = true; + }); + } else + previousBuffer->sendReleaseWithSurface(self.lock()); + + bufferReleased = true; + } +} + +void CWLSurfaceResource::presentFeedback(timespec* when, CMonitor* pMonitor, bool needsExplicitSync) { + frame(when); + auto FEEDBACK = makeShared<CQueuedPresentationData>(self.lock()); + FEEDBACK->attachMonitor(pMonitor); + FEEDBACK->discarded(); + PROTO::presentation->queueData(FEEDBACK); + + if (!pMonitor || !pMonitor->outTimeline || !syncobj || !needsExplicitSync) + return; + + // attach explicit sync + g_pHyprRenderer->explicitPresented.emplace_back(self.lock()); + + if (syncobj->acquirePoint > pMonitor->lastWaitPoint) { + Debug::log(TRACE, "presentFeedback lastWaitPoint {} -> {}", pMonitor->lastWaitPoint, syncobj->acquirePoint); + pMonitor->lastWaitPoint = syncobj->acquirePoint; + } } CWLCompositorResource::CWLCompositorResource(SP<CWlCompositor> resource_) : resource(resource_) { |
