diff options
author | Samuel Mira <samuel.mira@qt.io> | 2022-03-15 10:22:05 +0200 |
---|---|---|
committer | Samuel Mira <samuel.mira@qt.io> | 2022-03-15 13:35:43 +0200 |
commit | d5d9ee5e32dee63a6f4dd8d666177877284ff7e4 (patch) | |
tree | 978f67405c8378fbefd695a4a8963336fd8e9fcc | |
parent | e5948cc608c56fd69397614b408e66f3ff1f6f8c (diff) |
Fix Unable to create OpenGL context
This patch complements patch 34bdc50c8a74d92348970e943b80b278b08471d7
Found, while running examples, that could be another code path that
would trigger the same issue. This patch fixes those.
Fixes: QTBUG-100773
Change-Id: I6382840092d38b967a126470d0354dc411c25258
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
(cherry picked from commit 36f110e6c97e2c98ded86945825aa563fd93f2e0)
-rw-r--r-- | src/multimedia/platform/android/common/qandroidvideooutput.cpp | 60 | ||||
-rw-r--r-- | src/multimedia/platform/android/common/qandroidvideooutput_p.h | 2 |
2 files changed, 58 insertions, 4 deletions
diff --git a/src/multimedia/platform/android/common/qandroidvideooutput.cpp b/src/multimedia/platform/android/common/qandroidvideooutput.cpp index 6c15e8324..9f8d29430 100644 --- a/src/multimedia/platform/android/common/qandroidvideooutput.cpp +++ b/src/multimedia/platform/android/common/qandroidvideooutput.cpp @@ -259,12 +259,41 @@ void QAndroidTextureVideoOutput::reset() clearSurfaceTexture(); } +bool QAndroidTextureVideoOutput::moveToOpenGLContextThread() +{ + if (!m_sink) + return false; + + const auto rhi = m_sink->rhi(); + if (!rhi || rhi->backend() != QRhi::OpenGLES2) + return false; + + const auto nativeHandles = static_cast<const QRhiGles2NativeHandles *>(rhi->nativeHandles()); + if (!nativeHandles) + return false; + + const auto context = nativeHandles->context; + if (!context) + return false; + + // check if QAndroidTextureVideoOutput is already in the OpenGL context thread + if (QThread::currentThread() == context->thread()) + return false; + + // move to the OpenGL context thread; + parent()->moveToThread(context->thread()); + moveToThread(context->thread()); + + return true; +} + void QAndroidTextureVideoOutput::onFrameAvailable() { if (!m_nativeSize.isValid() || !m_sink || !m_started) return; QRhi *rhi = m_sink ? m_sink->rhi() : nullptr; + auto *buffer = new AndroidTextureVideoBuffer(rhi, this, m_nativeSize); const QVideoFrameFormat::PixelFormat format = rhi ? QVideoFrameFormat::Format_SamplerExternalOES : QVideoFrameFormat::Format_RGBA8888; @@ -300,19 +329,42 @@ bool QAndroidTextureVideoOutput::renderAndReadbackFrame() if (!m_nativeSize.isValid() || !m_surfaceTexture) return false; + if (moveToOpenGLContextThread()) { + // just moved to another thread, must close the execution of this method + QMetaObject::invokeMethod(this, "onFrameAvailable", Qt::QueuedConnection); + return false; + } + if (!m_readbackRhi) { QRhi *sinkRhi = m_sink ? m_sink->rhi() : nullptr; if (sinkRhi && sinkRhi->backend() == QRhi::OpenGLES2) { // There is an rhi from the sink, e.g. VideoOutput. We lack the necessary // insight to use that directly, so create our own a QRhi that just wraps the // same QOpenGLContext. + + const auto constHandles = + static_cast<const QRhiGles2NativeHandles *>(sinkRhi->nativeHandles()); + if (!constHandles) { + qWarning("Failed to get the QRhiGles2NativeHandles to create QRhi readback."); + return false; + } + + auto handles = const_cast<QRhiGles2NativeHandles *>(constHandles); + const auto context = handles->context; + if (!context) { + qWarning("Failed to get the QOpenGLContext to create QRhi readback."); + return false; + } + sinkRhi->finish(); - QRhiGles2NativeHandles h = *static_cast<const QRhiGles2NativeHandles *>(sinkRhi->nativeHandles()); - m_readbackRhiFallbackSurface = QRhiGles2InitParams::newFallbackSurface(h.context->format()); + m_readbackRhiFallbackSurface = + QRhiGles2InitParams::newFallbackSurface(context->format()); QRhiGles2InitParams initParams; - initParams.format = h.context->format(); + initParams.format = context->format(); initParams.fallbackSurface = m_readbackRhiFallbackSurface; - m_readbackRhi = QRhi::create(QRhi::OpenGLES2, &initParams, {}, &h); + context->doneCurrent(); + + m_readbackRhi = QRhi::create(QRhi::OpenGLES2, &initParams, {}, handles); } else { // No rhi from the sink, e.g. QVideoWidget. // We will fire up our own QRhi with its own QOpenGLContext. diff --git a/src/multimedia/platform/android/common/qandroidvideooutput_p.h b/src/multimedia/platform/android/common/qandroidvideooutput_p.h index 2bb1004be..4db1bba76 100644 --- a/src/multimedia/platform/android/common/qandroidvideooutput_p.h +++ b/src/multimedia/platform/android/common/qandroidvideooutput_p.h @@ -131,6 +131,8 @@ private: bool renderAndReadbackFrame(); void ensureExternalTexture(QRhi *rhi); + bool moveToOpenGLContextThread(); + QMutex m_mutex; QReadWriteLock m_subtitleLock; |