vtkPVDataDeliveryManager.cxx 26.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*=========================================================================

  Program:   ParaView
  Module:    $RCSfile$

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
15
#include "vtkPVDataDeliveryManager.h"
16 17

#include "vtkAlgorithmOutput.h"
18
#include "vtkDataObject.h"
19 20
#include "vtkExtentTranslator.h"
#include "vtkKdTreeManager.h"
21
#include "vtkMPIMoveData.h"
22 23 24 25 26
#include "vtkMultiProcessController.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOrderedCompositeDistributor.h"
#include "vtkPKdTree.h"
27
#include "vtkPVDataRepresentation.h"
28
#include "vtkPVRenderView.h"
29
#include "vtkPVStreamingMacros.h"
30 31
#include "vtkPVTrivialProducer.h"
#include "vtkSmartPointer.h"
32
#include "vtkStreamingDemandDrivenPipeline.h"
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
33
#include "vtkTimerLog.h"
34
#include "vtkWeakPointer.h"
35 36

#include <assert.h>
37 38 39 40 41 42 43 44 45
#include <map>
#include <queue>
#include <utility>

//*****************************************************************************
class vtkPVDataDeliveryManager::vtkInternals
{
public:
  class vtkPriorityQueueItem
Kitware Robot's avatar
Kitware Robot committed
46
  {
47 48 49 50 51 52 53
  public:
    unsigned int RepresentationId;
    unsigned int BlockId;
    unsigned int Level;
    unsigned int Index;
    double Priority;

Kitware Robot's avatar
Kitware Robot committed
54 55 56 57 58 59
    vtkPriorityQueueItem()
      : RepresentationId(0)
      , BlockId(0)
      , Level(0)
      , Index(0)
      , Priority(0)
60 61 62
    {
    }

Kitware Robot's avatar
Kitware Robot committed
63 64
    bool operator<(const vtkPriorityQueueItem& other) const
    {
65
      return this->Priority < other.Priority;
Kitware Robot's avatar
Kitware Robot committed
66 67
    }
  };
68 69 70 71

