summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mira <samuel.mira@qt.io>2022-03-15 10:22:05 +0200
committerSamuel Mira <samuel.mira@qt.io>2022-03-15 13:35:43 +0200
commitd5d9ee5e32dee63a6f4dd8d666177877284ff7e4 (patch)
tree978f67405c8378fbefd695a4a8963336fd8e9fcc
parente5948cc608c56fd69397614b408e66f3ff1f6f8c (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.cpp60
-rw-r--r--src/multimedia/platform/android/common/qandroidvideooutput_p.h2
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;