summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2019-09-12 16:09:36 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-09-13 10:47:34 +0200
commit39b0a6f152d70eff50fde978c074a6a0860e6394 (patch)
tree700493cdfea519b8dbc78326b8b75d08ceda829a /src
parentaf1c3bf884c896e42fd2a8b7847ae86743b2c4ca (diff)
rhi: gl: Pick up context loss
...and change the return value of makeThreadLocalNativeContextCurrent() to a bool since we expect this to mirror QOpenGLContext::makeCurrent(). Change-Id: I339507152e461fe28fcf7fe777165e6d0072f055 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/gui/rhi/qrhi.cpp43
-rw-r--r--src/gui/rhi/qrhi_p.h2
-rw-r--r--src/gui/rhi/qrhi_p_p.h2
-rw-r--r--src/gui/rhi/qrhid3d11.cpp5
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h2
-rw-r--r--src/gui/rhi/qrhigles2.cpp29
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h3
-rw-r--r--src/gui/rhi/qrhimetal.mm5
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h2
-rw-r--r--src/gui/rhi/qrhinull.cpp5
-rw-r--r--src/gui/rhi/qrhinull_p_p.h2
-rw-r--r--src/gui/rhi/qrhivulkan.cpp5
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h2
13 files changed, 76 insertions, 31 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 585dc8a8fa..858be0159b 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -468,7 +468,7 @@ Q_LOGGING_CATEGORY(QRHI_LOG_INFO, "qt.rhi.general")
\value FrameOpDeviceLost The graphics device was lost. This can be
recoverable by attempting to repeat the operation (such as, beginFrame())
after releasing and reinitializing all objects backed by native graphics
- resources.
+ resources. See isDeviceLost().
*/
/*!
@@ -5022,10 +5022,17 @@ const QRhiNativeHandles *QRhi::nativeHandles()
has to ensure external OpenGL code provided by the application can still
run like it did before with direct usage of OpenGL, as long as the QRhi is
using the OpenGL backend.
+
+ \return false when failed, similarly to QOpenGLContext::makeCurrent(). When
+ the operation failed, isDeviceLost() can be called to determine if there
+ was a loss of context situation. Such a check is equivalent to checking via
+ QOpenGLContext::isValid().
+
+ \sa QOpenGLContext::makeCurrent(), QOpenGLContext::isValid()
*/
-void QRhi::makeThreadLocalNativeContextCurrent()
+bool QRhi::makeThreadLocalNativeContextCurrent()
{
- d->makeThreadLocalNativeContextCurrent();
+ return d->makeThreadLocalNativeContextCurrent();
}
/*!
@@ -5092,6 +5099,12 @@ void QRhi::releaseCachedResources()
reinitialized then. However, applications and libraries working directly
with QRhi are expected to be prepared to check and handle device loss
situations themselves.
+
+ \note With OpenGL, applications may need to opt-in to context reset
+ notifications by setting QSurfaceFormat::ResetNotification on the
+ QOpenGLContext. This is typically done by enabling the flag in
+ QRhiGles2InitParams::format. Keep in mind however that some systems may
+ generate context resets situations even when this flag is not set.
*/
bool QRhi::isDeviceLost() const
{
@@ -5259,7 +5272,17 @@ QRhiSwapChain *QRhi::newSwapChain()
\endlist
- \sa endFrame(), beginOffscreenFrame()
+ \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
+ value on failure. Some of these should be treated as soft, "try again
+ later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
+ the swapchain is to be resized or updated by calling
+ QRhiSwapChain::buildOrResize(). The application should then attempt to
+ generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
+ lost but this may also be recoverable by releasing all resources, including
+ the QRhi itself, and then recreating all resources. See isDeviceLost() for
+ further discussion.
+
+ \sa endFrame(), beginOffscreenFrame(), isDeviceLost()
*/
QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags flags)
{
@@ -5284,7 +5307,17 @@ QRhi::FrameOpResult QRhi::beginFrame(QRhiSwapChain *swapChain, BeginFrameFlags f
Passing QRhi::SkipPresent skips queuing the Present command or calling
swapBuffers.
- \sa beginFrame()
+ \return QRhi::FrameOpSuccess on success, or another QRhi::FrameOpResult
+ value on failure. Some of these should be treated as soft, "try again
+ later" type of errors: When QRhi::FrameOpSwapChainOutOfDate is returned,
+ the swapchain is to be resized or updated by calling
+ QRhiSwapChain::buildOrResize(). The application should then attempt to
+ generate a new frame. QRhi::FrameOpDeviceLost means the graphics device is
+ lost but this may also be recoverable by releasing all resources, including
+ the QRhi itself, and then recreating all resources. See isDeviceLost() for
+ further discussion.
+
+ \sa beginFrame(), isDeviceLost()
*/
QRhi::FrameOpResult QRhi::endFrame(QRhiSwapChain *swapChain, EndFrameFlags flags)
{
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 6f0b8e0b04..c73f03cf72 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1414,7 +1414,7 @@ public:
int resourceLimit(ResourceLimit limit) const;
const QRhiNativeHandles *nativeHandles();
- void makeThreadLocalNativeContextCurrent();
+ bool makeThreadLocalNativeContextCurrent();
QRhiProfiler *profiler();
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 7c0b000c33..63f27b6de4 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -156,7 +156,7 @@ public:
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
virtual const QRhiNativeHandles *nativeHandles() = 0;
virtual void sendVMemStatsToProfiler() = 0;
- virtual void makeThreadLocalNativeContextCurrent() = 0;
+ virtual bool makeThreadLocalNativeContextCurrent() = 0;
virtual void releaseCachedResources() = 0;
virtual bool isDeviceLost() const = 0;
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 0977a3042d..1d2f3cfa80 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -502,9 +502,10 @@ void QRhiD3D11::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiD3D11::makeThreadLocalNativeContextCurrent()
+bool QRhiD3D11::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
}
void QRhiD3D11::releaseCachedResources()
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index da7fe84b1a..cf4808510c 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -631,7 +631,7 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
bool isDeviceLost() const override;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index d408490b34..2d51d892e3 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -371,7 +371,12 @@ bool QRhiGles2::ensureContext(QSurface *surface) const
return true;
if (!ctx->makeCurrent(surface)) {
- qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
+ if (ctx->isValid()) {
+ qWarning("QRhiGles2: Failed to make context current. Expect bad things to happen.");
+ } else {
+ qWarning("QRhiGles2: Context is lost.");
+ contextLost = true;
+ }
return false;
}
@@ -491,6 +496,8 @@ bool QRhiGles2::create(QRhi::Flags flags)
nativeHandlesStruct.context = ctx;
+ contextLost = false;
+
return true;
}
@@ -753,12 +760,12 @@ void QRhiGles2::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiGles2::makeThreadLocalNativeContextCurrent()
+bool QRhiGles2::makeThreadLocalNativeContextCurrent()
{
if (inFrame && !ofr.active)
- ensureContext(currentSwapChain->surface);
+ return ensureContext(currentSwapChain->surface);
else
- ensureContext();
+ return ensureContext();
}
void QRhiGles2::releaseCachedResources()
@@ -774,7 +781,7 @@ void QRhiGles2::releaseCachedResources()
bool QRhiGles2::isDeviceLost() const
{
- return false;
+ return contextLost;
}
QRhiRenderBuffer *QRhiGles2::createRenderBuffer(QRhiRenderBuffer::Type type, const QSize &pixelSize,
@@ -1161,7 +1168,7 @@ QRhi::FrameOpResult QRhiGles2::beginFrame(QRhiSwapChain *swapChain, QRhi::BeginF
QGles2SwapChain *swapChainD = QRHI_RES(QGles2SwapChain, swapChain);
if (!ensureContext(swapChainD->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
currentSwapChain = swapChainD;
@@ -1184,7 +1191,7 @@ QRhi::FrameOpResult QRhiGles2::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame
addBoundaryCommand(&swapChainD->cb, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext(swapChainD->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&swapChainD->cb);
@@ -1208,7 +1215,7 @@ QRhi::FrameOpResult QRhiGles2::beginOffscreenFrame(QRhiCommandBuffer **cb, QRhi:
{
Q_UNUSED(flags);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
ofr.active = true;
@@ -1230,7 +1237,7 @@ QRhi::FrameOpResult QRhiGles2::endOffscreenFrame(QRhi::EndFrameFlags flags)
addBoundaryCommand(&ofr.cbWrapper, QGles2CommandBuffer::Command::EndFrame);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper);
@@ -1244,14 +1251,14 @@ QRhi::FrameOpResult QRhiGles2::finish()
Q_ASSERT(!currentSwapChain);
Q_ASSERT(ofr.cbWrapper.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext())
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&ofr.cbWrapper);
ofr.cbWrapper.resetCommands();
} else {
Q_ASSERT(currentSwapChain);
Q_ASSERT(currentSwapChain->cb.recordingPass == QGles2CommandBuffer::NoPass);
if (!ensureContext(currentSwapChain->surface))
- return QRhi::FrameOpError;
+ return contextLost ? QRhi::FrameOpDeviceLost : QRhi::FrameOpError;
executeCommandBuffer(&currentSwapChain->cb);
currentSwapChain->cb.resetCommands();
}
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index 3664e7162b..e7bcb626b6 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -664,7 +664,7 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
bool isDeviceLost() const override;
@@ -770,6 +770,7 @@ public:
QVector<GLint> supportedCompressedFormats;
mutable QVector<int> supportedSampleCountList;
QRhiGles2NativeHandles nativeHandlesStruct;
+ mutable bool contextLost = false;
struct DeferredReleaseEntry {
enum Type {
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 2d85c86bf0..0b1ab72c2c 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -583,9 +583,10 @@ void QRhiMetal::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiMetal::makeThreadLocalNativeContextCurrent()
+bool QRhiMetal::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
}
void QRhiMetal::releaseCachedResources()
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index 633e9b8de4..a08f56072a 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -416,7 +416,7 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
bool isDeviceLost() const override;
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index b58d9f5c56..60d620813b 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -169,9 +169,10 @@ void QRhiNull::sendVMemStatsToProfiler()
// nothing to do here
}
-void QRhiNull::makeThreadLocalNativeContextCurrent()
+bool QRhiNull::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
}
void QRhiNull::releaseCachedResources()
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index d6dbdbdc75..ee301d247b 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -282,7 +282,7 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
bool isDeviceLost() const override;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index 64fea37292..444c91dd75 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -3767,9 +3767,10 @@ void QRhiVulkan::sendVMemStatsToProfiler()
quint32(stats.total.usedBytes), quint32(stats.total.unusedBytes)));
}
-void QRhiVulkan::makeThreadLocalNativeContextCurrent()
+bool QRhiVulkan::makeThreadLocalNativeContextCurrent()
{
- // nothing to do here
+ // not applicable
+ return false;
}
void QRhiVulkan::releaseCachedResources()
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index a53b3b88fb..a390bc3707 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -711,7 +711,7 @@ public:
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
void sendVMemStatsToProfiler() override;
- void makeThreadLocalNativeContextCurrent() override;
+ bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
bool isDeviceLost() const override;