summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Sørvig <morten.sorvig@qt.io>2023-03-03 16:00:47 +0100
committerMorten Sørvig <morten.sorvig@qt.io>2023-04-11 17:13:14 +0100
commit3965d808c086af9a4e4740ab2c7efe1a7ef6cb01 (patch)
treee6ef7c027ea46d96382441539d8e0ad5abf2942a
parentfc9853dcbf546c82a46cd526c04b80d4e59e99f0 (diff)
QWindow: Cache the devicePixelRatio value
Make each QWindow instance cache the current DPR value. This will make calling QWindow::devicePixelRatio() less costly, since it now does not have to compute the DPR value on each call. The cache is invalidated when the DevicePixelRatioChange event is sent. The common logic for handling this is implemented in QWindowPrivate::updateDevicePixelRatio(). Change-Id: I97231a230347358d8e565d2fd62e8a398adaedfc Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
-rw-r--r--src/gui/kernel/qguiapplication.cpp13
-rw-r--r--src/gui/kernel/qwindow.cpp33
-rw-r--r--src/gui/kernel/qwindow_p.h3
3 files changed, 28 insertions, 21 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index d26de0b07c..422c6ee8f6 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2565,8 +2565,6 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
if (window->screen() == wse->screen.data())
return;
- const qreal oldDevicePixelRatio = window->screen() ? window->screen()->devicePixelRatio() : 1.0;
-
if (QWindow *topLevelWindow = window->d_func()->topLevelWindow(QWindow::ExcludeTransients)) {
if (QScreen *screen = wse->screen.data())
topLevelWindow->d_func()->setTopLevelScreen(screen, false /* recreate */);
@@ -2583,12 +2581,7 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
processGeometryChangeEvent(&gce);
}
#endif
-
- const qreal newDevicePixelRatio = window->screen() ? window->screen()->devicePixelRatio() : 1.0;
- if (!qFuzzyCompare(oldDevicePixelRatio, newDevicePixelRatio)) {
- QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
- QGuiApplication::sendSpontaneousEvent(window, &dprChangeEvent);
- }
+ QWindowPrivate::get(window)->updateDevicePixelRatio();
}
}
@@ -2596,9 +2589,7 @@ void QGuiApplicationPrivate::processWindowDevicePixelRatioChangedEvent(QWindowSy
{
if (wde->window.isNull())
return;
-
- QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
- QGuiApplication::sendSpontaneousEvent(wde->window, &dprChangeEvent);
+ QWindowPrivate::get(wde->window)->updateDevicePixelRatio();
}
void QGuiApplicationPrivate::processSafeAreaMarginsChangedEvent(QWindowSystemInterfacePrivate::SafeAreaMarginsChangedEvent *wse)
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 2f775ec664..81a4469a9e 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -213,8 +213,10 @@ void QWindowPrivate::init(QScreen *targetScreen)
isWindow = true;
parentWindow = static_cast<QWindow *>(q->QObject::parent());
+ QScreen *connectScreen = targetScreen ? targetScreen : QGuiApplication::primaryScreen();
+
if (!parentWindow)
- connectToScreen(targetScreen ? targetScreen : QGuiApplication::primaryScreen());
+ connectToScreen(connectScreen);
// If your application aborts here, you are probably creating a QWindow
// before the screen list is populated.
@@ -224,6 +226,7 @@ void QWindowPrivate::init(QScreen *targetScreen)
QGuiApplicationPrivate::window_list.prepend(q);
requestedFormat = QSurfaceFormat::defaultFormat();
+ devicePixelRatio = connectScreen->devicePixelRatio();
}
/*!
@@ -505,8 +508,6 @@ void QWindowPrivate::create(bool recursive, WId nativeHandle)
// the platformWindow, if there was one, is now gone, so make this flag reflect reality now
updateRequestPending = false;
- const qreal currentDevicePixelRatio = q->devicePixelRatio();
-
if (q->parent())
q->parent()->create();
@@ -552,10 +553,7 @@ void QWindowPrivate::create(bool recursive, WId nativeHandle)
QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
QGuiApplication::sendEvent(q, &e);
- if (!qFuzzyCompare(currentDevicePixelRatio, q->devicePixelRatio())) {
- QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
- QGuiApplication::sendEvent(q, &dprChangeEvent);
- }
+ updateDevicePixelRatio();
if (needsUpdate)
q->requestUpdate();
@@ -1333,14 +1331,29 @@ Qt::ScreenOrientation QWindow::contentOrientation() const
qreal QWindow::devicePixelRatio() const
{
Q_D(const QWindow);
+ return d->devicePixelRatio;
+}
+
+/*
+ Updates the cached devicePixelRatio value by polling for a new value.
+ Sends QEvent::DevicePixelRatioChange to the window if the DPR has changed.
+*/
+void QWindowPrivate::updateDevicePixelRatio()
+{
+ Q_Q(QWindow);
// If there is no platform window use the associated screen's devicePixelRatio,
// which typically is the primary screen and will be correct for single-display
// systems (a very common case).
- if (!d->platformWindow)
- return screen()->devicePixelRatio();
+ const qreal newDevicePixelRatio = platformWindow ?
+ platformWindow->devicePixelRatio() * QHighDpiScaling::factor(q) : q->screen()->devicePixelRatio();
+
+ if (newDevicePixelRatio == devicePixelRatio)
+ return;
- return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
+ devicePixelRatio = newDevicePixelRatio;
+ QEvent dprChangeEvent(QEvent::DevicePixelRatioChange);
+ QGuiApplication::sendEvent(q, &dprChangeEvent);
}
Qt::WindowState QWindowPrivate::effectiveState(Qt::WindowStates state)
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index ef633d093a..96beb17bec 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -89,6 +89,8 @@ public:
void setAutomaticPositionAndResizeEnabled(bool a)
{ positionAutomatic = resizeAutomatic = a; }
+ void updateDevicePixelRatio();
+
static QWindowPrivate *get(QWindow *window) { return window->d_func(); }
static Qt::WindowState effectiveState(Qt::WindowStates);
@@ -106,6 +108,7 @@ public:
QString windowFilePath;
QIcon windowIcon;
QRect geometry;
+ qreal devicePixelRatio = 1.0;
Qt::WindowStates windowState = Qt::WindowNoState;
QWindow::Visibility visibility = QWindow::Hidden;
bool resizeEventPending = true;