  typedef std::priority_queue<vtkPriorityQueueItem> PriorityQueueType;
  PriorityQueueType PriorityQueue;

72
  class vtkOrderedCompositingInfo
Kitware Robot's avatar
Kitware Robot committed
73
  {
74 75 76 77 78
  public:
    vtkSmartPointer<vtkExtentTranslator> Translator;
    double Origin[3];
    double Spacing[3];
    int WholeExtent[6];
Kitware Robot's avatar
Kitware Robot committed
79
  };
80

81
  class vtkItem
Kitware Robot's avatar
Kitware Robot committed
82
  {
83
    vtkSmartPointer<vtkPVTrivialProducer> Producer;
84 85

    // Data object produced by the representation.
86
    vtkWeakPointer<vtkDataObject> DataObject;
87 88 89 90 91 92 93 94

    // 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;

95 96 97
    // Data object for a streamed piece.
    vtkSmartPointer<vtkDataObject> StreamedPiece;

98 99
    vtkMTimeType TimeStamp;
    vtkMTimeType ActualMemorySize;
Kitware Robot's avatar
Kitware Robot committed
100

101
  public:
102
    vtkOrderedCompositingInfo OrderedCompositingInfo;
103

104 105 106
    bool CloneDataToAllNodes;
    bool DeliverToClientAndRenderingProcesses;
    bool GatherBeforeDeliveringToClient;
107 108 109
    bool Redistributable;
    bool Streamable;

Kitware Robot's avatar
Kitware Robot committed
110 111 112 113 114 115 116 117 118 119 120
    vtkItem()
      : Producer(vtkSmartPointer<vtkPVTrivialProducer>::New())
      , TimeStamp(0)
      , ActualMemorySize(0)
      , CloneDataToAllNodes(false)
      , DeliverToClientAndRenderingProcesses(false)
      , GatherBeforeDeliveringToClient(false)
      , Redistributable(false)
      , Streamable(false)
    {
    }
121 122

    void SetDataObject(vtkDataObject* data)
Kitware Robot's avatar
Kitware Robot committed
123
    {
124
      this->DataObject = data;
Kitware Robot's avatar
Kitware Robot committed
125
      this->ActualMemorySize = data ? data->GetActualMemorySize() : 0;
126

Kitware Robot's avatar
Kitware Robot committed
127 128
      vtkTimeStamp ts;
      ts.Modified();
129
      this->TimeStamp = ts;
Kitware Robot's avatar
Kitware Robot committed
130
    }
131

Kitware Robot's avatar
Kitware Robot committed
132
    void SetActualMemorySize(unsigned long size) { this->ActualMemorySize = size; }
133
    unsigned long GetActualMemorySize() const { return this->ActualMemorySize; }
134

Kitware Robot's avatar
Kitware Robot committed
135
    void SetDeliveredDataObject(vtkDataObject* data) { this->DeliveredDataObject = data; }
136

Kitware Robot's avatar
Kitware Robot committed
137
    void SetRedistributedDataObject(vtkDataObject* data) { this->RedistributedDataObject = data; }
138

Kitware Robot's avatar
Kitware Robot committed
139
    vtkDataObject* GetDeliveredDataObject() { return this->DeliveredDataObject.GetPointer(); }
140 141

    vtkDataObject* GetRedistributedDataObject()
Kitware Robot's avatar
Kitware Robot committed
142
    {
143
      return this->RedistributedDataObject.GetPointer();
Kitware Robot's avatar
Kitware Robot committed
144
    }
145 146

    vtkPVTrivialProducer* GetProducer(bool use_redistributed_data)
Kitware Robot's avatar
Kitware Robot committed
147
    {
148
      if (use_redistributed_data && this->Redistributable)
Kitware Robot's avatar
Kitware Robot committed
149
      {
150
        this->Producer->SetOutput(this->RedistributedDataObject);
Kitware Robot's avatar
Kitware Robot committed
151
      }
152
      else
Kitware Robot's avatar
Kitware Robot committed
153
      {
154
        this->Producer->SetOutput(this->DeliveredDataObject);
155
      }
Kitware Robot's avatar
Kitware Robot committed
156 157
      return this->Producer.GetPointer();
    }
158

Kitware Robot's avatar
Kitware Robot committed
159
    vtkDataObject* GetDataObject() const { return this->DataObject.GetPointer(); }
160
    vtkMTimeType GetTimeStamp() const { return this->TimeStamp; }
Kitware Robot's avatar
Kitware Robot committed
161 162 163
    void SetNextStreamedPiece(vtkDataObject* data) { this->StreamedPiece = data; }
    vtkDataObject* GetStreamedPiece() { return this->StreamedPiece; }
  };
164

165 166 167
  // First is repr unique id, second is the input port.
  typedef std::pair<unsigned int, int> ReprPortType;
  typedef std::map<ReprPortType, std::pair<vtkItem, vtkItem> > ItemsMapType;
168

169 170 171 172
  // Keep track of representation and its uid.
  typedef std::map<unsigned int, vtkWeakPointer<vtkPVDataRepresentation> > RepresentationsMapType;

  vtkItem* GetItem(unsigned int index, bool use_second, int port, bool create_if_needed = false)
Kitware Robot's avatar
Kitware Robot committed
173
  {
174 175 176
    ReprPortType key(index, port);
    ItemsMapType::iterator items = this->ItemsMap.find(key);
    if (items != this->ItemsMap.end())
Kitware Robot's avatar
Kitware Robot committed
177
    {
178
      return use_second ? &(items->second.second) : &(items->second.first);
179
    }
180 181 182 183 184
    else if (create_if_needed)
    {
      std::pair<vtkItem, vtkItem>& itemsPair = this->ItemsMap[key];
      return use_second ? &(itemsPair.second) : &(itemsPair.first);
    }
Kitware Robot's avatar
Kitware Robot committed
185 186
    return NULL;
  }
187

188 189
  vtkItem* GetItem(
    vtkPVDataRepresentation* repr, bool use_second, int port, bool create_if_needed = false)
Kitware Robot's avatar
Kitware Robot committed
190
  {
191
    return this->GetItem(repr->GetUniqueIdentifier(), use_second, port, create_if_needed);
Kitware Robot's avatar
Kitware Robot committed
192
  }
193 194

