summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-03-10 11:06:23 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-03-10 17:32:44 +0000
commitb130d16a27399497739a56bd1a5a824a6a5885b1 (patch)
treeba15220f8916b873b4899b9c81bf0617191e23ec /src
parentb9091e4cec8be067509464ff068612a07ed4a95d (diff)
rhi: metal: Use the layer as the single source of truth
...when it comes to the output size. This mirrors what all other backends do. For example, with Vulkan the only source of size is the surface (VkSurfaceKHR), never the QWindow, even though we'd expect that the surface size equals to window_size * dpr, and that's almost always true, but there are exceptions. (e.g. we have seen bugs on Windows with some drivers in high DPI situations where the Vulkan surface did not fully match the window size, yet it is the surface, and only the surface, that matters for rendering, i.e. viewports and such must match the surface, not the native window) With Metal we hit a similar problem on iOS: the QWindow's size*dpr and what we calculate from the CAMetalLayer have a height difference of 1. Mitigate this by making QRhiSwapChain::surfacePixelSize() and the calculation for currentPixelSize() done via the same route (the CAMetalLayer). Otherwise, if there is a mismatch between what the QWindow and the layer says, Qt Quick will think that there is a resize happening (has happened) whenever starting a new frame, and that has far reaching consequences (suboptimal performance, increased memory usage by buffers, etc.) Change-Id: I114df92bf35622c99f2747420fdce401db7705a6 Fixes: QTBUG-91438 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit 83fb8fe208ec816df7d04c8247d5696d95f2cab1) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r--src/gui/rhi/qrhimetal.mm42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 9e0655ef06..507f63b9a9 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -3787,10 +3787,42 @@ QRhiRenderTarget *QMetalSwapChain::currentFrameRenderTarget()
return &rtWrapper;
}
+#ifdef TARGET_IPHONE_SIMULATOR
+API_AVAILABLE(ios(13.0))
+#endif
+static inline CAMetalLayer *layerForWindow(QWindow *window)
+{
+ Q_ASSERT(window);
+#ifdef Q_OS_MACOS
+ NSView *view = reinterpret_cast<NSView *>(window->winId());
+#else
+ UIView *view = reinterpret_cast<UIView *>(window->winId());
+#endif
+ Q_ASSERT(view);
+ return static_cast<CAMetalLayer *>(view.layer);
+}
+
QSize QMetalSwapChain::surfacePixelSize()
{
+#ifdef TARGET_IPHONE_SIMULATOR
+ if (@available(ios 13.0, *)) {
+#endif
+
Q_ASSERT(m_window);
- return m_window->size() * m_window->devicePixelRatio();
+ CAMetalLayer *layer = d->layer;
+ if (!layer)
+ layer = layerForWindow(m_window);
+
+ CGSize layerSize = layer.bounds.size;
+ layerSize.width *= layer.contentsScale;
+ layerSize.height *= layer.contentsScale;
+ return QSizeF::fromCGSize(layerSize).toSize();
+
+#ifdef TARGET_IPHONE_SIMULATOR
+ } else {
+ return QSize();
+ }
+#endif
}
QRhiRenderPassDescriptor *QMetalSwapChain::newCompatibleRenderPassDescriptor()
@@ -3849,13 +3881,7 @@ bool QMetalSwapChain::createOrResize()
return false;
}
-#ifdef Q_OS_MACOS
- NSView *view = reinterpret_cast<NSView *>(window->winId());
-#else
- UIView *view = reinterpret_cast<UIView *>(window->winId());
-#endif
- Q_ASSERT(view);
- d->layer = static_cast<CAMetalLayer *>(view.layer);
+ d->layer = layerForWindow(window);
Q_ASSERT(d->layer);
chooseFormats();