1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkParallelRenderManager.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10   Copyright 2003 Sandia Corporation. Under the terms of Contract
11   DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
12   or on behalf of the U.S. Government. Redistribution and use in source and
13   binary forms, with or without modification, are permitted provided that this
14   Notice and any statement of authorship are reproduced on all copies.
15 
16      This software is distributed WITHOUT ANY WARRANTY; without even
17      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18      PURPOSE.  See the above copyright notice for more information.
19 
20 =========================================================================*/
21 #include "vtkParallelRenderManager.h"
22 
23 #include "vtkActor.h"
24 #include "vtkActorCollection.h"
25 #include "vtkCallbackCommand.h"
26 #include "vtkCamera.h"
27 #include "vtkDoubleArray.h"
28 #include "vtkLight.h"
29 #include "vtkLightCollection.h"
30 #include "vtkMath.h"
31 #include "vtkMultiProcessController.h"
32 #include "vtkMultiProcessStream.h" // needed for vtkMultiProcessStream.
33 #include "vtkPolyDataMapper.h"
34 #include "vtkRenderWindow.h"
35 #include "vtkRenderWindowInteractor.h"
36 #include "vtkRenderer.h"
37 #include "vtkRendererCollection.h"
38 #include "vtkTimerLog.h"
39 #include "vtkUnsignedCharArray.h"
40 
41 static void AbortRenderCheck(
42   vtkObject* caller, unsigned long vtkNotUsed(event), void* clientData, void*);
43 
44 static void GenericStartRender(
45   vtkObject* caller, unsigned long vtkNotUsed(event), void* clientData, void*);
46 static void GenericEndRender(
47   vtkObject* caller, unsigned long vtkNotUsed(event), void* clientData, void*);
48 /*
49 static void ResetCamera(vtkObject *caller,
50                         unsigned long vtkNotUsed(event),
51                         void *clientData, void *);
52 static void ResetCameraClippingRange(vtkObject *caller,
53                                      unsigned long vtkNotUsed(event),
54                                      void *clientData, void *);
55 */
56 static void RenderRMI(void* arg, void*, int, int);
57 static void ComputeVisiblePropBoundsRMI(void* arg, void*, int, int);
58 bool vtkParallelRenderManager::DefaultRenderEventPropagation = true;
59 
60 //------------------------------------------------------------------------------
vtkParallelRenderManager()61 vtkParallelRenderManager::vtkParallelRenderManager()
62 {
63   this->RenderWindow = nullptr;
64   this->ObservingRenderWindow = 0;
65   this->ObservingAbort = 0;
66 
67   this->Controller = nullptr;
68   this->SetController(vtkMultiProcessController::GetGlobalController());
69   this->RootProcessId = 0;
70 
71   this->Renderers = vtkRendererCollection::New();
72   this->SyncRenderWindowRenderers = 1;
73 
74   this->Lock = 0;
75 
76   this->ImageReductionFactor = 1;
77   this->MaxImageReductionFactor = 16;
78   this->AutoImageReductionFactor = 0;
79   this->AverageTimePerPixel = 0.0;
80 
81   this->RenderTime = 0.0;
82   this->ImageProcessingTime = 0.0;
83 
84   this->ParallelRendering = 1;
85   this->WriteBackImages = 1;
86   this->MagnifyImages = 1;
87   this->MagnifyImageMethod = vtkParallelRenderManager::NEAREST;
88   this->RenderEventPropagation = vtkParallelRenderManager::DefaultRenderEventPropagation ? 1 : 0;
89   this->UseCompositing = 1;
90 
91   this->FullImage = vtkUnsignedCharArray::New();
92   this->ReducedImage = vtkUnsignedCharArray::New();
93   this->FullImageUpToDate = 0;
94   this->ReducedImageUpToDate = 0;
95   this->RenderWindowImageUpToDate = 0;
96   this->FullImageSize[0] = 0;
97   this->FullImageSize[1] = 0;
98 
99   this->ReducedImageSize[0] = 0;
100   this->ReducedImageSize[1] = 0;
101 
102   this->ForceRenderWindowSize = 0;
103   this->ForcedRenderWindowSize[0] = 0;
104   this->ForcedRenderWindowSize[1] = 0;
105 
106   this->Viewports = vtkDoubleArray::New();
107   this->Viewports->SetNumberOfComponents(4);
108 
109   this->UseRGBA = 1;
110 
111   this->AddedRMIs = 0;
112   this->RenderRMIId = 0;
113   this->BoundsRMIId = 0;
114   this->Timer = vtkTimerLog::New();
115 
116   this->UseBackBuffer = 1;
117   this->SynchronizeTileProperties = 1;
118 }
119 
120 //------------------------------------------------------------------------------
~vtkParallelRenderManager()121 vtkParallelRenderManager::~vtkParallelRenderManager()
122 {
123   this->SetRenderWindow(nullptr);
124   if (this->Controller && this->AddedRMIs)
125   {
126     this->Controller->RemoveRMI(this->RenderRMIId);
127     this->Controller->RemoveRMI(this->BoundsRMIId);
128     this->AddedRMIs = 0;
129   }
130   this->SetController(nullptr);
131   if (this->FullImage)
132     this->FullImage->Delete();
133   if (this->ReducedImage)
134     this->ReducedImage->Delete();
135   if (this->Viewports)
136     this->Viewports->Delete();
137   if (this->Timer)
138     this->Timer->Delete();
139   if (this->Renderers)
140     this->Renderers->Delete();
141 }
142 
143 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)144 void vtkParallelRenderManager::PrintSelf(ostream& os, vtkIndent indent)
145 {
146   this->Superclass::PrintSelf(os, indent);
147 
148   os << indent << "ParallelRendering: " << (this->ParallelRendering ? "on" : "off") << endl;
149   os << indent << "RenderEventPropagation: " << (this->RenderEventPropagation ? "on" : "off")
150      << endl;
151   os << indent << "UseCompositing: " << (this->UseCompositing ? "on" : "off") << endl;
152   os << indent << "SyncRenderWindowRenderers: " << (this->SyncRenderWindowRenderers ? "on" : "off")
153      << endl;
154 
155   os << indent << "ObservingRenderWindow: " << (this->ObservingRenderWindow ? "yes" : "no") << endl;
156   os << indent << "Locked: " << (this->Lock ? "yes" : "no") << endl;
157 
158   os << indent << "ImageReductionFactor: " << this->ImageReductionFactor << endl;
159   os << indent << "MaxImageReductionFactor: " << this->MaxImageReductionFactor << endl;
160   os << indent << "AutoImageReductionFactor: " << (this->AutoImageReductionFactor ? "on" : "off")
161      << endl;
162 
163   if (this->MagnifyImageMethod == vtkParallelRenderManager::LINEAR)
164   {
165     os << indent << "MagnifyImageMethod: LINEAR\n";
166   }
167   else if (this->MagnifyImageMethod == vtkParallelRenderManager::NEAREST)
168   {
169     os << indent << "MagnifyImageMethod: NEAREST\n";
170   }
171 
172   os << indent << "WriteBackImages: " << (this->WriteBackImages ? "on" : "off") << endl;
173   os << indent << "MagnifyImages: " << (this->MagnifyImages ? "on" : "off") << endl;
174 
175   os << indent << "FullImageSize: (" << this->FullImageSize[0] << ", " << this->FullImageSize[1]
176      << ")" << endl;
177   os << indent << "ReducedImageSize: (" << this->ReducedImageSize[0] << ", "
178      << this->ReducedImageSize[1] << ")" << endl;
179 
180   os << indent << "RenderWindow: " << this->RenderWindow << endl;
181   os << indent << "Controller: " << this->Controller << endl;
182   os << indent << "Renderers: " << this->Renderers << endl;
183   os << indent << "RootProcessId: " << this->RootProcessId << endl;
184 
185   os << indent << "Last render time: " << this->RenderTime << endl;
186 
187   os << indent << "Last image processing time: " << this->ImageProcessingTime << endl;
188   os << indent << "UseRGBA: " << this->UseRGBA << endl;
189   os << indent << "SynchronizeTileProperties: " << this->SynchronizeTileProperties << endl;
190 
191   os << indent << "FullImage: ";
192   if (this->FullImage)
193   {
194     this->FullImage->PrintSelf(os, indent.GetNextIndent());
195   }
196   else
197   {
198     os << "(none)" << endl;
199   }
200 
201   os << indent << "ForcedRenderWindowSize: " << this->ForcedRenderWindowSize[0] << " "
202      << this->ForcedRenderWindowSize[1] << endl;
203 
204   os << indent << "ForceRenderWindowSize: " << this->ForceRenderWindowSize << endl;
205 
206   os << indent << "UseBackBuffer: " << (this->UseBackBuffer ? "on" : "off") << endl;
207 }
208 
209 //------------------------------------------------------------------------------
MakeRenderWindow()210 vtkRenderWindow* vtkParallelRenderManager::MakeRenderWindow()
211 {
212   vtkDebugMacro("MakeRenderWindow");
213 
214   return vtkRenderWindow::New();
215 }
216 
217 //------------------------------------------------------------------------------
MakeRenderer()218 vtkRenderer* vtkParallelRenderManager::MakeRenderer()
219 {
220   vtkDebugMacro("MakeRenderer");
221 
222   return vtkRenderer::New();
223 }
224 
225 //------------------------------------------------------------------------------
AddRenderWindowEventHandlers()226 void vtkParallelRenderManager::AddRenderWindowEventHandlers()
227 {
228   if (this->RenderWindow && !this->ObservingRenderWindow)
229   {
230     vtkCallbackCommand* cbc = vtkCallbackCommand::New();
231     cbc->SetCallback(::GenericStartRender);
232     cbc->SetClientData((void*)this);
233     // renWin will delete the cbc when the observer is removed.
234     this->StartRenderTag = this->RenderWindow->AddObserver(vtkCommand::StartEvent, cbc);
235     cbc->Delete();
236 
237     cbc = vtkCallbackCommand::New();
238     cbc->SetCallback(::GenericEndRender);
239     cbc->SetClientData((void*)this);
240     // renWin will delete the cbc when the observer is removed.
241     this->EndRenderTag = this->RenderWindow->AddObserver(vtkCommand::EndEvent, cbc);
242     cbc->Delete();
243     this->ObservingRenderWindow = 1;
244   }
245 }
246 
247 //------------------------------------------------------------------------------
RemoveRenderWindowEventHandlers()248 void vtkParallelRenderManager::RemoveRenderWindowEventHandlers()
249 {
250   if (this->RenderWindow && this->ObservingRenderWindow)
251   {
252     this->RenderWindow->RemoveObserver(this->StartRenderTag);
253     this->RenderWindow->RemoveObserver(this->EndRenderTag);
254     this->StartRenderTag = 0;
255     this->EndRenderTag = 0;
256     this->ObservingRenderWindow = 0;
257   }
258 }
259 
260 //------------------------------------------------------------------------------
SetRenderWindow(vtkRenderWindow * renWin)261 void vtkParallelRenderManager::SetRenderWindow(vtkRenderWindow* renWin)
262 {
263   vtkDebugMacro("SetRenderWindow");
264   if (this->RenderWindow == renWin)
265   {
266     return;
267   }
268 
269   if (this->RenderWindow)
270   {
271     // Remove all of the observers.
272     if (this->ObservingAbort)
273     {
274       this->RenderWindow->RemoveObserver(this->AbortRenderCheckTag);
275       this->AbortRenderCheckTag = 0;
276       this->ObservingAbort = 0;
277     }
278     this->RemoveRenderWindowEventHandlers();
279   }
280 
281   vtkSetObjectBodyMacro(RenderWindow, vtkRenderWindow, renWin);
282 
283   if (this->RenderWindow)
284   {
285     vtkCallbackCommand* cbc;
286 
287     // In case a subclass wants to raise aborts.
288     cbc = vtkCallbackCommand::New();
289     cbc->SetCallback(::AbortRenderCheck);
290     cbc->SetClientData((void*)this);
291     // renWin will delete the cbc when the observer is removed.
292     this->AbortRenderCheckTag = renWin->AddObserver(vtkCommand::AbortCheckEvent, cbc);
293     cbc->Delete();
294     this->ObservingAbort = 1;
295 
296     this->AddRenderWindowEventHandlers();
297   }
298 }
299 
300 //------------------------------------------------------------------------------
SetController(vtkMultiProcessController * controller)301 void vtkParallelRenderManager::SetController(vtkMultiProcessController* controller)
302 {
303   // Regular vtkSetObjectMacro:
304   vtkSetObjectBodyMacro(Controller, vtkMultiProcessController, controller);
305 }
306 
307 //------------------------------------------------------------------------------
InitializePieces()308 void vtkParallelRenderManager::InitializePieces()
309 {
310   vtkDebugMacro("InitializePieces");
311 
312   vtkRendererCollection* rens;
313   vtkRenderer* ren;
314   vtkActorCollection* actors;
315   vtkActor* actor;
316   vtkMapper* mapper;
317   vtkPolyDataMapper* pdMapper;
318   int piece, numPieces;
319 
320   if ((this->RenderWindow == nullptr) || (this->Controller == nullptr))
321   {
322     vtkWarningMacro("Called InitializePieces before setting RenderWindow or Controller");
323     return;
324   }
325   piece = this->Controller->GetLocalProcessId();
326   numPieces = this->Controller->GetNumberOfProcesses();
327 
328   rens = this->GetRenderers();
329   vtkCollectionSimpleIterator rsit;
330   rens->InitTraversal(rsit);
331   while ((ren = rens->GetNextRenderer(rsit)))
332   {
333     actors = ren->GetActors();
334     vtkCollectionSimpleIterator ait;
335     actors->InitTraversal(ait);
336     while ((actor = actors->GetNextActor(ait)))
337     {
338       mapper = actor->GetMapper();
339       pdMapper = vtkPolyDataMapper::SafeDownCast(mapper);
340       if (pdMapper)
341       {
342         pdMapper->SetPiece(piece);
343         pdMapper->SetNumberOfPieces(numPieces);
344       }
345     }
346   }
347 }
348 
349 //------------------------------------------------------------------------------
InitializeOffScreen()350 void vtkParallelRenderManager::InitializeOffScreen()
351 {
352   vtkDebugMacro("InitializeOffScreen");
353 
354   if ((this->RenderWindow == nullptr) || (this->Controller == nullptr))
355   {
356     vtkWarningMacro("Called InitializeOffScreen before setting RenderWindow or Controller");
357     return;
358   }
359 
360   if ((this->Controller->GetLocalProcessId() != this->RootProcessId) || !this->WriteBackImages)
361   {
362     this->RenderWindow->OffScreenRenderingOn();
363   }
364   else
365   {
366     this->RenderWindow->OffScreenRenderingOff();
367   }
368 }
369 
370 //------------------------------------------------------------------------------
StartInteractor()371 void vtkParallelRenderManager::StartInteractor()
372 {
373   vtkDebugMacro("StartInteractor");
374 
375   if ((this->Controller == nullptr) || (this->RenderWindow == nullptr))
376   {
377     vtkErrorMacro("Must set Controller and RenderWindow before starting interactor.");
378     return;
379   }
380 
381   if (this->Controller->GetLocalProcessId() == this->RootProcessId)
382   {
383     vtkRenderWindowInteractor* inter = this->RenderWindow->GetInteractor();
384     if (!inter)
385     {
386       vtkErrorMacro("Render window does not have an interactor.");
387     }
388     else
389     {
390       inter->Initialize();
391       inter->Start();
392     }
393     // By the time we reach here, the interaction is finished.
394     this->StopServices();
395   }
396   else
397   {
398     this->StartServices();
399   }
400 }
401 
402 //------------------------------------------------------------------------------
StartServices()403 void vtkParallelRenderManager::StartServices()
404 {
405   vtkDebugMacro("StartServices");
406 
407   if (!this->Controller)
408   {
409     vtkErrorMacro("Must set Controller before starting service");
410     return;
411   }
412   if (this->Controller->GetLocalProcessId() == this->RootProcessId)
413   {
414     vtkWarningMacro("Starting service on root process (probably not what you wanted to do)");
415   }
416 
417   this->InitializeRMIs();
418   this->Controller->ProcessRMIs();
419 }
420 
421 //------------------------------------------------------------------------------
StopServices()422 void vtkParallelRenderManager::StopServices()
423 {
424   vtkDebugMacro("StopServices");
425 
426   if (!this->Controller)
427   {
428     vtkErrorMacro("Must set Controller before stopping service");
429     return;
430   }
431   if (this->Controller->GetLocalProcessId() != this->RootProcessId)
432   {
433     vtkErrorMacro("Can only stop services on root node");
434     return;
435   }
436 
437   this->Controller->TriggerRMIOnAllChildren(vtkMultiProcessController::BREAK_RMI_TAG);
438 }
439 
440 //------------------------------------------------------------------------------
GenericStartRenderCallback()441 void vtkParallelRenderManager::GenericStartRenderCallback()
442 {
443   if (!this->Controller)
444   {
445     return;
446   }
447 
448   if (this->Controller->GetLocalProcessId() == this->RootProcessId)
449   {
450     this->StartRender();
451   }
452   else // LocalProcessId != RootProcessId
453   {
454     this->SatelliteStartRender();
455   }
456 }
457 
458 //------------------------------------------------------------------------------
GenericEndRenderCallback()459 void vtkParallelRenderManager::GenericEndRenderCallback()
460 {
461   if (!this->Controller)
462   {
463     return;
464   }
465 
466   if (this->Controller->GetLocalProcessId() == this->RootProcessId)
467   {
468     this->EndRender();
469   }
470   else // LocalProcessId != RootProcessId
471   {
472     this->SatelliteEndRender();
473   }
474 }
475 
476 //------------------------------------------------------------------------------
StartRender()477 void vtkParallelRenderManager::StartRender()
478 {
479   vtkParallelRenderManager::RenderWindowInfo winInfo;
480   vtkParallelRenderManager::RendererInfo renInfo;
481   vtkParallelRenderManager::LightInfo lightInfo;
482 
483   vtkDebugMacro("StartRender");
484 
485   if ((this->Controller == nullptr) || (this->Lock))
486   {
487     return;
488   }
489   this->Lock = 1;
490 
491   this->FullImageUpToDate = 0;
492   this->ReducedImageUpToDate = 0;
493   this->RenderWindowImageUpToDate = 0;
494 
495   if (this->FullImage->GetPointer(0) == this->ReducedImage->GetPointer(0))
496   {
497     // "Un-share" pointer for full/reduced images in case we need separate
498     // arrays this run.
499     this->ReducedImage->Initialize();
500   }
501 
502   if (!this->ParallelRendering)
503   {
504     this->Lock = 0;
505     return;
506   }
507 
508   this->InvokeEvent(vtkCommand::StartEvent, nullptr);
509 
510   this->ImageProcessingTime = 0;
511 
512   // Used to time the total render (without compositing).
513   this->Timer->StartTimer();
514 
515   if (this->AutoImageReductionFactor)
516   {
517     this->SetImageReductionFactorForUpdateRate(this->RenderWindow->GetDesiredUpdateRate());
518   }
519 
520   // Make adjustments for window size.
521   int* tilesize;
522   if (this->ForceRenderWindowSize)
523   {
524     tilesize = this->ForcedRenderWindowSize;
525   }
526   else
527   {
528     tilesize = this->RenderWindow->GetActualSize();
529   }
530   int size[2];
531   size[0] = tilesize[0];
532   size[1] = tilesize[1];
533   if ((size[0] == 0) || (size[1] == 0))
534   {
535     // It helps to have a real window size.
536     vtkDebugMacro("Resetting window size to 300x300");
537     size[0] = size[1] = 300;
538     this->RenderWindow->SetSize(size[0], size[1]);
539   }
540   this->FullImageSize[0] = size[0];
541   this->FullImageSize[1] = size[1];
542 
543   // Round up.
544   this->ReducedImageSize[0] =
545     (int)((size[0] + this->ImageReductionFactor - 1) / this->ImageReductionFactor);
546   this->ReducedImageSize[1] =
547     (int)((size[1] + this->ImageReductionFactor - 1) / this->ImageReductionFactor);
548 
549   // Collect and distribute information about current state of RenderWindow
550   vtkRendererCollection* rens = this->GetRenderers();
551   winInfo.FullSize[0] = this->FullImageSize[0];
552   winInfo.FullSize[1] = this->FullImageSize[1];
553   winInfo.ReducedSize[0] = this->ReducedImageSize[0];
554   winInfo.ReducedSize[1] = this->ReducedImageSize[1];
555   winInfo.NumberOfRenderers = rens->GetNumberOfItems();
556   winInfo.ImageReductionFactor = this->ImageReductionFactor;
557   winInfo.UseCompositing = this->UseCompositing;
558   winInfo.DesiredUpdateRate = this->RenderWindow->GetDesiredUpdateRate();
559   this->RenderWindow->GetTileScale(winInfo.TileScale);
560   this->RenderWindow->GetTileViewport(winInfo.TileViewport);
561 
562   if (this->RenderEventPropagation)
563   {
564     this->Controller->TriggerRMIOnAllChildren(vtkParallelRenderManager::RENDER_RMI_TAG);
565   }
566 
567   // Gather information about the window to send.
568   vtkMultiProcessStream stream;
569   winInfo.Save(stream);
570   this->CollectWindowInformation(stream);
571 
572   if (this->ImageReductionFactor > 1)
573   {
574     this->Viewports->SetNumberOfTuples(rens->GetNumberOfItems());
575   }
576 
577   vtkCollectionSimpleIterator cookie;
578   vtkRenderer* ren;
579   int i;
580 
581   for (rens->InitTraversal(cookie), i = 0; (ren = rens->GetNextRenderer(cookie)) != nullptr; i++)
582   {
583     ren->GetViewport(renInfo.Viewport);
584 
585     // Adjust Renderer viewports to get reduced size image.
586     if (this->ImageReductionFactor > 1)
587     {
588       this->Viewports->SetTuple(i, renInfo.Viewport);
589       if (this->ImageReduceRenderer(ren))
590       {
591         renInfo.Viewport[0] /= this->ImageReductionFactor;
592         renInfo.Viewport[1] /= this->ImageReductionFactor;
593         renInfo.Viewport[2] /= this->ImageReductionFactor;
594         renInfo.Viewport[3] /= this->ImageReductionFactor;
595         ren->SetViewport(renInfo.Viewport);
596       }
597     }
598 
599     vtkTypeBool hasActiveCamera = ren->IsActiveCameraCreated();
600     vtkCamera* cam = ren->GetActiveCamera();
601     if (!hasActiveCamera)
602     {
603       this->ResetCamera(ren);
604     }
605     cam->GetPosition(renInfo.CameraPosition);
606     cam->GetFocalPoint(renInfo.CameraFocalPoint);
607     cam->GetViewUp(renInfo.CameraViewUp);
608     cam->GetClippingRange(renInfo.CameraClippingRange);
609     renInfo.CameraViewAngle = cam->GetViewAngle();
610     cam->GetWindowCenter(renInfo.WindowCenter);
611 
612     ren->GetBackground(renInfo.Background);
613     ren->GetBackground2(renInfo.Background2);
614     renInfo.GradientBackground = ren->GetGradientBackground();
615     if (cam->GetParallelProjection())
616     {
617       renInfo.ParallelScale = cam->GetParallelScale();
618     }
619     else
620     {
621       renInfo.ParallelScale = 0.0;
622     }
623     renInfo.Draw = ren->GetDraw();
624     vtkLightCollection* lc = ren->GetLights();
625     renInfo.NumberOfLights = lc->GetNumberOfItems();
626     renInfo.Save(stream);
627 
628     vtkLight* light;
629     vtkCollectionSimpleIterator lsit;
630     for (lc->InitTraversal(lsit); (light = lc->GetNextLight(lsit));)
631     {
632       lightInfo.Type = (double)(light->GetLightType());
633       light->GetPosition(lightInfo.Position);
634       light->GetFocalPoint(lightInfo.FocalPoint);
635       lightInfo.Save(stream);
636     }
637     this->CollectRendererInformation(ren, stream);
638   }
639 
640   if (!this->Controller->Broadcast(stream, this->Controller->GetLocalProcessId()))
641   {
642     return;
643   }
644 
645   // Backwards compatibility stuff.
646   this->SendWindowInformation();
647   rens->InitTraversal(cookie);
648   while ((ren = rens->GetNextRenderer(cookie)) != nullptr)
649   {
650     this->SendRendererInformation(ren);
651   }
652 
653   this->PreRenderProcessing();
654 }
655 
656 //------------------------------------------------------------------------------
EndRender()657 void vtkParallelRenderManager::EndRender()
658 {
659   if (!this->ParallelRendering)
660   {
661     return;
662   }
663 
664   this->Timer->StopTimer();
665   this->RenderTime = this->Timer->GetElapsedTime() - this->ImageProcessingTime;
666 
667   // Just because we are not doing compositing does not mean a subclass
668   // does not need to do post render processing.
669   //   if (!this->UseCompositing)
670   //     {
671   //     this->Lock = 0;
672   //     return;
673   //     }
674 
675   if (this->CheckForAbortComposite())
676   {
677     this->Lock = 0;
678     return;
679   }
680 
681   this->PostRenderProcessing();
682 
683   // Restore renderer viewports, if necessary.
684   if (this->ImageReductionFactor > 1)
685   {
686     vtkRendererCollection* rens = this->GetRenderers();
687     vtkCollectionSimpleIterator cookie;
688     vtkRenderer* ren;
689     int i;
690     for (rens->InitTraversal(cookie), i = 0; (ren = rens->GetNextRenderer(cookie)) != nullptr; i++)
691     {
692       ren->SetViewport(this->Viewports->GetPointer(4 * i));
693     }
694   }
695 
696   this->WriteFullImage();
697 
698   this->InvokeEvent(vtkCommand::EndEvent, nullptr);
699 
700   this->Lock = 0;
701 }
702 
703 //------------------------------------------------------------------------------
SatelliteEndRender()704 void vtkParallelRenderManager::SatelliteEndRender()
705 {
706   if (this->CheckForAbortComposite())
707   {
708     return;
709   }
710   // It's a mistake to check ParallelRendering on the Satellites.
711   // The Root node decides if the render calls are to be propagated to the
712   // satellites...the satellites always reply to the Root nodes requests.
713   //  if (!this->ParallelRendering)
714   //    {
715   //    return;
716   //    }
717   // Just because we are not doing compositing does not mean a subclass
718   // does not need to do post render processing.
719   //   if (!this->UseCompositing)
720   //     {
721   //     return;
722   //     }
723 
724   this->PostRenderProcessing();
725 
726   this->WriteFullImage();
727 
728   this->InvokeEvent(vtkCommand::EndEvent, nullptr);
729 }
730 
731 //------------------------------------------------------------------------------
RenderRMI()732 void vtkParallelRenderManager::RenderRMI()
733 {
734   this->RenderWindow->Render();
735 }
736 
737 //------------------------------------------------------------------------------
ResetCamera(vtkRenderer * ren)738 void vtkParallelRenderManager::ResetCamera(vtkRenderer* ren)
739 {
740   vtkDebugMacro("ResetCamera");
741 
742   double bounds[6];
743 
744   if (this->Lock)
745   {
746     // Can't query other processes in the middle of a render.
747     // Just grab local value instead.
748     this->LocalComputeVisiblePropBounds(ren, bounds);
749     ren->ResetCamera(bounds);
750     return;
751   }
752 
753   this->Lock = 1;
754 
755   this->ComputeVisiblePropBounds(ren, bounds);
756   // Keep from setting camera from some outrageous value.
757   if (!vtkMath::AreBoundsInitialized(bounds))
758   {
759     // See if the not pickable values are better.
760     ren->ComputeVisiblePropBounds(bounds);
761     if (!vtkMath::AreBoundsInitialized(bounds))
762     {
763       this->Lock = 0;
764       return;
765     }
766   }
767   ren->ResetCamera(bounds);
768 
769   this->Lock = 0;
770 }
771 
772 //------------------------------------------------------------------------------
ResetCameraClippingRange(vtkRenderer * ren)773 void vtkParallelRenderManager::ResetCameraClippingRange(vtkRenderer* ren)
774 {
775   vtkDebugMacro("ResetCameraClippingRange");
776 
777   double bounds[6];
778 
779   if (this->Lock)
780   {
781     // Can't query other processes in the middle of a render.
782     // Just grab local value instead.
783     this->LocalComputeVisiblePropBounds(ren, bounds);
784     ren->ResetCameraClippingRange(bounds);
785     return;
786   }
787 
788   this->Lock = 1;
789 
790   this->ComputeVisiblePropBounds(ren, bounds);
791   ren->ResetCameraClippingRange(bounds);
792 
793   this->Lock = 0;
794 }
795 
796 //------------------------------------------------------------------------------
ComputeVisiblePropBoundsRMI(int renderId)797 void vtkParallelRenderManager::ComputeVisiblePropBoundsRMI(int renderId)
798 {
799   vtkDebugMacro("ComputeVisiblePropBoundsRMI");
800   int i;
801 
802   vtkRendererCollection* rens = this->GetRenderers();
803   vtkRenderer* ren = nullptr;
804   vtkCollectionSimpleIterator rsit;
805   rens->InitTraversal(rsit);
806   for (i = 0; i <= renderId; i++)
807   {
808     ren = rens->GetNextRenderer(rsit);
809   }
810 
811   if (ren == nullptr)
812   {
813     vtkWarningMacro("Client requested invalid renderer in "
814                     "ComputeVisiblePropBoundsRMI\n"
815                     "Defaulting to first renderer");
816     ren = rens->GetFirstRenderer();
817   }
818 
819   double bounds[6];
820   this->LocalComputeVisiblePropBounds(ren, bounds);
821 
822   this->Controller->Send(bounds, 6, this->RootProcessId, vtkParallelRenderManager::BOUNDS_TAG);
823 }
824 
825 //------------------------------------------------------------------------------
LocalComputeVisiblePropBounds(vtkRenderer * ren,double bounds[6])826 void vtkParallelRenderManager::LocalComputeVisiblePropBounds(vtkRenderer* ren, double bounds[6])
827 {
828   ren->ComputeVisiblePropBounds(bounds);
829 }
830 
831 //------------------------------------------------------------------------------
ComputeVisiblePropBounds(vtkRenderer * ren,double bounds[6])832 void vtkParallelRenderManager::ComputeVisiblePropBounds(vtkRenderer* ren, double bounds[6])
833 {
834   vtkDebugMacro(<< "ComputeVisiblePropBounds");
835 
836   if (!this->ParallelRendering)
837   {
838     ren->ComputeVisiblePropBounds(bounds);
839     return;
840   }
841 
842   if (this->Controller)
843   {
844     if (this->Controller->GetLocalProcessId() != this->RootProcessId)
845     {
846       vtkErrorMacro("ComputeVisiblePropBounds/ResetCamera can only be called on root process");
847       return;
848     }
849 
850     vtkRendererCollection* rens = this->GetRenderers();
851     vtkCollectionSimpleIterator rsit;
852     rens->InitTraversal(rsit);
853     int renderId = 0;
854     while (true)
855     {
856       vtkRenderer* myren = rens->GetNextRenderer(rsit);
857       if (myren == nullptr)
858       {
859         vtkWarningMacro("ComputeVisiblePropBounds called with unregistered renderer "
860           << ren << "\nDefaulting to first renderer.");
861         renderId = 0;
862         break;
863       }
864       if (myren == ren)
865       {
866         // Found correct renderer.
867         break;
868       }
869       renderId++;
870     }
871 
872     // Invoke RMI's on servers to perform their own ComputeVisiblePropBounds.
873     int numProcs = this->Controller->GetNumberOfProcesses();
874     int id;
875     this->Controller->TriggerRMIOnAllChildren(
876       &renderId, sizeof(int), vtkParallelRenderManager::COMPUTE_VISIBLE_PROP_BOUNDS_RMI_TAG);
877 
878     // Now that all the RMI's have been invoked, we can safely query our
879     // local bounds even if an Update requires a parallel operation.
880 
881     this->LocalComputeVisiblePropBounds(ren, bounds);
882 
883     // Collect all the bounds.
884     for (id = 0; id < numProcs; id++)
885     {
886       double tmp[6];
887 
888       if (id == this->RootProcessId)
889       {
890         continue;
891       }
892 
893       this->Controller->Receive(tmp, 6, id, vtkParallelRenderManager::BOUNDS_TAG);
894 
895       if (tmp[0] < bounds[0])
896       {
897         bounds[0] = tmp[0];
898       }
899       if (tmp[1] > bounds[1])
900       {
901         bounds[1] = tmp[1];
902       }
903       if (tmp[2] < bounds[2])
904       {
905         bounds[2] = tmp[2];
906       }
907       if (tmp[3] > bounds[3])
908       {
909         bounds[3] = tmp[3];
910       }
911       if (tmp[4] < bounds[4])
912       {
913         bounds[4] = tmp[4];
914       }
915       if (tmp[5] > bounds[5])
916       {
917         bounds[5] = tmp[5];
918       }
919     }
920   }
921   else
922   {
923     vtkWarningMacro("ComputeVisiblePropBounds/ResetCamera called before Controller set");
924 
925     ren->ComputeVisiblePropBounds(bounds);
926   }
927 }
928 
929 //------------------------------------------------------------------------------
InitializeRMIs()930 void vtkParallelRenderManager::InitializeRMIs()
931 {
932   vtkDebugMacro("InitializeRMIs");
933 
934   if (this->Controller == nullptr)
935   {
936     vtkErrorMacro("InitializeRMIs requires a controller.");
937     return;
938   }
939 
940   if (!this->AddedRMIs)
941   {
942     this->AddedRMIs = 1;
943     this->RenderRMIId =
944       this->Controller->AddRMI(::RenderRMI, this, vtkParallelRenderManager::RENDER_RMI_TAG);
945     this->BoundsRMIId = this->Controller->AddRMI(::ComputeVisiblePropBoundsRMI, this,
946       vtkParallelRenderManager::COMPUTE_VISIBLE_PROP_BOUNDS_RMI_TAG);
947   }
948 }
949 
950 //------------------------------------------------------------------------------
ResetAllCameras()951 void vtkParallelRenderManager::ResetAllCameras()
952 {
953   vtkDebugMacro("ResetAllCameras");
954 
955   if (!this->RenderWindow)
956   {
957     vtkErrorMacro("Called ResetAllCameras before RenderWindow set");
958     return;
959   }
960 
961   vtkRendererCollection* rens;
962   vtkRenderer* ren;
963 
964   rens = this->GetRenderers();
965   vtkCollectionSimpleIterator rsit;
966   for (rens->InitTraversal(rsit); (ren = rens->GetNextRenderer(rsit));)
967   {
968     this->ResetCamera(ren);
969   }
970 }
971 
972 //------------------------------------------------------------------------------
SetImageReductionFactor(double factor)973 void vtkParallelRenderManager::SetImageReductionFactor(double factor)
974 {
975   // Clamp factor.
976   factor = (factor < 1) ? 1 : factor;
977   factor = (factor > this->MaxImageReductionFactor) ? this->MaxImageReductionFactor : factor;
978 
979   if (this->MagnifyImageMethod == LINEAR)
980   {
981     // Make factor be a power of 2.
982     int pow_of_2 = 1;
983     while (pow_of_2 <= factor)
984     {
985       pow_of_2 <<= 1;
986     }
987     factor = pow_of_2 >> 1;
988   }
989 
990   if (factor == this->ImageReductionFactor)
991   {
992     return;
993   }
994 
995   this->ImageReductionFactor = factor;
996   this->Modified();
997 }
998 
999 //------------------------------------------------------------------------------
SetMagnifyImageMethod(int method)1000 void vtkParallelRenderManager::SetMagnifyImageMethod(int method)
1001 {
1002   if (this->MagnifyImageMethod == method)
1003   {
1004     return;
1005   }
1006 
1007   this->MagnifyImageMethod = method;
1008   // May need to modify image reduction factor.
1009   this->SetImageReductionFactor(this->ImageReductionFactor);
1010 }
1011 
1012 //------------------------------------------------------------------------------
SetImageReductionFactorForUpdateRate(double desiredUpdateRate)1013 void vtkParallelRenderManager::SetImageReductionFactorForUpdateRate(double desiredUpdateRate)
1014 {
1015   vtkDebugMacro("Setting reduction factor for update rate of " << desiredUpdateRate);
1016 
1017   if (desiredUpdateRate == 0.0)
1018   {
1019     this->SetImageReductionFactor(1);
1020     return;
1021   }
1022 
1023   int* size;
1024   if (this->ForceRenderWindowSize)
1025   {
1026     size = this->ForcedRenderWindowSize;
1027   }
1028   else
1029   {
1030     size = this->RenderWindow->GetActualSize();
1031   }
1032   int numPixels = size[0] * size[1];
1033   int numReducedPixels =
1034     (int)(numPixels / (this->ImageReductionFactor * this->ImageReductionFactor));
1035 
1036   double renderTime = this->GetRenderTime();
1037   double pixelTime = this->GetImageProcessingTime();
1038 
1039   double timePerPixel;
1040   if (numReducedPixels > 0)
1041   {
1042     timePerPixel = pixelTime / numReducedPixels;
1043   }
1044   else
1045   {
1046     // Must be before first render.
1047     this->SetImageReductionFactor(1);
1048     return;
1049   }
1050 
1051   this->AverageTimePerPixel = (3 * this->AverageTimePerPixel + timePerPixel) / 4;
1052   if (this->AverageTimePerPixel <= 0)
1053   {
1054     this->AverageTimePerPixel = 0;
1055     this->SetImageReductionFactor(1);
1056     return;
1057   }
1058 
1059   double allottedPixelTime = 1.0 / desiredUpdateRate - renderTime;
1060   // Give ourselves at least 15% of render time.
1061   if (allottedPixelTime < 0.15 * renderTime)
1062   {
1063     allottedPixelTime = 0.15 * renderTime;
1064   }
1065 
1066   vtkDebugMacro("TimePerPixel: " << timePerPixel
1067                                  << ", AverageTimePerPixel: " << this->AverageTimePerPixel
1068                                  << ", AllottedPixelTime: " << allottedPixelTime);
1069 
1070   double pixelsToUse = allottedPixelTime / this->AverageTimePerPixel;
1071 
1072   if ((pixelsToUse < 1) || (numPixels / pixelsToUse > this->MaxImageReductionFactor))
1073   {
1074     this->SetImageReductionFactor(this->MaxImageReductionFactor);
1075   }
1076   else if (pixelsToUse >= numPixels)
1077   {
1078     this->SetImageReductionFactor(1);
1079   }
1080   else
1081   {
1082     this->SetImageReductionFactor((int)(numPixels / pixelsToUse));
1083   }
1084 }
1085 
1086 //------------------------------------------------------------------------------
SetRenderWindowSize()1087 void vtkParallelRenderManager::SetRenderWindowSize()
1088 {
1089   if (!this->RenderWindow->GetOffScreenRendering())
1090   {
1091     // Make sure we can support the requested image size.
1092     const int* screensize = this->RenderWindow->GetScreenSize();
1093     if (this->FullImageSize[0] > screensize[0])
1094     {
1095       // Reduce both dimensions to preserve aspect ratio.
1096       this->FullImageSize[1] = (this->FullImageSize[1] * screensize[0]) / this->FullImageSize[0];
1097       this->FullImageSize[0] = screensize[0];
1098     }
1099     if (this->FullImageSize[1] > screensize[1])
1100     {
1101       // Reduce both dimensions to preserve aspect ratio.
1102       this->FullImageSize[0] = (this->FullImageSize[0] * screensize[1]) / this->FullImageSize[1];
1103       this->FullImageSize[1] = screensize[1];
1104     }
1105 
1106     // Make sure the reduced image is no bigger than the full image.
1107     if (this->ReducedImageSize[0] > this->FullImageSize[0])
1108     {
1109       this->ReducedImageSize[0] = this->FullImageSize[0];
1110     }
1111     if (this->ReducedImageSize[1] > this->FullImageSize[1])
1112     {
1113       this->ReducedImageSize[1] = this->FullImageSize[1];
1114     }
1115   }
1116 
1117   // Correct image reduction factor.
1118   this->ImageReductionFactor = (double)this->FullImageSize[0] / this->ReducedImageSize[0];
1119 
1120   this->RenderWindow->SetSize(this->FullImageSize[0], this->FullImageSize[1]);
1121 }
1122 
1123 //------------------------------------------------------------------------------
GetRenderers()1124 vtkRendererCollection* vtkParallelRenderManager::GetRenderers()
1125 {
1126   if (this->SyncRenderWindowRenderers)
1127   {
1128     return this->RenderWindow->GetRenderers();
1129   }
1130   else
1131   {
1132     return this->Renderers;
1133   }
1134 }
1135 
1136 //------------------------------------------------------------------------------
AddRenderer(vtkRenderer * ren)1137 void vtkParallelRenderManager::AddRenderer(vtkRenderer* ren)
1138 {
1139   this->Renderers->AddItem(ren);
1140 }
1141 
1142 //------------------------------------------------------------------------------
RemoveRenderer(vtkRenderer * ren)1143 void vtkParallelRenderManager::RemoveRenderer(vtkRenderer* ren)
1144 {
1145   this->Renderers->RemoveItem(ren);
1146 }
1147 
1148 //------------------------------------------------------------------------------
RemoveAllRenderers()1149 void vtkParallelRenderManager::RemoveAllRenderers()
1150 {
1151   this->Renderers->RemoveAllItems();
1152 }
1153 
1154 //------------------------------------------------------------------------------
LastRenderInFrontBuffer()1155 int vtkParallelRenderManager::LastRenderInFrontBuffer()
1156 {
1157   return this->RenderWindow->GetSwapBuffers();
1158 }
1159 
1160 //------------------------------------------------------------------------------
ChooseBuffer()1161 int vtkParallelRenderManager::ChooseBuffer()
1162 {
1163   // always render buffer
1164   return 0;
1165 }
1166 
1167 //------------------------------------------------------------------------------
MagnifyImageNearest(vtkUnsignedCharArray * fullImage,const int fullImageSize[2],vtkUnsignedCharArray * reducedImage,const int reducedImageSize[2],const int fullImageViewport[4],const int reducedImageViewport[4])1168 void vtkParallelRenderManager::MagnifyImageNearest(vtkUnsignedCharArray* fullImage,
1169   const int fullImageSize[2], vtkUnsignedCharArray* reducedImage, const int reducedImageSize[2],
1170   const int fullImageViewport[4], const int reducedImageViewport[4])
1171 {
1172   int numComp = reducedImage->GetNumberOfComponents();
1173 
1174   fullImage->SetNumberOfComponents(4);
1175   fullImage->SetNumberOfTuples(fullImageSize[0] * fullImageSize[1]);
1176 
1177   int destLeft, destBottom, destWidth, destHeight;
1178   if (fullImageViewport)
1179   {
1180     destLeft = fullImageViewport[0];
1181     destBottom = fullImageViewport[1];
1182     destWidth = fullImageViewport[2] - fullImageViewport[0];
1183     destHeight = fullImageViewport[3] - fullImageViewport[1];
1184   }
1185   else
1186   {
1187     destLeft = destBottom = 0;
1188     destWidth = fullImageSize[0];
1189     destHeight = fullImageSize[1];
1190   }
1191 
1192   int srcLeft, srcBottom, srcWidth, srcHeight;
1193   if (reducedImageViewport)
1194   {
1195     srcLeft = reducedImageViewport[0];
1196     srcBottom = reducedImageViewport[1];
1197     srcWidth = reducedImageViewport[2] - reducedImageViewport[0];
1198     srcHeight = reducedImageViewport[3] - reducedImageViewport[1];
1199   }
1200   else
1201   {
1202     srcLeft = srcBottom = 0;
1203     srcWidth = reducedImageSize[0];
1204     srcHeight = reducedImageSize[1];
1205   }
1206 
1207   if (numComp == 4)
1208   {
1209     // If there are 4 components per pixel, we can speed up the inflation
1210     // by copying integers instead of characters.
1211 
1212     // Making a bunch of tmp variables for speed within the loops
1213     // Look I know the compiler should optimize this stuff
1214     // but I don't trust compilers... besides testing shows
1215     // this code is faster than the old code
1216     float xstep = (float)srcWidth / destWidth;
1217     float ystep = (float)srcHeight / destHeight;
1218     float xaccum = 0, yaccum = 0;
1219     int destlinesize = fullImageSize[0];
1220     int srclinesize = reducedImageSize[0];
1221     int xmemsize = 4 * destWidth;
1222     unsigned int* lastsrcline = nullptr;
1223     unsigned int* destline =
1224       (unsigned int*)fullImage->GetPointer(4 * (destBottom * destlinesize + destLeft));
1225     unsigned int* srcline =
1226       (unsigned int*)reducedImage->GetPointer(4 * (srcBottom * srclinesize + srcLeft));
1227     unsigned int* srczero = srcline;
1228 
1229     // Inflate image.
1230     for (int y = 0; y < destHeight; ++y, yaccum += ystep)
1231     {
1232       // If this line same as last one.
1233       if (srcline == lastsrcline)
1234       {
1235         memcpy(destline, destline - destlinesize, xmemsize);
1236       }
1237       else
1238       {
1239         for (int x = 0; x < destWidth; ++x, xaccum += xstep)
1240         {
1241           destline[x] = srcline[(int)(xaccum)];
1242         }
1243         xaccum = 0;
1244         lastsrcline = srcline;
1245       }
1246       destline += destlinesize;
1247       srcline = srczero + srclinesize * int(yaccum); // Performance fixme
1248     }
1249   }
1250   else
1251   {
1252     // Inflate image.
1253     double xstep = (double)srcWidth / destWidth;
1254     double ystep = (double)srcHeight / destHeight;
1255     unsigned char* lastsrcline = nullptr;
1256     for (int y = 0; y < destHeight; y++)
1257     {
1258       unsigned char* destline =
1259         fullImage->GetPointer(4 * (fullImageSize[0] * (y + destBottom) + destLeft));
1260       unsigned char* srcline = reducedImage->GetPointer(
1261         numComp * (reducedImageSize[0] * ((int)(ystep * y) + srcBottom) + srcLeft));
1262       if (srcline == lastsrcline)
1263       {
1264         // This line same as last one.
1265         memcpy(destline, (const unsigned char*)(destline - 4 * fullImageSize[0]), 4 * destWidth);
1266       }
1267       else
1268       {
1269         for (int x = 0; x < destWidth; x++)
1270         {
1271           int srcloc = numComp * (int)(x * xstep);
1272           int destloc = 4 * x;
1273           int i;
1274           for (i = 0; i < numComp; i++)
1275           {
1276             destline[destloc + i] = srcline[srcloc + i];
1277           }
1278           for (; i < 4; i++)
1279           {
1280             destline[destloc + i] = 0xFF;
1281           }
1282         }
1283         lastsrcline = srcline;
1284       }
1285     }
1286   }
1287 }
1288 
1289 //------------------------------------------------------------------------------
1290 // A neat trick to quickly divide all 4 of the bytes in an integer by 2.
1291 #define VTK_VEC_DIV_2(intvector) (((intvector) >> 1) & 0x7F7F7F7F)
1292 
MagnifyImageLinear(vtkUnsignedCharArray * fullImage,const int fullImageSize[2],vtkUnsignedCharArray * reducedImage,const int reducedImageSize[2],const int fullImageViewport[4],const int reducedImageViewport[4])1293 void vtkParallelRenderManager::MagnifyImageLinear(vtkUnsignedCharArray* fullImage,
1294   const int fullImageSize[2], vtkUnsignedCharArray* reducedImage, const int reducedImageSize[2],
1295   const int fullImageViewport[4], const int reducedImageViewport[4])
1296 {
1297   int xmag, ymag;
1298   int x, y;
1299   int srcComp = reducedImage->GetNumberOfComponents();
1300 
1301   // Allocate full image so all pixels are on 4-byte integer boundaries.
1302   fullImage->SetNumberOfComponents(4);
1303   fullImage->SetNumberOfTuples(fullImageSize[0] * fullImageSize[1]);
1304 
1305   int destLeft, destBottom, destWidth, destHeight;
1306   if (fullImageViewport)
1307   {
1308     destLeft = fullImageViewport[0];
1309     destBottom = fullImageViewport[1];
1310     destWidth = fullImageViewport[2] - fullImageViewport[0];
1311     destHeight = fullImageViewport[3] - fullImageViewport[1];
1312   }
1313   else
1314   {
1315     destLeft = destBottom = 0;
1316     destWidth = fullImageSize[0];
1317     destHeight = fullImageSize[1];
1318   }
1319 
1320   int srcLeft, srcBottom, srcWidth, srcHeight;
1321   if (reducedImageViewport)
1322   {
1323     srcLeft = reducedImageViewport[0];
1324     srcBottom = reducedImageViewport[1];
1325     srcWidth = reducedImageViewport[2] - reducedImageViewport[0];
1326     srcHeight = reducedImageViewport[3] - reducedImageViewport[1];
1327   }
1328   else
1329   {
1330     srcLeft = srcBottom = 0;
1331     srcWidth = reducedImageSize[0];
1332     srcHeight = reducedImageSize[1];
1333   }
1334 
1335   // Guess x and y magnification.  Round up to ensure we do not try to
1336   // read data from the image data that does not exist.
1337   xmag = (destWidth + srcWidth - 1) / srcWidth;
1338   ymag = (destHeight + srcHeight - 1) / srcHeight;
1339 
1340   // For speed, we only magnify by powers of 2.  Round up to the nearest
1341   // power of 2 to ensure that the reduced image is large enough.
1342   int powOf2;
1343   for (powOf2 = 1; powOf2 < xmag; powOf2 <<= 1)
1344   {
1345   }
1346   xmag = powOf2;
1347   for (powOf2 = 1; powOf2 < ymag; powOf2 <<= 1)
1348   {
1349   }
1350   ymag = powOf2;
1351 
1352   unsigned char* srcline = reducedImage->GetPointer(srcComp * srcBottom * reducedImageSize[0]);
1353   unsigned char* destline = fullImage->GetPointer(4 * destBottom * fullImageSize[0]);
1354   for (y = 0; y < destHeight; y += ymag)
1355   {
1356     unsigned char* srcval = srcline + srcComp * srcLeft;
1357     unsigned char* destval = destline + 4 * destLeft;
1358     for (x = 0; x < destWidth; x += xmag)
1359     {
1360       destval[0] = srcval[0];
1361       destval[1] = srcval[1];
1362       destval[2] = srcval[2];
1363       destval[3] = 0xFF; // Hope we don't need the alpha value.
1364       srcval += srcComp;
1365       destval += 4 * xmag;
1366     }
1367     srcline += srcComp * reducedImageSize[0];
1368     destline += 4 * fullImageSize[0] * ymag;
1369   }
1370 
1371   // Now that we have everything on 4-byte boundaries, we will treat
1372   // everything as integers for much faster computation.
1373   unsigned int* image =
1374     (unsigned int*)fullImage->GetPointer(0) + destBottom * fullImageSize[0] + destLeft;
1375 
1376   // Fill in scanlines.
1377   for (; xmag > 1; xmag >>= 1)
1378   {
1379     int halfXMag = xmag / 2;
1380     for (y = 0; y < destHeight; y += ymag)
1381     {
1382       unsigned int* scanline = image + y * fullImageSize[0];
1383       int maxX = destWidth - halfXMag; // Don't access bad memory.
1384       for (x = halfXMag; x < maxX; x += xmag)
1385       {
1386         scanline[x] = VTK_VEC_DIV_2(scanline[x - halfXMag]) + VTK_VEC_DIV_2(scanline[x + halfXMag]);
1387       }
1388       if (x < destWidth)
1389       {
1390         scanline[x] = scanline[x - halfXMag];
1391       }
1392     }
1393   }
1394 
1395   // Add blank scanlines.
1396   for (; ymag > 1; ymag >>= 1)
1397   {
1398     int halfYMag = ymag / 2;
1399     int maxY = destHeight - halfYMag; // Don't access bad memory.
1400     for (y = halfYMag; y < maxY; y += ymag)
1401     {
1402       unsigned int* destline2 = image + y * fullImageSize[0];
1403       unsigned int* srcline1 = image + (y - halfYMag) * fullImageSize[0];
1404       unsigned int* srcline2 = image + (y + halfYMag) * fullImageSize[0];
1405       for (x = 0; x < destWidth; x++)
1406       {
1407         destline2[x] = VTK_VEC_DIV_2(srcline1[x]) + VTK_VEC_DIV_2(srcline2[x]);
1408       }
1409     }
1410     if (y < destHeight)
1411     {
1412       unsigned int* destline2 = image + y * fullImageSize[0];
1413       unsigned int* srcline1 = image + (y - halfYMag) * fullImageSize[0];
1414       for (x = 0; x < destWidth; x++)
1415       {
1416         destline2[x] = srcline1[x];
1417       }
1418     }
1419   }
1420 }
1421 
1422 //------------------------------------------------------------------------------
MagnifyImage(vtkUnsignedCharArray * fullImage,const int fullImageSize[2],vtkUnsignedCharArray * reducedImage,const int reducedImageSize[2],const int fullImageViewport[4],const int reducedImageViewport[4])1423 void vtkParallelRenderManager::MagnifyImage(vtkUnsignedCharArray* fullImage,
1424   const int fullImageSize[2], vtkUnsignedCharArray* reducedImage, const int reducedImageSize[2],
1425   const int fullImageViewport[4], const int reducedImageViewport[4])
1426 {
1427   switch (this->MagnifyImageMethod)
1428   {
1429     case vtkParallelRenderManager::NEAREST:
1430       this->MagnifyImageNearest(fullImage, fullImageSize, reducedImage, reducedImageSize,
1431         fullImageViewport, reducedImageViewport);
1432       break;
1433     case LINEAR:
1434       this->MagnifyImageLinear(fullImage, fullImageSize, reducedImage, reducedImageSize,
1435         fullImageViewport, reducedImageViewport);
1436       break;
1437   }
1438 }
1439 
1440 //------------------------------------------------------------------------------
MagnifyReducedImage()1441 void vtkParallelRenderManager::MagnifyReducedImage()
1442 {
1443   if ((this->FullImageUpToDate))
1444   {
1445     return;
1446   }
1447 
1448   this->ReadReducedImage();
1449 
1450   if (this->FullImage->GetPointer(0) != this->ReducedImage->GetPointer(0))
1451   {
1452     this->Timer->StartTimer();
1453     this->MagnifyImage(
1454       this->FullImage, this->FullImageSize, this->ReducedImage, this->ReducedImageSize);
1455     this->Timer->StopTimer();
1456     // We log the image inflation under render time because it is inversely
1457     // proportional to the image size.  This makes the auto image reduction
1458     // calculation work better.
1459     this->RenderTime += this->Timer->GetElapsedTime();
1460   }
1461 
1462   this->FullImageUpToDate = 1;
1463 }
1464 
1465 //------------------------------------------------------------------------------
WriteFullImage()1466 void vtkParallelRenderManager::WriteFullImage()
1467 {
1468   if (this->RenderWindowImageUpToDate || !this->WriteBackImages)
1469   {
1470     return;
1471   }
1472 
1473   if (this->MagnifyImages &&
1474     ((this->FullImageSize[0] != this->ReducedImageSize[0]) ||
1475       (this->FullImageSize[1] != this->ReducedImageSize[1])))
1476   {
1477     this->MagnifyReducedImage();
1478     this->SetRenderWindowPixelData(this->FullImage, this->FullImageSize);
1479   }
1480   else
1481   {
1482     // Only write back image if it has already been read and potentially
1483     // changed.
1484     if (this->ReducedImageUpToDate)
1485     {
1486       this->SetRenderWindowPixelData(this->ReducedImage, this->ReducedImageSize);
1487     }
1488   }
1489 
1490   this->RenderWindowImageUpToDate = 1;
1491 }
1492 
1493 //------------------------------------------------------------------------------
SetRenderWindowPixelData(vtkUnsignedCharArray * pixels,const int pixelDimensions[2])1494 void vtkParallelRenderManager::SetRenderWindowPixelData(
1495   vtkUnsignedCharArray* pixels, const int pixelDimensions[2])
1496 {
1497   if (pixels->GetNumberOfComponents() == 4)
1498   {
1499     this->RenderWindow->SetRGBACharPixelData(
1500       0, 0, pixelDimensions[0] - 1, pixelDimensions[1] - 1, pixels, this->ChooseBuffer());
1501   }
1502   else
1503   {
1504     this->RenderWindow->SetPixelData(
1505       0, 0, pixelDimensions[0] - 1, pixelDimensions[1] - 1, pixels, this->ChooseBuffer());
1506   }
1507 }
1508 
1509 //------------------------------------------------------------------------------
ReadReducedImage()1510 void vtkParallelRenderManager::ReadReducedImage()
1511 {
1512   if (this->ReducedImageUpToDate)
1513   {
1514     return;
1515   }
1516 
1517   this->Timer->StartTimer();
1518 
1519   if (this->ImageReductionFactor > 1)
1520   {
1521     if (this->UseRGBA)
1522     {
1523       this->RenderWindow->GetRGBACharPixelData(0, 0, this->ReducedImageSize[0] - 1,
1524         this->ReducedImageSize[1] - 1, this->ChooseBuffer(), this->ReducedImage);
1525     }
1526     else
1527     {
1528       this->RenderWindow->GetPixelData(0, 0, this->ReducedImageSize[0] - 1,
1529         this->ReducedImageSize[1] - 1, this->ChooseBuffer(), this->ReducedImage);
1530     }
1531   }
1532   else
1533   {
1534     if (this->UseRGBA)
1535     {
1536       this->RenderWindow->GetRGBACharPixelData(0, 0, this->FullImageSize[0] - 1,
1537         this->FullImageSize[1] - 1, this->ChooseBuffer(), this->FullImage);
1538     }
1539     else
1540     {
1541       this->RenderWindow->GetPixelData(0, 0, this->FullImageSize[0] - 1, this->FullImageSize[1] - 1,
1542         this->ChooseBuffer(), this->FullImage);
1543     }
1544     this->FullImageUpToDate = 1;
1545     this->ReducedImage->SetNumberOfComponents(this->FullImage->GetNumberOfComponents());
1546     this->ReducedImage->SetArray(this->FullImage->GetPointer(0), this->FullImage->GetSize(), 1);
1547     this->ReducedImage->SetNumberOfTuples(this->FullImage->GetNumberOfTuples());
1548   }
1549 
1550   this->Timer->StopTimer();
1551   this->ImageProcessingTime += this->Timer->GetElapsedTime();
1552 
1553   this->ReducedImageUpToDate = 1;
1554 }
1555 
1556 //------------------------------------------------------------------------------
GetPixelData(vtkUnsignedCharArray * data)1557 void vtkParallelRenderManager::GetPixelData(vtkUnsignedCharArray* data)
1558 {
1559   if (!this->RenderWindow)
1560   {
1561     vtkErrorMacro("Tried to read pixel data from non-existent RenderWindow");
1562     return;
1563   }
1564 
1565   // Read image from RenderWindow and magnify if necessary.
1566   this->MagnifyReducedImage();
1567 
1568   data->SetNumberOfComponents(this->FullImage->GetNumberOfComponents());
1569   data->SetArray(this->FullImage->GetPointer(0), this->FullImage->GetSize(), 1);
1570   data->SetNumberOfTuples(this->FullImage->GetNumberOfTuples());
1571 }
1572 
1573 //------------------------------------------------------------------------------
GetPixelData(int x1,int y1,int x2,int y2,vtkUnsignedCharArray * data)1574 void vtkParallelRenderManager::GetPixelData(
1575   int x1, int y1, int x2, int y2, vtkUnsignedCharArray* data)
1576 {
1577   if (!this->RenderWindow)
1578   {
1579     vtkErrorMacro("Tried to read pixel data from non-existent RenderWindow");
1580     return;
1581   }
1582 
1583   this->MagnifyReducedImage();
1584 
1585   if (x1 > x2)
1586   {
1587     int tmp = x1;
1588     x1 = x2;
1589     x2 = tmp;
1590   }
1591   if (y1 > y2)
1592   {
1593     int tmp = y1;
1594     y1 = y2;
1595     y2 = tmp;
1596   }
1597 
1598   if ((x1 < 0) || (x2 >= this->FullImageSize[0]) || (y1 < 0) || (y2 >= this->FullImageSize[1]))
1599   {
1600     vtkErrorMacro("Requested pixel data out of RenderWindow bounds");
1601     return;
1602   }
1603 
1604   vtkIdType width = x2 - x1 + 1;
1605   vtkIdType height = y2 - y1 + 1;
1606 
1607   int numComp = this->FullImage->GetNumberOfComponents();
1608 
1609   data->SetNumberOfComponents(numComp);
1610   data->SetNumberOfTuples(width * height);
1611 
1612   const unsigned char* src = this->FullImage->GetPointer(0);
1613   unsigned char* dest = data->WritePointer(0, width * height * numComp);
1614 
1615   for (int row = 0; row < height; row++)
1616   {
1617     memcpy(dest + row * width * numComp,
1618       src + (row + y1) * this->FullImageSize[0] * numComp + x1 * numComp, width * numComp);
1619   }
1620 }
1621 
1622 //------------------------------------------------------------------------------
GetReducedPixelData(vtkUnsignedCharArray * data)1623 void vtkParallelRenderManager::GetReducedPixelData(vtkUnsignedCharArray* data)
1624 {
1625   if (!this->RenderWindow)
1626   {
1627     vtkErrorMacro("Tried to read pixel data from non-existent RenderWindow");
1628     return;
1629   }
1630 
1631   // Read image from RenderWindow and magnify if necessary.
1632   this->ReadReducedImage();
1633 
1634   data->SetNumberOfComponents(this->ReducedImage->GetNumberOfComponents());
1635   data->SetArray(this->ReducedImage->GetPointer(0), this->ReducedImage->GetSize(), 1);
1636   data->SetNumberOfTuples(this->ReducedImage->GetNumberOfTuples());
1637 }
1638 
1639 //------------------------------------------------------------------------------
GetReducedPixelData(int x1,int y1,int x2,int y2,vtkUnsignedCharArray * data)1640 void vtkParallelRenderManager::GetReducedPixelData(
1641   int x1, int y1, int x2, int y2, vtkUnsignedCharArray* data)
1642 {
1643   if (!this->RenderWindow)
1644   {
1645     vtkErrorMacro("Tried to read pixel data from non-existent RenderWindow");
1646     return;
1647   }
1648 
1649   this->ReadReducedImage();
1650 
1651   if (x1 > x2)
1652   {
1653     int tmp = x1;
1654     x1 = x2;
1655     x2 = tmp;
1656   }
1657   if (y1 > y2)
1658   {
1659     int tmp = y1;
1660     y1 = y2;
1661     y2 = tmp;
1662   }
1663 
1664   if ((x1 < 0) || (x2 >= this->ReducedImageSize[0]) || (y1 < 0) ||
1665     (y2 >= this->ReducedImageSize[1]))
1666   {
1667     vtkErrorMacro("Requested pixel data out of RenderWindow bounds");
1668     return;
1669   }
1670 
1671   vtkIdType width = x2 - x1 + 1;
1672   vtkIdType height = y2 - y1 + 1;
1673 
1674   int numComp = this->ReducedImage->GetNumberOfComponents();
1675 
1676   data->SetNumberOfComponents(numComp);
1677   data->SetNumberOfTuples(width * height);
1678 
1679   const unsigned char* src = this->ReducedImage->GetPointer(0);
1680   unsigned char* dest = data->WritePointer(0, width * height * numComp);
1681 
1682   for (int row = 0; row < height; row++)
1683   {
1684     memcpy(dest + row * width * numComp,
1685       src + (row + y1) * this->ReducedImageSize[0] * numComp + x1 * numComp, width * numComp);
1686   }
1687 }
1688 
1689 // Static function prototypes --------------------------------------------
1690 
AbortRenderCheck(vtkObject * vtkNotUsed (caller),unsigned long vtkNotUsed (event),void * clientData,void *)1691 static void AbortRenderCheck(
1692   vtkObject* vtkNotUsed(caller), unsigned long vtkNotUsed(event), void* clientData, void*)
1693 {
1694   vtkParallelRenderManager* self = (vtkParallelRenderManager*)clientData;
1695   self->CheckForAbortRender();
1696 }
1697 
GenericStartRender(vtkObject * vtkNotUsed (caller),unsigned long vtkNotUsed (event),void * clientData,void *)1698 static void GenericStartRender(
1699   vtkObject* vtkNotUsed(caller), unsigned long vtkNotUsed(event), void* clientData, void*)
1700 {
1701   vtkParallelRenderManager* self = (vtkParallelRenderManager*)clientData;
1702   self->GenericStartRenderCallback();
1703 }
1704 
GenericEndRender(vtkObject * vtkNotUsed (caller),unsigned long vtkNotUsed (event),void * clientData,void *)1705 static void GenericEndRender(
1706   vtkObject* vtkNotUsed(caller), unsigned long vtkNotUsed(event), void* clientData, void*)
1707 {
1708   vtkParallelRenderManager* self = (vtkParallelRenderManager*)clientData;
1709   self->GenericEndRenderCallback();
1710 }
1711 
1712 /*
1713 static void ResetCamera(vtkObject *caller,
1714                         unsigned long vtkNotUsed(event),
1715                         void *clientData, void *)
1716 {
1717   vtkParallelRenderManager *self = (vtkParallelRenderManager *)clientData;
1718   vtkRenderer *ren = (vtkRenderer *)caller;
1719   self->ResetCamera(ren);
1720 }
1721 
1722 static void ResetCameraClippingRange(vtkObject *caller,
1723                                      unsigned long vtkNotUsed(event),
1724                                      void *clientData, void *)
1725 {
1726   vtkParallelRenderManager *self = (vtkParallelRenderManager *)clientData;
1727   vtkRenderer *ren = (vtkRenderer *)caller;
1728   self->ResetCameraClippingRange(ren);
1729 }
1730 */
1731 
RenderRMI(void * arg,void *,int,int)1732 static void RenderRMI(void* arg, void*, int, int)
1733 {
1734   vtkParallelRenderManager* self = (vtkParallelRenderManager*)arg;
1735   self->RenderRMI();
1736 }
1737 
ComputeVisiblePropBoundsRMI(void * arg,void * remoteArg,int remoteArgLength,int)1738 static void ComputeVisiblePropBoundsRMI(void* arg, void* remoteArg, int remoteArgLength, int)
1739 {
1740   assert(remoteArgLength == sizeof(int));
1741   (void)remoteArgLength;
1742   int* iarg = reinterpret_cast<int*>(remoteArg);
1743 
1744   vtkParallelRenderManager* self = (vtkParallelRenderManager*)arg;
1745   self->ComputeVisiblePropBoundsRMI(*iarg);
1746 }
1747 
1748 //------------------------------------------------------------------------------
SatelliteStartRender()1749 void vtkParallelRenderManager::SatelliteStartRender()
1750 {
1751   vtkParallelRenderManager::RenderWindowInfo winInfo;
1752   vtkParallelRenderManager::RendererInfo renInfo;
1753   vtkParallelRenderManager::LightInfo lightInfo;
1754   int i, j;
1755 
1756   vtkDebugMacro("SatelliteStartRender");
1757 
1758   this->FullImageUpToDate = 0;
1759   this->ReducedImageUpToDate = 0;
1760   this->RenderWindowImageUpToDate = 0;
1761 
1762   if (this->FullImage->GetPointer(0) == this->ReducedImage->GetPointer(0))
1763   {
1764     // "Un-share" pointer for full/reduced images in case we need separate
1765     // arrays this run.
1766     this->ReducedImage->Initialize();
1767   }
1768 
1769   // if (!this->ParallelRendering)
1770   //  {
1771   //  return;
1772   //  }
1773 
1774   this->InvokeEvent(vtkCommand::StartEvent, nullptr);
1775   vtkMultiProcessStream stream;
1776   if (!this->Controller->Broadcast(stream, this->RootProcessId))
1777   {
1778     return;
1779   }
1780 
1781   if (!winInfo.Restore(stream))
1782   {
1783     vtkErrorMacro("Failed to read window information");
1784     return;
1785   }
1786 
1787   this->RenderWindow->SetDesiredUpdateRate(winInfo.DesiredUpdateRate);
1788   if (this->SynchronizeTileProperties)
1789   {
1790     this->RenderWindow->SetTileViewport(winInfo.TileViewport);
1791     this->RenderWindow->SetTileScale(winInfo.TileScale);
1792   }
1793   this->SetUseCompositing(winInfo.UseCompositing);
1794   if (this->MaxImageReductionFactor < winInfo.ImageReductionFactor)
1795   {
1796     this->SetMaxImageReductionFactor(winInfo.ImageReductionFactor);
1797   }
1798   this->SetImageReductionFactor(winInfo.ImageReductionFactor);
1799   this->FullImageSize[0] = winInfo.FullSize[0];
1800   this->FullImageSize[1] = winInfo.FullSize[1];
1801   this->ReducedImageSize[0] = winInfo.ReducedSize[0];
1802   this->ReducedImageSize[1] = winInfo.ReducedSize[1];
1803 
1804   // Backwards compatibility.
1805   this->ReceiveWindowInformation();
1806 
1807   if (!this->ProcessWindowInformation(stream))
1808   {
1809     vtkErrorMacro("Failed to process window information correctly.");
1810     return;
1811   }
1812 
1813   this->SetRenderWindowSize();
1814 
1815   vtkCollectionSimpleIterator rsit;
1816   vtkRendererCollection* rens = this->GetRenderers();
1817 
1818   this->Viewports->SetNumberOfTuples(rens->GetNumberOfItems());
1819 
1820   rens->InitTraversal(rsit);
1821   for (i = 0; i < winInfo.NumberOfRenderers; i++)
1822   {
1823     vtkLightCollection* lc = nullptr;
1824     vtkCollectionSimpleIterator lsit;
1825     vtkRenderer* ren = rens->GetNextRenderer(rsit);
1826     if (ren == nullptr)
1827     {
1828       vtkErrorMacro("Not enough renderers");
1829     }
1830     else
1831     {
1832       // Backwards compatibility
1833       this->ReceiveRendererInformation(ren);
1834 
1835       if (!renInfo.Restore(stream))
1836       {
1837         vtkErrorMacro("Failed to read renderer information for " << i);
1838         continue;
1839       }
1840 
1841       this->Viewports->SetTuple(i, ren->GetViewport());
1842       ren->SetViewport(renInfo.Viewport);
1843       ren->SetBackground(renInfo.Background[0], renInfo.Background[1], renInfo.Background[2]);
1844       ren->SetBackground2(renInfo.Background2[0], renInfo.Background2[1], renInfo.Background2[2]);
1845       ren->SetGradientBackground(renInfo.GradientBackground);
1846       vtkCamera* cam = ren->GetActiveCamera();
1847       cam->SetPosition(renInfo.CameraPosition);
1848       cam->SetFocalPoint(renInfo.CameraFocalPoint);
1849       cam->SetViewUp(renInfo.CameraViewUp);
1850       cam->SetClippingRange(renInfo.CameraClippingRange);
1851       cam->SetViewAngle(renInfo.CameraViewAngle);
1852       cam->SetWindowCenter(renInfo.WindowCenter[0], renInfo.WindowCenter[1]);
1853       if (renInfo.ParallelScale != 0.0)
1854       {
1855         cam->ParallelProjectionOn();
1856         cam->SetParallelScale(renInfo.ParallelScale);
1857       }
1858       else
1859       {
1860         cam->ParallelProjectionOff();
1861       }
1862       ren->SetDraw(renInfo.Draw);
1863       lc = ren->GetLights();
1864       lc->InitTraversal(lsit);
1865     }
1866 
1867     for (j = 0; j < renInfo.NumberOfLights; j++)
1868     {
1869       if (ren != nullptr && lc != nullptr)
1870       {
1871         vtkLight* light = lc->GetNextLight(lsit);
1872         if (light == nullptr)
1873         {
1874           // Not enough lights?  Just create them.
1875           vtkDebugMacro("Adding light");
1876           light = vtkLight::New();
1877           ren->AddLight(light);
1878           light->Delete();
1879         }
1880 
1881         if (!lightInfo.Restore(stream))
1882         {
1883           vtkErrorMacro("Failed to read light information");
1884           continue;
1885         }
1886         light->SetLightType((int)(lightInfo.Type));
1887         light->SetPosition(lightInfo.Position);
1888         light->SetFocalPoint(lightInfo.FocalPoint);
1889       }
1890     }
1891 
1892     if (ren != nullptr)
1893     {
1894       vtkLight* light;
1895       while ((light = lc->GetNextLight(lsit)))
1896       {
1897         // To many lights?  Just remove the extras.
1898         ren->RemoveLight(light);
1899       }
1900     }
1901 
1902     if (!this->ProcessRendererInformation(ren, stream))
1903     {
1904       vtkErrorMacro("Failed to process renderer information correctly.");
1905     }
1906   }
1907 
1908   if (rens->GetNextRenderer(rsit))
1909   {
1910     vtkErrorMacro("Too many renderers.");
1911   }
1912 
1913   this->PreRenderProcessing();
1914 }
1915 
1916 //------------------------------------------------------------------------------
TileWindows(int xsize,int ysize,int ncolumn)1917 void vtkParallelRenderManager::TileWindows(int xsize, int ysize, int ncolumn)
1918 {
1919   if (!this->RenderWindow || !this->Controller)
1920   {
1921     return;
1922   }
1923 
1924   int procId = this->Controller->GetLocalProcessId();
1925 
1926   int row = procId / ncolumn;
1927   int column = procId % ncolumn;
1928 
1929   this->RenderWindow->SetPosition(xsize * column, ysize * row);
1930 }
1931 
1932 //------------------------------------------------------------------------------
1933 // ********* INFO OBJECT METHODS ***************************
1934 //------------------------------------------------------------------------------
Save(vtkMultiProcessStream & stream)1935 void vtkParallelRenderManager::RenderWindowInfo::Save(vtkMultiProcessStream& stream)
1936 {
1937   stream << vtkParallelRenderManager::WIN_INFO_TAG << this->FullSize[0] << this->FullSize[1]
1938          << this->ReducedSize[0] << this->ReducedSize[1] << this->NumberOfRenderers
1939          << this->UseCompositing << this->TileScale[0] << this->TileScale[1]
1940          << this->ImageReductionFactor << this->DesiredUpdateRate << this->TileViewport[0]
1941          << this->TileViewport[1] << this->TileViewport[2] << this->TileViewport[3];
1942 }
1943 
1944 //------------------------------------------------------------------------------
Restore(vtkMultiProcessStream & stream)1945 bool vtkParallelRenderManager::RenderWindowInfo::Restore(vtkMultiProcessStream& stream)
1946 {
1947   int tag;
1948   stream >> tag;
1949   if (tag != vtkParallelRenderManager::WIN_INFO_TAG)
1950   {
1951     return false;
1952   }
1953   stream >> this->FullSize[0] >> this->FullSize[1] >> this->ReducedSize[0] >>
1954     this->ReducedSize[1] >> this->NumberOfRenderers >> this->UseCompositing >> this->TileScale[0] >>
1955     this->TileScale[1] >> this->ImageReductionFactor >> this->DesiredUpdateRate >>
1956     this->TileViewport[0] >> this->TileViewport[1] >> this->TileViewport[2] >>
1957     this->TileViewport[3];
1958   return true;
1959 }
1960 
1961 //------------------------------------------------------------------------------
Save(vtkMultiProcessStream & stream)1962 void vtkParallelRenderManager::RendererInfo::Save(vtkMultiProcessStream& stream)
1963 {
1964   int value = this->GradientBackground;
1965   stream << vtkParallelRenderManager::REN_INFO_TAG << this->Draw << this->NumberOfLights
1966          << this->Viewport[0] << this->Viewport[1] << this->Viewport[2] << this->Viewport[3]
1967          << this->CameraPosition[0] << this->CameraPosition[1] << this->CameraPosition[2]
1968          << this->CameraFocalPoint[0] << this->CameraFocalPoint[1] << this->CameraFocalPoint[2]
1969          << this->CameraViewUp[0] << this->CameraViewUp[1] << this->CameraViewUp[2]
1970          << this->WindowCenter[0] << this->WindowCenter[1] << this->CameraClippingRange[0]
1971          << this->CameraClippingRange[1] << this->CameraViewAngle << this->Background[0]
1972          << this->Background[1] << this->Background[2] << this->Background2[0]
1973          << this->Background2[1] << this->Background2[2] << value << this->ParallelScale;
1974 }
1975 
1976 //------------------------------------------------------------------------------
Restore(vtkMultiProcessStream & stream)1977 bool vtkParallelRenderManager::RendererInfo::Restore(vtkMultiProcessStream& stream)
1978 {
1979   int tag;
1980   stream >> tag;
1981   if (tag != vtkParallelRenderManager::REN_INFO_TAG)
1982   {
1983     return false;
1984   }
1985 
1986   int value;
1987 
1988   stream >> this->Draw >> this->NumberOfLights >> this->Viewport[0] >> this->Viewport[1] >>
1989     this->Viewport[2] >> this->Viewport[3] >> this->CameraPosition[0] >> this->CameraPosition[1] >>
1990     this->CameraPosition[2] >> this->CameraFocalPoint[0] >> this->CameraFocalPoint[1] >>
1991     this->CameraFocalPoint[2] >> this->CameraViewUp[0] >> this->CameraViewUp[1] >>
1992     this->CameraViewUp[2] >> this->WindowCenter[0] >> this->WindowCenter[1] >>
1993     this->CameraClippingRange[0] >> this->CameraClippingRange[1] >> this->CameraViewAngle >>
1994     this->Background[0] >> this->Background[1] >> this->Background[2] >> this->Background2[0] >>
1995     this->Background2[1] >> this->Background2[2] >> value >> this->ParallelScale;
1996 
1997   this->GradientBackground = value == 1;
1998   return true;
1999 }
2000 
2001 //------------------------------------------------------------------------------
Restore(vtkMultiProcessStream & stream)2002 bool vtkParallelRenderManager::LightInfo::Restore(vtkMultiProcessStream& stream)
2003 {
2004   int tag;
2005   stream >> tag;
2006   if (tag != vtkParallelRenderManager::LIGHT_INFO_TAG)
2007   {
2008     return false;
2009   }
2010   stream >> this->Position[0] >> this->Position[1] >> this->Position[2] >> this->FocalPoint[0] >>
2011     this->FocalPoint[1] >> this->FocalPoint[2] >> this->Type;
2012   return true;
2013 }
2014 
2015 //------------------------------------------------------------------------------
Save(vtkMultiProcessStream & stream)2016 void vtkParallelRenderManager::LightInfo::Save(vtkMultiProcessStream& stream)
2017 {
2018   stream << vtkParallelRenderManager::LIGHT_INFO_TAG << this->Position[0] << this->Position[1]
2019          << this->Position[2] << this->FocalPoint[0] << this->FocalPoint[1] << this->FocalPoint[2]
2020          << this->Type;
2021 }
2022