  unsigned long GetVisibleDataSize(bool use_second_if_available)
Kitware Robot's avatar
Kitware Robot committed
195
  {
196 197 198
    unsigned long size = 0;
    ItemsMapType::iterator iter;
    for (iter = this->ItemsMap.begin(); iter != this->ItemsMap.end(); ++iter)
Kitware Robot's avatar
Kitware Robot committed
199
    {
200 201 202 203 204 205 206
      const ReprPortType& key = iter->first;
      if (!this->IsRepresentationVisible(key.first))
      {
        // skip hidden representations.
        continue;
      }

207
      if (use_second_if_available && iter->second.second.GetDataObject())
Kitware Robot's avatar
Kitware Robot committed
208
      {
209
        size += iter->second.second.GetActualMemorySize();
Kitware Robot's avatar
Kitware Robot committed
210
      }
211
      else
Kitware Robot's avatar
Kitware Robot committed
212
      {
213
        size += iter->second.first.GetActualMemorySize();
214 215
      }
    }
Kitware Robot's avatar
Kitware Robot committed
216 217
    return size;
  }
218

219 220 221 222 223 224 225
  bool IsRepresentationVisible(unsigned int id) const
  {
    RepresentationsMapType::const_iterator riter = this->RepresentationsMap.find(id);
    return (riter != this->RepresentationsMap.end() && riter->second.GetPointer() != NULL &&
      riter->second->GetVisibility());
  }

226
  ItemsMapType ItemsMap;
227
  RepresentationsMapType RepresentationsMap;
228
};
229

230 231 232
//*****************************************************************************

vtkStandardNewMacro(vtkPVDataDeliveryManager);
233
//----------------------------------------------------------------------------
234
vtkPVDataDeliveryManager::vtkPVDataDeliveryManager()
235 236 237 238 239
  : Internals(new vtkInternals())
{
}

//----------------------------------------------------------------------------
240
vtkPVDataDeliveryManager::~vtkPVDataDeliveryManager()
241 242 243 244 245
{
  delete this->Internals;
  this->Internals = 0;
}

246
//----------------------------------------------------------------------------
247
void vtkPVDataDeliveryManager::SetRenderView(vtkPVRenderView* view)
248
{
249
  this->RenderView = view;
250 251
}

252
//----------------------------------------------------------------------------
253
vtkPVRenderView* vtkPVDataDeliveryManager::GetRenderView()
254
{
255
  return this->RenderView;
256 257
}

Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
258
//----------------------------------------------------------------------------
259
unsigned long vtkPVDataDeliveryManager::GetVisibleDataSize(bool low_res)
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
260 261 262
{
  return this->Internals->GetVisibleDataSize(low_res);
}
263 264

