[vtkusers] Multi-threaded VTK
Aashish Chaudhary
aashish.chaudhary at kitware.com
Mon Jun 27 10:03:13 EDT 2011
On Mon, Jun 27, 2011 at 8:36 AM, Chris Volpe ARA/SED <cvolpe at ara.com> wrote:
> Thanks, Aashish, I believe I understand the situation now. Please see my reply to T.R. from a few minutes ago, and let me know if I have misunderstood the situation, or if you have a suggestion on the latency problem I mention there.
>
> As for what I am trying to achieve, here's the situation: I am supplying a library to a co-worker for use in his application. His application is not built with CMake and does not know about VTK in any way -- I am hiding those details behind an API via a pure-virtual abstract base class and a factory function that instantiates the concrete subclass that does all the VTK stuff. The client application needs to instantiate the class, set some parameters, call an initialization routine (which should pop up an interactive VTK window and return), and then periodically call routines which supply new data and camera positions and render the result, thereby producing an animation computed on the fly. In the midst of all this, the user has to be able to click in the window and do trackball-style interactions, pausing the application's animation during the user interaction. My initial approach was to use a mutex (actually, a vtkCriticalSection object), along with callbacks for StartInteraction and EndInteraction, to ensure that only *one* thread was accessing the graphics pipeline at a time. But now I see that that is not enough, since the OpenGL context is apparently thread-specific, so I need to get all the graphics out of the main application thread.
>
That explains it. I think you understand the situation.
So to answer to your question, No VTK does not provide a mechanism to
transfer data / information between threads in a thread safe way (or
any mechanism to invoke other thread in a safe way)
For our application we required something similar and since it is Qt
based we used Qt signals slots which allowed us to invoke render
thread with new data as soon as we get it. You may encounter issues if
you have multiple receivers. Also do not use vtkSmartPointer as means
to pass data (no atomic ref count increments / decrements). We have a
class that provides atomic increments / decrements. We will see if
that code could be released.
Let me know if you have any other questions.
> -Chris
>
>
>> -----Original Message-----
>> From: Aashish Chaudhary [mailto:aashish.chaudhary at kitware.com]
>> Sent: Friday, June 24, 2011 4:45 PM
>> To: Shashwath T.R.
>> Cc: Chris Volpe ARA/SED; vtkusers
>> Subject: Re: [vtkusers] Multi-threaded VTK
>>
>> Chris,
>>
>> If I understood your design then it won't work. Since the context is
>> not shared and is not made active by the thread then you will have a
>> crash eventually.
>>
>> What exactly you are trying to achieve with two threads?
>>
>> Regards,
>> Aashish
>>
>> On Fri, Jun 24, 2011 at 2:57 AM, Shashwath T.R. <trshash at gmail.com>
>> wrote:
>> > Right, there are obviously good reasons to want multi-threading, but
>> the
>> > tradeoffs have to be analyzed.
>> >
>> > Like I said earlier, in any case, the interactive thread should be
>> the
>> > primary thread of the application. In Windows, cross-thread GUI calls
>> > (rendering, for example), are undefined.
>> >
>> > Regards,
>> > Shash
>> >
>> > On Thu, Jun 23, 2011 at 5:43 PM, Chris Volpe ARA/SED <cvolpe at ara.com>
>> wrote:
>> >>
>> >> I misspoke: I said "non-rendering thread" when I meant "non-
>> interactive
>> >> thread"
>> >>
>> >>
>> >>
>> >> -Chris
>> >>
>> >>
>> >>
>> >> From: Chris Volpe ARA/SED
>> >> Sent: Thursday, June 23, 2011 7:41 AM
>> >> To: 'Shashwath T.R.'
>> >> Subject: RE: [vtkusers] Multi-threaded VTK
>> >>
>> >>
>> >>
>> >> Using a timer was my fallback approach. I wanted to avoid it because
>> data
>> >> changes are going to be driven asynchronously by the non-rendering
>> thread.
>> >>
>> >>
>> >>
>> >> Thanks,
>> >>
>> >>
>> >>
>> >> -Chris
>> >>
>> >>
>> >>
>> >> From: Shashwath T.R. [mailto:trshash at gmail.com]
>> >>
>> >> Sent: Thursday, June 23, 2011 1:54 AM
>> >> To: Chris Volpe ARA/SED
>> >> Subject: Re: [vtkusers] Multi-threaded VTK
>> >>
>> >>
>> >>
>> >> If you're doing this in Windows, I'd definitely suggest doing it the
>> other
>> >> way around; that is, run the interactor in the main thread and the
>> updation
>> >> in the worker thread.
>> >>
>> >> Generally, in Windows, the UI cannot be touched on a cross-thread
>> call;
>> >> the thread that created the UI should handle it. It's always better
>> to run
>> >> the interactor in the main thread.
>> >>
>> >> In any case, for a simple azimuth change once a second, it should be
>> >> possible to create a timer on the interactor and do your camera
>> management
>> >> inside the timer callback.
>> >>
>> >> Regards,
>> >> Shash
>> >>
>> >> On Thu, Jun 23, 2011 at 2:11 AM, Chris Volpe ARA/SED
>> <cvolpe at ara.com>
>> >> wrote:
>> >>
>> >> At the moment, I'm doing a very simplified version (for proof of
>> concept)
>> >> of my ultimate goal. The simplified version is to azimuth the camera
>> by 10
>> >> degrees once a second in the main thread while showing a cone in the
>> render
>> >> window. So, no, I am not currently creating vtkObjects in the main
>> thread
>> >> once the background thread (interactor) starts..
>> >>
>> >>
>> >>
>> >> Here's an excerpt of code from my "FeatureViewer" class. In my
>> simplified
>> >> proof of concept, the main program instantiates FeatureViewer and
>> invokes
>> >> the RunTest method, which sets everything up and spawns the
>> background
>> >> thread to run the interactor loop. When RunTest returns, the main
>> program
>> >> enters a loop in which it invokes CameraAzimuth once per second.
>> You'll
>> >> notice a couple references to a class called "vtkCommandDelegator" -
>> - this
>> >> is a template subclass of vtkCommand I wrote that allows you to
>> specify and
>> >> arbitrary method of an arbitrary class instance as the command
>> callback. I
>> >> wrote it because it seemed silly to have to create a new subclass of
>> >> vtkCommand every time I want to have a callback for something.
>> >>
>> >>
>> >>
>> >> I'll leave out the class def and just include the relevant methods
>> for
>> >> brevity.
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> static DWORD WINAPI ThreadCallbackFunction(LPVOID lpParameter)
>> >>
>> >> {
>> >>
>> >> FeatureViewer *This = static_cast<FeatureViewer
>> *>(lpParameter);
>> >>
>> >>
>> >>
>> >> // Start the render window interactor in the background
>> >>
>> >> This->InternalRunInteractor();
>> >>
>> >> return 0;
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> FeatureViewer::FeatureViewer()
>> >>
>> >> {
>> >>
>> >> CS = vtkCriticalSection::New();
>> >>
>> >> pCam = NULL;
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> void FeatureViewer::LockCriticalSection(vtkObject *caller, unsigned
>> long
>> >> eventID, void *callData)
>> >>
>> >> {
>> >>
>> >> CS->Lock();
>> >>
>> >> fprintf(stderr,"Interactor about to render\n");
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> void FeatureViewer::UnlockCriticalSection(vtkObject *caller,
>> unsigned long
>> >> eventID, void *callData)
>> >>
>> >> {
>> >>
>> >> fprintf(stderr,"Interactor done rendering\n");
>> >>
>> >> CS->Unlock();
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> void FeatureViewer::RunInteractorInBackground()
>> >>
>> >> {
>> >>
>> >> // Start up the thread
>> >>
>> >> LPSECURITY_ATTRIBUTES attr = NULL;
>> >>
>> >> SIZE_T stackSize = 0; // default = 1 MB
>> >>
>> >> DWORD dwCreationFlags = 0;
>> >>
>> >> LPDWORD noThreadID = NULL;
>> >>
>> >>
>> >>
>> >> HANDLE m_hThreadHandle = CreateThread(attr, stackSize,
>> >> ThreadCallbackFunction,
>> >>
>> >> this, dwCreationFlags, noThreadID);
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> void FeatureViewer::InternalRunInteractor()
>> >>
>> >> {
>> >>
>> >> // Called in background thread.
>> >>
>> >> pIRen->Initialize();
>> >>
>> >> pIRen->Start();
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> void FeatureViewer::CameraAzimuth(double rot)
>> >>
>> >> {
>> >>
>> >> // Rotate camera here. Called by main thread
>> >>
>> >> CS->Lock();
>> >>
>> >> fprintf(stderr, "About to rotate camera\n");
>> >>
>> >> pCam->Azimuth(rot);
>> >>
>> >> pRenWin->Render();
>> >>
>> >> fprintf(stderr,"Done rotating camera\n");
>> >>
>> >> CS->Unlock();
>> >>
>> >>
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> void FeatureViewer::RunTest()
>> >>
>> >> {
>> >>
>> >> vtkConeSource *cone = vtkConeSource::New();
>> >>
>> >> cone->SetHeight( 3.0 );
>> >>
>> >> cone->SetRadius( 1.0 );
>> >>
>> >> cone->SetResolution( 10 );
>> >>
>> >> vtkPolyDataMapper *coneMapper = vtkPolyDataMapper::New();
>> >>
>> >> coneMapper->SetInputConnection( cone->GetOutputPort() );
>> >>
>> >> vtkActor *coneActor = vtkActor::New();
>> >>
>> >> coneActor->SetMapper( coneMapper );
>> >>
>> >>
>> >>
>> >> pRen = vtkRenderer::New();
>> >>
>> >> pRen->AddActor( coneActor );
>> >>
>> >> pRen->SetBackground( 0.1, 0.2, 0.4 );
>> >>
>> >> pRenWin = vtkRenderWindow::New();
>> >>
>> >> pRenWin->AddRenderer( pRen );
>> >>
>> >> pRenWin->SetSize( 300, 300 );
>> >>
>> >>
>> >>
>> >> pIRen = vtkRenderWindowInteractor::New();
>> >>
>> >> pIRen->SetRenderWindow(pRenWin);
>> >>
>> >>
>> >>
>> >> vtkInteractorStyleTrackballCamera *style =
>> >>
>> >> vtkInteractorStyleTrackballCamera::New();
>> >>
>> >> pIRen->SetInteractorStyle(style);
>> >>
>> >>
>> >>
>> >> pCam = pRen->GetActiveCamera();
>> >>
>> >>
>> >>
>> >> pStartInteractionCommand =
>> >> vtkCommandDelegator<FeatureViewer>::New();
>> >>
>> >> pStartInteractionCommand->RegisterCallback(this,
>> >> &FeatureViewer::LockCriticalSection);
>> >>
>> >> pEndInteractionCommand =
>> vtkCommandDelegator<FeatureViewer>::New();
>> >>
>> >> pEndInteractionCommand->RegisterCallback(this,
>> >> &FeatureViewer::UnlockCriticalSection);
>> >>
>> >>
>> >> style-
>> >AddObserver(vtkCommand::StartInteractionEvent,pStartInteractionCommand
>> );
>> >>
>> >> style->AddObserver(vtkCommand::EndInteractionEvent,
>> >> pEndInteractionCommand);
>> >>
>> >>
>> >>
>> >> RunInteractorInBackground();
>> >>
>> >> }
>> >>
>> >>
>> >>
>> >> Thanks,
>> >>
>> >> -Chris
>> >>
>> >>
>> >>
>> >>
>> >>
>> >> > -----Original Message-----
>> >>
>> >> > From: Aashish Chaudhary [mailto:aashish.chaudhary at kitware.com]
>> >>
>> >> > Sent: Wednesday, June 22, 2011 12:46 PM
>> >>
>> >> > To: Chris Volpe ARA/SED
>> >>
>> >> > Cc: vtkusers at vtk.org
>> >>
>> >> > Subject: Re: [vtkusers] Multi-threaded VTK
>> >>
>> >> >
>> >>
>> >> > On Wed, Jun 22, 2011 at 12:27 PM, Chris Volpe ARA/SED
>> <cvolpe at ara.com>
>> >>
>> >> > wrote:
>> >>
>> >> > > I'm trying to have an application that drives scene content
>> change on
>> >>
>> >> > its
>> >>
>> >> > > own, while still allowing the user to manipulate the scene with
>> >>
>> >> > > vtkRenderWindowInteractor. The approach I'm trying to use is to
>> have
>> >>
>> >> > the
>> >>
>> >> > > vtkRenderWindowInteractor run in a background thread, with some
>> >>
>> >> > concurrency
>> >>
>> >> > > protection to keep it from invoking the rendering pipeline at
>> the
>> >>
>> >> > same time
>> >>
>> >> > > the main thread tries to do so. My application main thread
>> creates
>> >>
>> >> > all the
>> >>
>> >> > > vtk objects (actor, render window, renderer, interactor),
>> registers a
>> >>
>> >> > couple
>> >>
>> >> > > of callbacks for the interactor style's StartInteractionEvent
>> and
>> >>
>> >> > > EndInteractionEvent which lock and unlock a vtkCriticalSection,
>> >>
>> >> > > respectively, and then spawns a background thread in which the
>> >>
>> >> > interactor is
>> >>
>> >> > > started. The main thread then, periodically, locks the critical
>> >>
>> >> > section,
>> >>
>> >> > > makes scene changes, renders, and unlocks the critical section.
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > > Although this approach seems sound in principle, I'm
>> encountering
>> >>
>> >> > corruption
>> >>
>> >> > > that leads me to believe that there is some kind of pipeline
>> >>
>> >> > manipulation
>> >>
>> >> > > occurring before processing the StartInteractionEvent that is
>> >>
>> >> > conflicting
>> >>
>> >> > > with what I'm doing in my main thread. Can someone with detailed
>> >>
>> >> > knowledge
>> >>
>> >> > > of pipeline bowels provide some insight as to what might be
>> going on,
>> >>
>> >> > and
>> >>
>> >> > > perhaps provide an alternate course of action?
>> >>
>> >> >
>> >>
>> >> > Do you produce new vtk objects in the background thread? If yes do
>> you
>> >>
>> >> > use vtkSmartPointer? That could be cause of the problem depending
>> on
>> >>
>> >> > how you are passing vtk objects from one thread to another.
>> >>
>> >> >
>> >>
>> >> > Also it might help if you can attach a minimal code to reproduce
>> the
>> >>
>> >> > behavior.
>> >>
>> >> >
>> >>
>> >> > Thanks
>> >>
>> >> >
>> >>
>> >> >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > > Thanks,
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > > Chris
>> >>
>> >> > >
>> >>
>> >> > > --
>> >>
>> >> > > Christopher R. Volpe,
>> >>
>> >> > > Ph.D.
>> >>
>> >> > Email:
>> >>
>> >> > > cvolpe at ara.com
>> >>
>> >> > >
>> >>
>> >> > > Senior Scientist, Information Exploitation Systems
>> Main
>> >>
>> >> > Desk:
>> >>
>> >> > > 919-582-3300
>> >>
>> >> > >
>> >>
>> >> > > Applied Research Associates,
>> >>
>> >> > > Inc Direct:
>> 919-
>> >>
>> >> > 582-3380
>> >>
>> >> > >
>> >>
>> >> > > 8537 Six Forks Rd., Suite
>> >>
>> >> > > 6000
>> Fax :
>> >>
>> >> > > 919-582-3301
>> >>
>> >> > >
>> >>
>> >> > > Raleigh, NC 27615 Web:
>> >>
>> >> > > http://www.ara.com/offices/NC.htm
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> > > _______________________________________________
>> >>
>> >> > > Powered by www.kitware.com
>> >>
>> >> > >
>> >>
>> >> > > Visit other Kitware open-source projects at
>> >>
>> >> > > http://www.kitware.com/opensource/opensource.html
>> >>
>> >> > >
>> >>
>> >> > > Please keep messages on-topic and check the VTK FAQ at:
>> >>
>> >> > > http://www.vtk.org/Wiki/VTK_FAQ
>> >>
>> >> > >
>> >>
>> >> > > Follow this link to subscribe/unsubscribe:
>> >>
>> >> > > http://www.vtk.org/mailman/listinfo/vtkusers
>> >>
>> >> > >
>> >>
>> >> > >
>> >>
>> >> >
>> >>
>> >> >
>> >>
>> >> >
>> >>
>> >> > --
>> >>
>> >> > | Aashish Chaudhary
>> >>
>> >> > | R&D Engineer
>> >>
>> >> > | Kitware Inc.
>> >>
>> >> > | www.kitware.com
>> >>
>> >> _______________________________________________
>> >> Powered by www.kitware.com
>> >>
>> >> Visit other Kitware open-source projects at
>> >> http://www.kitware.com/opensource/opensource.html
>> >>
>> >> Please keep messages on-topic and check the VTK FAQ at:
>> >> http://www.vtk.org/Wiki/VTK_FAQ
>> >>
>> >> Follow this link to subscribe/unsubscribe:
>> >> http://www.vtk.org/mailman/listinfo/vtkusers
>> >>
>> >>
>> >
>> > _______________________________________________
>> > Powered by www.kitware.com
>> >
>> > Visit other Kitware open-source projects at
>> > http://www.kitware.com/opensource/opensource.html
>> >
>> > Please keep messages on-topic and check the VTK FAQ at:
>> > http://www.vtk.org/Wiki/VTK_FAQ
>> >
>> > Follow this link to subscribe/unsubscribe:
>> > http://www.vtk.org/mailman/listinfo/vtkusers
>> >
>> >
>>
>>
>>
>> --
>> | Aashish Chaudhary
>> | R&D Engineer
>> | Kitware Inc.
>> | www.kitware.com
>
--
| Aashish Chaudhary
| R&D Engineer
| Kitware Inc.
| www.kitware.com
More information about the vtkusers
mailing list