2025-03-22 11:13:44 -05:00
|
|
|
#include "SurfaceState.hpp"
|
|
|
|
|
#include "helpers/Format.hpp"
|
|
|
|
|
#include "protocols/types/Buffer.hpp"
|
|
|
|
|
#include "render/Texture.hpp"
|
|
|
|
|
|
|
|
|
|
Vector2D SSurfaceState::sourceSize() {
|
|
|
|
|
if UNLIKELY (!texture)
|
|
|
|
|
return {};
|
|
|
|
|
|
|
|
|
|
if UNLIKELY (viewport.hasSource)
|
|
|
|
|
return viewport.source.size();
|
|
|
|
|
|
|
|
|
|
Vector2D trc = transform % 2 == 1 ? Vector2D{bufferSize.y, bufferSize.x} : bufferSize;
|
|
|
|
|
return trc / scale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CRegion SSurfaceState::accumulateBufferDamage() {
|
|
|
|
|
if (damage.empty())
|
|
|
|
|
return bufferDamage;
|
|
|
|
|
|
|
|
|
|
CRegion surfaceDamage = damage;
|
|
|
|
|
if (viewport.hasDestination) {
|
|
|
|
|
Vector2D scale = sourceSize() / viewport.destination;
|
|
|
|
|
surfaceDamage.scale(scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (viewport.hasSource)
|
|
|
|
|
surfaceDamage.translate(viewport.source.pos());
|
|
|
|
|
|
|
|
|
|
Vector2D trc = transform % 2 == 1 ? Vector2D{bufferSize.y, bufferSize.x} : bufferSize;
|
|
|
|
|
|
|
|
|
|
bufferDamage = surfaceDamage.scale(scale).transform(wlTransformToHyprutils(invertTransform(transform)), trc.x, trc.y).add(bufferDamage);
|
|
|
|
|
damage.clear();
|
|
|
|
|
return bufferDamage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SSurfaceState::updateSynchronousTexture(SP<CTexture> lastTexture) {
|
2025-04-07 14:03:27 -05:00
|
|
|
auto [dataPtr, fmt, size] = buffer->beginDataPtr(0);
|
2025-03-22 11:13:44 -05:00
|
|
|
if (dataPtr) {
|
|
|
|
|
auto drmFmt = NFormatUtils::shmToDRM(fmt);
|
|
|
|
|
auto stride = bufferSize.y ? size / bufferSize.y : 0;
|
2025-05-05 23:44:49 +02:00
|
|
|
if (lastTexture && lastTexture->m_isSynchronous && lastTexture->m_size == bufferSize) {
|
2025-03-22 11:13:44 -05:00
|
|
|
texture = lastTexture;
|
|
|
|
|
texture->update(drmFmt, dataPtr, stride, accumulateBufferDamage());
|
|
|
|
|
} else
|
|
|
|
|
texture = makeShared<CTexture>(drmFmt, dataPtr, stride, bufferSize);
|
|
|
|
|
}
|
2025-04-07 14:03:27 -05:00
|
|
|
buffer->endDataPtr();
|
2025-03-22 11:13:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SSurfaceState::reset() {
|
2025-04-07 14:03:27 -05:00
|
|
|
updated.all = false;
|
|
|
|
|
|
|
|
|
|
// After commit, there is no pending buffer until the next attach.
|
|
|
|
|
buffer = {};
|
|
|
|
|
|
|
|
|
|
// applies only to the buffer that is attached to the surface
|
|
|
|
|
acquire = {};
|
|
|
|
|
|
2025-07-25 15:19:23 +00:00
|
|
|
// wl_surface.commit assigns pending ... and clears pending damage.
|
2025-03-22 11:13:44 -05:00
|
|
|
damage.clear();
|
|
|
|
|
bufferDamage.clear();
|
2025-10-07 13:47:07 +02:00
|
|
|
|
|
|
|
|
callbacks.clear();
|
2025-11-06 14:25:49 +01:00
|
|
|
lockMask = LOCK_REASON_NONE;
|
2025-03-22 11:13:44 -05:00
|
|
|
}
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-11-25 23:51:51 +01:00
|
|
|
void SSurfaceState::updateFrom(SSurfaceState& ref) {
|
|
|
|
|
updated = ref.updated;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.buffer) {
|
2025-04-07 14:03:27 -05:00
|
|
|
buffer = ref.buffer;
|
2025-11-06 14:25:49 +01:00
|
|
|
texture = ref.texture;
|
2025-04-07 14:03:27 -05:00
|
|
|
size = ref.size;
|
|
|
|
|
bufferSize = ref.bufferSize;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.damage) {
|
2025-04-07 14:03:27 -05:00
|
|
|
damage = ref.damage;
|
|
|
|
|
bufferDamage = ref.bufferDamage;
|
2025-11-25 23:51:51 +01:00
|
|
|
} else {
|
|
|
|
|
// damage is always relative to the current commit
|
|
|
|
|
damage.clear();
|
|
|
|
|
bufferDamage.clear();
|
2025-04-07 14:03:27 -05:00
|
|
|
}
|
|
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.input)
|
2025-04-07 14:03:27 -05:00
|
|
|
input = ref.input;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.opaque)
|
2025-04-07 14:03:27 -05:00
|
|
|
opaque = ref.opaque;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.offset)
|
2025-04-07 14:03:27 -05:00
|
|
|
offset = ref.offset;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.scale)
|
2025-04-07 14:03:27 -05:00
|
|
|
scale = ref.scale;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.transform)
|
2025-04-07 14:03:27 -05:00
|
|
|
transform = ref.transform;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.viewport)
|
2025-04-07 14:03:27 -05:00
|
|
|
viewport = ref.viewport;
|
2025-03-26 15:11:19 +00:00
|
|
|
|
2025-07-07 16:18:06 +02:00
|
|
|
if (ref.updated.bits.acquire)
|
2025-04-07 14:03:27 -05:00
|
|
|
acquire = ref.acquire;
|
2025-09-21 19:27:56 +02:00
|
|
|
|
|
|
|
|
if (ref.updated.bits.acked)
|
|
|
|
|
ackedSize = ref.ackedSize;
|
2025-10-07 13:47:07 +02:00
|
|
|
|
|
|
|
|
if (ref.updated.bits.frame) {
|
|
|
|
|
callbacks.insert(callbacks.end(), std::make_move_iterator(ref.callbacks.begin()), std::make_move_iterator(ref.callbacks.end()));
|
|
|
|
|
ref.callbacks.clear();
|
|
|
|
|
}
|
2025-03-26 15:11:19 +00:00
|
|
|
}
|