//----------------------------------------------------------------------------
265
void vtkPVDataDeliveryManager::RegisterRepresentation(vtkPVDataRepresentation* repr)
266
{
Kitware Robot's avatar
Kitware Robot committed
267
  assert("A representation must have a valid UniqueIdentifier" && repr->GetUniqueIdentifier());
268
  this->Internals->RepresentationsMap[repr->GetUniqueIdentifier()] = repr;
269 270 271
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
272
void vtkPVDataDeliveryManager::UnRegisterRepresentation(vtkPVDataRepresentation* repr)
273
{
274 275
  unsigned int rid = repr->GetUniqueIdentifier();
  this->Internals->RepresentationsMap.erase(rid);
276

277 278
  vtkInternals::ItemsMapType::iterator iter = this->Internals->ItemsMap.begin();
  while (iter != this->Internals->ItemsMap.end())
279
  {
280 281 282 283 284 285 286 287 288 289 290
    const vtkInternals::ReprPortType& key = iter->first;
    if (key.first == rid)
    {
      vtkInternals::ItemsMapType::iterator toerase = iter;
      ++iter;
      this->Internals->ItemsMap.erase(toerase);
    }
    else
    {
      ++iter;
    }
291
  }
292 293 294
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
295
vtkPVDataRepresentation* vtkPVDataDeliveryManager::GetRepresentation(unsigned int index)
296
{
297 298 299
  vtkInternals::RepresentationsMapType::const_iterator iter =
    this->Internals->RepresentationsMap.find(index);
  return iter != this->Internals->RepresentationsMap.end() ? iter->second.GetPointer() : NULL;
300 301
}

302
//----------------------------------------------------------------------------
303
void vtkPVDataDeliveryManager::SetDeliverToAllProcesses(
304
  vtkPVDataRepresentation* repr, bool mode, bool low_res, int port)
305
{
306 307
  vtkInternals::vtkItem* item =
    this->Internals->GetItem(repr, low_res, port, /*create_if_needed=*/true);
308
  if (item)
Kitware Robot's avatar
Kitware Robot committed
309
  {
310
    item->CloneDataToAllNodes = mode;
Kitware Robot's avatar
Kitware Robot committed
311
  }
312
  else
Kitware Robot's avatar
Kitware Robot committed
313
  {
314
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
315
  }
316 317 318 319
}

//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::SetDeliverToClientAndRenderingProcesses(
320 321
  vtkPVDataRepresentation* repr, bool deliver_to_client, bool gather_before_delivery, bool low_res,
  int port)
322
{
323 324
  vtkInternals::vtkItem* item =
    this->Internals->GetItem(repr, low_res, port, /*create_if_needed=*/true);
325
  if (item)
Kitware Robot's avatar
Kitware Robot committed
326
  {
327 328
    item->DeliverToClientAndRenderingProcesses = deliver_to_client;
    item->GatherBeforeDeliveringToClient = gather_before_delivery;
Kitware Robot's avatar
Kitware Robot committed
329
  }
330
  else
Kitware Robot's avatar
Kitware Robot committed
331
  {
332
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
333
  }
334 335
}

336
//----------------------------------------------------------------------------
337
void vtkPVDataDeliveryManager::MarkAsRedistributable(
338
  vtkPVDataRepresentation* repr, bool value /*=true*/, int port)
339
{
340 341
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
  vtkInternals::vtkItem* low_item = this->Internals->GetItem(repr, true, port, true);
342
  if (item)
Kitware Robot's avatar
Kitware Robot committed
343
  {
344 345
    item->Redistributable = value;
    low_item->Redistributable = value;
Kitware Robot's avatar
Kitware Robot committed
346
  }
347
  else
Kitware Robot's avatar
Kitware Robot committed
348
  {
349
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
350
  }
351
}
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
352

353
//----------------------------------------------------------------------------
354
void vtkPVDataDeliveryManager::SetStreamable(vtkPVDataRepresentation* repr, bool val, int port)
355
{
356 357
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
  vtkInternals::vtkItem* low_item = this->Internals->GetItem(repr, true, port, true);
358
  if (item)
Kitware Robot's avatar
Kitware Robot committed
359
  {
360 361
    item->Streamable = val;
    low_item->Streamable = val;
Kitware Robot's avatar
Kitware Robot committed
362
  }
363
  else
Kitware Robot's avatar
Kitware Robot committed
364
  {
365
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
366
  }
367 368
}

369
//----------------------------------------------------------------------------
370 371
void vtkPVDataDeliveryManager::SetPiece(vtkPVDataRepresentation* repr, vtkDataObject* data,
  bool low_res, unsigned long trueSize, int port)
372
{
373 374
  vtkInternals::vtkItem* item =
    this->Internals->GetItem(repr, low_res, port, /*create_if_needed=*/true);
375
  if (item)
Kitware Robot's avatar
Kitware Robot committed
376
  {
377
    vtkMTimeType data_time = 0;
378
    if (data && (data->GetMTime() > data_time))
Kitware Robot's avatar
Kitware Robot committed
379
    {
380
      data_time = data->GetMTime();
Kitware Robot's avatar
Kitware Robot committed
381
    }
382 383 384 385
    if (repr && repr->GetPipelineDataTime() > data_time)
    {
      data_time = repr->GetPipelineDataTime();
    }
Kitware Robot's avatar
Kitware Robot committed
386 387
    if (data_time > item->GetTimeStamp() || item->GetDataObject() != data)
    {
388
      item->SetDataObject(data);
Kitware Robot's avatar
Kitware Robot committed
389
    }
390
    if (trueSize > 0)
Kitware Robot's avatar
Kitware Robot committed
391
    {
392
      item->SetActualMemorySize(trueSize);
393
    }
Kitware Robot's avatar
Kitware Robot committed
394
  }
395
  else
Kitware Robot's avatar
Kitware Robot committed
396
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
397
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
398
  }
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
399 400 401
}

