From 7dbf070dd1a15ea99b3d5d2e528c9d4c75eafff6 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Tue, 9 Jan 2024 02:51:05 +0400 Subject: [PATCH] Make the high dpi downscaling work with Wayland MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wayland provides fractional device pixel ratio without using QHighDpiScaling so it should work when QHighDpiScaling::isActive returns false. There are also invalidation adjustments given that high dpi backing store's device pixel ratio could lead to different native sizes depending on platform's device pixel ratio. Fixes: QTBUG-115462 Change-Id: Ib799272cd0108af6a5886496874349ff04352333 Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qhighdpiscaling_p.h | 4 ++-- src/gui/painting/qbackingstore.cpp | 29 ++++++++++++++++------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 189f31fd0a..d6deb8a72a 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -172,7 +172,7 @@ inline QMargins scale(const QMargins &margins, qreal scaleFactor, QPoint origin template QList scale(const QList &list, qreal scaleFactor, QPoint origin = QPoint(0, 0)) { - if (!QHighDpiScaling::isActive()) + if (qFuzzyCompare(scaleFactor, qreal(1))) return list; QList scaled; @@ -184,7 +184,7 @@ QList scale(const QList &list, qreal scaleFactor, QPoint origin = QPoint(0 inline QRegion scale(const QRegion ®ion, qreal scaleFactor, QPoint origin = QPoint(0, 0)) { - if (!QHighDpiScaling::isActive()) + if (qFuzzyCompare(scaleFactor, qreal(1))) return region; QRegion scaled = region.translated(-origin); diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 2304ee2256..3b709ec77b 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -50,6 +50,7 @@ public: QScopedPointer highDpiBackingstore; QRegion staticContents; QSize size; + QSize nativeSize; bool downscale = qEnvironmentVariableIntValue("QT_WIDGETS_HIGHDPI_DOWNSCALE") > 0; }; @@ -115,14 +116,13 @@ QWindow* QBackingStore::window() const void QBackingStore::beginPaint(const QRegion ®ion) { - const qreal dpr = d_ptr->backingStoreDevicePixelRatio(); + const qreal toNativeFactor = d_ptr->deviceIndependentToNativeFactor(); - if (d_ptr->highDpiBackingstore && - d_ptr->highDpiBackingstore->devicePixelRatio() != dpr) + if (d_ptr->nativeSize != QHighDpi::scale(size(), toNativeFactor)) resize(size()); QPlatformBackingStore *platformBackingStore = handle(); - platformBackingStore->beginPaint(QHighDpi::scale(region, d_ptr->deviceIndependentToNativeFactor())); + platformBackingStore->beginPaint(QHighDpi::scale(region, toNativeFactor)); // When QtGui is applying a high-dpi scale factor the backing store // creates a "large" backing store image. This image needs to be @@ -131,18 +131,20 @@ void QBackingStore::beginPaint(const QRegion ®ion) // the image data to avoid having the new devicePixelRatio be propagated // back to the platform plugin. QPaintDevice *device = platformBackingStore->paintDevice(); - if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) { + if (!qFuzzyCompare(toNativeFactor, qreal(1)) && device->devType() == QInternal::Image) { QImage *source = static_cast(device); const bool needsNewImage = d_ptr->highDpiBackingstore.isNull() - || source->data_ptr() != d_ptr->highDpiBackingstore->data_ptr() + || source->constBits() != d_ptr->highDpiBackingstore->constBits() || source->size() != d_ptr->highDpiBackingstore->size() - || source->devicePixelRatio() != d_ptr->highDpiBackingstore->devicePixelRatio(); - if (needsNewImage) { + || source->bytesPerLine() != d_ptr->highDpiBackingstore->bytesPerLine() + || source->format() != d_ptr->highDpiBackingstore->format(); + if (needsNewImage) d_ptr->highDpiBackingstore.reset( new QImage(source->bits(), source->width(), source->height(), source->bytesPerLine(), source->format())); - d_ptr->highDpiBackingstore->setDevicePixelRatio(dpr); - } + d_ptr->highDpiBackingstore->setDevicePixelRatio(d_ptr->backingStoreDevicePixelRatio()); + } else { + d_ptr->highDpiBackingstore.reset(); } } @@ -156,7 +158,7 @@ QPaintDevice *QBackingStore::paintDevice() { QPaintDevice *device = handle()->paintDevice(); - if (QHighDpiScaling::isActive() && device->devType() == QInternal::Image) + if (!qFuzzyCompare(d_ptr->deviceIndependentToNativeFactor(), qreal(1)) && device->devType() == QInternal::Image) return d_ptr->highDpiBackingstore.data(); return device; @@ -229,9 +231,10 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *window, const QPoint & */ void QBackingStore::resize(const QSize &size) { - d_ptr->size = size; const qreal factor = d_ptr->deviceIndependentToNativeFactor(); - handle()->resize(QHighDpi::scale(size, factor), QHighDpi::scale(d_ptr->staticContents, factor)); + d_ptr->size = size; + d_ptr->nativeSize = QHighDpi::scale(size, factor); + handle()->resize(d_ptr->nativeSize, QHighDpi::scale(d_ptr->staticContents, factor)); } /*!