AIS_ViewController multithread usage

Hello,

From what I understand, AIS_ViewController could be use in multithread, one running the GUI and one the rendering.

But as is, it is not multithread, I mean using the class as is all methods will be executed in the same thread.  If I understand correctly, AIS_ViewController::FlushViewEvents() should be use from the GUI thread to signal the Rendering thread which should "handle" the queued event using AIS_ViewController::HandleViewEvents​()...

Is that correct?  Is there other things that should be taken into account to use AIS_ViewController with 2 threads.

Best regards,

François.

Kirill Gavrilov's picture

From documentation:

       //! Update buffer for rendering thread.
 426   //! This method is expected to be called within synchronization barrier between GUI
 427   //! and Rendering threads (e.g. GUI thread should be locked beforehand to avoid data races).
 428   //! @param theCtx interactive context
 429   //! @param theView active view
 430   //! @param theToHandle if TRUE, the HandleViewEvents() will be called
 431   Standard_EXPORT virtual void FlushViewEvents (const Handle(AIS_InteractiveContext)& theCtx,
 432                                                 const Handle(V3d_View)& theView,
 433                                                 Standard_Boolean theToHandle = Standard_False);
 434 

So it should be called from OpenGL thread, not GUI thread, and with a garantee from application, that it will not put something new into buffer during this method execution (either by using own mutex, or by calling this method within appropriate place - like QtQuick provides).

Francois Lauzon's picture

Thanks for the reply Kirill.

I implemented the solution on my side quite like it is use by the Draw Harness (like suggested here https://www.opencascade.com/content/example-how-use-aisviewcontroller), where the FlushViewEvent​ is use in the same thread as UpdateMousePosition, but I guess it shouldn't be use that way.

But from what you replied, FlushViewEvent  should be called from the rendering thread, which make sense when looking at the source code.  So I guess I must triggered the flushing of events from the GUI side so the rendering thread could execute FlushViewEvent.  So I guess the 3d view and interactive context pass to FlushViewEvent​ must also be protected by mutex between UI and rendering thread...  

I guess what I'm trying to explain is that single thread usage is shown in the Draw Harness, but I'm looking for a simple explaination of how to use it with 2 threads: UI and rendering in my context: Qt Widgets + OCC V3D_View+Interactive Context.

Best regards,

Francois

Kirill Gavrilov's picture

I haven't heard that Qt Widgets can work with multiple threads. From my understanding only QtQuick uses 2-threads system (which is optional and can be disabled via options).
Qt Widgets integration with OpenGL is less straightforward and may require extra configuring for achieving desired result.

In QtQuick there is QQuickWindow::beforeSynchronizing signal which is called when both GUI and GL threads are synchronized (locked, hence extra application-specific mutex is not necessary).
But otherwise - yes, extra mutex should be used as neither AIS_InteractiveContext nor AIS_ViewController will handle threads concurrency (although Aspect_VKeySet has its own mutex as exception for simplicity).

Francois Lauzon's picture

Thanks for the reply Kirill,

I modified the way my subclass of AIS_ViewController worked when given selection/preselection feedback to my application so it could work in single thread.

Best regards,

François.