//----------------------------------------------------------------------------
402
vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(
403
  vtkPVDataRepresentation* repr, bool low_res, int port)
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
404
{
405
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, low_res, port);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
406
  if (!item)
Kitware Robot's avatar
Kitware Robot committed
407
  {
408
    vtkErrorMacro("Invalid arguments.");
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
409
    return NULL;
Kitware Robot's avatar
Kitware Robot committed
410
  }
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
411

Kitware Robot's avatar
Kitware Robot committed
412
  return item->GetProducer(this->RenderView->GetUseOrderedCompositing())->GetOutputPort(0);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
413 414 415
}

//----------------------------------------------------------------------------
416 417
void vtkPVDataDeliveryManager::SetPiece(
  unsigned int id, vtkDataObject* data, bool low_res, int port)
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
418
{
419
  vtkInternals::vtkItem* item = this->Internals->GetItem(id, low_res, port, true);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
420
  if (item)
Kitware Robot's avatar
Kitware Robot committed
421
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
422
    item->SetDataObject(data);
Kitware Robot's avatar
Kitware Robot committed
423
  }
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
424
  else
Kitware Robot's avatar
Kitware Robot committed
425
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
426
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
427
  }
428 429
}

430
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
431 432
void vtkPVDataDeliveryManager::SetOrderedCompositingInformation(vtkPVDataRepresentation* repr,
  vtkExtentTranslator* translator, const int whole_extents[6], const double origin[3],
433
  const double spacing[3], int port)
434
{
435
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr, false, port, true);
436
  if (item)
Kitware Robot's avatar
Kitware Robot committed
437
  {
438 439
    vtkInternals::vtkOrderedCompositingInfo info;
    info.Translator = translator;
Kitware Robot's avatar
Kitware Robot committed
440 441 442
    memcpy(info.WholeExtent, whole_extents, sizeof(int) * 6);
    memcpy(info.Origin, origin, sizeof(double) * 3);
    memcpy(info.Spacing, spacing, sizeof(double) * 3);
443 444

    item->OrderedCompositingInfo = info;
Kitware Robot's avatar
Kitware Robot committed
445
  }
446
  else
Kitware Robot's avatar
Kitware Robot committed
447
  {
448
    vtkErrorMacro("Invalid argument.");
Kitware Robot's avatar
Kitware Robot committed
449
  }
450 451
}

452
//----------------------------------------------------------------------------
453
vtkAlgorithmOutput* vtkPVDataDeliveryManager::GetProducer(unsigned int id, bool low_res, int port)
454
{
455
  vtkInternals::vtkItem* item = this->Internals->GetItem(id, low_res, port);
456
  if (!item)
Kitware Robot's avatar
Kitware Robot committed
457
  {
458 459
    vtkErrorMacro("Invalid arguments.");
    return NULL;
Kitware Robot's avatar
Kitware Robot committed
460
  }
461

Kitware Robot's avatar
Kitware Robot committed
462
  return item->GetProducer(this->RenderView->GetUseOrderedCompositing())->GetOutputPort(0);
463 464
}

465
//----------------------------------------------------------------------------
466
bool vtkPVDataDeliveryManager::NeedsDelivery(
467
  vtkMTimeType timestamp, std::vector<unsigned int>& keys_to_deliver, bool use_low)
