Skip to content

Commit 1b6d803

Browse files
committed
core/window: handle graphics context loss
1 parent f48a5ca commit 1b6d803

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

src/window/proxywindow.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "proxywindow.hpp"
22

33
#include <private/qquickwindow_p.h>
4+
#include <qcontainerfwd.h>
45
#include <qcoreevent.h>
56
#include <qevent.h>
67
#include <qguiapplication.h>
@@ -112,6 +113,8 @@ void ProxyWindowBase::ensureQWindow() {
112113
auto opaque = this->qsSurfaceFormat.opaqueModified ? this->qsSurfaceFormat.opaque
113114
: this->mColor.alpha() >= 255;
114115

116+
format.setOption(QSurfaceFormat::ResetNotification);
117+
115118
if (opaque) format.setAlphaBufferSize(0);
116119
else format.setAlphaBufferSize(8);
117120

@@ -195,6 +198,7 @@ void ProxyWindowBase::connectWindow() {
195198
QObject::connect(this->window, &QWindow::heightChanged, this, &ProxyWindowBase::heightChanged);
196199
QObject::connect(this->window, &QWindow::screenChanged, this, &ProxyWindowBase::screenChanged);
197200
QObject::connect(this->window, &QQuickWindow::colorChanged, this, &ProxyWindowBase::colorChanged);
201+
QObject::connect(this->window, &QQuickWindow::sceneGraphError, this, &ProxyWindowBase::onSceneGraphError);
198202
QObject::connect(this->window, &ProxiedWindow::exposed, this, &ProxyWindowBase::onExposed);
199203
QObject::connect(this->window, &ProxiedWindow::devicePixelRatioChanged, this, &ProxyWindowBase::devicePixelRatioChanged);
200204
// clang-format on
@@ -226,6 +230,22 @@ void ProxyWindowBase::completeWindow() {
226230
emit this->screenChanged();
227231
}
228232

233+
void ProxyWindowBase::onSceneGraphError(
234+
QQuickWindow::SceneGraphError error,
235+
const QString& message
236+
) {
237+
if (error == QQuickWindow::ContextNotAvailable) {
238+
qCritical().nospace() << "Failed to create graphics context for " << this << ": " << message;
239+
} else {
240+
qCritical().nospace() << "Scene graph error " << error << " occurred for " << this << ": "
241+
<< message;
242+
}
243+
244+
emit this->resourcesLost();
245+
this->mVisible = false;
246+
this->setVisibleDirect(false);
247+
}
248+
229249
void ProxyWindowBase::onVisibleChanged() {
230250
if (this->mVisible && !this->window->isVisible()) {
231251
this->mVisible = false;

src/window/proxywindow.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ class ProxyWindowBase: public Reloadable {
142142

143143
signals:
144144
void closed();
145+
void resourcesLost();
145146
void windowConnected();
146147
void windowDestroyed();
147148
void visibleChanged();
@@ -163,10 +164,14 @@ class ProxyWindowBase: public Reloadable {
163164
protected slots:
164165
virtual void onWidthChanged();
165166
virtual void onHeightChanged();
167+
virtual void onPolished();
168+
169+
private slots:
170+
void onSceneGraphError(QQuickWindow::SceneGraphError error, const QString& message);
171+
void onVisibleChanged();
166172
void onMaskChanged();
167173
void onMaskDestroyed();
168174
void onScreenDestroyed();
169-
virtual void onPolished();
170175
void onExposed();
171176

172177
protected:

src/window/windowinterface.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ void WindowInterface::connectSignals() const {
134134
auto* window = this->proxyWindow();
135135
// clang-format off
136136
QObject::connect(window, &ProxyWindowBase::closed, this, &WindowInterface::closed);
137+
QObject::connect(window, &ProxyWindowBase::resourcesLost, this, &WindowInterface::resourcesLost);
137138
QObject::connect(window, &ProxyWindowBase::windowConnected, this, &WindowInterface::windowConnected);
138139
QObject::connect(window, &ProxyWindowBase::visibleChanged, this, &WindowInterface::visibleChanged);
139140
QObject::connect(window, &ProxyWindowBase::backerVisibilityChanged, this, &WindowInterface::backingWindowVisibleChanged);

src/window/windowinterface.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,12 @@ class WindowInterface: public Reloadable {
239239
/// This signal is emitted when the window is closed by the user, the display server,
240240
/// or an error. It is not emitted when @@visible is set to false.
241241
void closed();
242+
/// This signal is emitted when resources a window depends on to display are lost,
243+
/// or could not be acquired during window creation. The most common trigger for
244+
/// this signal is a lack of VRAM when creating or resizing a window.
245+
///
246+
/// Following this signal, @@closed(s) will be sent.
247+
void resourcesLost();
242248
void windowConnected();
243249
void visibleChanged();
244250
void backingWindowVisibleChanged();

0 commit comments

Comments
 (0)