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>
This commit is contained in:
parent
af1c3bf884
commit
39b0a6f152
@ -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)
|
||||
{
|
||||
|
@ -1414,7 +1414,7 @@ public:
|
||||
int resourceLimit(ResourceLimit limit) const;
|
||||
|
||||
const QRhiNativeHandles *nativeHandles();
|
||||
void makeThreadLocalNativeContextCurrent();
|
||||
bool makeThreadLocalNativeContextCurrent();
|
||||
|
||||
QRhiProfiler *profiler();
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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(¤tSwapChain->cb);
|
||||
currentSwapChain->cb.resetCommands();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user