468 469
{
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
470 471
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
472
    if (this->Internals->IsRepresentationVisible(iter->first.first))
Kitware Robot's avatar
Kitware Robot committed
473
    {
474 475 476 477 478 479 480
      vtkInternals::vtkItem& item = use_low ? iter->second.second : iter->second.first;
      if (item.GetTimeStamp() > timestamp)
      {
        // FIXME: convert keys_to_deliver to a vector of pairs.
        keys_to_deliver.push_back(iter->first.first);
        keys_to_deliver.push_back(static_cast<unsigned int>(iter->first.second));
      }
481
    }
Kitware Robot's avatar
Kitware Robot committed
482
  }
483 484 485 486
  return keys_to_deliver.size() > 0;
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
487
void vtkPVDataDeliveryManager::Deliver(int use_lod, unsigned int size, unsigned int* values)
488 489

{
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
490 491 492 493 494 495 496 497 498 499 500 501
  // This method gets called on all processes with the list of representations
  // to "deliver". We check with the view what mode we're operating in and
  // decide where the data needs to be delivered.
  //
  // Representations can provide overrides, e.g. though the view says data is
  // merely "pass-through", some representation says we need to clone the data
  // everywhere. That makes it critical that this method is called on all
  // processes at the same time to avoid deadlocks and other complications.
  //
  // This method will be implemented in "view-specific" subclasses since how the
  // data is delivered is very view specific.

502 503
  assert(size % 2 == 0);

Kitware Robot's avatar
Kitware Robot committed
504
  vtkTimerLog::MarkStartEvent(use_lod ? "LowRes Data Migration" : "FullRes Data Migration");
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
505

Kitware Robot's avatar
Kitware Robot committed
506 507 508
  bool using_remote_rendering = use_lod
    ? this->RenderView->GetUseDistributedRenderingForInteractiveRender()
    : this->RenderView->GetUseDistributedRenderingForStillRender();
509
  int mode = this->RenderView->GetDataDistributionMode(using_remote_rendering);
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
510

511
  for (unsigned int cc = 0; cc < size; cc += 2)
Kitware Robot's avatar
Kitware Robot committed
512
  {
513
    int port = static_cast<int>(values[cc + 1]);
514

515 516 517
    vtkInternals::vtkItem* item = this->Internals->GetItem(values[cc], use_lod != 0, port);
    vtkDataObject* data = item ? item->GetDataObject() : NULL;
    if (!data)
518
    {
519 520
      // ideally, we want to sync this info between all ranks some other rank
      // doesn't deadlock (esp. in collaboration mode).
521 522
      continue;
    }
523

524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
    //    if (data != NULL && data->IsA("vtkUniformGridAMR"))
    //      {
    //      // we are dealing with AMR datasets.
    //      // We assume for now we're not running in render-server mode. We can
    //      // ensure that at some point in future.
    //      // So we are either in pass-through or collect mode.

    //      // FIXME: check that the mode flags are "suitable" for AMR.
    //      }

    vtkNew<vtkMPIMoveData> dataMover;
    dataMover->InitializeForCommunicationForParaView();
    dataMover->SetOutputDataType(data ? data->GetDataObjectType() : VTK_POLY_DATA);
    dataMover->SetMoveMode(mode);
    if (item->CloneDataToAllNodes)
    {
      dataMover->SetMoveModeToClone();
    }
    else if (item->DeliverToClientAndRenderingProcesses)
    {
      if (mode == vtkMPIMoveData::PASS_THROUGH)
Kitware Robot's avatar
Kitware Robot committed
545
      {
546
        dataMover->SetMoveMode(vtkMPIMoveData::COLLECT_AND_PASS_THROUGH);
Kitware Robot's avatar
Kitware Robot committed
547
      }
548
      else
Kitware Robot's avatar
Kitware Robot committed
549
      {
550 551
        // nothing to do, since the data is going to be delivered to the client
        // anyways.
552
      }
553 554 555
      dataMover->SetSkipDataServerGatherToZero(item->GatherBeforeDeliveringToClient == false);
    }
    dataMover->SetInputData(data);
556

557 558 559 560 561 562 563 564 565
    if (dataMover->GetOutputGeneratedOnProcess())
    {
      // release old memory (not necessarily, but try).
      item->SetDeliveredDataObject(NULL);
    }
    dataMover->Update();
    if (item->GetDeliveredDataObject() == NULL)
    {
      item->SetDeliveredDataObject(dataMover->GetOutputDataObject(0));
566
    }
Kitware Robot's avatar
Kitware Robot committed
567
  }
568

Kitware Robot's avatar
Kitware Robot committed
569
  vtkTimerLog::MarkEndEvent(use_lod ? "LowRes Data Migration" : "FullRes Data Migration");
570
}
571

