Commit 034e49d4 authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

improve vtkPVDataDeliveryManager's data delivery logic.

When doing remote rendering, the client's mtime for when data delivery
happened was not correctly updated. That was causing the data delivery
logic to reexecute on each render. That was causing #18340.

Fixed vtkPVDataDeliveryManager to keep separate delivery objects for
each delivery mode. This ensures that the client doesn't end up with a
data delivery timestamp mismatch, as before. Also simplified the code in
general and adding timer log entries to catch such bug easily in the
future.

Fixes #18340.
parent 47089b5c
......@@ -185,7 +185,7 @@ public:
* server-sides using Deliver().
*/
bool NeedsDelivery(
vtkMTimeType timestamp, std::vector<unsigned int>& keys_to_deliver, bool use_low_res);
vtkMTimeType timestamp, std::vector<unsigned int>& keys_to_deliver, bool interactive);
/**
* Triggers delivery for the geometries of indicated representations.
......@@ -232,10 +232,17 @@ protected:
vtkPVDataDeliveryManager();
~vtkPVDataDeliveryManager() override;
/**
* Helper method to return the current data distribution mode by querying the
* vtkPVRenderView.
*/
int GetViewDataDistributionMode(bool use_lod);
vtkWeakPointer<vtkPVRenderView> RenderView;
vtkSmartPointer<vtkPKdTree> KdTree;
vtkTimeStamp RedistributionTimeStamp;
std::string LastCutsGeneratorToken;
private:
vtkPVDataDeliveryManager(const vtkPVDataDeliveryManager&) = delete;
......
......@@ -1433,23 +1433,45 @@ void vtkPVRenderView::Render(bool interactive, bool skip_rendering)
? this->GetUseDistributedRenderingForLODRender()
: this->GetUseDistributedRenderingForRender();
if (this->GetUseOrderedCompositing())
const bool use_ordered_compositing = this->GetUseOrderedCompositing();
vtkTimerLog::FormatAndMarkEvent(
"Render (use_lod: %d), (use_distributed_rendering: %d), (use_ordered_compositing: %d)",
use_lod_rendering, use_distributed_rendering, use_ordered_compositing);
// If ordered compositing is needed, we have two options: either we're
// supposed to (i) build a KdTree and redistribute data or we are expected to (ii) use
// a custom partition provided via `vtkPartitionOrder` built using local data
// bounds and not bother redistributing data at all. Let's determine which
// path we're expected to take and do work accordingly.
if (use_ordered_compositing)
{
if (this->PartitionOrdering->GetImplementation() == NULL ||
this->PartitionOrdering->GetImplementation()->IsA("vtkPKdTree"))
auto poImpl = this->PartitionOrdering->GetImplementation();
if (poImpl == nullptr || vtkPKdTree::SafeDownCast(poImpl) != nullptr)
{
vtkTimerLog::FormatAndMarkEvent(
"Using ordered compositing w/ data redistribution, if needed");
// not using a custom (bounds-based ordering) i.e. we use in path (i). Let
// the delivery manager redistrbute data as it deems necessary.
this->Internals->DeliveryManager->RedistributeDataForOrderedCompositing(use_lod_rendering);
this->PartitionOrdering->SetImplementation(this->Internals->DeliveryManager->GetKdTree());
}
else
{
vtkTimerLog::FormatAndMarkEvent("Using ordered compositing with w/o data redistribution");
// using custom rendering ordering without any data redistribution i.e.
// path (ii).
// clear off redistributed data.
this->Internals->DeliveryManager->ClearRedistributedData(use_lod_rendering);
}
// tell `this->SynchronizedRenderers` who to order the ranks when doing
// parallel rendering.
this->SynchronizedRenderers->SetPartitionOrdering(this->PartitionOrdering.GetPointer());
}
else
{
this->SynchronizedRenderers->SetPartitionOrdering(NULL);
this->SynchronizedRenderers->SetPartitionOrdering(nullptr);
}
// enable render empty images if it was requested
......@@ -1759,12 +1781,6 @@ void vtkPVRenderView::SetOrderedCompositingInformation(vtkInformation* info, con
view->PartitionOrdering->SetImplementation(partitionOrdering.GetPointer());
}
//----------------------------------------------------------------------------
void vtkPVRenderView::ClearOrderedCompositingInformation()
{
this->PartitionOrdering->SetImplementation(NULL);
}
//----------------------------------------------------------------------------
void vtkPVRenderView::SetDeliverToAllProcesses(
vtkInformation* info, vtkPVDataRepresentation* repr, bool clone)
......
......@@ -514,7 +514,6 @@ public:
vtkExtentTranslator* translator, const int whole_extents[6], const double origin[3],
const double spacing[3]);
static void SetOrderedCompositingInformation(vtkInformation* info, const double bounds[6]);
void ClearOrderedCompositingInformation();
//@}
//@{
......
......@@ -31,7 +31,6 @@
vtkStandardNewMacro(vtkSMDataDeliveryManager);
//----------------------------------------------------------------------------
vtkSMDataDeliveryManager::vtkSMDataDeliveryManager()
: PreviousForceDataDistributionMode(-1)
{
}
......@@ -57,54 +56,35 @@ void vtkSMDataDeliveryManager::Deliver(bool interactive)
assert(this->ViewProxy != NULL);
vtkPVRenderView* view = vtkPVRenderView::SafeDownCast(this->ViewProxy->GetClientSideObject());
bool use_lod = interactive && view->GetUseLODForInteractiveRender();
bool use_distributed_rendering = use_lod ? view->GetUseDistributedRenderingForRender()
: view->GetUseDistributedRenderingForLODRender();
if (this->PreviousForceDataDistributionMode != view->GetForceDataDistributionMode())
{
// if distribution mode is forced and different from previous,
// there's no guarantee what it will be and which nodes will have geometry.
// So we simply clear delivery timestamps to do deliveries with a clean
// slate.
this->PreviousForceDataDistributionMode = view->GetForceDataDistributionMode();
for (int cc = 0; cc < 4; ++cc)
{
this->DeliveryTimestamps[cc] = vtkTimeStamp();
}
}
const bool use_lod = interactive && view->GetUseLODForInteractiveRender();
const bool use_distributed_rendering = use_lod ? view->GetUseDistributedRenderingForLODRender()
: view->GetUseDistributedRenderingForRender();
const int data_distribution_mode = view->GetDataDistributionMode(use_distributed_rendering);
vtkMTimeType update_ts = view->GetUpdateTimeStamp();
int delivery_type = LOCAL_RENDERING_AND_FULL_RES;
if (!use_lod && use_distributed_rendering)
{
delivery_type = REMOTE_RENDERING_AND_FULL_RES;
}
else if (use_lod && !use_distributed_rendering)
{
delivery_type = LOCAL_RENDERING_AND_LOW_RES;
}
else if (use_lod && use_distributed_rendering)
{
delivery_type = REMOTE_RENDERING_AND_LOW_RES;
}
vtkTimeStamp& timeStamp = this->DeliveryTimestamps[delivery_type];
// note: this will create new vtkTimeStamp, if needed.
vtkTimeStamp& timeStamp = this->DeliveryTimestamps[data_distribution_mode];
if (timeStamp > update_ts)
{
// we delivered the data since the update. Nothing delivery to be done.
// we have delivered the data since the last update on this view for the
// chosen data delivery mode. No delivery needs to be done at this time.
return;
}
// Get a list of representations for which we need to delivery data.
std::vector<unsigned int> keys_to_deliver;
if (!view->GetDeliveryManager()->NeedsDelivery(timeStamp, keys_to_deliver, use_lod))
{
timeStamp.Modified();
return;
vtkTimerLogScope logscope(
use_lod ? "check for data delivery (use_lod: 1)" : "check for delivery (use_lod: 0)");
if (!view->GetDeliveryManager()->NeedsDelivery(timeStamp, keys_to_deliver, interactive))
{
timeStamp.Modified();
return;
}
}
// cout << "Request Delivery: " << keys_to_deliver.size() << endl;
vtkTimerLog::MarkStartEvent("vtkSMDataDeliveryManager: Deliver Geometry");
vtkTimerLogScope logscope("do data delivery");
vtkClientServerStream stream;
stream << vtkClientServerStream::Invoke << VTKOBJECT(this->ViewProxy) << "Deliver"
<< static_cast<int>(use_lod) << static_cast<unsigned int>(keys_to_deliver.size())
......@@ -113,7 +93,6 @@ void vtkSMDataDeliveryManager::Deliver(bool interactive)
<< vtkClientServerStream::End;
this->ViewProxy->GetSession()->ExecuteStream(this->ViewProxy->GetLocation(), stream, false);
timeStamp.Modified();
vtkTimerLog::MarkEndEvent("vtkSMDataDeliveryManager: Deliver Geometry");
}
//----------------------------------------------------------------------------
......
......@@ -34,8 +34,10 @@
#include "vtkPVServerManagerRenderingModule.h" //needed for exports
#include "vtkSMObject.h"
#include "vtkWeakPointer.h" // needed for iVars
class vtkSMViewProxy;
#include <map> // for std::map
class vtkSMViewProxy;
class VTKPVSERVERMANAGERRENDERING_EXPORT vtkSMDataDeliveryManager : public vtkSMObject
{
public:
......@@ -67,16 +69,7 @@ protected:
~vtkSMDataDeliveryManager() override;
vtkWeakPointer<vtkSMViewProxy> ViewProxy;
enum
{
LOCAL_RENDERING_AND_FULL_RES = 0,
LOCAL_RENDERING_AND_LOW_RES = 1,
REMOTE_RENDERING_AND_FULL_RES = 2,
REMOTE_RENDERING_AND_LOW_RES = 3,
};
vtkTimeStamp DeliveryTimestamps[4];
int PreviousForceDataDistributionMode;
std::map<int, vtkTimeStamp> DeliveryTimestamps;
private:
vtkSMDataDeliveryManager(const vtkSMDataDeliveryManager&) = delete;
......
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