vlc | branch: master | Alexandre Janniaux <[email protected]> | Mon Nov 9 16:27:11 2020 +0100| [13286dc2c6493feeeedd9191fdd4bfd77291f0d8] | committer: Alexandre Janniaux
doc: QtGl: refactor with two contexts Since there were two threads running concurrently for the same context, eglMakeCurrent could fail almost everytime. When two such threads exist, different OpenGL context must be assigned to each of them and the correct resource sharing mechanism must be enabled so that the rendering thread can use the resources generated by the producing (VLC) thread. In addition, we need the OpenGL context from the actual window for the rendering, which will not be available right in the constructor, so synchronize its creation through a semaphore, delaying the opening of the vglmem module on the VLC side until the video is ready to be rendered on the Qt side too. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=13286dc2c6493feeeedd9191fdd4bfd77291f0d8 --- doc/libvlc/QtGL/qtvlcwidget.cpp | 37 +++++++++++++++++++++++++++++++++---- doc/libvlc/QtGL/qtvlcwidget.h | 3 +++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/doc/libvlc/QtGL/qtvlcwidget.cpp b/doc/libvlc/QtGL/qtvlcwidget.cpp index ef712390cc..c45324e106 100644 --- a/doc/libvlc/QtGL/qtvlcwidget.cpp +++ b/doc/libvlc/QtGL/qtvlcwidget.cpp @@ -4,7 +4,9 @@ #include <QCoreApplication> #include <QOpenGLFramebufferObject> #include <QOpenGLFunctions> +#include <QOffscreenSurface> #include <QThread> +#include <QSemaphore> #include <cmath> #include <mutex> @@ -20,6 +22,25 @@ public: mBuffers[0] = NULL; mBuffers[1] = NULL; mBuffers[2] = NULL; + + /* Use default format for context. */ + mContext = new QOpenGLContext(widget); + + /* Use offscreen surface to render the buffers */ + mSurface = new QOffscreenSurface(nullptr, widget); + + /* Widget doesn't have an OpenGL context right now, we'll get it later. */ + QObject::connect(widget, &QtVLCWidget::contextReady, [this](QOpenGLContext *render_context) { + /* Video view is now ready, we can start */ + mSurface->setFormat(mWidget->format()); + mSurface->create(); + + mContext->setFormat(mWidget->format()); + mContext->setShareContext(render_context); + mContext->create(); + + videoReady.release(); + }); } ~VLCVideo() @@ -72,6 +93,10 @@ public: return false; VLCVideo* that = static_cast<VLCVideo*>(*data); + + /* Wait for rendering view to be ready. */ + that->videoReady.acquire(); + that->m_width = 0; that->m_height = 0; return true; @@ -108,9 +133,9 @@ public: { VLCVideo* that = static_cast<VLCVideo*>(data); if (current) - that->mWidget->makeCurrent(); + that->mContext->makeCurrent(that->mSurface); else - that->mWidget->doneCurrent(); + that->mContext->doneCurrent(); return true; } @@ -118,12 +143,14 @@ public: static void* get_proc_address(void* data, const char* current) { VLCVideo* that = static_cast<VLCVideo*>(data); - QOpenGLContext *ctx = that->mWidget->context(); - return reinterpret_cast<void*>(ctx->getProcAddress(current)); + return reinterpret_cast<void*>(that->mContext->getProcAddress(current)); } private: QtVLCWidget *mWidget; + QOpenGLContext *mContext; + QOffscreenSurface *mSurface; + QSemaphore videoReady; //FBO data unsigned m_width = 0; @@ -281,6 +308,8 @@ void QtVLCWidget::initializeGL() m_program->setUniformValue("texture", 0); m_program->bindAttributeLocation("position", 0); + + emit contextReady(context()); } void QtVLCWidget::paintGL() diff --git a/doc/libvlc/QtGL/qtvlcwidget.h b/doc/libvlc/QtGL/qtvlcwidget.h index a52026c003..0d3e745c87 100644 --- a/doc/libvlc/QtGL/qtvlcwidget.h +++ b/doc/libvlc/QtGL/qtvlcwidget.h @@ -20,6 +20,9 @@ public: bool playMedia(const char* url); +signals: + void contextReady(QOpenGLContext *ctx); + public slots: void cleanup(); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
