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
58
src/protocols/types/SurfaceState.cpp
Normal file
58
src/protocols/types/SurfaceState.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
#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) {
|
||||
auto [dataPtr, fmt, size] = buffer->buffer->beginDataPtr(0);
|
||||
if (dataPtr) {
|
||||
auto drmFmt = NFormatUtils::shmToDRM(fmt);
|
||||
auto stride = bufferSize.y ? size / bufferSize.y : 0;
|
||||
if (lastTexture && lastTexture->m_isSynchronous && lastTexture->m_vSize == bufferSize) {
|
||||
texture = lastTexture;
|
||||
texture->update(drmFmt, dataPtr, stride, accumulateBufferDamage());
|
||||
} else
|
||||
texture = makeShared<CTexture>(drmFmt, dataPtr, stride, bufferSize);
|
||||
}
|
||||
buffer->buffer->endDataPtr();
|
||||
}
|
||||
|
||||
void SSurfaceState::reset() {
|
||||
damage.clear();
|
||||
bufferDamage.clear();
|
||||
transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
scale = 1;
|
||||
offset = {};
|
||||
size = {};
|
||||
}
|
||||
|
|
@ -20,16 +20,12 @@ struct SSurfaceState {
|
|||
Vector2D destination;
|
||||
CBox source;
|
||||
} viewport;
|
||||
bool rejected = false;
|
||||
bool newBuffer = false;
|
||||
bool rejected = false;
|
||||
bool newBuffer = false;
|
||||
|
||||
//
|
||||
void reset() {
|
||||
damage.clear();
|
||||
bufferDamage.clear();
|
||||
transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
||||
scale = 1;
|
||||
offset = {};
|
||||
size = {};
|
||||
}
|
||||
Vector2D sourceSize();
|
||||
// Translates damage into bufferDamage, clearing damage and returning the updated bufferDamage
|
||||
CRegion accumulateBufferDamage();
|
||||
void updateSynchronousTexture(SP<CTexture> lastTexture);
|
||||
void reset();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue