scene: Add SurfaceItem::destinationSize()

Its main purpose is to reroute surface size updates through SurfaceItem
so it can invalidate quads cache. Not all SurfaceItems currently discard
them when needed. When proper item transform support lands,
setDestinationSize() could also change the surface scale instead.
This commit is contained in:
Vlad Zahorodnii 2023-12-21 12:07:08 +02:00
parent 6510fe6e5d
commit f7e8d3cefb
6 changed files with 31 additions and 14 deletions

View file

@ -140,7 +140,7 @@ void ItemRendererQPainter::renderSurfaceItem(QPainter *painter, SurfaceItem *sur
surfaceItem->resetDamage();
const OutputTransform surfaceToBufferTransform = surfaceItem->bufferTransform();
const QSizeF transformedSize = surfaceToBufferTransform.map(surfaceItem->size());
const QSizeF transformedSize = surfaceToBufferTransform.map(surfaceItem->destinationSize());
painter->save();
switch (surfaceToBufferTransform.kind()) {

View file

@ -16,6 +16,20 @@ SurfaceItem::SurfaceItem(Scene *scene, Item *parent)
{
}
QSizeF SurfaceItem::destinationSize() const
{
return m_destinationSize;
}
void SurfaceItem::setDestinationSize(const QSizeF &size)
{
if (m_destinationSize != size) {
m_destinationSize = size;
setSize(size);
discardQuads();
}
}
QRectF SurfaceItem::bufferSourceBox() const
{
return m_bufferSourceBox;
@ -60,8 +74,8 @@ void SurfaceItem::setBufferSize(const QSize &size)
QRegion SurfaceItem::mapFromBuffer(const QRegion &region) const
{
const QRectF sourceBox = m_bufferToSurfaceTransform.map(m_bufferSourceBox, m_bufferSize);
const qreal xScale = size().width() / sourceBox.width();
const qreal yScale = size().height() / sourceBox.height();
const qreal xScale = m_destinationSize.width() / sourceBox.width();
const qreal yScale = m_destinationSize.height() / sourceBox.height();
QRegion result;
for (QRectF rect : region) {
@ -100,8 +114,8 @@ void SurfaceItem::addDamage(const QRegion &region)
m_damage += region;
const QRectF sourceBox = m_bufferToSurfaceTransform.map(m_bufferSourceBox, m_bufferSize);
const qreal xScale = sourceBox.width() / size().width();
const qreal yScale = sourceBox.height() / size().height();
const qreal xScale = sourceBox.width() / m_destinationSize.width();
const qreal yScale = sourceBox.height() / m_destinationSize.height();
const QRegion logicalDamage = mapFromBuffer(region);
const auto delegates = scene()->delegates();
@ -214,8 +228,8 @@ WindowQuadList SurfaceItem::buildQuads() const
quads.reserve(region.count());
const QRectF sourceBox = m_bufferToSurfaceTransform.map(m_bufferSourceBox, m_bufferSize);
const qreal xScale = sourceBox.width() / size().width();
const qreal yScale = sourceBox.height() / size().height();
const qreal xScale = sourceBox.width() / m_destinationSize.width();
const qreal yScale = sourceBox.height() / m_destinationSize.height();
for (const QRectF rect : region) {
WindowQuad quad;

View file

@ -26,6 +26,9 @@ class KWIN_EXPORT SurfaceItem : public Item
Q_OBJECT
public:
QSizeF destinationSize() const;
void setDestinationSize(const QSizeF &size);
QRectF bufferSourceBox() const;
void setBufferSourceBox(const QRectF &box);
@ -72,6 +75,7 @@ protected:
OutputTransform m_surfaceToBufferTransform;
QRectF m_bufferSourceBox;
QSize m_bufferSize;
QSizeF m_destinationSize;
std::unique_ptr<SurfacePixmap> m_pixmap;
std::unique_ptr<SurfacePixmap> m_previousPixmap;
int m_referencePixmapCounter = 0;

View file

@ -19,7 +19,7 @@ SurfaceItemInternal::SurfaceItemInternal(InternalWindow *window, Scene *scene, I
connect(window, &Window::bufferGeometryChanged,
this, &SurfaceItemInternal::handleBufferGeometryChanged);
setSize(window->bufferGeometry().size());
setDestinationSize(window->bufferGeometry().size());
setBufferSourceBox(QRectF(QPointF(0, 0), window->bufferGeometry().size() * window->bufferScale()));
setBufferSize((window->bufferGeometry().size() * window->bufferScale()).toSize());
}
@ -41,7 +41,7 @@ std::unique_ptr<SurfacePixmap> SurfaceItemInternal::createPixmap()
void SurfaceItemInternal::handleBufferGeometryChanged()
{
setSize(m_window->bufferGeometry().size());
setDestinationSize(m_window->bufferGeometry().size());
setBufferSourceBox(QRectF(QPointF(0, 0), m_window->bufferGeometry().size() * m_window->bufferScale()));
setBufferSize((m_window->bufferGeometry().size() * m_window->bufferScale()).toSize());
}

View file

@ -55,7 +55,7 @@ SurfaceItemWayland::SurfaceItemWayland(SurfaceInterface *surface, Scene *scene,
}
handleChildSubSurfacesChanged();
setSize(surface->size());
setDestinationSize(surface->size());
setBufferTransform(surface->bufferTransform());
setBufferSourceBox(surface->bufferSourceBox());
setBufferSize(surface->bufferSize());
@ -82,8 +82,7 @@ SurfaceInterface *SurfaceItemWayland::surface() const
void SurfaceItemWayland::handleSurfaceSizeChanged()
{
setSize(m_surface->size());
discardQuads();
setDestinationSize(m_surface->size());
}
void SurfaceItemWayland::handleBufferSizeChanged()

View file

@ -34,7 +34,7 @@ SurfaceItemX11::SurfaceItemX11(X11Window *window, Scene *scene, Item *parent)
m_isDamaged = true;
}
setSize(window->bufferGeometry().size());
setDestinationSize(window->bufferGeometry().size());
setBufferSourceBox(QRectF(QPointF(0, 0), window->bufferGeometry().size()));
setBufferSize(window->bufferGeometry().size().toSize());
}
@ -142,7 +142,7 @@ void SurfaceItemX11::destroyDamage()
void SurfaceItemX11::handleBufferGeometryChanged()
{
setSize(m_window->bufferGeometry().size());
setDestinationSize(m_window->bufferGeometry().size());
setBufferSourceBox(QRectF(QPointF(0, 0), m_window->bufferGeometry().size()));
setBufferSize(m_window->bufferGeometry().size().toSize());
}