Commit d2fe1dd8 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Cleaned up ordered compositing code.

* Reintroduced support for generating kdtree using image data extents.
* Restructured code to ensure redistribution happens correctly for every render.
  The previous implementation required that the client triggered the
  redistribution in Delivery() call which was not possible esp. as
  representations were added/removed (since Delivery() is only called when data
  really needs to be delivered which is not the case when representations are
  removed).
parent 777f36be
......@@ -96,16 +96,20 @@ int vtkImageVolumeRepresentation::ProcessViewRequest(
}
if (request_type == vtkPVView::REQUEST_UPDATE())
{
// FIXME:STREAMING :- how do we tell the view to use "cuts" from this
// representation for ordered compositing?
// At the same time, the image data is not the data being delivered
// anywhere, so we don't really report it to the view's storage.
// vtkPVRenderView::SetPiece(inInfo, this, this->Cache);
vtkPVRenderView::SetPiece(inInfo, this,
this->OutlineSource->GetOutputDataObject(0));
outInfo->Set(vtkPVRenderView::NEED_ORDERED_COMPOSITING(), 1);
vtkPVRenderView::SetGeometryBounds(inInfo, this->DataBounds);
// The KdTree generation code that uses the image cuts needs to be updated
// bigtime. But due to time shortage, I'm leaving the old code as is. We
// will get back to it later.
if (this->GetNumberOfInputConnections(0) == 1)
{
vtkPVRenderView::SetImageDataProducer(inInfo, this,
this->GetInputConnection(0, 0));
}
}
else if (request_type == vtkPVView::REQUEST_RENDER())
{
......
......@@ -80,10 +80,23 @@ public:
class vtkItem
{
vtkSmartPointer<vtkPVTrivialProducer> Producer;
// Data object produced by the representation.
vtkWeakPointer<vtkDataObject> DataObject;
// Data object available after delivery to the "rendering" node.
vtkSmartPointer<vtkDataObject> DeliveredDataObject;
// Data object after re-distributing when using ordered compositing, for
// example.
vtkSmartPointer<vtkDataObject> RedistributedDataObject;
unsigned long TimeStamp;
unsigned long ActualMemorySize;
public:
vtkWeakPointer<vtkAlgorithmOutput> ImageDataProducer;
// <-- HACK for image data volume rendering.
vtkWeakPointer<vtkPVDataRepresentation> Representation;
bool AlwaysClone;
bool Redistributable;
......@@ -100,35 +113,54 @@ public:
void SetDataObject(vtkDataObject* data)
{
if (data != this->DataObject ||
(data && data->GetMTime() > this->TimeStamp))
{
vtkTimeStamp ts; ts.Modified();
this->TimeStamp = ts;
}
this->DataObject = data;
this->Producer->SetOutput(data);
// the vtkTrivialProducer's MTime is is changed whenever the data itself
// changes or the data's mtime changes and hence we get a good indication
// of when we have a new piece for real.
this->TimeStamp = this->Producer->GetMTime();
this->ActualMemorySize = data? data->GetActualMemorySize() : 0;
}
void SetDeliveredDataObject(vtkDataObject* data)
{
this->Producer->SetOutput(data);
this->ActualMemorySize = data? data->GetActualMemorySize() : 0;
this->DeliveredDataObject = data;
}
void SetRedistributedDataObject(vtkDataObject* data)
{
this->RedistributedDataObject = data;
}
vtkDataObject* GetDeliveredDataObject()
{
return this->Producer->GetOutputDataObject(0);
return this->DeliveredDataObject.GetPointer();
}
vtkDataObject* GetRedistributedDataObject()
{
return this->RedistributedDataObject.GetPointer();
}
vtkPVTrivialProducer* GetProducer(bool use_redistributed_data)
{
if (use_redistributed_data && this->Redistributable)
{
this->Producer->SetOutput(this->RedistributedDataObject);
}
else
{
this->Producer->SetOutput(this->DeliveredDataObject);
}
return this->Producer.GetPointer();
}
vtkPVTrivialProducer* GetProducer() const
{ return this->Producer.GetPointer(); }
vtkDataObject* GetDataObject() const
{ return this->DataObject.GetPointer(); }
unsigned long GetTimeStamp() const
{ return this->TimeStamp; }
void SetTimeStamp(unsigned long ts)
{ this->TimeStamp = ts; }
unsigned long GetVisibleDataSize()
{
if (this->Representation && this->Representation->GetVisibility())
......@@ -458,7 +490,8 @@ vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(
return NULL;
}
return item->GetProducer()->GetOutputPort(0);
return item->GetProducer(
this->RenderView->GetUseOrderedCompositing())->GetOutputPort(0);
}
//----------------------------------------------------------------------------
......@@ -476,6 +509,21 @@ void vtkPVDataDeliveryManager::SetPiece(unsigned int id, vtkDataObject* data, bo
}
}
//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetImageDataProducer(
vtkPVDataRepresentation* repr, vtkAlgorithmOutput *producer)
{
vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false);
if (item)
{
item->ImageDataProducer = producer;
}
else
{
vtkErrorMacro("Invalid argument.");
}
}
//----------------------------------------------------------------------------
vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(
unsigned int id, bool low_res)
......@@ -487,7 +535,8 @@ vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(
return NULL;
}
return item->GetProducer()->GetOutputPort(0);
return item->GetProducer(
this->RenderView->GetUseOrderedCompositing())->GetOutputPort(0);
}
//----------------------------------------------------------------------------
......@@ -534,7 +583,6 @@ void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned
this->RenderView->GetUseDistributedRenderingForStillRender();
int mode = this->RenderView->GetDataDistributionMode(using_remote_rendering);
for (unsigned int cc=0; cc < size; cc++)
{
vtkInternals::vtkItem* item = this->Internals->GetItem(values[cc], use_lod !=0);
......@@ -551,6 +599,9 @@ void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned
// FIXME: check that the mode flags are "suitable" for AMR.
}
// release old memory (not necessarily, but try).
item->SetDeliveredDataObject(NULL);
vtkNew<vtkMPIMoveData> dataMover;
dataMover->InitializeForCommunicationForParaView();
dataMover->SetOutputDataType(data->GetDataObjectType());
......@@ -565,13 +616,20 @@ void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned
item->SetDeliveredDataObject(dataMover->GetOutputDataObject(0));
}
// There's a possibility that we'd need to do ordered compositing.
// Ask the view if we need to redistribute the data for ordered compositing.
bool use_ordered_compositing = using_remote_rendering &&
this->RenderView->GetUseOrderedCompositing();
vtkTimerLog::MarkEndEvent(use_lod?
"LowRes Data Migration" : "FullRes Data Migration");
}
if (use_ordered_compositing && !use_lod)
//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::RedistributeDataForOrderedCompositing(
bool use_lod)
{
if (this->RenderView->GetUpdateTimeStamp() > this->RedistributionTimeStamp)
{
vtkTimerLog::MarkStartEvent("Regenerate Kd-Tree");
// need to re-generate the kd-tree.
this->RedistributionTimeStamp.Modified();
vtkNew<vtkBSPCutsGenerator> cutsGenerator;
vtkInternals::ItemsMapType::iterator iter;
for (iter = this->Internals->ItemsMap.begin();
......@@ -579,10 +637,16 @@ void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned
{
vtkInternals::vtkItem& item = iter->second.first;
if (item.Representation &&
item.Representation->GetVisibility() &&
item.Redistributable)
item.Representation->GetVisibility())
{
cutsGenerator->AddInputData(item.GetDeliveredDataObject());
if (item.Redistributable)
{
cutsGenerator->AddInputData(item.GetDeliveredDataObject());
}
else if (item.ImageDataProducer)
{
cutsGenerator->AddInputConnection(item.ImageDataProducer);
}
}
}
......@@ -595,42 +659,58 @@ void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned
sddp->Update(0);
this->KdTree = cutsGenerator->GetPKdTree();
vtkTimerLog::MarkEndEvent("Regenerate Kd-Tree");
}
else if (!use_lod)
if (this->KdTree == NULL)
{
this->KdTree = NULL;
return;
}
// FIXME:STREAMING
// 1. Fix code to avoid recomputing of KdTree unless really necessary.
// 2. If KdTree is recomputed and is indeed different, then we need to
// redistribute all the visible "redistributable" datasets, not just the
// ones being requested.
if (this->KdTree)
vtkTimerLog::MarkStartEvent("Redistributing Data for Ordered Compositing");
vtkInternals::ItemsMapType::iterator iter;
for (iter = this->Internals->ItemsMap.begin();
iter != this->Internals->ItemsMap.end(); ++iter)
{
vtkTimerLog::MarkStartEvent("Redistributing Data for Ordered Compositing");
for (unsigned int cc=0; cc < size; cc++)
vtkInternals::vtkItem& item = use_lod? iter->second.second : iter->second.first;
if (!item.Redistributable ||
item.Representation == NULL ||
item.Representation->GetVisibility() == false ||
// delivered object can be null in case we're updating lod and the
// representation doeesn't have any LOD data.
item.GetDeliveredDataObject() == NULL)
{
vtkInternals::vtkItem* item = this->Internals->GetItem(values[cc], use_lod !=0);
if (!item->Redistributable)
{
continue;
}
continue;
}
if (item.GetRedistributedDataObject() &&
vtkNew<vtkOrderedCompositeDistributor> redistributor;
redistributor->SetController(vtkMultiProcessController::GetGlobalController());
redistributor->SetInputData(item->GetDeliveredDataObject());
redistributor->SetPKdTree(this->KdTree);
redistributor->SetPassThrough(0);
redistributor->Update();
item->SetDataObject(redistributor->GetOutputDataObject(0));
// input-data didn't change
(item.GetDeliveredDataObject()->GetMTime() <
item.GetRedistributedDataObject()->GetMTime()) &&
// kd-tree didn't change
(item.GetRedistributedDataObject()->GetMTime() >
this->KdTree->GetMTime()))
{
// skip redistribution.
continue;
}
vtkTimerLog::MarkEndEvent("Redistributing Data for Ordered Compositing");
}
// release old memory (not necessarily, but try).
item.SetRedistributedDataObject(NULL);
vtkTimerLog::MarkEndEvent(use_lod?
"LowRes Data Migration" : "FullRes Data Migration");
vtkNew<vtkOrderedCompositeDistributor> redistributor;
redistributor->SetController(vtkMultiProcessController::GetGlobalController());
redistributor->SetInputData(item.GetDeliveredDataObject());
redistributor->SetPKdTree(this->KdTree);
redistributor->SetPassThrough(0);
redistributor->Update();
item.SetRedistributedDataObject(redistributor->GetOutputDataObject(0));
}
vtkTimerLog::MarkEndEvent("Redistributing Data for Ordered Compositing");
}
//----------------------------------------------------------------------------
......
......@@ -106,6 +106,11 @@ public:
void SetRenderView(vtkPVRenderView*);
vtkPVRenderView* GetRenderView();
// Description:
// Called by the view on ever render when ordered compositing is to be used to
// ensure that the geometries are redistributed, as needed.
void RedistributeDataForOrderedCompositing(bool use_lod);
//BTX
// Description:
// Internal method used to determine the list of representations that need
......@@ -137,6 +142,11 @@ public:
void StreamingDeliver(unsigned int key);
// *******************************************************************
// *******************************************************************
// HACK for dealing with volume rendering for image data
void SetImageDataProducer(vtkPVDataRepresentation* repr, vtkAlgorithmOutput*);
//BTX
protected:
vtkPVDataDeliveryManager();
......@@ -145,6 +155,7 @@ protected:
vtkWeakPointer<vtkPVRenderView> RenderView;
vtkSmartPointer<vtkPKdTree> KdTree;
vtkTimeStamp RedistributionTimeStamp;
private:
vtkPVDataDeliveryManager(const vtkPVDataDeliveryManager&); // Not implemented
void operator=(const vtkPVDataDeliveryManager&); // Not implemented
......
......@@ -976,6 +976,18 @@ void vtkPVRenderView::Render(bool interactive, bool skip_rendering)
this->GetUseDistributedRenderingForInteractiveRender():
this->GetUseDistributedRenderingForStillRender();
if (this->GetUseOrderedCompositing())
{
this->Internals->DeliveryManager->RedistributeDataForOrderedCompositing(
use_lod_rendering);
this->SynchronizedRenderers->SetKdTree(
this->Internals->DeliveryManager->GetKdTree());
}
else
{
this->SynchronizedRenderers->SetKdTree(NULL);
}
// Render each representation with available geometry.
// This is the pass where representations get an opportunity to get the
// currently "available" represented data and try to render it.
......@@ -1007,8 +1019,6 @@ void vtkPVRenderView::Render(bool interactive, bool skip_rendering)
in_cave_mode ||
(!use_distributed_rendering && in_tile_display_mode));
this->SynchronizedRenderers->SetKdTree(
this->Internals->DeliveryManager->GetKdTree());
// When in batch mode, we are using the same render window for all views. That
// makes it impossible for vtkPVSynchronizedRenderWindows to identify which
......@@ -1164,6 +1174,20 @@ void vtkPVRenderView::SetStreamable(
view->GetDeliveryManager()->SetStreamable(repr, val);
}
//----------------------------------------------------------------------------
void vtkPVRenderView::SetImageDataProducer(
vtkInformation* info, vtkPVDataRepresentation* repr,
vtkAlgorithmOutput* producer)
{
vtkPVRenderView* view = vtkPVRenderView::SafeDownCast(info->Get(VIEW()));
if (!view)
{
vtkGenericWarningMacro("Missing VIEW().");
return;
}
view->GetDeliveryManager()->SetImageDataProducer(repr, producer);
}
//----------------------------------------------------------------------------
void vtkPVRenderView::SetDeliverToAllProcesses(vtkInformation* info,
......@@ -1260,7 +1284,7 @@ bool vtkPVRenderView::GetUseOrderedCompositing()
return false;
}
if (!this->NeedsOrderedCompositing)
if (!this->NeedsOrderedCompositing || this->MakingSelection)
{
return false;
}
......
......@@ -310,6 +310,12 @@ public:
static void SetStreamable(
vtkInformation* info, vtkPVDataRepresentation* repr, bool streamable);
// Description:
// Hack to pass along image data producer to use to generate the KdTree cuts
// when volume rendering image data. This code needs refactoring.
static void SetImageDataProducer(
vtkInformation* info, vtkPVDataRepresentation* repr, vtkAlgorithmOutput*);
// Description:
// Representations that support hardware (render-buffer based) selection,
// should register the prop that they use for selection rendering. They can do
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment