Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QopenglWidget share context among thread



  • I create a QOpenglWidget and I'm trying to share context in a WorkerThread to load textures:
    void VideoWidget::updateVideoFrame(QVideoFrame frame)
    {
    QOpenGLContext* ctx = new QOpenGLContext();
    QOpenGLContext* sharectx = QOpenGLContext::currentContext();
    ctx->setFormat(sharectx->format());
    ctx->setShareContext(sharectx);
    ctx->create();
    if (ctx->isValid()){

        qDebug()<<"valid";
    }
    WorkerThread *workerThread = new WorkerThread();
    ctx->moveToThread(workerThread);
    connect(workerThread,SIGNAL(resultReady(QOpenGLTexture*)), this, SLOT(updateTexture(QOpenGLTexture*)));
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->setFrame(frame);
    

    workerThread->start();
    }

    here it is workerthread.h

    class WorkerThread : public QThread
    {
    Q_OBJECT

    void run() override {
        //    Q_UNUSED(frame);
    
        // Handle the frame and do your processing
        QVideoFrame cloneFrame(frametexture);
        cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
        QImage image(cloneFrame.bits(),
                     cloneFrame.width(),
                     cloneFrame.height(),
                     QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
    
    
        QOpenGLTexture* texture = new QOpenGLTexture(image);
    
        cloneFrame.unmap();
    
    }
    

    But when i try to create the texture there is no valid context.
    What I'm missing?
    thanks



  • This post is deleted!

  • Lifetime Qt Champion

    The thread is stopped (and deleted in your case since your signals/slot connection) as soon as run() finishes which is pretty fast in your case...
    The signal resultReady is also not emitted anywhere



  • @Christian-Ehrlicher
    thank you for the reply, the signal is received correvtly in the main thread. but when i cretae the opengltexture the context is not valid


  • Lifetime Qt Champion

    The signal resultReady() is not sent in your example so I guess it's incomplete.



  • @Christian-Ehrlicher you are right copy/paste error but i sent the signal right the unmap of the frame.
    But it gives error when create the opengltexture because the context is not valid


  • Lifetime Qt Champion

    And where do you use the QOpenGLContext created in updateVideoFrame()? Did you check that the generated QImage is valid?



  • @Christian-Ehrlicher
    the image is correct i also save it on hdd and it is fine.
    in the updatevideoframe i just create the context share it and move the thread. Maybe do i need something else?


  • Lifetime Qt Champion

    I've no more idea but I think you don't need a context at all. From the QOpenGLTexture ctor description:

    This does create the underlying OpenGL texture object. Therefore, construction using this constructor does require a valid current OpenGL context.
    

    Maybe also check for QOpenGLTexture::isCreated() in thread and main thread.
    And I wonder if you need a thread for this small calculation at all - since not much is done the thread overhead looks much bigger than the benefit.



  • @Christian-Ehrlicher i know that the qopenglwidget creates the underlying context and it is shared among all the others widget and it works because i used it.
    but for documentation to use context in a different thread i have to use share context but...



  • I use

        QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
    

    before I create my QApplication in main to make sure all contexts are sharing by default. I had some trouble getting sharing to work after porting some code from QGLWidget to QopenGLWidget a few years back, and that was the bit that got everything working for me.


Log in to reply