diff --git a/src/scene/surfaceitem_wayland.cpp b/src/scene/surfaceitem_wayland.cpp index 6303298710..8f7591ad99 100644 --- a/src/scene/surfaceitem_wayland.cpp +++ b/src/scene/surfaceitem_wayland.cpp @@ -27,6 +27,10 @@ SurfaceItemWayland::SurfaceItemWayland(KWaylandServer::SurfaceInterface *surface this, &SurfaceItemWayland::handleSurfaceSizeChanged); connect(surface, &KWaylandServer::SurfaceInterface::bufferSizeChanged, this, &SurfaceItemWayland::handleBufferSizeChanged); + connect(surface, &KWaylandServer::SurfaceInterface::bufferSourceBoxChanged, + this, &SurfaceItemWayland::handleBufferSourceBoxChanged); + connect(surface, &KWaylandServer::SurfaceInterface::bufferTransformChanged, + this, &SurfaceItemWayland::handleBufferTransformChanged); connect(surface, &KWaylandServer::SurfaceInterface::childSubSurfacesChanged, this, &SurfaceItemWayland::handleChildSubSurfacesChanged); @@ -77,8 +81,6 @@ KWaylandServer::SurfaceInterface *SurfaceItemWayland::surface() const void SurfaceItemWayland::handleSurfaceToBufferMatrixChanged() { - setBufferTransform(m_surface->bufferTransform()); - setBufferSourceBox(m_surface->bufferSourceBox()); setSurfaceToBufferMatrix(m_surface->surfaceToBufferMatrix()); discardQuads(); discardPixmap(); @@ -91,11 +93,20 @@ void SurfaceItemWayland::handleSurfaceSizeChanged() void SurfaceItemWayland::handleBufferSizeChanged() { - setBufferSourceBox(m_surface->bufferSourceBox()); setBufferSize(m_surface->bufferSize()); discardPixmap(); } +void SurfaceItemWayland::handleBufferSourceBoxChanged() +{ + setBufferSourceBox(m_surface->bufferSourceBox()); +} + +void SurfaceItemWayland::handleBufferTransformChanged() +{ + setBufferTransform(m_surface->bufferTransform()); +} + void SurfaceItemWayland::handleSurfaceCommitted() { if (m_surface->hasFrameCallbacks()) { diff --git a/src/scene/surfaceitem_wayland.h b/src/scene/surfaceitem_wayland.h index a8eeb61d29..22a5b1ff2c 100644 --- a/src/scene/surfaceitem_wayland.h +++ b/src/scene/surfaceitem_wayland.h @@ -41,6 +41,8 @@ private Q_SLOTS: void handleSurfaceCommitted(); void handleSurfaceSizeChanged(); void handleBufferSizeChanged(); + void handleBufferSourceBoxChanged(); + void handleBufferTransformChanged(); void handleChildSubSurfaceRemoved(KWaylandServer::SubSurfaceInterface *child); void handleChildSubSurfacesChanged(); diff --git a/src/wayland/surface_interface.cpp b/src/wayland/surface_interface.cpp index 94d46ef195..144ad6bde2 100644 --- a/src/wayland/surface_interface.cpp +++ b/src/wayland/surface_interface.cpp @@ -476,6 +476,20 @@ QMatrix4x4 SurfaceInterfacePrivate::buildSurfaceToBufferMatrix() return surfaceToBufferMatrix; } +QRectF SurfaceInterfacePrivate::computeBufferSourceBox() const +{ + if (!current.viewport.sourceGeometry.isValid()) { + return QRectF(0, 0, bufferSize.width(), bufferSize.height()); + } + + const QRectF box(current.viewport.sourceGeometry.x() * current.bufferScale, + current.viewport.sourceGeometry.y() * current.bufferScale, + current.viewport.sourceGeometry.width() * current.bufferScale, + current.viewport.sourceGeometry.height() * current.bufferScale); + + return current.bufferTransform.inverted().map(box, bufferSize); +} + void SurfaceState::mergeInto(SurfaceState *target) { if (bufferIsSet) { @@ -561,6 +575,7 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) const QSizeF oldSurfaceSize = surfaceSize; const QSize oldBufferSize = bufferSize; + const QRectF oldBufferSourceBox = bufferSourceBox; const QMatrix4x4 oldSurfaceToBufferMatrix = surfaceToBufferMatrix; const QRegion oldInputRegion = inputRegion; @@ -571,6 +586,7 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) // TODO: Refactor the state management code because it gets more clumsy. if (current.buffer) { bufferSize = current.buffer->size(); + bufferSourceBox = computeBufferSourceBox(); implicitSurfaceSize = current.buffer->size() / current.bufferScale; switch (current.bufferTransform.kind()) { @@ -617,6 +633,7 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) surfaceSize = QSizeF(0, 0); implicitSurfaceSize = QSizeF(0, 0); bufferSize = QSize(0, 0); + bufferSourceBox = QRectF(); inputRegion = QRegion(); opaqueRegion = QRegion(); } @@ -647,6 +664,9 @@ void SurfaceInterfacePrivate::applyState(SurfaceState *next) if (surfaceToBufferMatrix != oldSurfaceToBufferMatrix) { Q_EMIT q->surfaceToBufferMatrixChanged(); } + if (bufferSourceBox != oldBufferSourceBox) { + Q_EMIT q->bufferSourceBoxChanged(); + } if (bufferSize != oldBufferSize) { Q_EMIT q->bufferSizeChanged(); } @@ -787,16 +807,7 @@ QRegion SurfaceInterface::input() const QRectF SurfaceInterface::bufferSourceBox() const { - if (!d->current.viewport.sourceGeometry.isValid()) { - return QRectF(0, 0, d->bufferSize.width(), d->bufferSize.height()); - } - - const QRectF box(d->current.viewport.sourceGeometry.x() * d->current.bufferScale, - d->current.viewport.sourceGeometry.y() * d->current.bufferScale, - d->current.viewport.sourceGeometry.width() * d->current.bufferScale, - d->current.viewport.sourceGeometry.height() * d->current.bufferScale); - - return d->current.bufferTransform.inverted().map(box, d->bufferSize); + return d->bufferSourceBox; } KWin::OutputTransform SurfaceInterface::bufferTransform() const diff --git a/src/wayland/surface_interface.h b/src/wayland/surface_interface.h index 8fc8a25964..e36f80e240 100644 --- a/src/wayland/surface_interface.h +++ b/src/wayland/surface_interface.h @@ -371,6 +371,7 @@ Q_SIGNALS: * This signal is emitted when the buffer transform has changed. */ void bufferTransformChanged(KWin::OutputTransform); + void bufferSourceBoxChanged(); /** * This signal is emitted when the size of the attached buffer has changed. */ diff --git a/src/wayland/surface_interface_p.h b/src/wayland/surface_interface_p.h index c4ce0bcdfc..799a9dae81 100644 --- a/src/wayland/surface_interface_p.h +++ b/src/wayland/surface_interface_p.h @@ -99,6 +99,7 @@ public: void commitSubSurface(); QMatrix4x4 buildSurfaceToBufferMatrix(); + QRectF computeBufferSourceBox() const; void applyState(SurfaceState *next); bool computeEffectiveMapped() const; @@ -120,6 +121,7 @@ public: SubSurfaceInterface *subSurface = nullptr; QMatrix4x4 surfaceToBufferMatrix; QSize bufferSize = QSize(0, 0); + QRectF bufferSourceBox; QSizeF implicitSurfaceSize = QSizeF(0, 0); QSizeF surfaceSize = QSizeF(0, 0);