Commit 1a6c65cd authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

Added support to use view-based block prioritization.

parent 4f8f5634
......@@ -842,21 +842,31 @@ void vtkPVRenderView::InteractiveRender()
}
//----------------------------------------------------------------------------
unsigned int vtkPVRenderView::GetNextPieceToDeliver()
unsigned int vtkPVRenderView::GetNextPieceToDeliver(double planes[24])
{
if (!vtkPVView::GetEnableStreaming())
{
return 0;
}
bool force_modified = false;
static double prev_planes[24];
for (int cc=0; cc < 24 && !force_modified;cc++)
{
force_modified = prev_planes[cc] != planes[cc];
}
memcpy(prev_planes, planes, 24*sizeof(double));
if (this->UpdateTimeStamp > this->PriorityQueueBuildTimeStamp ||
this->GetActiveCamera()->GetMTime() > this->PriorityQueueBuildTimeStamp)
this->GetActiveCamera()->GetMTime() > this->PriorityQueueBuildTimeStamp ||
force_modified)
{
// either the data or the camera has changed. Regenerate the priority queue.
// Priority queue contains a list of (representation-id, block-id) tuples
// indicating the blocks to request.
vtkTimerLog::MarkStartEvent("Build View Priority Queue");
this->GetGeometryStore()->BuildPriorityQueue();
this->GetGeometryStore()->BuildPriorityQueue(planes);
vtkTimerLog::MarkEndEvent("Build View Priority Queue");
this->PriorityQueueBuildTimeStamp.Modified();
}
......
......@@ -173,7 +173,7 @@ public:
// Description:
// Returns the representation id which is going to deliver the next piece for
// streaming.
unsigned int GetNextPieceToDeliver();
unsigned int GetNextPieceToDeliver(double planes[24]);
void StreamingUpdate();
......
......@@ -18,7 +18,7 @@
#include "vtkAlgorithmOutput.h"
#include "vtkAMRVolumeRepresentation.h"
#include "vtkBSPCutsGenerator.h"
#include "vtkPointData.h"
#include "vtkCamera.h"
#include "vtkMPIMoveData.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkMultiProcessController.h"
......@@ -27,17 +27,116 @@
#include "vtkOrderedCompositeDistributor.h"
#include "vtkOverlappingAMR.h"
#include "vtkPKdTree.h"
#include "vtkPointData.h"
#include "vtkProcessModule.h"
#include "vtkPVRenderView.h"
#include "vtkPVSession.h"
#include "vtkRenderer.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkTimerLog.h"
#include "vtkUniformGridAMRDataIterator.h"
#include "vtkUniformGrid.h"
#include "vtkUnsignedIntArray.h"
#include "vtkAMRBox.h"
#include "vtkMath.h"
#include <assert.h>
namespace
{
// this code is stolen from vtkFrustumCoverageCuller.
double vtkComputeScreenCoverage(const double planes[24],
const double bounds[6], double &distance)
{
distance = 0.0;
// a duff dataset like a polydata with no cells will have bad bounds
if (!vtkMath::AreBoundsInitialized(const_cast<double*>(bounds)))
{
return 0.0;
}
double screen_bounds[4];
double center[3];
center[0] = (bounds[0] + bounds[1]) / 2.0;
center[1] = (bounds[2] + bounds[3]) / 2.0;
center[2] = (bounds[4] + bounds[5]) / 2.0;
double radius = 0.5 * sqrt(
( bounds[1] - bounds[0] ) * ( bounds[1] - bounds[0] ) +
( bounds[3] - bounds[2] ) * ( bounds[3] - bounds[2] ) +
( bounds[5] - bounds[4] ) * ( bounds[5] - bounds[4] ) );
for (int i = 0; i < 6; i++ )
{
// Compute how far the center of the sphere is from this plane
double d = planes[i*4 + 0] * center[0] +
planes[i*4 + 1] * center[1] +
planes[i*4 + 2] * center[2] +
planes[i*4 + 3];
// If d < -radius the prop is not within the view frustum
if ( d < -radius )
{
return 0.0;
}
// The first four planes are the ones bounding the edges of the
// view plane (the last two are the near and far planes) The
// distance from the edge of the sphere to these planes is stored
// to compute coverage.
if ( i < 4 )
{
screen_bounds[i] = d - radius;
}
// The fifth plane is the near plane - use the distance to
// the center (d) as the value to sort by
if ( i == 4 )
{
distance = d;
}
}
// If the prop wasn't culled during the plane tests...
// Compute the width and height of this slice through the
// view frustum that contains the center of the sphere
double full_w = screen_bounds[0] + screen_bounds[1] + 2.0 * radius;
double full_h = screen_bounds[2] + screen_bounds[3] + 2.0 * radius;
// Subtract from the full width to get the width of the square
// enclosing the circle slice from the sphere in the plane
// through the center of the sphere. If the screen bounds for
// the left and right planes (0,1) are greater than zero, then
// the edge of the sphere was a positive distance away from the
// plane, so there is a gap between the edge of the plane and
// the edge of the box.
double part_w = full_w;
if ( screen_bounds[0] > 0.0 )
{
part_w -= screen_bounds[0];
}
if ( screen_bounds[1] > 0.0 )
{
part_w -= screen_bounds[1];
}
// Do the same thing for the height with the top and bottom
// planes (2,3).
double part_h = full_h;
if ( screen_bounds[2] > 0.0 )
{
part_h -= screen_bounds[2];
}
if ( screen_bounds[3] > 0.0 )
{
part_h -= screen_bounds[3];
}
// Compute the fraction of coverage
if ((full_w * full_h)!=0.0)
{
return (part_w * part_h) / (full_w * full_h);
}
return 0;
}
};
vtkStandardNewMacro(vtkRepresentedDataStorage);
//----------------------------------------------------------------------------
vtkRepresentedDataStorage::vtkRepresentedDataStorage()
......@@ -375,13 +474,15 @@ vtkPKdTree* vtkRepresentedDataStorage::GetKdTree()
}
//----------------------------------------------------------------------------
bool vtkRepresentedDataStorage::BuildPriorityQueue()
bool vtkRepresentedDataStorage::BuildPriorityQueue(double planes[24])
{
cout << "BuildPriorityQueue" << endl;
// just find the first visible AMR dataset and build priority queue for that
// dataset alone. In future, we can fix it to use information provided by
// representation indicating if streaming is possible (since not every AMR
// source is streambale).
this->Internals->PriorityQueue = vtkInternals::PriorityQueueType();
vtkOverlappingAMR* oamr = NULL;
......@@ -408,6 +509,12 @@ bool vtkRepresentedDataStorage::BuildPriorityQueue()
// note: amr block ids currently don't match up with composite dataset ids :/.
// now build a priority queue for absent blocks using the current camera.
//double planes[24];
//vtkRenderer* ren = this->View->GetRenderer();
//ren->GetActiveCamera()->GetFrustumPlanes(
// ren->GetTiledAspectRatio(), planes);
for (unsigned int level=0; level < oamr->GetNumberOfLevels(); level++)
{
for (unsigned int index=0;
......@@ -415,12 +522,32 @@ bool vtkRepresentedDataStorage::BuildPriorityQueue()
{
if (oamr->GetDataSet(level, index) == NULL)
{
vtkAMRBox amrBox;
if (!oamr->GetMetaData(level, index, amrBox))
{
vtkWarningMacro("Missing AMRBox meta-data for "
<< level << ", " << index);
continue;
}
vtkInternals::vtkPriorityQueueItem item;
item.RepresentationId = iter->first;
item.BlockId = oamr->GetCompositeIndex(level, index);
item.Priority = 1.0 / (1.0 + item.BlockId);
item.Level = level;
item.Index = index;
double bounds[6];
amrBox.GetBounds(bounds);
double depth = 1.0;
double coverage = vtkComputeScreenCoverage(planes, bounds, depth);
//cout << level <<"," << index << "(" << item.BlockId << ")" << " = " << coverage << ", " << depth << endl;
if (coverage == 0.0)
{
// skip blocks that are not covered in the view.
continue;
}
item.Priority = coverage / (depth > 1? depth : 1.0);
this->Internals->PriorityQueue.push(item);
}
}
......
......@@ -84,7 +84,7 @@ public:
// Description:
// Based on the current camera and currently available datasets, build a
// priority queue.
bool BuildPriorityQueue();
bool BuildPriorityQueue(double planes[24]);
unsigned int GetRepresentationIdFromQueue();
void StreamingDeliver(unsigned int key);
......
......@@ -14,11 +14,13 @@
=========================================================================*/
#include "vtkSMDataDeliveryManager.h"
#include "vtkCamera.h"
#include "vtkClientServerStream.h"
#include "vtkCommand.h"
#include "vtkObjectFactory.h"
#include "vtkObjectFactory.h"
#include "vtkPVRenderView.h"
#include "vtkRenderer.h"
#include "vtkRepresentedDataStorage.h"
#include "vtkSMSession.h"
#include "vtkSMViewProxy.h"
......@@ -142,10 +144,20 @@ bool vtkSMDataDeliveryManager::DeliverNextPiece()
vtkTimerLog::MarkStartEvent("DeliverNextPiece");
vtkSMSession* session = this->ViewProxy->GetSession();
vtkPVRenderView* view = vtkPVRenderView::SafeDownCast(
this->ViewProxy->GetClientSideObject());
double planes[24];
vtkRenderer* ren = view->GetRenderer();
ren->GetActiveCamera()->GetFrustumPlanes(
ren->GetTiledAspectRatio(), planes);
vtkClientServerStream stream;
stream << vtkClientServerStream::Invoke
<< VTKOBJECT(this->ViewProxy)
<< "GetNextPieceToDeliver"
<< vtkClientServerStream::InsertArray(planes, 24)
<< vtkClientServerStream::End;
session->ExecuteStream(vtkPVSession::DATA_SERVER_ROOT, stream, false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment