core/compositor: Correctly track SHM buffer damage (#9678)
This commit is contained in:
parent
4600043a49
commit
6384f4acf4
15 changed files with 103 additions and 82 deletions
|
|
@ -12,6 +12,7 @@
|
|||
#include "../DRMSyncobj.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
#include "config/ConfigValue.hpp"
|
||||
#include "render/Texture.hpp"
|
||||
#include <cstring>
|
||||
|
||||
class CDefaultSurfaceRole : public ISurfaceRole {
|
||||
|
|
@ -91,10 +92,10 @@ CWLSurfaceResource::CWLSurfaceResource(SP<CWlSurface> 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<IHLBuffer>{};
|
||||
|
||||
if UNLIKELY (!buf)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <vector>
|
||||
#include <cstdint>
|
||||
#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<CWlSurface> getResource();
|
||||
CBox extends();
|
||||
void resetRole();
|
||||
Vector2D sourceSize();
|
||||
|
||||
struct {
|
||||
CSignal precommit; // before commit
|
||||
|
|
@ -102,7 +102,6 @@ class CWLSurfaceResource {
|
|||
|
||||
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
||||
SP<CWLSurfaceResource> findFirstPreorder(std::function<bool(SP<CWLSurfaceResource>)> fn);
|
||||
CRegion accumulateCurrentBufferDamage();
|
||||
void presentFeedback(timespec* when, PHLMONITOR pMonitor, bool discarded = false);
|
||||
void commitPendingState(SSurfaceState& state);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,19 +22,12 @@ CWLSHMBuffer::CWLSHMBuffer(SP<CWLSHMPoolResource> pool_, uint32_t id, int32_t of
|
|||
offset = offset_;
|
||||
opaque = NFormatUtils::isFormatOpaque(NFormatUtils::shmToDRM(fmt_));
|
||||
|
||||
texture = makeShared<CTexture>(NFormatUtils::shmToDRM(fmt), (uint8_t*)pool->data + offset, stride, size_);
|
||||
|
||||
resource = CWLBufferResource::create(makeShared<CWlBuffer>(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)) {
|
||||
|
|
|
|||
|
|
@ -50,8 +50,6 @@ class CWLSHMBuffer : public IHLBuffer {
|
|||
SP<CSHMPool> pool;
|
||||
|
||||
private:
|
||||
bool success = false;
|
||||
|
||||
struct {
|
||||
CHyprSignalListener bufferResourceDestroy;
|
||||
} listeners;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue