From fa3bfa72da56fced5c8bd72a0d43f7f17de29a5a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 16 Mar 2023 14:50:40 +0100 Subject: macOS: Skip DisplayLink updates when in live resize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ...and the view is using a CAMetalLayer and a non-default contents placement. (the default would be scaling/stretching of the content, that hides a lot of out-of-sync size problems during resize, but is not great for UIs so we never use that in practice) This achieves two things: - when presenting from the main thread with transactions (i.e. with parent patch in place), resizing the window will be even nicer, basically flicker free on the M1 Mini as well, - when presenting from outside the main thread, resizing becomes a lot smoother, even if the window background is still visible from time to time due to the size not catching up and due to Qt having to use NSViewLayerContentsPlacementTopLeft. Thus resizing Qt Quick-based windows, which use the threaded render loop by default and cannot use presentsWithTransaction, becomes a nicer experience than before, even if not always perfect. This comes at the expense of not animating during the live resize operation whenever the size is not changed (because only a resize triggers updates then, the CVDisplayLink-based updates are skipped in order to reduce flicker due to out of sync sizes) To force the old behavior, set QT_MAC_DISPLAY_LINK_UPDATE_IN_RESIZE. Task-number: QTBUG-107198 Change-Id: I796c3a74119510c62f7245b0ebbe78797d2df03e Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qcocoascreen.mm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'src/plugins/platforms/cocoa') diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm index 10b739d6d8..078d8a1c72 100644 --- a/src/plugins/platforms/cocoa/qcocoascreen.mm +++ b/src/plugins/platforms/cocoa/qcocoascreen.mm @@ -454,6 +454,25 @@ void QCocoaScreen::deliverUpdateRequests() if (!platformWindow->updatesWithDisplayLink()) continue; + // QTBUG-107198: Skip updates in a live resize for a better resize experience. + if (platformWindow->isContentView() && platformWindow->view().inLiveResize) { + const QSurface::SurfaceType surfaceType = window->surfaceType(); + const bool usesMetalLayer = surfaceType == QWindow::MetalSurface || surfaceType == QWindow::VulkanSurface; + const bool usesNonDefaultContentsPlacement = [platformWindow->view() layerContentsPlacement] + != NSViewLayerContentsPlacementScaleAxesIndependently; + if (usesMetalLayer && usesNonDefaultContentsPlacement) { + static bool deliverDisplayLinkUpdatesDuringLiveResize = + qEnvironmentVariableIsSet("QT_MAC_DISPLAY_LINK_UPDATE_IN_RESIZE"); + if (!deliverDisplayLinkUpdatesDuringLiveResize) { + // Must keep the link running, we do not know what the event + // handlers for UpdateRequest (which is not sent now) would do, + // would they trigger a new requestUpdate() or not. + pauseUpdates = false; + continue; + } + } + } + platformWindow->deliverUpdateRequest(); // Another update request was triggered, keep the display link running -- cgit v1.2.3