572
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
573
void vtkPVDataDeliveryManager::RedistributeDataForOrderedCompositing(bool use_lod)
574 575
{
  if (this->RenderView->GetUpdateTimeStamp() > this->RedistributionTimeStamp)
Kitware Robot's avatar
Kitware Robot committed
576
  {
577 578 579 580
    vtkTimerLog::MarkStartEvent("Regenerate Kd-Tree");
    // need to re-generate the kd-tree.
    this->RedistributionTimeStamp.Modified();

581
    vtkNew<vtkKdTreeManager> cutsGenerator;
582
    vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
583 584 585
    for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
    {
      vtkInternals::vtkItem& item = iter->second.first;
586
      if (this->Internals->IsRepresentationVisible(iter->first.first))
587
      {
588
        if (item.OrderedCompositingInfo.Translator)
Kitware Robot's avatar
Kitware Robot committed
589
        {
590 591
          // implies that the representation is providing us with means to
          // override how the ordered compositing happens.
Kitware Robot's avatar
Kitware Robot committed
592 593 594 595
          const vtkInternals::vtkOrderedCompositingInfo& info = item.OrderedCompositingInfo;
          cutsGenerator->SetStructuredDataInformation(
            info.Translator, info.WholeExtent, info.Origin, info.Spacing);
        }
596
        else if (item.Redistributable)
Kitware Robot's avatar
Kitware Robot committed
597
        {
598
          cutsGenerator->AddDataObject(item.GetDeliveredDataObject());
599 600
        }
      }
Kitware Robot's avatar
Kitware Robot committed
601
    }
602 603
    cutsGenerator->GenerateKdTree();
    this->KdTree = cutsGenerator->GetKdTree();
604
    vtkTimerLog::MarkEndEvent("Regenerate Kd-Tree");
Kitware Robot's avatar
Kitware Robot committed
605
  }
606 607

  if (this->KdTree == NULL)
Kitware Robot's avatar
Kitware Robot committed
608
  {
609
    return;
Kitware Robot's avatar
Kitware Robot committed
610
  }
611

612 613
  vtkTimerLog::MarkStartEvent("Redistributing Data for Ordered Compositing");
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
614 615
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
616 617 618 619 620
    if (!this->Internals->IsRepresentationVisible(iter->first.first))
    {
      // skip hidden representations;
      continue;
    }
621

622 623
    vtkInternals::vtkItem& item = use_lod ? iter->second.second : iter->second.first;
    if (!item.Redistributable ||
624 625
      // delivered object can be null in case we're updating lod and the
      // representation doeesn't have any LOD data.
626
      item.GetDeliveredDataObject() == NULL)
Kitware Robot's avatar
Kitware Robot committed
627
    {
628
      continue;
Kitware Robot's avatar
Kitware Robot committed
629
    }
630

631 632 633
    if (item.GetRedistributedDataObject() &&

      // input-data didn't change
Kitware Robot's avatar
Kitware Robot committed
634
      (item.GetDeliveredDataObject()->GetMTime() < item.GetRedistributedDataObject()->GetMTime()) &&
635 636

      // kd-tree didn't change
Kitware Robot's avatar
Kitware Robot committed
637 638
      (item.GetRedistributedDataObject()->GetMTime() > this->KdTree->GetMTime()))
    {
639 640
      // skip redistribution.
      continue;
Kitware Robot's avatar
Kitware Robot committed
641
    }
642

643 644
    // release old memory (not necessarily, but try).
    item.SetRedistributedDataObject(NULL);
645

646 647 648 649 650 651 652
    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));
