[vtkusers] Multi-threaded VTK

Chris Volpe ARA/SED cvolpe at ara.com
Mon Jun 27 08:09:58 EDT 2011


The interactive thread *can't* be the primary thread of the application, because I'm providing a library that the primary thread of the application has to call to create a window, get everything set up, and then return so that the primary application thread can continue where it left off, generating content and doing the rest of what it does. However, it shouldn't matter which thread does the graphics: if I understand the situation correctly, all that matters is that *one* thread does *all* the graphics work - I can't split it between two threads. So, instead of having the foreground thread to periodic rendering and the background thread do the interaction, I need to restrict the foreground thread's activity to data-transfer only, and have the background thread pick up the new data in a timer callback and render it. Not a big deal, but it does introduce a little unwanted latency in the process (say, if the main thread provides new data *right after* the last timer callback determines there was no data change since the previous timer).

Now, if there were some way I could have the main thread generate some event that the interactive thread could respond to as soon as it happens, rather than waiting for a timer to occur, that would mitigate my latency problem. Does VTK provide support for doing this in a thread-safe way?

Thanks for the help.

-Chris

From: Shashwath T.R. [mailto:trshash at gmail.com]
Sent: Friday, June 24, 2011 2:58 AM
To: Chris Volpe ARA/SED
Cc: vtkusers
Subject: Re: [vtkusers] Multi-threaded VTK

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<mailto: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<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<mailto: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<mailto:aashish.chaudhary at kitware.com>]

> Sent: Wednesday, June 22, 2011 12:46 PM

> To: Chris Volpe ARA/SED

> Cc: vtkusers at vtk.org<mailto: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<mailto: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<mailto: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<http://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<http://www.kitware.com>

_______________________________________________
Powered by www.kitware.com<http://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


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20110627/69bd0f0d/attachment.htm>


More information about the vtkusers mailing list