Results 1 to 4 of 4

Thread: A worker thread with OpenGL support, am I doing it right?

  1. #1
    Join Date
    Mar 2014
    Posts
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default A worker thread with OpenGL support, am I doing it right?

    Ik work on an application where it's possible to load very large CAD files, loading can take quite some time, so to keep the UI responsive loading is done in a workerthread.
    The workerthread requires an active OpenGL context as well, so it can upload vertexbuffers to the GPU. I came up with the following solution.

    - in main thread first make current context not current
    - store pointer to surface
    - create Worker Object and pass pointers to surface and context
    - change thread affinity of context (moveToThread)
    - start workerthread
    - make context current in workerthread
    - do work
    - when work is finished call doneCurrent (make not current)
    - restore thread affinity
    - make context active again in main thread

    It requires some hassle but it works, I am wondering how other applications deal with this problem?


    Qt Code:
    1. /// <summary>Starts a workerthread and handles its progress events</summary>
    2. int ProgressHandler::handleWork(boost::function<int(void)>& functor, bool requiresRenderContext/* = false*/)
    3. {
    4. // careful only call this method from the main thread
    5. //ASSERT(GetCurrentThreadId() == theApp.GetThreadId());
    6.  
    7. QOpenGLContext* context = nullptr;
    8. QSurface* surface = nullptr;
    9.  
    10. // make current OpenGL context not current if required, this is needed to be able to make it current in the workerthread
    11. if (requiresRenderContext)
    12. {
    13. context = QOpenGLContext::currentContext();
    14. surface = context->surface();
    15. context->doneCurrent();
    16. }
    17.  
    18. // create a Worker object
    19. int result = 0;
    20. deskproto::Worker work(functor, result, context, surface);
    21. context->moveToThread(&work);
    22.  
    23. connect(&work, &QThread::finished, this, &ProgressHandler::onWorkerFinished);
    24.  
    25. // start workerthread
    26. work.start();
    27.  
    28. // enter modal loop
    29. m_progressDialog.exec();
    30.  
    31. // wait until thread finishes
    32. work.wait();
    33.  
    34. // make RenderContext current again for main thread
    35. if (requiresRenderContext)
    36. {
    37. bool result = context->makeCurrent(surface);
    38. assert(result);
    39. }
    40.  
    41. // re-throw any uncaught exception in main thread
    42. work.rethrow();
    43.  
    44. return result;
    45. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. /// <summary>
    2. /// SwapContext allows to make an OpenGL context active for a different thread without changing the function
    3. /// e.g. used for loading 3D geometry, plotdata and bitmapdata in a workerthread (functions which require an active OpenGL context)
    4. /// </summary>
    5. void Worker::run()
    6. {
    7. #ifdef _DEBUG
    8. util::SetThreadName("Worker");
    9. #endif
    10.  
    11. // Make context active for current thread, only works if previous context is made not current
    12. if (m_context)
    13. {
    14. m_context->makeCurrent(m_surface);
    15. }
    16.  
    17. try
    18. {
    19. // Call the functor object
    20. m_result = m_functor();
    21. }
    22. catch(...)
    23. {
    24. // catch any uncaught exceptions and re-trow them on main thread
    25. Worker::m_exception = std::current_exception();
    26. }
    27.  
    28. // Make context not current(restore)
    29. if (m_context)
    30. {
    31. m_context->doneCurrent();
    32. m_context->moveToThread(QApplication::instance()->thread());
    33. }
    34. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: A worker thread with OpenGL support, am I doing it right?

    Why not load all the data in a worker thread and then push it to the GPU in the main thread?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Mar 2014
    Posts
    2
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: A worker thread with OpenGL support, am I doing it right?

    That is to keep the GUI thread responsive, uploading the vertex buffers to the GPU might take 5 - 6 seconds as wel (depending on your machine).

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: A worker thread with OpenGL support, am I doing it right?

    Then I don't see how you can improve what you already have
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 4
    Last Post: 17th October 2013, 11:12
  2. Sharing opengl context with worker thread
    By Lauvak in forum Qt Programming
    Replies: 2
    Last Post: 11th November 2010, 15:23
  3. Worker thread
    By doggrant in forum Newbie
    Replies: 4
    Last Post: 3rd November 2009, 15:49
  4. Worker thread problem
    By hkvm in forum Qt Programming
    Replies: 4
    Last Post: 6th September 2009, 20:12
  5. Main thread - worker thread communication.
    By kikapu in forum Newbie
    Replies: 25
    Last Post: 23rd May 2007, 22:09

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.