Kitware Robot's avatar
Kitware Robot committed
653
  }
654
  vtkTimerLog::MarkEndEvent("Redistributing Data for Ordered Compositing");
655 656
}

657
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
658
void vtkPVDataDeliveryManager::ClearRedistributedData(bool use_lod)
659 660 661 662 663 664
{
  // It seems like we should be able to set each item's RedistributedDataObject
  // to NULL in this loop but that doesn't work. For now we're leaving this as
  // is to make sure we don't break functionality but this should be revisited
  // later.
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
665 666
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
667 668 669 670
    if (!this->Internals->IsRepresentationVisible(iter->first.first))
    {
      continue;
    }
Kitware Robot's avatar
Kitware Robot committed
671
    vtkInternals::vtkItem& item = use_lod ? iter->second.second : iter->second.first;
672
    if (!item.Redistributable ||
673 674 675
      // delivered object can be null in case we're updating lod and the
      // representation doeesn't have any LOD data.
      item.GetDeliveredDataObject() == NULL)
Kitware Robot's avatar
Kitware Robot committed
676
    {
677 678
      continue;
    }
Kitware Robot's avatar
Kitware Robot committed
679 680
    item.SetRedistributedDataObject(item.GetDeliveredDataObject());
  }
681 682
}

683
//----------------------------------------------------------------------------
684
vtkPKdTree* vtkPVDataDeliveryManager::GetKdTree()
685 686 687
{
  return this->KdTree;
}
688 689

//----------------------------------------------------------------------------
690
void vtkPVDataDeliveryManager::SetNextStreamedPiece(
691
  vtkPVDataRepresentation* repr, vtkDataObject* data, int port)
692
{
693
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr,
694
    /*low_res=*/false, port, true);
695
  if (item == NULL)
Kitware Robot's avatar
Kitware Robot committed
696
  {
697 698
    vtkErrorMacro("Invalid argument.");
    return;
Kitware Robot's avatar
Kitware Robot committed
699 700
  }

701 702 703 704
  // For now, I am going to keep things simple. Piece is delivered to the
  // representation separately. That's it.
  item->SetNextStreamedPiece(data);
}
705

706
//----------------------------------------------------------------------------
707 708
vtkDataObject* vtkPVDataDeliveryManager::GetCurrentStreamedPiece(
  vtkPVDataRepresentation* repr, int port)
709
{
710 711
  vtkInternals::vtkItem* item = this->Internals->GetItem(repr,
    /*low_res=*/false, port);
712
  if (item == NULL)
Kitware Robot's avatar
Kitware Robot committed
713
  {
714 715
    vtkErrorMacro("Invalid argument.");
    return NULL;
Kitware Robot's avatar
Kitware Robot committed
716
  }
717 718
  return item->GetStreamedPiece();
}
719

720 721 722 723 724
//----------------------------------------------------------------------------
void vtkPVDataDeliveryManager::ClearStreamedPieces()
{
  // I am not too sure if I want to do this. Right now I am thinking once a
  // piece is delivered, the delivery manager should no longer bother about it.
725
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
726 727
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
728
    vtkInternals::vtkItem& item = iter->second.first;
729
    item.SetNextStreamedPiece(NULL);
Kitware Robot's avatar
Kitware Robot committed
730
  }
731 732 733
}

//----------------------------------------------------------------------------
734 735
bool vtkPVDataDeliveryManager::GetRepresentationsReadyToStreamPieces(
  std::vector<unsigned int>& keys)
736
{
737 738
  // I am not too sure if I want to do this. Right now I am thinking once a
  // piece is delivered, the delivery manager should no longer bother about it.
739
  vtkInternals::ItemsMapType::iterator iter;
Kitware Robot's avatar
Kitware Robot committed
740 741
  for (iter = this->Internals->ItemsMap.begin(); iter != this->Internals->ItemsMap.end(); ++iter)
  {
Utkarsh Ayachit's avatar