QWaylandShmBackingStore: Implement scroll

Allows to more efficiently scroll existing buffer contents
as opposed to having them redrawn by the application.

Change-Id: I1005b718a18f078f6bbf47f08dbda4f87b3ab0f5
Reviewed-by: David Redondo <qt@david-redondo.de>
This commit is contained in:
Kai Uwe Broulik 2024-08-26 19:08:36 +02:00
parent 12e55c95b2
commit dfed8e3c3d
2 changed files with 37 additions and 0 deletions

View File

@ -45,6 +45,8 @@
QT_BEGIN_NAMESPACE
extern void qt_scrollRectInImage(QImage &, const QRect &, const QPoint &);
namespace QtWaylandClient {
QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display,
@ -210,6 +212,40 @@ void QWaylandShmBackingStore::endPaint()
flush(window(), mPendingRegion, QPoint());
}
// Inspired by QCALayerBackingStore.
bool QWaylandShmBackingStore::scroll(const QRegion &region, int dx, int dy)
{
if (!mBackBuffer)
return false;
QImage *backBufferImage = mBackBuffer->image();
const qreal devicePixelRatio = backBufferImage->devicePixelRatio();
// On Wayland, the window can have a device pixel ratio different from
// the window/screen, therefore we cannot rely on QHighDpi here, cf. QBackingStore::scroll.
// With fractional scaling we cannot easily scroll the existing pixels.
if (!qFuzzyIsNull(devicePixelRatio - static_cast<int>(devicePixelRatio)))
return false;
const QPoint scrollDelta(dx, dy);
const QMargins margins = windowDecorationMargins();
const QRegion adjustedRegion = region.translated(margins.left(), margins.top());
const QRect boundingRect = adjustedRegion.boundingRect();
const QPoint devicePixelDelta = scrollDelta * devicePixelRatio;
qt_scrollRectInImage(*backBufferImage,
QRect(boundingRect.topLeft() * devicePixelRatio,
boundingRect.size() * devicePixelRatio),
devicePixelDelta);
// We do not mark the source region as dirty, even though it technically has "moved".
// This matches the behavior of other backingstore implementations using qt_scrollRectInImage.
updateDirtyStates(adjustedRegion.translated(scrollDelta));
return true;
}
void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(offset)

View File

@ -66,6 +66,7 @@ public:
void resize(const QSize &size, const QRegion &staticContents) override;
void beginPaint(const QRegion &region) override;
void endPaint() override;
bool scroll(const QRegion &region, int dx, int dy) override;
QWaylandAbstractDecoration *windowDecoration() const;