From 6384f4acf4e2988bcb35d3dfc5821f07867a34d0 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Sat, 22 Mar 2025 11:13:44 -0500 Subject: core/compositor: Correctly track SHM buffer damage (#9678) --- src/protocols/core/Compositor.cpp | 53 +++++++++++---------------------------- src/protocols/core/Compositor.hpp | 3 +-- src/protocols/core/Shm.cpp | 11 ++------ src/protocols/core/Shm.hpp | 2 -- 4 files changed, 17 insertions(+), 52 deletions(-) (limited to 'src/protocols/core') diff --git a/src/protocols/core/Compositor.cpp b/src/protocols/core/Compositor.cpp index 6b47b503..5462fbe9 100644 --- a/src/protocols/core/Compositor.cpp +++ b/src/protocols/core/Compositor.cpp @@ -12,6 +12,7 @@ #include "../DRMSyncobj.hpp" #include "../../render/Renderer.hpp" #include "config/ConfigValue.hpp" +#include "render/Texture.hpp" #include class CDefaultSurfaceRole : public ISurfaceRole { @@ -91,10 +92,10 @@ CWLSurfaceResource::CWLSurfaceResource(SP resource_) : resource(reso }); resource->setCommit([this](CWlSurface* r) { - if (pending.texture) + if (pending.buffer) pending.bufferDamage.intersect(CBox{{}, pending.bufferSize}); - if (!pending.texture) + if (!pending.buffer) pending.size = {}; else if (pending.viewport.hasDestination) pending.size = pending.viewport.destination; @@ -399,36 +400,8 @@ CBox CWLSurfaceResource::extends() { return full.getExtents(); } -Vector2D CWLSurfaceResource::sourceSize() { - if UNLIKELY (!current.texture) - return {}; - - if UNLIKELY (current.viewport.hasSource) - return current.viewport.source.size(); - - Vector2D trc = current.transform % 2 == 1 ? Vector2D{current.bufferSize.y, current.bufferSize.x} : current.bufferSize; - return trc / current.scale; -} - -CRegion CWLSurfaceResource::accumulateCurrentBufferDamage() { - if UNLIKELY (!current.texture) - return {}; - - CRegion surfaceDamage = current.damage; - if (current.viewport.hasDestination) { - Vector2D scale = sourceSize() / current.viewport.destination; - surfaceDamage.scale(scale); - } - - if (current.viewport.hasSource) - surfaceDamage.translate(current.viewport.source.pos()); - - Vector2D trc = current.transform % 2 == 1 ? Vector2D{current.bufferSize.y, current.bufferSize.x} : current.bufferSize; - - return surfaceDamage.scale(current.scale).transform(wlTransformToHyprutils(invertTransform(current.transform)), trc.x, trc.y).add(current.bufferDamage); -} - void CWLSurfaceResource::commitPendingState(SSurfaceState& state) { + auto lastTexture = current.texture; if (state.newBuffer) { state.newBuffer = false; current = state; @@ -437,20 +410,19 @@ void CWLSurfaceResource::commitPendingState(SSurfaceState& state) { state.buffer.reset(); } - if (current.texture) - current.texture->m_eTransform = wlTransformToHyprutils(current.transform); - if (current.buffer) { - const auto DAMAGE = accumulateCurrentBufferDamage(); - current.buffer->buffer->update(DAMAGE); + if (current.buffer->buffer->isSynchronous()) + current.updateSynchronousTexture(lastTexture); // if the surface is a cursor, update the shm buffer // TODO: don't update the entire texture - if (role->role() == SURFACE_ROLE_CURSOR && !DAMAGE.empty()) - updateCursorShm(DAMAGE); + if (role->role() == SURFACE_ROLE_CURSOR) + updateCursorShm(current.accumulateBufferDamage()); } - // TODO: we should _accumulate_ and not replace above if sync + if (current.texture) + current.texture->m_eTransform = wlTransformToHyprutils(current.transform); + if (role->role() == SURFACE_ROLE_SUBSURFACE) { auto subsurface = ((CSubsurfaceRole*)role.get())->subsurface.lock(); if (subsurface->sync) @@ -478,6 +450,9 @@ void CWLSurfaceResource::commitPendingState(SSurfaceState& state) { } void CWLSurfaceResource::updateCursorShm(CRegion damage) { + if (damage.empty()) + return; + auto buf = current.buffer ? current.buffer->buffer : SP{}; if UNLIKELY (!buf) diff --git a/src/protocols/core/Compositor.hpp b/src/protocols/core/Compositor.hpp index f958528c..5d2240a7 100644 --- a/src/protocols/core/Compositor.hpp +++ b/src/protocols/core/Compositor.hpp @@ -11,6 +11,7 @@ #include #include #include "../WaylandProtocol.hpp" +#include "render/Texture.hpp" #include "wayland.hpp" #include "../../helpers/signal/Signal.hpp" #include "../../helpers/math/Math.hpp" @@ -75,7 +76,6 @@ class CWLSurfaceResource { SP getResource(); CBox extends(); void resetRole(); - Vector2D sourceSize(); struct { CSignal precommit; // before commit @@ -102,7 +102,6 @@ class CWLSurfaceResource { void breadthfirst(std::function, const Vector2D&, void*)> fn, void* data); SP findFirstPreorder(std::function)> fn); - CRegion accumulateCurrentBufferDamage(); void presentFeedback(timespec* when, PHLMONITOR pMonitor, bool discarded = false); void commitPendingState(SSurfaceState& state); diff --git a/src/protocols/core/Shm.cpp b/src/protocols/core/Shm.cpp index 37a48fd3..420b4a3f 100644 --- a/src/protocols/core/Shm.cpp +++ b/src/protocols/core/Shm.cpp @@ -22,19 +22,12 @@ CWLSHMBuffer::CWLSHMBuffer(SP pool_, uint32_t id, int32_t of offset = offset_; opaque = NFormatUtils::isFormatOpaque(NFormatUtils::shmToDRM(fmt_)); - texture = makeShared(NFormatUtils::shmToDRM(fmt), (uint8_t*)pool->data + offset, stride, size_); - resource = CWLBufferResource::create(makeShared(pool_->resource->client(), 1, id)); listeners.bufferResourceDestroy = events.destroy.registerListener([this](std::any d) { listeners.bufferResourceDestroy.reset(); PROTO::shm->destroyResource(this); }); - - success = texture->m_iTexID; - - if UNLIKELY (!success) - Debug::log(ERR, "Failed creating a shm texture: null texture id"); } CWLSHMBuffer::~CWLSHMBuffer() { @@ -74,11 +67,11 @@ void CWLSHMBuffer::endDataPtr() { } bool CWLSHMBuffer::good() { - return success; + return true; } void CWLSHMBuffer::update(const CRegion& damage) { - texture->update(NFormatUtils::shmToDRM(fmt), (uint8_t*)pool->data + offset, stride, damage); + ; } CSHMPool::CSHMPool(CFileDescriptor fd_, size_t size_) : fd(std::move(fd_)), size(size_), data(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0)) { diff --git a/src/protocols/core/Shm.hpp b/src/protocols/core/Shm.hpp index fa5f29a4..61b26f12 100644 --- a/src/protocols/core/Shm.hpp +++ b/src/protocols/core/Shm.hpp @@ -50,8 +50,6 @@ class CWLSHMBuffer : public IHLBuffer { SP pool; private: - bool success = false; - struct { CHyprSignalListener bufferResourceDestroy; } listeners; -- cgit v1.2.3