Skip to content

Commit f2b8467

Browse files
senthilauto2023alpqrtorarnv
authored andcommitted
MAYA-132068: Unusable UI when docking with QWebEngineView (qtbase) (qt#104)
* rhi: d3d11: Flush() when destroying a swapchain Task-number: QTBUG-120276 Pick-to: 6.7 6.6 6.5 Change-Id: Iaf79c4dcf60d9a52bd562fd94976402cf570147d Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io> (cherry picked from commit cff5a49) * widgets: Invalidate RHI swapchain when window moves to new top level When a QWidget with an associated RHI swapchain (via its QWindow) is moved to a different top level window, that top level window has its own backing store, and QBackingStoreRhiSupport, which doesn't know anything about the fact that the window already has an associated swap chain in the original top level window's QBackingStoreRhiSupport. As having multiple swap chains for the same window is not supported on all RHI backends (Vulkan and DX in particular), we need to throw away the swap chain when detecting that the window is moved to a new top level. We do this by hooking into the existing WindowAboutToChangeInternal event delivery to renderToTexture children, which now delivers the event both to renderToTexture QWidget children as well as QWindows in the hierarchy. The condition of when to deliver the event has been updated to reflect whether the top level uses RHI for flushing, instead of only including renderToTexture children, as the former also includes setting QT_WIDGETS_RHI=1 explicitly. The event is then caught by QBackingStoreRhiSupportWindowWatcher, and handled the same way as for SurfaceAboutToBeDestroyed. Renaming qSendWindowChangeToTextureChildrenRecursively would make sense at this point, but to make cherry-picks easier we keep the current name for now. Fixes: QTBUG-120276 Pick-to: 6.7 6.5 Change-Id: Ic4c60e89be985f12a84e9f893c299e602b70851a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit 1bd7554) rename sendWindowChangeToTextureChildrenRecursively Change-Id: I457f50b68d5813e3ef09c31749dc3db8d0dc6822 --------- Co-authored-by: Laszlo Agocs <laszlo.agocs@qt.io> Co-authored-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
1 parent aaca5d7 commit f2b8467

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

src/gui/painting/qbackingstorerhisupport.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,13 +181,14 @@ QRhiSwapChain *QBackingStoreRhiSupport::swapChainForWindow(QWindow *window)
181181

182182
bool QBackingStoreRhiSupportWindowWatcher::eventFilter(QObject *obj, QEvent *event)
183183
{
184-
if (event->type() == QEvent::PlatformSurface
185-
&& static_cast<QPlatformSurfaceEvent *>(event)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed)
184+
if (event->type() == QEvent::WindowAboutToChangeInternal
185+
|| (event->type() == QEvent::PlatformSurface
186+
&& static_cast<QPlatformSurfaceEvent *>(event)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed))
186187
{
187188
QWindow *window = qobject_cast<QWindow *>(obj);
188189
auto it = m_rhiSupport->m_swapchains.find(window);
189190
if (it != m_rhiSupport->m_swapchains.end()) {
190-
qCDebug(lcQpaBackingStore) << "SurfaceAboutToBeDestroyed received for tracked window" << window << "cleaning up swapchain";
191+
qCDebug(lcQpaBackingStore) << event << "received for" << window << "- cleaning up swapchain";
191192
auto data = *it;
192193
m_rhiSupport->m_swapchains.erase(it);
193194
data.reset(); // deletes 'this'

src/gui/rhi/qrhid3d11.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4738,8 +4738,12 @@ void QD3D11SwapChain::destroy()
47384738
}
47394739

47404740
QRHI_RES_RHI(QRhiD3D11);
4741-
if (rhiD)
4741+
if (rhiD) {
47424742
rhiD->unregisterResource(this);
4743+
// See Deferred Destruction Issues with Flip Presentation Swap Chains in
4744+
// https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-flush
4745+
rhiD->context->Flush();
4746+
}
47434747
}
47444748

47454749
QRhiCommandBuffer *QD3D11SwapChain::currentFrameCommandBuffer()

src/widgets/kernel/qwidget.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10659,9 +10659,15 @@ static void sendWindowChangeToTextureChildrenRecursively(QWidget *widget, QEvent
1065910659

1066010660
for (int i = 0; i < d->children.size(); ++i) {
1066110661
QWidget *w = qobject_cast<QWidget *>(d->children.at(i));
10662-
if (w && !w->isWindow() && QWidgetPrivate::get(w)->textureChildSeen)
10662+
if (w && !w->isWindow())
1066310663
sendWindowChangeToTextureChildrenRecursively(w, eventType);
1066410664
}
10665+
10666+
// Notify QWidgetWindow after we've notified all child QWidgets
10667+
if (auto *window = d->windowHandle(QWidgetPrivate::WindowHandleMode::Direct)) {
10668+
QEvent e(eventType);
10669+
QCoreApplication::sendEvent(window, &e);
10670+
}
1066510671
}
1066610672

1066710673
/*!
@@ -10721,7 +10727,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
1072110727

1072210728
// texture-based widgets need a pre-notification when their associated top-level window changes
1072310729
// This is not under the wasCreated/newParent conditions above in order to also play nice with QDockWidget.
10724-
if (d->textureChildSeen && ((!parent && parentWidget()) || (parent && parent->window() != oldtlw)))
10730+
if ((oldtlw && oldtlw->d_func()->usesRhiFlush) && ((!parent && parentWidget()) || (parent && parent->window() != oldtlw)))
1072510731
sendWindowChangeToTextureChildrenRecursively(this, QEvent::WindowAboutToChangeInternal);
1072610732

1072710733
// If we get parented into another window, children will be folded
@@ -10802,7 +10808,7 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
1080210808

1080310809
// texture-based widgets need another event when their top-level window
1080410810
// changes (more precisely, has already changed at this point)
10805-
if (d->textureChildSeen && oldtlw != window())
10811+
if ((oldtlw && oldtlw->d_func()->usesRhiFlush) && oldtlw != window())
1080610812
sendWindowChangeToTextureChildrenRecursively(this, QEvent::WindowChangeInternal);
1080710813

1080810814
if (!wasCreated) {

0 commit comments

Comments
 (0)