Text archives Help
- From: abe@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r502 - in branches/AFR: Engine/Control Interface
- Date: Thu, 25 Aug 2005 17:26:24 -0600 (MDT)
Author: abe
Date: Thu Aug 25 17:26:23 2005
New Revision: 502
Added:
branches/AFR/Engine/Control/AFRPipeline.cc
branches/AFR/Engine/Control/AFRPipeline.h
branches/AFR/Engine/Control/RTRT_register.h
Modified:
branches/AFR/Engine/Control/CMakeLists.txt
branches/AFR/Engine/Control/Worker.cc
branches/AFR/Engine/Control/Worker.h
branches/AFR/Interface/RTRTInterface.h
Log:
Added basic AFRPipeline (which implements RTRTInterface, which is the normal
manta pipeline). The code compiles, although since we haven't put everything
together yet, it is unlikely it will work without some revision.
M Interface/RTRTInterface.h
M Engine/Control/Worker.h
A Engine/Control/AFRPipeline.cc
A Engine/Control/AFRPipeline.h
A Engine/Control/RTRT_register.h
M Engine/Control/CMakeLists.txt
M Engine/Control/Worker.cc
Added: branches/AFR/Engine/Control/AFRPipeline.cc
==============================================================================
--- (empty file)
+++ branches/AFR/Engine/Control/AFRPipeline.cc Thu Aug 25 17:26:23 2005
@@ -0,0 +1,1164 @@
+
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005 Scientific Computing and Imaging Institute,
+ University of Utah.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include <Engine/Control/AFRPipeline.h>
+
+#include <Core/Util/Args.h>
+#include <Engine/Control/Worker.h>
+#include <Engine/Control/RTRT_register.h>
+#include <Interface/AmbientLight.h>
+#include <Interface/Background.h>
+#include <Interface/Callback.h>
+#include <Interface/Context.h>
+#include <Interface/IdleMode.h>
+#include <Interface/Image.h>
+#include <Interface/ImageDisplay.h>
+#include <Interface/ImageTraverser.h>
+#include <Interface/Light.h>
+#include <Interface/LightSet.h>
+#include <Interface/LoadBalancer.h>
+#include <Interface/Object.h>
+#include <Interface/PixelSampler.h>
+#include <Interface/Renderer.h>
+#include <Interface/Scene.h>
+#include <Interface/SetupCallback.h>
+#include <Interface/UserInterface.h>
+#include <Interface/ShadowAlgorithm.h>
+#include <Core/Containers/StringUtil.h>
+#include <Core/Exceptions/IllegalValue.h>
+#include <Core/Exceptions/InternalError.h>
+#include <Core/Exceptions/InvalidState.h>
+#include <Core/Thread/Thread.h>
+#include <Core/Thread/Time.h>
+#include <Core/Util/Assert.h>
+#include <Core/Util/NotFinished.h>
+
+#include <sgi_stl_warnings_off.h>
+#include <sstream>
+#include <iostream>
+#include <sgi_stl_warnings_on.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+
+using namespace Manta;
+using namespace Manta::Afr;
+using namespace std;
+
+using SCIRun::IllegalValue;
+using SCIRun::InvalidState;
+using SCIRun::InternalError;
+using SCIRun::Thread;
+using SCIRun::Time;
+using SCIRun::split_string;
+
+#define RENDER_THREAD_STACKSIZE 1024*1024
+
+RTRTInterface* Manta::Afr::createAFRPipeline() {
+ return new AFRPipeline();
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// CONSTRUCTOR
+///////////////////////////////////////////////////////////////////////////////
+AFRPipeline::AFRPipeline()
+ : runningLock("AFRPipeline running mutex"),
+ callbackLock("AFRPipeline callback r/w lock"),
+ outer_loop_barrier("AFRPipeline frame barrier #1"),
+ // barrier2("AFRPipeline frame barrier #2"),
+ pipeline_setup_barrier("AFRPipeline frame barrier #3"),
+ transaction_lock("AFRPipeline transaction lock"),
+ ids("AFRPipeline id counter", 1)
+{
+ workersWanted=0;
+ workersRendering=0;
+ workersAnimAndImage=0;
+ running=false;
+ animFrameState.frameNumber = 0;
+ animFrameState.frameTime = 0;
+ timeMode = RTRTInterface::RealTime;
+ timeScale = 1;
+ frameRate = 15;
+ pipelineNeedsSetup = true;
+ currentImageCreator = 0;
+ registerKnownComponents(this);
+ scene = 0;
+ verbose_transactions = false;
+ currentPixelSampler = 0;
+}
+
+AFRPipeline::~AFRPipeline()
+{
+ for(ChannelListType::iterator iter = channels.begin();
+ iter != channels.end(); iter++){
+ Channel* channel = *iter;
+ delete channel->display;
+ for(vector<Image*>::iterator iter = channel->images.begin();
+ iter != channel->images.end(); iter++)
+ delete *iter;
+ }
+ delete currentImageTraverser;
+ delete currentLoadBalancer;
+ delete currentPixelSampler;
+ delete currentRenderer;
+}
+
+void AFRPipeline::changeNumWorkers(int newNumWorkers)
+{
+ if(newNumWorkers <= 0)
+ throw IllegalValue<int>("AFRPipeline::changeNumWorkers, number of
workers should be > 0", newNumWorkers);
+
+ workersWanted=newNumWorkers;
+}
+
+TValue<int>& AFRPipeline::numWorkers()
+{
+ return workersWanted;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// ADD CALLBACKS
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::addOneShotCallback(Whence /*whence*/, long frame,
+ CallbackBase_2Data<int, int>* callback)
+{
+#if NOTFINISHED
+ // What about adding callbacks during anim cycle?
+#endif
+ callbackLock.writeLock();
+#if NOTFINISHED
+ if(whence == RTRTInterface::Relative)
+ frame += current Fame;
+#endif
+ oneShots.insert(OneShotMapType::value_type(frame, callback));
+ callbackLock.writeUnlock();
+}
+
+void AFRPipeline::registerSetupCallback(SetupCallback* callback)
+{
+ setupCallbacks.push_back(callback);
+}
+
+void AFRPipeline::registerParallelAnimationCallback(CallbackBase_3Data<int,
int, bool&>* cb)
+{
+ callbackLock.writeLock();
+ parallelAnimationCallbacks.push_back(cb);
+ callbackLock.writeUnlock();
+}
+
+void AFRPipeline::registerSerialAnimationCallback(CallbackBase_3Data<int,
int, bool&>* cb)
+{
+ callbackLock.writeLock();
+ serialAnimationCallbacks.push_back(cb);
+ callbackLock.writeUnlock();
+}
+
+void AFRPipeline::setTimeMode(TimeMode /*tm*/, double /*rate*/)
+{
+ NOT_FINISHED("AFRPipeline::setTimeMode");
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PREPROCESS
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::beginRendering(bool blockUntilFinished)
+{
+ // Establish that the renderer is running.
+ runningLock.lock();
+ if(running)
+ throw InvalidState("renderLoop started while it is already running",
+ __FILE__, __LINE__);
+ running=true;
+ runningLock.unlock();
+
+
////////////////////////////////////////////////////////////////////////////
+ // Preprocess
+ LightSet* lights = scene->getLights();
+
+ // Lights.
+ PreprocessContext context(this, lights);
+ lights->preprocess(context);
+
+ // Background.
+ scene->getBackground()->preprocess(context);
+
+ // Root object.
+ scene->getObject()->preprocess(context);
+
+ if(!currentImageCreator)
+ throw InvalidState("Image type was not selected", __FILE__, __LINE__);
+
+ // Make sure an acceptable number of workers is requested.
+ if(workersWanted <= 0){
+ runningLock.unlock();
+ throw IllegalValue<int>("workersWanted should be positive",
workersWanted);
+ }
+
+ if(workersRendering != 0){
+ runningLock.unlock();
+ throw IllegalValue<int>("workersRendering should be zero",
workersRendering);
+ }
+ workersRendering=workersWanted;
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Start up all of the Worker threads.
+ workers.resize(workersWanted);
+ changedFlags.resize(workersWanted);
+
+ for(int i=0;i<workersWanted;i++){
+
+ // Create each additional thread.
+ if(i>0 || !blockUntilFinished){
+
+ // Create a name for the thread.
+ ostringstream name;
+ name << "AFRPipeline Worker " << i;
+
+ // Construct the thread.
+ Thread* t = new Thread(new Worker(this, i, false), name.str().c_str(),
0, Thread::NotActivated);
+ t->setStackSize(RENDER_THREAD_STACKSIZE);
+ t->activate(false);
+ workers[i] = t;
+ }
+ }
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Enter the main rendering loop.
+ if(blockUntilFinished)
+ internalRenderLoop(0, false);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::blockUntilFinished()
+{
+ ASSERT(running);
+ ASSERT(workers.size()>0);
+ workers[0]->join();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// MAIN RENDERING LOOP
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::internalRenderLoop(int proc, bool lateComerFlag)
+{
+ bool changed = true;
+ bool firstFrame = true;
+
+ //if(lateComerFlag){
+ // firstFrame = false;
+ // goto skipToRendering;
+ //}
+
+ // Begin the outer rendering loop.
+ // This updates renderer state and then
+ for(;;){
+
+
///////////////////////////////////////////////////////////////////////////
+ // Update animation state.
+ // P0 update frame number, time, etc.
+ if(proc == 0){
+ animFrameState.frameNumber++;
+ switch(timeMode){
+ case RealTime:
+ animFrameState.frameTime =
Time::currentSeconds() * timeScale;
+ break;
+ case FixedRate:
+ animFrameState.frameTime =
static_cast<double>(animFrameState.frameNumber) / frameRate;
+ break;
+ case Static:
+ break;
+ }
+
+ // Update the number of workers to be used for the animation and
+ // image display portion
+ workersAnimAndImage = workersRendering;
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+ // Start of non-rendering portion of the loop. Make callbacks
+ // that could possibly change state and get everything set up to
+ // render the next frame
+ outer_loop_barrier.wait(workersRendering);
+
+ // Copy over the frame state
+ if(proc == 0) {
+ renderFrameState = animFrameState;
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ // Outer Loop: Pipeline Stage 1.
+ // Callbacks & Transactions.
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ changed=false;
+
+ doParallelAnimationCallbacks(changed, proc, workersAnimAndImage);
+ doSerialAnimationCallbacks (changed, proc, workersAnimAndImage);
+
+ // Post Transactions.
+ if(proc == 0)
+ postTransactions(changed);
+
+
///////////////////////////////////////////////////////////////////////////
+ // Setup the frame??
+#if 0
+ if(!firstFrame){
+ for(int index = 0;index < static_cast<int>(channels.size());index++){
+ Channel* channel = channels[index];
+ RenderContext myContext(this, index, proc,
workersAnimAndImage,
+
&animFrameState,
+
currentLoadBalancer,
currentPixelSampler,
+
currentRenderer,
currentShadowAlgorithm,
+
channel->camera, scene);
+ currentImageTraverser->setupFrame(myContext);
+ }
+ }
+#endif
+
+
///////////////////////////////////////////////////////////////////////////
+ // Resize the image. rebuild per thread kd-trees.
+ // Note all threads call this, which is different from trunk/
+ resizeImages(animFrameState.frameNumber);
+
+ // Note that the AFRPipeline doesn't support changing the
number of processors.
+
+
///////////////////////////////////////////////////////////////////////////
+ // Check to see if we need to setup a pipeline (after a state change for
+ // example)
+ int numProcs = workersAnimAndImage;
+
+ // Note doIdleModeCallbacks is omitted -- the pipeline should
never be idle.
+
+ if (pipelineNeedsSetup) {
+
+ // Negotiate the image pipeline for each channel
+ if(proc == 0){
+ setupPipelines(numProcs);
+ resizeImages(renderFrameState.frameNumber);
+ }
+
+ // Perhaps KD-tree creation goes here??
+
+ // Wait for all of the other processors to finish
setup.
+ pipeline_setup_barrier.wait(numProcs);
+
+ pipelineNeedsSetup = false;
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ // Outer Loop: Pipeline Stage 2.
+ // Image Display (Eventually reconstruction)
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+
+ for(ChannelListType::iterator iter = channels.begin(); iter
!= channels.end(); iter++){
+
+ Channel* channel = *iter;
+ long displayFrame =
(renderFrameState.frameNumber-1)%channel->pipelineDepth;
+ Image* image = channel->images[displayFrame];
+
+ if(image && image->isValid()){
+ DisplayContext myContext(proc,
workersAnimAndImage);
+ channel->display->displayImage(myContext,
image);
+ }
+ }
+
+// skipToRendering:
+ for (;;) {
+
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
+ // Inner Loop: Pipeline Stage 1.
+ // Update Tiling. (Master task)
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
+
+ // currentImageTraverser->updateTiling();
!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
/////////////////////////////////////////////////////////////////////////
+ // Pre-render callbacks
+ doParallelPreRenderCallbacks(proc, workersRendering);
+ doSerialPreRenderCallbacks(proc, workersRendering);
+
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
+ // Inner Loop: Pipeline Stage 2.
+ // Sampling / Rendering
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
+
+ for(int index = 0;index <
static_cast<int>(channels.size());index++){
+ Channel* channel = channels[index];
+ long renderFrame =
renderFrameState.frameNumber%channel->pipelineDepth;
+ Image* image = channel->images[renderFrame];
+ RenderContext myContext(this, index, proc,
workersRendering, &renderFrameState,
+
currentLoadBalancer,
currentPixelSampler,
+
currentRenderer,
currentShadowAlgorithm,
+
channel->camera, scene);
+
+ // Have the Afr compliant image traverser
render samples.
+ currentImageTraverser->renderImage(myContext,
image);
+ }
+
+ // Determine how to break out of inner loop.
!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+ } // End of inner loop.
+
+ } // End of outer loop.
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// TRANSACTIONS & CALLBACKS
+///////////////////////////////////////////////////////////////////////////////
+
+void AFRPipeline::doParallelAnimationCallbacks(bool& changed, int proc, int
numProcs)
+{
+ // All threads do the parallel animation callbacks
+ for(ACallbackMapType::iterator iter = parallelAnimationCallbacks.begin();
+ iter != parallelAnimationCallbacks.end(); iter++){
+ (*iter)->call(proc, numProcs, changed);
+ }
+}
+
+void AFRPipeline::doSerialAnimationCallbacks(bool& changed, int proc, int
numProcs)
+{
+ if(proc == 0){
+ // One-shots are always done by p0, since we do not always know
+ // how many there will be, and we need to potentially update the map
+ OneShotMapType::iterator iter = oneShots.begin();
+ while(iter != oneShots.end() && iter->first <
animFrameState.frameNumber){
+ iter->second->call(proc, numProcs);
+ delete iter->second;
+ oneShots.erase(iter);
+ iter = oneShots.begin();
+ }
+ }
+ unsigned long totalCallbacks = serialAnimationCallbacks.size();
+ unsigned long start = proc*totalCallbacks/numProcs;
+ unsigned long end = (proc+1)*totalCallbacks/numProcs;
+ ACallbackMapType::iterator iter = start+serialAnimationCallbacks.begin();
+ ACallbackMapType::iterator stop = end+serialAnimationCallbacks.begin();
+ for(; iter != stop; iter++)
+ (*iter)->call(proc, numProcs, changed);
+}
+
+void AFRPipeline::postTransactions(bool& changed)
+{
+ if(transactions.size() > 0){
+ transaction_lock.lock();
+ changed = true;
+ for(TransactionListType::iterator iter = transactions.begin();
+ iter != transactions.end(); iter++){
+ TransactionBase* transaction = *iter;
+ if(verbose_transactions){
+ cerr << "Apply transaction: " << transaction->getName() << " : ";
+ transaction->printValue(cerr);
+ cerr << " : ";
+ transaction->printOp(cerr);
+ cerr << " : ";
+ }
+ transaction->apply();
+ if(verbose_transactions){
+ transaction->printValue(cerr);
+ cerr << '\n';
+ }
+ delete transaction;
+ }
+ transactions.resize(0);
+ transaction_lock.unlock();
+ }
+}
+
+void AFRPipeline::doParallelPreRenderCallbacks(int proc, int numProcs)
+{
+ // All threads do the parallel pre-render callbacks
+ for(PRCallbackMapType::iterator iter = parallelPreRenderCallbacks.begin();
+ iter != parallelPreRenderCallbacks.end(); iter++){
+ (*iter)->call(proc, numProcs);
+ }
+}
+
+void AFRPipeline::doSerialPreRenderCallbacks(int proc, int numProcs)
+{
+ unsigned long totalCallbacks = serialPreRenderCallbacks.size();
+ unsigned long start = proc*totalCallbacks/numProcs;
+ unsigned long end = (proc+1)*totalCallbacks/numProcs;
+ PRCallbackMapType::iterator iter = start+serialPreRenderCallbacks.begin();
+ PRCallbackMapType::iterator stop = end+serialPreRenderCallbacks.begin();
+ for(; iter != stop; iter++)
+ (*iter)->call(proc, numProcs);
+}
+
+void AFRPipeline::processDeletions()
+{
+#if NOTFINISHED
+#endif
+}
+
+void AFRPipeline::doIdleModeCallbacks(bool changed, bool firstFrame,
+ bool& pipelineNeedsSetup,
+ int proc, int numProcs)
+{
+ int numChannels = static_cast<int>(channels.size());
+ SetupContext globalcontext(this, numChannels, proc, numProcs,
+ currentLoadBalancer, currentPixelSampler,
+ currentRenderer);
+ for(vector<IdleMode*>::iterator iter = currentIdleModes.begin();
+ iter != currentIdleModes.end(); iter++){
+ IdleMode* im = *iter;
+ im->changeIdleMode(globalcontext, changed, firstFrame,
pipelineNeedsSetup);
+ }
+}
+
+void AFRPipeline::finish()
+{
+#if NOTFINISHED
+ decide what to do based on whether we are in animation section or not or
an external thread... How to do this efficiently? Thread-local data?;
+ how to do this everywhere without massive code duplication?;
+#endif
+ workersWanted = 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// CREATE CHANNEL
+///////////////////////////////////////////////////////////////////////////////
+int AFRPipeline::createChannel(const string& spec, Camera* camera, bool
stereo, int xres, int yres)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ ImageDisplayMapType::iterator iter = imageDisplays.find(name);
+ if(iter == imageDisplays.end())
+ return 0;
+ Channel* channel = new Channel;
+ channel->id = ids++;
+ channel->display = (*iter->second)(args);
+ channel->stereo = stereo;
+ channel->xres = xres;
+ channel->yres = yres;
+ channel->active = true;
+ channel->imageCreator = 0;
+ channel->pipelineDepth = 2;
+ channel->images.resize(channel->pipelineDepth);
+ channel->camera = camera;
+ for(int i=0;i<channel->pipelineDepth;i++)
+ channel->images[i] = 0;
+ pipelineNeedsSetup = true;
+ channels.push_back(channel);
+ return channel->id;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Component Selectors.
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::registerComponent(const string& name, ImageDisplayCreator
fun)
+{
+ ImageDisplayMapType::iterator iter = imageDisplays.find(name);
+ if(iter != imageDisplays.end())
+ throw IllegalValue<string>("Duplicate ImageDisplay component", name);
+ imageDisplays[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listImageDisplays() const
+{
+ RTRTInterface::listType list;
+ for(ImageDisplayMapType::const_iterator iter = imageDisplays.begin();
+ iter != imageDisplays.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+Camera* AFRPipeline::getCamera(int channel) const
+{
+ return channels[channel]->camera;
+}
+
+void AFRPipeline::getResolution(int channel, bool& stereo, int& xres, int&
yres)
+{
+ stereo = channels[channel]->stereo;
+ xres = channels[channel]->xres;
+ yres = channels[channel]->yres;
+}
+
+void AFRPipeline::changeResolution(int channel, int xres, int yres,
+ bool changePipeline)
+{
+ channels[channel]->xres = xres;
+ channels[channel]->yres = yres;
+ if (changePipeline)
+ pipelineNeedsSetup = true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SETUP PIPELINES
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::setupPipelines(int numProcs)
+{
+ int numChannels = static_cast<int>(channels.size());
+ SetupContext globalcontext(this, numChannels, 0, numProcs,
+ currentLoadBalancer, currentPixelSampler,
+ currentRenderer);
+ currentImageTraverser->setupBegin(globalcontext, numChannels);
+ for(vector<SetupCallback*>::iterator iter = setupCallbacks.begin();
+ iter != setupCallbacks.end(); iter++)
+ (*iter)->setupBegin(globalcontext, numChannels);
+ for(int index = 0;index < static_cast<int>(channels.size());index++){
+ Channel* channel = channels[index];
+ SetupContext context(this, index, numChannels, 0, numProcs,
+ channel->stereo, channel->xres, channel->yres,
+ currentLoadBalancer, currentPixelSampler,
+ currentRenderer);
+ int iteration = 100;
+ do {
+ context.setChanged(false);
+ context.clearMasterWindow();
+ for(vector<SetupCallback*>::iterator iter = setupCallbacks.begin();
+ iter != setupCallbacks.end(); iter++)
+ (*iter)->setupDisplayChannel(context);
+ currentImageTraverser->setupDisplayChannel(context);
+ channel->display->setupDisplayChannel(context);
+ } while(context.isChanged() && --iteration > 0);
+ if(!iteration)
+ throw InternalError("Pipeline/resolution negotiation failed",
+ __FILE__, __LINE__);
+ context.getResolution(channel->stereo, channel->xres, channel->yres);
+ if(channel->xres <= 0)
+ throw IllegalValue<int>("Resolution should be positive",
channel->xres);
+ if(channel->yres <= 0)
+ throw IllegalValue<int>("Resolution should be positive",
channel->yres);
+
+ if(context.getMinDepth() > context.getMaxDepth())
+ throw InternalError("Pipeline depth negotiation failed",
+ __FILE__, __LINE__);
+ int depth = context.getMinDepth();
+ if(depth == 1 && context.getMaxDepth() > 1)
+ depth = 2; // Prefer double-buffering
+ cerr << "AFRPipeline::setupPipelines:: depth = "<< depth << "\n";
+ channel->pipelineDepth = depth;
+ unsigned long osize = channel->images.size();
+ for(unsigned long i=depth;i<osize;i++)
+ delete channel->images[i];
+ for(unsigned long i=osize;i<static_cast<unsigned long>(depth);i++)
+ channel->images[i]=0;
+ channel->images.resize(depth);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// RESIZE IMAGES
+///////////////////////////////////////////////////////////////////////////////
+void AFRPipeline::resizeImages(long frame)
+{
+ for(ChannelListType::iterator iter = channels.begin();
+ iter != channels.end(); iter++){
+ Channel* channel = *iter;
+ // Potentially resize the current rendering frame
+ long which = frame%channel->pipelineDepth;
+ bool stereo;
+ int xres, yres;
+ if(channel->images[which])
+ channel->images[which]->getResolution(stereo, xres, yres);
+ if(!channel->images[which] || channel->stereo != stereo
+ || channel->xres != xres || channel->yres != yres){
+ if(channel->images[which])
+ delete channel->images[which];
+ ImageCreator creator = channel->imageCreator;
+ if(!creator)
+ creator = currentImageCreator;
+ channel->images[which] = (creator)(currentImageCreatorArgs,
+ channel->stereo,
+ channel->xres, channel->yres);
+ } else {
+ if (channel->pipelineDepth > 1)
+ channel->images[which]->setValid(false);
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Component selectors.
+///////////////////////////////////////////////////////////////////////////////
+bool AFRPipeline::selectImageType(const string& spec)
+{
+ string name;
+ currentImageCreatorArgs.resize(0);
+ parseSpec(spec, name, currentImageCreatorArgs);
+ ImageCreatorMapType::iterator iter = imageCreators.find(name);
+ if(iter == imageCreators.end())
+ return false;
+ currentImageCreator = iter->second;
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name, ImageCreator fun)
+{
+ ImageCreatorMapType::iterator iter = imageCreators.find(name);
+ if(iter != imageCreators.end())
+ throw IllegalValue<string>("Duplicate ImageCreator component", name);
+ imageCreators[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listImageTypes() const
+{
+ RTRTInterface::listType list;
+ for(ImageCreatorMapType::const_iterator iter = imageCreators.begin();
+ iter != imageCreators.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::selectImageTraverser(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ ImageTraverserMapType::iterator iter = imageTraversers.find(name);
+ if(iter == imageTraversers.end())
+ return false;
+ currentImageTraverser = (*iter->second)(args);
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name,
ImageTraverserCreator fun)
+{
+ ImageTraverserMapType::iterator iter = imageTraversers.find(name);
+ if(iter != imageTraversers.end())
+ throw IllegalValue<string>("Duplicate ImageTraverser component", name);
+ imageTraversers[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listImageTraversers() const
+{
+ RTRTInterface::listType list;
+ for(ImageTraverserMapType::const_iterator iter = imageTraversers.begin();
+ iter != imageTraversers.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::selectLoadBalancer(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ LoadBalancerMapType::iterator iter = loadBalancers.find(name);
+ if(iter == loadBalancers.end())
+ return false;
+ currentLoadBalancer = (*iter->second)(args);
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name, LoadBalancerCreator
fun)
+{
+ LoadBalancerMapType::iterator iter = loadBalancers.find(name);
+ if(iter != loadBalancers.end())
+ throw IllegalValue<string>("Duplicate LoadBalancer component", name);
+ loadBalancers[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listLoadBalancers() const
+{
+ RTRTInterface::listType list;
+ for(LoadBalancerMapType::const_iterator iter = loadBalancers.begin();
+ iter != loadBalancers.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::selectPixelSampler(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ PixelSamplerMapType::iterator iter = pixelSamplers.find(name);
+ if(iter == pixelSamplers.end())
+ return false;
+ // Try to clean up our memory. This function should be called with
+ // the transactions or before rendering.
+ if (running) {
+ // Currently there isn't anything special to make sure this is
+ // called safely, so you are on your own.
+ }
+ if (currentPixelSampler) {
+ // It would be nice to see if the current pixel sampler can be
+ // simply updated rather than recreated, but for now we will do it
+ // the hard way.
+ delete currentPixelSampler;
+ }
+ currentPixelSampler = (*iter->second)(args);
+ pipelineNeedsSetup = true;
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name, PixelSamplerCreator
fun)
+{
+ PixelSamplerMapType::iterator iter = pixelSamplers.find(name);
+ if(iter != pixelSamplers.end())
+ throw IllegalValue<string>("Duplicate PixelSampler component", name);
+ pixelSamplers[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listPixelSamplers() const
+{
+ RTRTInterface::listType list;
+ for(PixelSamplerMapType::const_iterator iter = pixelSamplers.begin();
+ iter != pixelSamplers.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::selectRenderer(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ RendererMapType::iterator iter = renderers.find(name);
+ if(iter == renderers.end())
+ return false;
+ currentRenderer = (*iter->second)(args);
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name, RendererCreator fun)
+{
+ RendererMapType::iterator iter = renderers.find(name);
+ if(iter != renderers.end())
+ throw IllegalValue<string>("Duplicate Renderer component", name);
+ renderers[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listRenderers() const
+{
+ RTRTInterface::listType list;
+ for(RendererMapType::const_iterator iter = renderers.begin();
+ iter != renderers.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::addIdleMode(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ IdleModeMapType::iterator iter = idleModes.find(name);
+ if(iter == idleModes.end())
+ return false;
+ currentIdleModes.push_back((*iter->second)(args));
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name, IdleModeCreator fun)
+{
+ IdleModeMapType::iterator iter = idleModes.find(name);
+ if(iter != idleModes.end())
+ throw IllegalValue<string>("Duplicate IdleMode component", name);
+ idleModes[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listIdleModes() const
+{
+ RTRTInterface::listType list;
+ for(IdleModeMapType::const_iterator iter = idleModes.begin();
+ iter != idleModes.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::selectShadowAlgorithm(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ ShadowAlgorithmMapType::iterator iter = shadowAlgorithms.find(name);
+ if(iter == shadowAlgorithms.end())
+ return false;
+ currentShadowAlgorithm = (*iter->second)(args);
+ return true;
+}
+
+void AFRPipeline::registerComponent(const string& name,
ShadowAlgorithmCreator fun)
+{
+ ShadowAlgorithmMapType::iterator iter = shadowAlgorithms.find(name);
+ if(iter != shadowAlgorithms.end())
+ throw IllegalValue<string>("Duplicate ShadowAlgorithm component", name);
+ shadowAlgorithms[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listShadowAlgorithms() const
+{
+ RTRTInterface::listType list;
+ for(ShadowAlgorithmMapType::const_iterator iter = shadowAlgorithms.begin();
+ iter != shadowAlgorithms.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+Camera* AFRPipeline::createCamera(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ CameraMapType::iterator iter = cameras.find(name);
+ if(iter == cameras.end()){
+ return 0;
+ }
+ return (*iter->second)(args);
+}
+
+void AFRPipeline::registerComponent(const string& name, CameraCreator fun)
+{
+ CameraMapType::iterator iter = cameras.find(name);
+ if(iter != cameras.end())
+ throw IllegalValue<string>("Duplicate Camera component", name);
+ cameras[name] = fun;
+}
+
+RTRTInterface::listType AFRPipeline::listCameras() const
+{
+ RTRTInterface::listType list;
+ for(CameraMapType::const_iterator iter = cameras.begin();
+ iter != cameras.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::haveScene()
+{
+ return scene != 0;
+}
+
+void AFRPipeline::setScene(Scene* newScene)
+{
+ scene = newScene;
+}
+
+bool AFRPipeline::readScene(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+
+ // Pull off the suffix...
+ string::size_type dot = name.rfind('.');
+ string suffix;
+ if(dot == string::npos){
+ suffix="";
+ } else {
+ suffix = name.substr(dot+1);
+ }
+ Scene* newScene = 0;
+
+ // These are to try and guess what the shared library extension is
+ // on various systems.
+ string system_suffix;
+#if defined (__APPLE__)
+ system_suffix = "dylib";
+#elif defined (_WIN32) || defined (__CYGWIN__)
+ system_suffix = "dll";
+#else
+ system_suffix = "so";
+#endif
+
+ std::cout << "Scene suffix: " << suffix << std::endl;
+
+ if((suffix == "mo") || (suffix == "so") || (suffix == "dylib") ||
+ (suffix == "dll")) {
+ // Do this twice - once silently and once printing errors
+ std::cout << "Reading "<<suffix<<" scene\n";
+
+ newScene = readMOScene(name, args, false);
+ if(!newScene)
+ readMOScene(name, args, true);
+ } else {
+ // Try reading it as an MO
+ std::cout << "Appending "<<system_suffix<<" to scene" << std::endl;
+
+ newScene = readMOScene(name+"."+system_suffix, args, false);
+
+#if 0
+ // This looks redundant, going to nix it.
+ if(!newScene){
+ readMOScene(name+".so", args, true);
+ }
+#endif
+ }
+ if(!newScene){
+ return false;
+ } else {
+ scene = newScene;
+ return true;
+ }
+}
+
+void AFRPipeline::setScenePath(const string& path)
+{
+ scenePath = path;
+}
+
+Group* AFRPipeline::makeGroup(const string& groupSpec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(groupSpec, name, args);
+ GroupMapType::iterator iter = groups.find(name);
+ if(iter == groups.end())
+ return 0;
+ Group* group = (*iter->second)(args);
+ return group;
+}
+
+void AFRPipeline::registerObject(const string& name, GroupCreator creator)
+{
+ GroupMapType::iterator iter = groups.find(name);
+ if(iter != groups.end())
+ throw IllegalValue<string>("Duplicate group", name);
+ groups[name] = creator;
+}
+
+RTRTInterface::listType AFRPipeline::listGroups() const
+{
+ RTRTInterface::listType list;
+ for(GroupMapType::const_iterator iter = groups.begin();
+ iter != groups.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+Scene* AFRPipeline::readMOScene(const string& name, const vector<string>&
args,
+ bool printErrors)
+{
+ vector<string> dirs = split_string(scenePath, ':');
+ for(vector<string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++){
+ string fullname = *dir + "/"+name;
+ struct stat statbuf;
+ if(stat(fullname.c_str(), &statbuf) != 0){
+ if(printErrors){
+ cerr << "Error reading " << fullname << ": " << strerror(errno) <<
'\n';
+ }
+ continue;
+ }
+ void* handle=dlopen(fullname.c_str(), RTLD_NOW);
+ if(!handle){
+ if(printErrors){
+ cerr << "Error opening scene: " << fullname << '\n';
+ cerr << dlerror() << '\n';
+ }
+ continue;
+ }
+ void* scene_fn=dlsym(handle, "make_scene");
+ if(!scene_fn){
+ if(printErrors){
+ cerr << "Scene file found, but make_scene() function not found\n";
+ }
+ // If we get here, we fail so that we don't keep searching the path
+ // for another scene
+ return 0;
+ }
+ typedef Scene* (*MakerType)(const ReadContext&, const vector<string>&);
+ // MakerType make_scene = reinterpret_cast<MakerType>(scene_fn);
+ MakerType make_scene = (MakerType)(scene_fn);
+ ReadContext context(this);
+ Scene* scene=(*make_scene)(context, args);
+ if(!scene){
+ if(printErrors)
+ cerr << "scene " << name << " did not produce a scene\n";
+ return 0;
+ }
+ return scene;
+ }
+ return 0;
+}
+
+UserInterface* AFRPipeline::createUserInterface(const string& spec)
+{
+ string name;
+ vector<string> args;
+ parseSpec(spec, name, args);
+ UserInterfaceMapType::iterator iter = userInterfaces.find(name);
+ if(iter == userInterfaces.end())
+ return 0;
+ // This will create a new UserInterface
+ UserInterface *ui = (*iter->second)(args, this);
+ return ui;
+}
+
+void AFRPipeline::registerComponent(const string& name, UserInterfaceCreator
creator)
+{
+ UserInterfaceMapType::iterator iter = userInterfaces.find(name);
+ if(iter != userInterfaces.end())
+ throw IllegalValue<string>("Duplicate User Interface component", name);
+ userInterfaces[name] = creator;
+}
+
+RTRTInterface::listType AFRPipeline::listUserInterfaces() const
+{
+ RTRTInterface::listType list;
+ for(UserInterfaceMapType::const_iterator iter = userInterfaces.begin();
+ iter != userInterfaces.end(); iter++)
+ list.push_back(iter->first);
+ return list;
+}
+
+bool AFRPipeline::queryState(const string& which, vector<string>& results) {
+ if (which == "shadows") {
+ results.push_back(currentShadowAlgorithm->getName());
+ results.push_back(currentShadowAlgorithm->getSpecs());
+ } else if (which == "numworkers") {
+ int numworkers = static_cast<int>(workers.size());
+ char buf[100];
+ sprintf(buf, "%d", numworkers);
+ results.push_back(buf);
+ } else {
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Transactions
+ */
+
+void AFRPipeline::addTransaction(TransactionBase* transaction)
+{
+ transaction_lock.lock();
+ transactions.push_back(transaction);
+ transaction_lock.unlock();
+}
Added: branches/AFR/Engine/Control/AFRPipeline.h
==============================================================================
--- (empty file)
+++ branches/AFR/Engine/Control/AFRPipeline.h Thu Aug 25 17:26:23 2005
@@ -0,0 +1,304 @@
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005 Scientific Computing and Imaging Institute,
+ University of Utah.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef Manta_Engine_AFRPipeline_h
+#define Manta_Engine_AFRPipeline_h
+
+#include <Interface/RTRTInterface.h>
+#include <Interface/FrameState.h>
+#include <Interface/Parameters.h>
+#include <Core/Thread/AtomicCounter.h>
+#include <Core/Thread/Barrier.h>
+#include <Core/Thread/CrowdMonitor.h>
+#include <Core/Thread/Mutex.h>
+#include <Core/Thread/Semaphore.h>
+#include <map>
+#include <set>
+#include <vector>
+
+namespace SCIRun {
+ class Thread;
+}
+
+namespace Manta {
+
+ class Camera;
+ class Image;
+ class Scene;
+
+ namespace Afr {
+
+ using namespace std;
+
+ RTRTInterface* createAFRPipeline();
+
+ class AFRPipeline : public RTRTInterface {
+ public:
+ AFRPipeline();
+ ~AFRPipeline();
+
+ // Image Modes (opengl, file, mpeg, etc.)
+ virtual int createChannel(const string& modespec,
Camera* camera,
+ bool stereo, int
xres, int yres);
+ virtual void registerComponent(const string& name,
ImageDisplayCreator display);
+ virtual listType listImageDisplays() const;
+ virtual Camera* getCamera(int channel) const;
+ virtual void getResolution(int channel, bool& stereo,
int& xres, int& yres);
+ virtual void changeResolution(int channel, int xres,
int yres,
+
bool
changePipeline);
+
+ // Image Traversers
+ virtual bool selectImageTraverser(const string& spec);
+ virtual void registerComponent(const string& name,
ImageTraverserCreator creator);
+ virtual listType listImageTraversers() const;
+
+ // Image Types (rgb, rgba, float, etc.)
+ virtual bool selectImageType(const string& spec);
+ virtual void registerComponent(const string& name,
ImageCreator display);
+ virtual listType listImageTypes() const;
+
+ // Load Balancers
+ virtual bool selectLoadBalancer(const string& spec);
+ virtual void registerComponent(const string& name,
LoadBalancerCreator creator);
+ virtual listType listLoadBalancers() const;
+
+ // PixelSamplers
+ virtual bool selectPixelSampler(const string& spec);
+ virtual void registerComponent(const string& name,
PixelSamplerCreator creator);
+ virtual listType listPixelSamplers() const;
+
+ // Renderers
+ virtual bool selectRenderer(const string& spec);
+ virtual void registerComponent(const string& name,
RendererCreator creator);
+ virtual listType listRenderers() const;
+
+ // Shadow Algorithms
+ virtual bool selectShadowAlgorithm(const string&
spec);
+ virtual void registerComponent(const string& name,
ShadowAlgorithmCreator creator);
+ virtual listType listShadowAlgorithms() const;
+
+ // Idle modes
+ virtual bool addIdleMode(const string& spec);
+ virtual void registerComponent(const string& name,
IdleModeCreator creator);
+ virtual listType listIdleModes() const;
+
+ // Camera
+ virtual Camera* createCamera(const string& spec);
+ virtual void registerComponent(const string& name,
CameraCreator creator);
+ virtual listType listCameras() const;
+
+ // Scenes
+ virtual bool haveScene();
+ virtual void setScene(Scene* scene);
+ virtual bool readScene(const string& sceneSpec/*,
const vector<string> &args*/);
+ virtual void setScenePath(const string& path);
+
+ // Groups
+ virtual Group* makeGroup(const string& groupSpec);
+ virtual void registerObject(const string& name,
GroupCreator creator);
+ virtual listType listGroups() const;
+
+ // Callbacks
+ virtual void addOneShotCallback(Whence whence, long
frame,
+
CallbackBase_2Data<int, int>* callback);
+ virtual void registerSetupCallback(SetupCallback*);
+ virtual void
registerSerialAnimationCallback(CallbackBase_3Data<int, int, bool&>*);
+ virtual void
registerParallelAnimationCallback(CallbackBase_3Data<int, int, bool&>*);
+
+ // Control of time/animation
+ virtual void setTimeMode(TimeMode tm, double rate);
+
+ // Parallel processing
+ virtual void changeNumWorkers(int workers);
+ virtual TValue<int>& numWorkers();
+
+ // Control
+ virtual void beginRendering(bool blockUntilFinished);
+ virtual void blockUntilFinished();
+
+ // Control
+ virtual void finish();
+
+ // User Interfaces
+ virtual UserInterface* createUserInterface(const
string& spec);
+ virtual void registerComponent(const string& name,
UserInterfaceCreator creator);
+ virtual listType listUserInterfaces() const;
+
+
+ // Query functions
+
+ // what specifies what you want which is then placed
in result.
+ // If the function cannot determine what you want,
false is return.
+ virtual bool queryState(const string& what,
vector<string>& results);
+
+ inline void barrierWait();
+
+ // Transactions
+ virtual void addTransaction(TransactionBase*);
+ protected:
+ friend class Worker;
+ void internalRenderLoop(int workerIndex, bool
lateComerFlag);
+
+ private:
+ AFRPipeline(const AFRPipeline&);
+ AFRPipeline& operator=(const AFRPipeline&);
+
+ void doParallelAnimationCallbacks(bool& changed, int
proc, int numProcs);
+ void doSerialAnimationCallbacks(bool& changed, int
proc, int numProcs);
+ void doParallelPreRenderCallbacks(int proc, int
numProcs);
+ void doSerialPreRenderCallbacks(int proc, int
numProcs);
+ void processDeletions();
+ void doIdleModeCallbacks(bool changed, bool
firstFrame,
+
bool& pipelineNeedsSetup,
+
int proc, int numProcs);
+
+ void resizeImages(long frameNumber);
+ void setupPipelines(int numProcs);
+ TValue<int> workersWanted;
+ int workersRendering;
+ int workersAnimAndImage;
+ bool workersChanged;
+ vector<SCIRun::Thread*> workers;
+
+ SCIRun::Mutex runningLock;
+ bool running;
+
+ SCIRun::CrowdMonitor callbackLock;
+ SCIRun::Barrier outer_loop_barrier;
+ SCIRun::Barrier pipeline_setup_barrier;
+
+ struct ReductionData {
+ bool changed;
+ char pad[MAXCACHELINESIZE-sizeof(bool)];
+ };
+ vector<ReductionData> changedFlags;
+ bool lastChanged;
+
+ // Callbacks
+ typedef multimap<long, CallbackBase_2Data<int, int>*,
less<long> > OneShotMapType;
+ OneShotMapType oneShots;
+ typedef vector<CallbackBase_2Data<int, int>*>
PRCallbackMapType;
+ typedef vector<CallbackBase_3Data<int, int, bool&>*>
ACallbackMapType;
+ PRCallbackMapType parallelPreRenderCallbacks;
+ PRCallbackMapType serialPreRenderCallbacks;
+ ACallbackMapType parallelAnimationCallbacks;
+ ACallbackMapType serialAnimationCallbacks;
+ vector<SetupCallback*> setupCallbacks;
+
+ // Transactions
+ typedef vector<TransactionBase*> TransactionListType;
+ TransactionListType transactions;
+ SCIRun::Mutex transaction_lock;
+ void postTransactions(bool& changed);
+ bool verbose_transactions;
+
+ // Component databases and current instances
+ typedef map<string, ImageDisplayCreator>
ImageDisplayMapType;
+ ImageDisplayMapType imageDisplays;
+
+ typedef map<string, ImageCreator> ImageCreatorMapType;
+ ImageCreatorMapType imageCreators;
+ vector<string> currentImageCreatorArgs;
+ ImageCreator currentImageCreator;
+
+ typedef map<string, ImageTraverserCreator>
ImageTraverserMapType;
+ ImageTraverserMapType imageTraversers;
+ ImageTraverser* currentImageTraverser;
+
+ typedef map<string, LoadBalancerCreator>
LoadBalancerMapType;
+ LoadBalancerMapType loadBalancers;
+ LoadBalancer* currentLoadBalancer;
+
+ typedef map<string, PixelSamplerCreator>
PixelSamplerMapType;
+ PixelSamplerMapType pixelSamplers;
+ PixelSampler* currentPixelSampler;
+
+ typedef map<string, RendererCreator> RendererMapType;
+ RendererMapType renderers;
+ Renderer* currentRenderer;
+
+ typedef map<string, ShadowAlgorithmCreator>
ShadowAlgorithmMapType;
+ ShadowAlgorithmMapType shadowAlgorithms;
+ ShadowAlgorithm* currentShadowAlgorithm;
+
+ typedef map<string, IdleModeCreator> IdleModeMapType;
+ IdleModeMapType idleModes;
+ vector<IdleMode*> currentIdleModes;
+
+ typedef map<string, CameraCreator> CameraMapType;
+ CameraMapType cameras;
+
+ typedef map<string, UserInterfaceCreator>
UserInterfaceMapType;
+ UserInterfaceMapType userInterfaces;
+
+ typedef map<string, GroupCreator> GroupMapType;
+ GroupMapType groups;
+
+ // The pipeline
+ bool pipelineNeedsSetup;
+
+ // Time control
+ TimeMode timeMode;
+ double timeScale;
+ double frameRate;
+
+ char pad0[MAXCACHELINESIZE];
+ FrameState animFrameState;
+ char pad1[MAXCACHELINESIZE];
+ FrameState renderFrameState;
+ char pad2[MAXCACHELINESIZE];
+
+
///////////////////////////////////////////////////////////////////////////
+ // Channel structure.
+ struct Channel {
+ int id;
+ ImageDisplay* display;
+ int xres, yres;
+ bool stereo;
+ int pipelineDepth;
+ bool active;
+ ImageCreator imageCreator;
+ vector<Image*> images;
+ Camera* camera;
+ };
+ typedef vector<Channel*> ChannelListType;
+ ChannelListType channels;
+
+ Scene* scene;
+ string scenePath;
+
+ SCIRun::AtomicCounter ids;
+
+ Scene* readMOScene(const string& name, const
vector<string>& args,
+ bool printErrors);
+ };
+ };
+}
+
+#endif
Modified: branches/AFR/Engine/Control/CMakeLists.txt
==============================================================================
--- branches/AFR/Engine/Control/CMakeLists.txt (original)
+++ branches/AFR/Engine/Control/CMakeLists.txt Thu Aug 25 17:26:23 2005
@@ -1,6 +1,11 @@
SET (Manta_Control_SRCS
+ Control/RTRT.h
Control/RTRT.cc
+ Control/RTRT_register.h
Control/RTRT_register.cc
+ Control/AFRPipeline.h
+ Control/AFRPipeline.cc
+ Control/Worker.h
Control/Worker.cc
)
Added: branches/AFR/Engine/Control/RTRT_register.h
==============================================================================
--- (empty file)
+++ branches/AFR/Engine/Control/RTRT_register.h Thu Aug 25 17:26:23 2005
@@ -0,0 +1,42 @@
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005 Scientific Computing and Imaging Institute,
+ University of Utah.
+
+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef Manta_Engine_RTRT_register_h
+#define Manta_Engine_RTRT_register_h
+
+namespace Manta {
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Register all "known" components with the RTRTInterface.
+ // ImageTraversers, PixelSamplers, other command line args should be
added to
+ // the RTRT_register.cc file.
+ void registerKnownComponents(RTRTInterface* rtrt);
+};
+
+#endif
\ No newline at end of file
Modified: branches/AFR/Engine/Control/Worker.cc
==============================================================================
--- branches/AFR/Engine/Control/Worker.cc (original)
+++ branches/AFR/Engine/Control/Worker.cc Thu Aug 25 17:26:23 2005
@@ -1,6 +1,6 @@
#include <Engine/Control/Worker.h>
-#include <Engine/Control/RTRT.h>
+#include <Interface/RTRTInterface.h>
#include <sgi_stl_warnings_off.h>
#include <iostream>
#include <sgi_stl_warnings_on.h>
@@ -8,7 +8,7 @@
using namespace Manta;
using namespace std;
-Worker::Worker(RTRT* rtrt, int workerIndex, bool lateComerFlag)
+Worker::Worker(RTRTInterface* rtrt, int workerIndex, bool lateComerFlag)
: rtrt(rtrt), workerIndex(workerIndex), lateComerFlag(lateComerFlag)
{
}
Modified: branches/AFR/Engine/Control/Worker.h
==============================================================================
--- branches/AFR/Engine/Control/Worker.h (original)
+++ branches/AFR/Engine/Control/Worker.h Thu Aug 25 17:26:23 2005
@@ -5,16 +5,17 @@
#include <Core/Thread/Runnable.h>
namespace Manta {
- class RTRT;
+ class RTRTInterface;
class Worker : public SCIRun::Runnable {
public:
- Worker(RTRT* rtrt, int workerIndex, bool lateComerFlag);
+ Worker(RTRTInterface* rtrt, int workerIndex, bool lateComerFlag);
virtual ~Worker();
virtual void run();
- private:
- RTRT* rtrt;
+
+ private:
+ RTRTInterface* rtrt;
int workerIndex;
bool lateComerFlag;
};
Modified: branches/AFR/Interface/RTRTInterface.h
==============================================================================
--- branches/AFR/Interface/RTRTInterface.h (original)
+++ branches/AFR/Interface/RTRTInterface.h Thu Aug 25 17:26:23 2005
@@ -130,6 +130,7 @@
// Control
virtual void beginRendering(bool blockUntilFinished) = 0;
+
virtual void blockUntilFinished() = 0;
// Control
@@ -160,6 +161,9 @@
protected:
RTRTInterface();
+ friend class Worker;
+ virtual void internalRenderLoop(int workerIndex, bool
lateComerFlag) = 0;
+
private:
RTRTInterface(const RTRTInterface&);
RTRTInterface& operator=(const RTRTInterface&);
- [MANTA] r502 - in branches/AFR: Engine/Control Interface, abe, 08/25/2005
Archive powered by MHonArc 2.6.16.