Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r741 - in branches/itanium2: Core/Util Engine/Control Engine/Display Engine/ImageTraversers Engine/ImageTraversers/AFR Interface Model/Cameras StandAlone fox scenes


Chronological Thread 
  • From: abe@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r741 - in branches/itanium2: Core/Util Engine/Control Engine/Display Engine/ImageTraversers Engine/ImageTraversers/AFR Interface Model/Cameras StandAlone fox scenes
  • Date: Thu, 1 Dec 2005 01:30:46 -0700 (MST)

Author: abe
Date: Thu Dec  1 01:30:42 2005
New Revision: 741

Added:
   branches/itanium2/Core/Util/ThreadStorageAllocator.cc
   branches/itanium2/Core/Util/ThreadStorageAllocator.h
Removed:
   branches/itanium2/Engine/ImageTraversers/AFImageTraverser.cc
   branches/itanium2/Engine/ImageTraversers/AFImageTraverser.h
   branches/itanium2/Engine/ImageTraversers/AFR/
Modified:
   branches/itanium2/Engine/Control/RTRT.cc
   branches/itanium2/Engine/Control/RTRT.h
   branches/itanium2/Engine/Control/RTRT_register.cc
   branches/itanium2/Engine/Display/GLXImageDisplay.cc
   branches/itanium2/Engine/Display/GLXImageDisplay.h
   branches/itanium2/Engine/Display/XHelper.cc
   branches/itanium2/Engine/ImageTraversers/CMakeLists.txt
   branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc
   branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc
   branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h
   branches/itanium2/Interface/Context.h
   branches/itanium2/Interface/Fragment.h
   branches/itanium2/Interface/RTRTInterface.h
   branches/itanium2/Model/Cameras/StereoPinholeCamera.cc
   branches/itanium2/Model/Cameras/StereoPinholeCamera.h
   branches/itanium2/StandAlone/CMakeLists.txt
   branches/itanium2/StandAlone/frust-test.cc
   branches/itanium2/StandAlone/manta_tile_size.pl
   branches/itanium2/StandAlone/mf_stream_test.cc
   branches/itanium2/fox/FMantaStereo.cc
   branches/itanium2/fox/FMantaStereo.h
   branches/itanium2/fox/FMantaWindow.cc
   branches/itanium2/fox/FMantaWindow.h
   branches/itanium2/scenes/boeing777.cc
Log:



Added ability for components on the rendering stack to request thread local 
storage which is allocated by each thread instead of by the setup thread.
A    Core/Util/ThreadStorageAllocator.cc
A    Core/Util/ThreadStorageAllocator.h


M    scenes/boeing777.cc
M    StandAlone/mf_stream_test.cc
M    StandAlone/manta_tile_size.pl
M    StandAlone/frust-test.cc
M    StandAlone/CMakeLists.txt

Fixed exit behavior, added "Safe Exit" and "Fast Exit" menu options.
M    fox/FMantaWindow.cc
M    fox/FMantaWindow.h
M    fox/FMantaStereo.cc
M    fox/FMantaStereo.h

M    Interface/Fragment.h
M    Interface/Context.h
M    Interface/RTRTInterface.h

Hopefully fixed the stereo camera. Note that you have to use the -stereo 
command line option AND specify a "stereo" camera (and have stereo hardware). 
M    Model/Cameras/StereoPinholeCamera.h
M    Model/Cameras/StereoPinholeCamera.cc

M    Engine/Control/RTRT.cc
M    Engine/Control/RTRT.h
M    Engine/Control/RTRT_register.cc

M    Engine/ImageTraversers/TiledImageTraverser.cc
M    Engine/ImageTraversers/TiledImageTraverser.h
M    Engine/ImageTraversers/FramelessImageTraverser.cc

Removed AFR code since it has its own branch now
D    Engine/ImageTraversers/AFR
D    Engine/ImageTraversers/AFImageTraverser.cc
D    Engine/ImageTraversers/AFImageTraverser.h
M    Engine/ImageTraversers/CMakeLists.txt

Added fps output to glx image display
M    Engine/Display/XHelper.cc
M    Engine/Display/GLXImageDisplay.cc
M    Engine/Display/GLXImageDisplay.h



Added: branches/itanium2/Core/Util/ThreadStorageAllocator.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Core/Util/ThreadStorageAllocator.cc       Thu Dec  1 
01:30:42 2005
@@ -0,0 +1,75 @@
+/*
+  For more information, please see: http://software.sci.utah.edu

+  The MIT License

+  Copyright (c) 2005
+  Scientific Computing and Imaging Institute

+  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 <Core/Util/ThreadStorageAllocator.h>
+
+#include <malloc.h>
+
+using namespace Manta;
+
+ThreadStorageAllocator::ThreadStorageAllocator( int num_procs_ ) :
+  requested( 0 ),
+  num_procs( num_procs_ )
+{
+  // Pad the array up to a cache line.
+  size_t bytes = (num_procs_*sizeof(char *));
+  bytes = (bytes % 128) ? ((bytes/128)+1)*128 : bytes;
+  
+  // Allocate array of pointers.
+  storage = (char **)memalign( 128, bytes );
+
+  // Initialize all of the pointers to zero.
+  for (int i=0;i<num_procs;++i) {
+    storage[i] = 0;
+  }
+};
+
+ThreadStorageAllocator::~ThreadStorageAllocator() {
+
+  // Free the local memory for each thread.
+  for (int i=0;i<num_procs;++i) {
+    if (storage[i])
+      free( storage[i] );
+  }  
+  free( storage );
+}
+
+// Called by each thread to allocate its memory. Will reallocate if 
necessary.
+void ThreadStorageAllocator::allocateStorage( int proc ) {
+
+  // Delete the storage if it exists.
+  if (storage[proc])
+    free( storage[proc] );
+
+  // Allocate aligned storage.
+  storage[proc] = (char *)memalign( 128, requested );
+
+  if (storage[proc] == 0)
+    throw InternalError( "Could not allocate thread local memory", __FILE__, 
__LINE__ );
+}
+

Added: branches/itanium2/Core/Util/ThreadStorageAllocator.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Core/Util/ThreadStorageAllocator.h        Thu Dec  1 
01:30:42 2005
@@ -0,0 +1,117 @@
+/*
+  For more information, please see: http://software.sci.utah.edu

+  The MIT License

+  Copyright (c) 2005
+  Scientific Computing and Imaging Institute

+  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.
+*/
+
+// Abe Stephens
+
+#include <SCIRun/Core/Exceptions/InternalError.h>
+
+#include <vector>
+
+namespace Manta {
+
+  using SCIRun::InternalError;
+  using std::vector;
+  
+  ///////////////////////////////////////////////////////////////////////////
+  // Thread local storage allocation.
+  // Storage will be allocated after setupDisplayChannel but before the next
+  // call to setupFrame.
+  class ThreadStorageAllocator {
+  private:
+    // Actual storage.
+    char ** storage;
+    int     num_procs;
+
+    // Requested storage.
+    size_t requested;
+       
+  public:
+    
+    
///////////////////////////////////////////////////////////////////////////
+    // Token is returned by an allocation request.
+    class Token {
+      friend class ThreadStorageAllocator;
+    private:
+      size_t offset;
+
+    protected:
+      Token( size_t offset_ ) : offset( offset_ ) {  };
+    };    
+
+    
///////////////////////////////////////////////////////////////////////////
+    // Accessor provides access to the memory allocated for a specific 
request.
+    // Each request produces a token, which may be used to obtain an 
Accessor after
+    // the memory is allocated.
+    class Accessor {
+      friend class ThreadStorageAllocator;
+    private:
+      char *storage;
+    public:
+    protected:
+      Accessor( void *storage_ ) :
+        storage( static_cast<char *>( storage_ ) ) { };
+
+    public:
+      Accessor() { };
+    };
+
+    
///////////////////////////////////////////////////////////////////////////
+    // Constructor.
+    ThreadStorageAllocator( int num_procs_ );
+    ThreadStorageAllocator(  );
+    ~ThreadStorageAllocator();
+
+    Token requestStorage( size_t size, size_t aligned ) {
+
+      // Determine how many bytes needed.
+      size_t bytes = size;
+      
+      // Find the next aligned offset.
+      size_t offset = requested +
+        ((requested % aligned) ? ((requested/aligned)+1)*aligned : 0);
+
+      requested = offset + bytes;
+
+      return Token( offset );
+    }
+
+    // Obtain an accessor to the storage. This is only possible after it has 
been allocated.
+    template< typename StorageType >
+    StorageType getStorage( int proc, const Token &token ) {
+      if (storage[proc]) {
+        return static_cast<StorageType>(storage[proc]);
+      }
+      throw InternalError( "Attempt to access unallocated thread local 
storage.", __FILE__, __LINE__ );
+    }
+    
+    // Called by each thread to allocate its memory. Will reallocate if 
necessary.
+    void allocateStorage( int proc );
+
+  };
+};
+

Modified: branches/itanium2/Engine/Control/RTRT.cc
==============================================================================
--- branches/itanium2/Engine/Control/RTRT.cc    (original)
+++ branches/itanium2/Engine/Control/RTRT.cc    Thu Dec  1 01:30:42 2005
@@ -61,13 +61,14 @@
 }
 
 RTRT::RTRT()
-: runningLock("RTRT running mutex"),
-callbackLock("RTRT callback r/w lock"),
-barrier1("RTRT frame barrier #1"),
-barrier2("RTRT frame barrier #2"),
-barrier3("RTRT frame barrier #3"),
-transaction_lock("RTRT transaction lock"),
-ids("RTRT id counter", 1)
+  : runningLock("RTRT running mutex"),
+    callbackLock("RTRT callback r/w lock"),
+    barrier1("RTRT frame barrier #1"),
+    barrier2("RTRT frame barrier #2"),
+    barrier3("RTRT frame barrier #3"),
+    transaction_lock("RTRT transaction lock"),
+    ids("RTRT id counter", 1),
+    thread_storage( 0 )
 {
   workersWanted=0;
   workersRendering=0;
@@ -92,7 +93,7 @@
     Channel* channel = *iter;
     delete channel->display;
     for(vector<Image*>::iterator iter = channel->images.begin();
-                                iter != channel->images.end(); iter++)
+        iter != channel->images.end(); iter++)
       delete *iter;
   }
   delete currentImageTraverser;
@@ -103,7 +104,7 @@
 
 void RTRT::changeNumWorkers(int newNumWorkers)
 {
-  if(newNumWorkers <= 0)
+  if(newNumWorkers < 0)
     throw IllegalValue<int>("RTRT::changeNumWorkers, number of workers 
should be > 0", newNumWorkers);
 
   workersWanted=newNumWorkers;
@@ -121,19 +122,19 @@
   // What about adding callbacks during anim cycle?
 #endif
   callbackLock.writeLock();
-// #if NOTFINISHED
+  // #if NOTFINISHED
 
   if(whence == RTRTInterface::Relative) {
     frame += animFrameState.frameNumber;
        }
-// #endif
+  // #endif
 
   oneShots.insert(OneShotMapType::value_type(frame, callback));
   callbackLock.writeUnlock();
 }
 
 void RTRT::addParallelOneShotCallback(Whence whence, long frame,
-                              CallbackBase_2Data<int, int>* callback)
+                                      CallbackBase_2Data<int, int>* callback)
 {
   callbackLock.writeLock();
 
@@ -165,6 +166,13 @@
   callbackLock.writeUnlock();
 }
 
+void RTRT::registerTerminationCallback( CallbackBase_1Data< RTRTInterface *> 
*cb ) {
+  callbackLock.writeLock();
+  terminationCallbacks.push_back(cb);
+  callbackLock.writeUnlock();
+}
+
+
 void RTRT::setTimeMode(TimeMode /*tm*/, double /*rate*/)
 {
   NOT_FINISHED("RTRT::setTimeMode");
@@ -192,10 +200,10 @@
   check for existence of other components;
 #endif
 
-                if(workersWanted <= 0){
-                        runningLock.unlock();
-                        throw IllegalValue<int>("workersWanted should be 
positive", workersWanted);
-                }
+  if(workersWanted <= 0){
+    runningLock.unlock();
+    throw IllegalValue<int>("workersWanted should be positive", 
workersWanted);
+  }
 
   if(workersRendering != 0){
     runningLock.unlock();
@@ -212,14 +220,17 @@
       ostringstream name;
       name << "RTRT Worker " << i;
       Thread* t = new Thread(new Worker(this, i, false), name.str().c_str(),
-                                                                             
                                    0, Thread::NotActivated);
+                             0, Thread::NotActivated);
       t->setStackSize(RENDER_THREAD_STACKSIZE);
       t->activate(false);
       workers[i] = t;
     }
   }
+
+  // Block until finished is set while running in bin/manta
   if(blockUntilFinished)
     internalRenderLoop(0, false);
+
 }
 
 void RTRT::blockUntilFinished()
@@ -242,14 +253,14 @@
     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;
+      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
@@ -276,13 +287,13 @@
 
     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);
+        Channel* channel = channels[index];
+        RenderContext myContext(this, index, proc, workersAnimAndImage,
+                                &animFrameState,
+                                currentLoadBalancer, currentPixelSampler,
+                                currentRenderer, currentShadowAlgorithm,
+                                channel->camera, scene, thread_storage );
+        currentImageTraverser->setupFrame(myContext);
       }
     }
     //callbackLock.readUnlock();
@@ -297,29 +308,29 @@
       // in case it changes
       int newWorkers = workersWanted;
       if(newWorkers > workersRendering){
-                                // We must start new threads, if the number 
increased.  Mark
-                                // these threads as "latecomers", which will 
skip to the rendering
-                                // section of this loop for the first frame
-                                workersChanged = true;
-                                workers.resize(newWorkers);
-                                int oldworkers = workersRendering;
-                                workersRendering = workersWanted;
-                                for(int i=oldworkers;i<newWorkers;i++){
-                                        ostringstream name;
-                                        name << "RTRT Worker " << i;
-                                        workers[i] = new Thread(new 
Worker(this, i, true), name.str().c_str(),
-                                                                             
                                                           0, 
Thread::NotActivated);
-                                        
workers[i]->setStackSize(RENDER_THREAD_STACKSIZE);
-                                        workers[i]->activate(false);
-                                }
+        // We must start new threads, if the number increased.  Mark
+        // these threads as "latecomers", which will skip to the rendering
+        // section of this loop for the first frame
+        workersChanged = true;
+        workers.resize(newWorkers);
+        int oldworkers = workersRendering;
+        workersRendering = workersWanted;
+        for(int i=oldworkers;i<newWorkers;i++){
+          ostringstream name;
+          name << "RTRT Worker " << i;
+          workers[i] = new Thread(new Worker(this, i, true), 
name.str().c_str(),
+                                  0, Thread::NotActivated);
+          workers[i]->setStackSize(RENDER_THREAD_STACKSIZE);
+          workers[i]->activate(false);
+        }
       } else if(newWorkers < workersRendering) {
-                                workersChanged = true;
-                                workersRendering = workersWanted;
+        workersChanged = true;
+        workersRendering = workersWanted;
       } else {
-                                // Don't set it to false if it is already 
false - avoids
-                                // flushing the other caches
-                                if(workersChanged)
-                                        workersChanged = false;
+        // Don't set it to false if it is already false - avoids
+        // flushing the other caches
+        if(workersChanged)
+          workersChanged = false;
       }
     }
 
@@ -333,17 +344,17 @@
       barrier2.wait(numProcs);
       changed=false;
       for(int i=0;i<numProcs;i++){
-                                if(changedFlags[i].changed){
-                                        changed=true;
-                                        break;
-                                }
+        if(changedFlags[i].changed){
+          changed=true;
+          break;
+        }
       }
 
       if(changed != lastChanged || firstFrame){
         if(proc == 0)
           doIdleModeCallbacks(changed, firstFrame, pipelineNeedsSetup,
                               proc, numProcs);
-                                barrier2.wait(numProcs);
+        barrier2.wait(numProcs);
         lastChanged = changed;
       }
       if(firstFrame)
@@ -351,95 +362,116 @@
 
       // P0 process deletions
       if(proc == 0){
-                                //callbackLock.readLock();
-                                processDeletions();
-                                //callbackLock.readUnlock();
+        //callbackLock.readLock();
+        processDeletions();
+        //callbackLock.readUnlock();
       }
 
       if(pipelineNeedsSetup){
-                                // Negotiate the image pipeline for each 
channel
-                                if(proc == 0){
-                                        setupPipelines(numProcs);
-                                        
resizeImages(renderFrameState.frameNumber);
-                                }
-                                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);
-                                }
-                                barrier3.wait(numProcs);
-                                pipelineNeedsSetup = false;
+
+        // Negotiate the image pipeline for each channel
+        if(proc == 0){
+          setupPipelines(numProcs);
+          resizeImages(renderFrameState.frameNumber);
+        }
+
+        // Wait for processor zero to setup the image pipeline
+        barrier3.wait(numProcs);
+
+        // Allocate thread local storage for each thread.
+        thread_storage->allocateStorage( proc );
+        
+        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,
+                                  thread_storage );
+
+          currentImageTraverser->setupFrame(myContext);
+        }
+        barrier3.wait(numProcs);
+        pipelineNeedsSetup = false;
       }
 
       // Image display, if image is valid
       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);
-                                }
+          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);
+        }
       }
 
       // Possibly change # of workers
       if(proc == 0 && workersRendering < numProcs){
-                                for(int i = workersRendering; i<numProcs; 
i++){
-                                        // Clean up after worker.  Don't 
attempt to join with self
-                                        if(i != 0)
-                                                workers[i]->join();
-                                }
-                                workers.resize(workersRendering == 
0?1:workersRendering);
+        for(int i = workersRendering; i<numProcs; i++){
+          // Clean up after worker.  Don't attempt to join with self
+          if(i != 0)
+            workers[i]->join();
+        }
+        workers.resize(workersRendering == 0?1:workersRendering);
+      }
+      
+      if(proc >= workersRendering) {
+
+        // If proc 0 is exiting invoke the termination callbacks.
+        if (proc == 0) {
+          doTerminationCallbacks();
+        }
+        
+        break;
       }
-      if(proc >= workersRendering)
-                                break;
     }
-skipToRendering:
-                        // Pre-render callbacks
-                        //callbackLock.readLock();
-                        doParallelPreRenderCallbacks(proc, workersRendering);
+  skipToRendering:
+    // Pre-render callbacks
+    //callbackLock.readLock();
+    doParallelPreRenderCallbacks(proc, workersRendering);
     doSerialPreRenderCallbacks(proc, workersRendering);
     //callbackLock.readUnlock();
 
     if(workersChanged){
       barrier3.wait(workersRendering);
       if(proc == 0)
-                                changedFlags.resize(workersRendering);
+        changedFlags.resize(workersRendering);
     }
 
-#if NOTFINISHED
+    // #if NOTFINISHED
     //if(!idle){
-#endif
+    // #endif
     {
       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);
-                                
currentImageTraverser->renderImage(myContext, image);
+        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, thread_storage );
+        currentImageTraverser->renderImage(myContext, image);
       }
     }
-#if NOTFINISHED
-                how to set rendering complete flag?;
-    } else {
-      //callbackLock.readLock();
-      idle callbacks;
-      //callbackLock.readUnlock();
-    }
-#endif
+    // #if NOTFINISHED
+    //    how to set rendering complete flag?;
+    //  } else {
+    //callbackLock.readLock();
+    //    idle callbacks;
+    //callbackLock.readUnlock();
+    //  }
+    //#endif
   }
 }
 
 void RTRT::doParallelAnimationCallbacks(bool& changed, int proc, int 
numProcs) {
-
+  
   // Parallel one shot callbacks.
   ParallelOneShotMapType::iterator iter = parallelOneShots.begin();
   while(iter != parallelOneShots.end() && iter->first < 
animFrameState.frameNumber){
@@ -478,25 +510,37 @@
     (*iter)->call(proc, numProcs, changed);
 }
 
+void RTRT::doTerminationCallbacks() {
+
+  // All threads have terminated.
+  TCallbackMapType::iterator iter = terminationCallbacks.begin();
+  while (iter != terminationCallbacks.end()) {
+
+    // Invoke the callback and pass in the RTRTInterface.
+    (*iter)->call( this );
+    ++iter;
+  }
+}
+
 void RTRT::postTransactions(bool& changed)
 {
   if(transactions.size() > 0){
     transaction_lock.lock();
     changed = true;
     for(TransactionListType::iterator iter = transactions.begin();
-                                iter != transactions.end(); iter++){
+        iter != transactions.end(); iter++){
       TransactionBase* transaction = *iter;
       if(verbose_transactions){
-                                cerr << "Apply transaction: " << 
transaction->getName() << " : ";
-                                transaction->printValue(cerr);
-                                cerr << " : ";
-                                transaction->printOp(cerr);
-                                cerr << " : ";
+        cerr << "Apply transaction: " << transaction->getName() << " : ";
+        transaction->printValue(cerr);
+        cerr << " : ";
+        transaction->printOp(cerr);
+        cerr << " : ";
       }
       transaction->apply();
       if(verbose_transactions){
-                                transaction->printValue(cerr);
-                                cerr << '\n';
+        transaction->printValue(cerr);
+        cerr << '\n';
       }
       delete transaction;
     }
@@ -560,16 +604,16 @@
   string name;
   vector<string> args;
 
-        // Parse the arg string.
+  // Parse the arg string.
   parseSpec(spec, name, args);
 
-        // Search for an image display with the name.
+  // Search for an image display with the name.
   ImageDisplayMapType::iterator iter = imageDisplays.find(name);
   if(iter == imageDisplays.end())
     return 0;
 
-        // Create the channel with the image display.
-        return createChannel( (*iter->second)(args), camera, stereo, xres, 
yres );
+  // Create the channel with the image display.
+  return createChannel( (*iter->second)(args), camera, stereo, xres, yres );
 }
 
 int RTRT::createChannel(ImageDisplay *image_display, Camera* camera, bool 
stereo, int xres, int yres)
@@ -588,14 +632,14 @@
   channel->images.resize(channel->pipelineDepth);
   channel->camera = camera;
 
-        // Setup images for pipeline.
+  // Setup images for pipeline.
   for(int i=0;i<channel->pipelineDepth;i++)
     channel->images[i] = 0;
 
-        pipelineNeedsSetup = true;
+  pipelineNeedsSetup = true;
 
-        // Add the channel to the renderer.
-        channels.push_back(channel);
+  // Add the channel to the renderer.
+  channels.push_back(channel);
   return channel->id;
 }
 
@@ -623,7 +667,7 @@
 
 void RTRT::setCamera(int channel, Camera *camera ) {
 
-        channels[channel]->camera = camera;
+  channels[channel]->camera = camera;
 }
 
 void RTRT::getResolution(int channel, bool& stereo, int& xres, int& yres)
@@ -644,53 +688,61 @@
 
 void RTRT::setupPipelines(int numProcs)
 {
-        // Total number of channels.
+  // Total number of channels.
   int numChannels = static_cast<int>(channels.size());
 
-        // Create a setup context.
-        SetupContext globalcontext(this, numChannels, 0, numProcs,
+  // Create a setup context.
+  SetupContext globalcontext(this, numChannels, 0, numProcs,
                              currentLoadBalancer, currentPixelSampler,
                              currentRenderer);
 
-        // Setup the image traverser.
+  // Setup the image traverser.
   currentImageTraverser->setupBegin(globalcontext, numChannels);
 
-        // Proceess setup callbacks.
+  // Proceess setup callbacks.
   for(vector<SetupCallback*>::iterator iter = setupCallbacks.begin(); iter 
!= setupCallbacks.end(); iter++)
-                (*iter)->setupBegin(globalcontext, numChannels);
+    (*iter)->setupBegin(globalcontext, numChannels);
 
-        // Setup each channel.
+  // Allocate/resize per thread local storage.
+  if (thread_storage != 0)
+    delete thread_storage;
+  thread_storage = new ThreadStorageAllocator( numProcs );
+  
+  // Setup each channel.
   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);
+                         currentLoadBalancer,
+                         currentPixelSampler,
+                         currentRenderer,
+                         thread_storage );
 
-                // Setup the channel iteratively, until context.isChanged() 
is false.
+    // Setup the channel iteratively, until context.isChanged() is false.
     int iteration = 100;
+
     do {
       context.setChanged(false);
       context.clearMasterWindow();
 
-                        // Call setup callbacks.
+      // Call setup callbacks.
       for(vector<SetupCallback*>::iterator iter = setupCallbacks.begin(); 
iter != setupCallbacks.end(); iter++)
-                                (*iter)->setupDisplayChannel(context);
+        (*iter)->setupDisplayChannel(context);
 
-                        // Setup the image display.
+      // Setup the image display.
       channel->display->setupDisplayChannel(context);
 
-                        // Setup the image traverser.
+      // Setup the image traverser.
       currentImageTraverser->setupDisplayChannel(context);
 
     } while(context.isChanged() && --iteration > 0);
 
-                // Check to for errors.
+    // Check to for errors.
     if(!iteration)
       throw InternalError("Pipeline/resolution negotiation failed", 
__FILE__, __LINE__ );
     context.getResolution(channel->stereo, channel->xres, channel->yres);
 
-                if(channel->xres <= 0)
+    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);
@@ -701,19 +753,19 @@
     if(depth == 1 && context.getMaxDepth() > 1)
       depth = 2; // Prefer double-buffering
 
-                //cerr << "RTRT::setupPipelines:: depth = "<< depth << "\n";
+    //cerr << "RTRT::setupPipelines:: depth = "<< depth << "\n";
 
-                // Set the pipeline depth.
-                channel->pipelineDepth = depth;
+    // Set the pipeline depth.
+    channel->pipelineDepth = depth;
     unsigned long osize = channel->images.size();
     for(unsigned long i=depth;i<osize;i++)
       delete channel->images[i];
 
-                // Zero pointers to images.
+    // Zero pointers to images.
     for(unsigned long i=osize;i<static_cast<unsigned long>(depth);i++)
       channel->images[i]=0;
 
-                // Specify the number of frames needed for the entire 
pipeline.
+    // Specify the number of frames needed for the entire pipeline.
     channel->images.resize(depth);
   }
 }
@@ -734,10 +786,10 @@
     if(!channel->images[which] || channel->stereo != stereo
        || channel->xres != xres || channel->yres != yres){
       if(channel->images[which])
-                                delete channel->images[which];
+        delete channel->images[which];
       ImageCreator creator = channel->imageCreator;
       if(!creator)
-                                creator = currentImageCreator;
+        creator = currentImageCreator;
       channel->images[which] = (creator)(currentImageCreatorArgs,
                                          channel->stereo,
                                          channel->xres, channel->yres);
@@ -842,7 +894,7 @@
 }
 
 void RTRT::setPixelSampler( PixelSampler *sampler_ ) {
-        currentPixelSampler = sampler_;
+  currentPixelSampler = sampler_;
 }
 
 bool RTRT::selectPixelSampler(const string& spec)
@@ -854,7 +906,7 @@
   if(iter == pixelSamplers.end())
     return false;
   currentPixelSampler = (*iter->second)(args);
-        pipelineNeedsSetup = true;
+  pipelineNeedsSetup = true;
   return true;
 }
 
@@ -1003,7 +1055,7 @@
 
 Scene *RTRT::getScene() {
 
-        return scene;
+  return scene;
 }
 
 bool RTRT::readScene(const string& spec)
@@ -1084,7 +1136,7 @@
 }
 
 Scene* RTRT::readMOScene(const string& name, const vector<string>& args,
-                                                                             
                    bool printErrors)
+                         bool printErrors)
 {
   vector<string> dirs = split_string(scenePath, ':');
   for(vector<string>::iterator dir = dirs.begin(); dir != dirs.end(); dir++){
@@ -1092,22 +1144,22 @@
     struct stat statbuf;
     if(stat(fullname.c_str(), &statbuf) != 0){
       if(printErrors){
-                                cerr << "Error reading " << fullname << ": " 
<< strerror(errno) << '\n';
+        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';
+        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";
+        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
@@ -1120,7 +1172,7 @@
     Scene* scene=(*make_scene)(context, args);
     if(!scene){
       if(printErrors)
-                                cerr << "scene " << name << " did not 
produce a scene\n";
+        cerr << "scene " << name << " did not produce a scene\n";
       return 0;
     }
     return scene;
@@ -1193,37 +1245,37 @@
 
 void RTRT::shootOneRay( Color &result_color, RayPacket &result_rays, Real 
image_x, Real image_y, int channel_index ) {
 
-        // Only shoot one ray.
-        result_rays.resize( 1 );
+  // Only shoot one ray.
+  result_rays.resize( 1 );
 
-        // Set the image space coordinates of the pixel.
-        result_rays.setPixel(0, 0, image_x, image_y, &result_color );
-        result_rays.setFlag ( RayPacket::HaveImageCoordinates );
+  // Set the image space coordinates of the pixel.
+  result_rays.setPixel(0, 0, image_x, image_y, &result_color );
+  result_rays.setFlag ( RayPacket::HaveImageCoordinates );
 
-        // Get a pointer to the channel.
-        Channel *channel = channels[ channel_index ];
+  // Get a pointer to the channel.
+  Channel *channel = channels[ channel_index ];
 
-        // Create a render context.
-        RenderContext render_context(this, channel_index, workersRendering, 
workersRendering+1, 0,
-                                                                             
                                currentLoadBalancer, currentPixelSampler,
-                                                                             
                                            currentRenderer, 
currentShadowAlgorithm,
-                                                                             
                                            channel->camera, scene );
+  // Create a render context.
+  RenderContext render_context(this, channel_index, workersRendering, 0, 0,
+                               currentLoadBalancer, currentPixelSampler,
+                               currentRenderer, currentShadowAlgorithm,
+                               channel->camera, scene, thread_storage );
 
-        // Send this to the renderer.
-        currentRenderer->traceEyeRays( render_context, result_rays );
+  // Send this to the renderer.
+  currentRenderer->traceEyeRays( render_context, result_rays );
 
-        // Check to see if the ray hit anything.
-        if (result_rays.hitInfo(0).wasHit()) {
+  // Check to see if the ray hit anything.
+  if (result_rays.hitInfo(0).wasHit()) {
 
-                // Compute hit positions.
-                result_rays.computeHitPositions();
+    // Compute hit positions.
+    result_rays.computeHitPositions();
 
-                // Compute the normal.
-                result_rays.computeNormals( render_context );
+    // Compute the normal.
+    result_rays.computeNormals( render_context );
 
-                // Shade.
-                result_rays.hitInfo(0).hitMaterial()->shade( render_context, 
result_rays );
-        }
+    // Shade.
+    result_rays.hitInfo(0).hitMaterial()->shade( render_context, result_rays 
);
+  }
 }
 
 

Modified: branches/itanium2/Engine/Control/RTRT.h
==============================================================================
--- branches/itanium2/Engine/Control/RTRT.h     (original)
+++ branches/itanium2/Engine/Control/RTRT.h     Thu Dec  1 01:30:42 2005
@@ -10,6 +10,7 @@
 #include <Core/Thread/CrowdMonitor.h>
 #include <Core/Thread/Mutex.h>
 #include <Core/Thread/Semaphore.h>
+#include <Core/Util/ThreadStorageAllocator.h>
 #include <map>
 #include <set>
 #include <vector>
@@ -111,6 +112,7 @@
     virtual void registerSetupCallback(SetupCallback*);
     virtual void registerSerialAnimationCallback(CallbackBase_3Data<int, 
int, bool&>*);
     virtual void registerParallelAnimationCallback(CallbackBase_3Data<int, 
int, bool&>*);
+    virtual void registerTerminationCallback( CallbackBase_1Data< 
RTRTInterface *> *);
 
     // Control of time/animation
     virtual void setTimeMode(TimeMode tm, double rate);
@@ -164,7 +166,8 @@
     void doIdleModeCallbacks(bool changed, bool firstFrame,
                              bool& pipelineNeedsSetup,
                              int proc, int numProcs);
-
+    void doTerminationCallbacks();
+    
     void resizeImages(long frameNumber);
     void setupPipelines(int numProcs);
     TValue<int> workersWanted;
@@ -202,6 +205,10 @@
     ACallbackMapType serialAnimationCallbacks;
     vector<SetupCallback*> setupCallbacks;
 
+    typedef vector<CallbackBase_1Data<RTRTInterface *>*> TCallbackMapType;
+    TCallbackMapType terminationCallbacks;
+    
+
     // Transactions
     typedef vector<TransactionBase*> TransactionListType;
     TransactionListType transactions;
@@ -280,6 +287,9 @@
     typedef vector<Channel*> ChannelListType;
     ChannelListType channels;
 
+    // Thread local storage allocator.
+    ThreadStorageAllocator *thread_storage;
+    
     Scene* scene;
     string scenePath;
 

Modified: branches/itanium2/Engine/Control/RTRT_register.cc
==============================================================================
--- branches/itanium2/Engine/Control/RTRT_register.cc   (original)
+++ branches/itanium2/Engine/Control/RTRT_register.cc   Thu Dec  1 01:30:42 
2005
@@ -6,8 +6,7 @@
 #include <Engine/IdleModes/ZoomIdleMode.h>
 #include <Engine/ImageTraversers/NullImageTraverser.h>
 #include <Engine/ImageTraversers/TiledImageTraverser.h>
-#include <Engine/ImageTraversers/FramelessImageTraverser.h>
-#include <Engine/ImageTraversers/AFImageTraverser.h>
+// #include <Engine/ImageTraversers/FramelessImageTraverser.h>
 #include <Engine/ImageTraversers/DissolveImageTraverser.h>
 #include <Engine/ImageTraversers/DissolveTiledImageTraverser.h>
 #include <Engine/LoadBalancers/CyclicLoadBalancer.h>
@@ -60,8 +59,8 @@
     // Register image traversers
     rtrt->registerComponent("null", &NullImageTraverser::create);
     rtrt->registerComponent("tiled", &TiledImageTraverser::create);
-    rtrt->registerComponent("frameless", &FramelessImageTraverser::create);
-    rtrt->registerComponent("afr", &AFImageTraverser::create);
+    // rtrt->registerComponent("frameless", 
&FramelessImageTraverser::create);
+    // rtrt->registerComponent("afr", &AFImageTraverser::create);
     rtrt->registerComponent("dissolve", &DissolveImageTraverser::create);
     rtrt->registerComponent("dissolvetiled", 
&DissolveTiledImageTraverser::create);
 

Modified: branches/itanium2/Engine/Display/GLXImageDisplay.cc
==============================================================================
--- branches/itanium2/Engine/Display/GLXImageDisplay.cc (original)
+++ branches/itanium2/Engine/Display/GLXImageDisplay.cc Thu Dec  1 01:30:42 
2005
@@ -9,6 +9,7 @@
 #include <Image/Pixel.h>
 #include <Interface/Image.h>
 #include <Interface/Context.h>
+#include <Engine/Display/XHelper.h>
 
 #include <iostream>
 #include <vector>
@@ -118,6 +119,22 @@
        
        // Copy out the manta channel.
        manta_channel = context.channelIndex;
+
+  // Get the fonts.  You need to call this with a current GL context.
+  if (!(font_info = XHelper::getX11Font( x_display )))
+    throw new InternalError("getX11Font failed!\n", __FILE__, __LINE__ );
+
+  if (!(fontbase = XHelper::getGLFont(font_info))) 
+    throw new InternalError("getGLFont failed!\n", __FILE__, __LINE__ );
+
+  // Setup opengl.
+  glDisable( GL_DEPTH_TEST );
+  
+  // Clear the screen.
+  glClearColor(.05, .1, .2, 0);
+  glClear(GL_COLOR_BUFFER_BIT);
+  glXSwapBuffers( x_display, glx_drawable );
+  glFinish();
 }
 
 void GLXImageDisplay::displayImage( const DisplayContext &context, const 
Image* image ) {
@@ -225,6 +242,9 @@
                        }
                } 
 
+    // Output fps.
+    // display_frame_rate( 1.0 );
+    
                // Swap buffers.
                glXSwapBuffers( x_display, glx_drawable );
                
@@ -236,3 +256,25 @@
        }
 }
 
+void GLXImageDisplay::display_frame_rate(double framerate) {
+
+  // Display textual information on the screen:
+  char buf[200];
+  if (framerate > 1)
+    sprintf( buf, "%3.1lf fps", framerate);
+  else
+    sprintf( buf, "%2.2lf fps - %3.1lf spf", framerate , 1.0f/framerate);
+
+  // Figure out how wide the string is
+  int width = XHelper::calc_width(font_info, buf);
+
+  // Now we want to draw a gray box beneth the font using blending. :)
+  glRasterPos2i(0,0);
+  glEnable(GL_BLEND);
+  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+  glColor4f(0.5,0.5,0.5,0.5);
+  glRecti(8,3-font_info->descent-2,12+width,font_info->ascent+3);
+  glDisable(GL_BLEND);
+
+  XHelper::printString(fontbase, 10, 3, buf, RGBColor(1,1,1));
+}

Modified: branches/itanium2/Engine/Display/GLXImageDisplay.h
==============================================================================
--- branches/itanium2/Engine/Display/GLXImageDisplay.h  (original)
+++ branches/itanium2/Engine/Display/GLXImageDisplay.h  Thu Dec  1 01:30:42 
2005
@@ -21,11 +21,16 @@
                Display     *x_display;
                XVisualInfo *x_visual_info;
 
+    // Font info
+    XFontStruct* font_info;
+    GLuint fontbase;
+    
     bool use_stereo;   // Setup parameter used when creating the visual
                int manta_channel; // The last channel number to call 
setupDisplayChannel.
 
     static void createVisual( bool stereo_ );
-
+    void display_frame_rate(double framerate);
+    
        public:
                // Note that the GLXImage display must be passed a GLX 
context by the
                // application it is embedded inside of.

Modified: branches/itanium2/Engine/Display/XHelper.cc
==============================================================================
--- branches/itanium2/Engine/Display/XHelper.cc (original)
+++ branches/itanium2/Engine/Display/XHelper.cc Thu Dec  1 01:30:42 2005
@@ -16,8 +16,8 @@
 XFontStruct* XHelper::getX11Font(Display* dpy,
                                  const char* fontstring) {
   // Should we lock X?
-  cerr << "XHelper::getX11Font: Trying to load in font:\n"
-       << fontstring << "\n";
+  // cerr << "XHelper::getX11Font: Trying to load in font:\n"
+  //    << fontstring << "\n";
   return XLoadQueryFont(dpy, fontstring);
 }
 

Modified: branches/itanium2/Engine/ImageTraversers/CMakeLists.txt
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/CMakeLists.txt     (original)
+++ branches/itanium2/Engine/ImageTraversers/CMakeLists.txt     Thu Dec  1 
01:30:42 2005
@@ -4,18 +4,10 @@
      ImageTraversers/NullImageTraverser.cc
      ImageTraversers/TiledImageTraverser.h
      ImageTraversers/TiledImageTraverser.cc
-     ImageTraversers/FramelessImageTraverser.h
-     ImageTraversers/FramelessImageTraverser.cc
+     # ImageTraversers/FramelessImageTraverser.h
+     # ImageTraversers/FramelessImageTraverser.cc
      ImageTraversers/DissolveImageTraverser.h
      ImageTraversers/DissolveImageTraverser.cc
      ImageTraversers/DissolveTiledImageTraverser.h
      ImageTraversers/DissolveTiledImageTraverser.cc
-     ImageTraversers/AFImageTraverser.h
-     ImageTraversers/AFImageTraverser.cc
-     ImageTraversers/AFR/stats.h
-     ImageTraversers/AFR/stats.cc
-     ImageTraversers/AFR/tiles.h
-     ImageTraversers/AFR/tiles.cc
-     ImageTraversers/AFR/kdtree.h
-     ImageTraversers/AFR/kdtree.cc
      )

Modified: branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc 
(original)
+++ branches/itanium2/Engine/ImageTraversers/FramelessImageTraverser.cc Thu 
Dec  1 01:30:42 2005
@@ -219,27 +219,66 @@
   bool stereo;
   int xres, yres;
   image->getResolution(stereo, xres, yres);
-  int s,e;
+  
   // this is what every thread does: gets the next assignment and render it.
+  int s,e;
   while(context.loadBalancer->getNextAssignment(context, s, e)) {
+
     for(int assignment = s; assignment < e; assignment++) {
       int size = 8;
+
       Fragment fragment;
-      fragment.createRandom(size, shuffledTiles[assignment].xstart,
+
+      // Set size and flags.
+      fragment.setSize ( size );
+      fragment.setFlags( Fragment::ConstantEye );
+
+
+fragment.createRandom(size, shuffledTiles[assignment].xstart,
                             shuffledTiles[assignment].ystart,
                             shuffledTiles[assignment].xend,
                             shuffledTiles[assignment].yend, 
                             0, myRandomNumber[context.proc]);
+      
+      // Set individual pixel locations.
+      for (int i=0;i<size;++i) {
+
+        int x = (int)(xstart+myRandomNumber[context.proc].genfrand()*(xend - 
xstart));
+        int y = (int)(ystart+myRandomNumber[context.proc].genfrand()*(yend - 
ystart));
+
+        if (x >= xend) x = (xend - 1);
+        if (y >= yend) y = (yend - 1);        
+      }
+
+      // Render the fragment.
       renderFragment(context, fragment, xres, yres);
-      /*for(int i = 0; i < fragment.getSize(); i++) {
-        Fragment::Element& e = fragment.get(i);
-        //printf("%d,%d\n", e.x, e.y);
-        float val = ((float)e.x/xres)*((float)e.y/yres);
-        e.color = Color(GrayColor(val));
-        }*/
+
       image->set(fragment);
     }
   }
   if(context.proc == 0)
     image->setValid(true);
 }
+
+// This code was moved over from Fragment where it really didn't belong.
+void createRandom( Fragment &fragment,
+                   int size,
+                   int xstart, int ystart,
+                   int xend,   int yend, int which_eye, 
+                   MT_RNG &myRandomNumber)
+{
+  size = numElements;
+  flags = ConstantEye;
+
+  int 
+  
+  for(int i=0;i<size;i++) {
+    data[i].x = (int)(xstart+myRandomNumber.genfrand()*(xend - xstart));
+    data[i].y = (int)(ystart+myRandomNumber.genfrand()*(yend - ystart));
+    
+
+    
+    data[i].which_eye = which_eye;
+  }
+}
+

Modified: branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc     
(original)
+++ branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.cc     Thu 
Dec  1 01:30:42 2005
@@ -26,7 +26,7 @@
     string arg = args[i];
     if(arg == "-tilesize"){
       if(!getResolutionArg(i, args, xtilesize, ytilesize))
-       throw IllegalArgument("TiledImageTraverser -tilesize", i, args);
+        throw IllegalArgument("TiledImageTraverser -tilesize", i, args);
     } else {
       throw IllegalArgument("TiledImageTraverser", i, args);
     }
@@ -45,13 +45,20 @@
 
 void TiledImageTraverser::setupDisplayChannel(SetupContext& context)
 {
+  // Determine the resolution.
   bool stereo;
   int xres, yres;
   context.getResolution(stereo, xres, yres);
-  int xtiles = (xres + xtilesize-1)/xtilesize;
-  int ytiles = (yres + ytilesize-1)/ytilesize;
+
+  // Determine how many tiles are needed.
+  xtiles = (xres + xtilesize-1)/xtilesize;
+  ytiles = (yres + ytilesize-1)/ytilesize;
+
+  // Tell the load balancer how much work to assign.
   int numAssignments = xtiles * ytiles;
   context.loadBalancer->setupDisplayChannel(context, numAssignments);
+
+  // Continue setting up the rendering stack.
   context.pixelSampler->setupDisplayChannel(context);
 }
 
@@ -63,35 +70,47 @@
 
 void TiledImageTraverser::renderImage(const RenderContext& context, Image* 
image)
 {
+
+  // Determine number of tiles.
   bool stereo;
   int xres, yres;
   image->getResolution(stereo, xres, yres);
-  int ytiles = (yres + ytilesize-1)/ytilesize;
+  
   int s,e;
   while(context.loadBalancer->getNextAssignment(context, s, e)){
+
     for(int assignment = s; assignment < e; assignment++){
+      
       int xtile = assignment/ytiles;
       int ytile = assignment%ytiles;
       int xstart = xtile * xtilesize;
       int xend = (xtile+1) * xtilesize;
+
       if(xend > xres)
-       xend = xres;
+        xend = xres;
+
       int ystart = ytile * ytilesize;
       int yend = (ytile+1) * ytilesize;
+
       if(yend > yres)
-       yend = yres;
+        yend = yres;
+      
       for(int y = ystart; y<yend; y++){
-       for(int x = xstart; x<xend; x+= Fragment::MaxFragmentSize){
-         // Create a Fragment that is consecutive in X pixels
-         Fragment frag(0, x, xend, y);
-         context.pixelSampler->renderFragment(context, frag);
-         image->set(frag);
-         if(stereo){
-           Fragment frag(1, x, xend, y);
-           context.pixelSampler->renderFragment(context, frag);
-           image->set(frag);
-         }
-       }
+        for(int x = xstart; x<xend; x+= Fragment::MaxFragmentSize){
+
+          // Create a Fragment that is consecutive in X pixels
+          Fragment frag(0, x, xend, y);
+          context.pixelSampler->renderFragment(context, frag);
+          image->set(frag);
+
+          // Check to see if we need to render another copy in setero.
+          if(stereo){
+            Fragment frag(1, x, xend, y);
+            context.pixelSampler->renderFragment(context, frag);
+            image->set(frag);
+          }
+
+        }
       }
     }
   }

Modified: branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h
==============================================================================
--- branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h      
(original)
+++ branches/itanium2/Engine/ImageTraversers/TiledImageTraverser.h      Thu 
Dec  1 01:30:42 2005
@@ -26,6 +26,9 @@
 
     int xtilesize;
     int ytilesize;
+
+    int xtiles;
+    int ytiles;
   };
 }
 

Modified: branches/itanium2/Interface/Context.h
==============================================================================
--- branches/itanium2/Interface/Context.h       (original)
+++ branches/itanium2/Interface/Context.h       Thu Dec  1 01:30:42 2005
@@ -14,45 +14,57 @@
   class Scene;
   class ShadowAlgorithm;
   class XWindow;
-
+  class ThreadStorageAllocator;
+  
   class ReadContext {
   public:
     ReadContext(RTRTInterface* rtrt_int)
       : rtrt_int(rtrt_int)
     {
     }
-    RTRTInterface* rtrt_int;
+    mutable RTRTInterface* rtrt_int;
 
   private:
     ReadContext(const ReadContext&);
     ReadContext& operator=(const ReadContext&);
   };
 
+
+
+  
+  
/////////////////////////////////////////////////////////////////////////////
+  // Setup context is used to configure rendering stack components.
+
+
+
   class SetupContext {
   public:
     SetupContext(RTRTInterface* rtrt_int,
                  int channelIndex, int numChannels, int proc, int numProcs,
-                bool stereo, int xres, int yres,
-                LoadBalancer* loadBalancer,  PixelSampler* pixelSampler,
-                Renderer* renderer)
+                 bool stereo, int xres, int yres,
+                 LoadBalancer* loadBalancer,  PixelSampler* pixelSampler,
+                 Renderer* renderer,
+                 ThreadStorageAllocator *storage_allocator_ )
+      
       : rtrt_int(rtrt_int),
         channelIndex(channelIndex), numChannels(numChannels),
         proc(proc), numProcs(numProcs),
-       loadBalancer(loadBalancer), pixelSampler(pixelSampler),
-       renderer(renderer),
-       stereo(stereo), xres(xres), yres(yres)
+        loadBalancer(loadBalancer), pixelSampler(pixelSampler),
+        renderer(renderer),
+        stereo(stereo), xres(xres), yres(yres),
+        storage_allocator( storage_allocator_ )
     {
       init();
     }
     SetupContext(RTRTInterface* rtrt_int, int numChannels,
                  int proc, int numProcs,
-                LoadBalancer* loadBalancer,  PixelSampler* pixelSampler,
-                Renderer* renderer)
+                 LoadBalancer* loadBalancer,  PixelSampler* pixelSampler,
+                 Renderer* renderer)
       : rtrt_int(rtrt_int), channelIndex(-1), numChannels(numChannels),
         proc(proc), numProcs(numProcs),
-       loadBalancer(loadBalancer), pixelSampler(pixelSampler),
-       renderer(renderer),
-       stereo(false), xres(-1), yres(-1)
+        loadBalancer(loadBalancer), pixelSampler(pixelSampler),
+        renderer(renderer),
+        stereo(false), xres(-1), yres(-1)
     {
       init();
     }
@@ -71,14 +83,16 @@
     LoadBalancer* loadBalancer;
     PixelSampler* pixelSampler;
     Renderer* renderer;
+    
+    ThreadStorageAllocator *storage_allocator;
     mutable XWindow* masterWindow;
 
     void changeResolution(bool new_stereo, int new_xres, int new_yres) {
       if(new_stereo != stereo || new_xres != xres || new_yres != yres){
-       stereo = new_stereo;
-       xres = new_xres;
-       yres = new_yres;
-       changed=true;
+        stereo = new_stereo;
+        xres = new_xres;
+        yres = new_yres;
+        changed=true;
       }
     }
     void getResolution(bool& out_stereo, int& out_xres, int& out_yres) const 
{
@@ -89,9 +103,9 @@
 
     void constrainPipelineDepth(int newmin, int newmax) {
       if(newmin > minPipelineDepth)
-       minPipelineDepth = newmin;
+        minPipelineDepth = newmin;
       if(newmax < maxPipelineDepth)
-       maxPipelineDepth = newmax;
+        maxPipelineDepth = newmax;
     }
     int getMinDepth() const {
       return minPipelineDepth;
@@ -118,6 +132,7 @@
     bool getMultipleGLWindows() {
       return multipleGLWindows;
     }
+
   private:
     SetupContext(const SetupContext&);
     SetupContext& operator=(const SetupContext&);
@@ -145,16 +160,18 @@
   public:
     RenderContext(RTRTInterface* rtrt_int,
                   int channelIndex, int proc, int numProcs,
-                 const FrameState* frameState,
-                 LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
-                 Renderer* renderer, ShadowAlgorithm* shadowAlgorithm,
-                 const Camera* camera, const Scene* scene)
+                  const FrameState* frameState,
+                  LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
+                  Renderer* renderer, ShadowAlgorithm* shadowAlgorithm,
+                  const Camera* camera, const Scene* scene,
+                  ThreadStorageAllocator *storage_allocator_ )
       : rtrt_int(rtrt_int), channelIndex(channelIndex),
         proc(proc), numProcs(numProcs),
         frameState(frameState),
         loadBalancer(loadBalancer), pixelSampler(pixelSampler),
         renderer(renderer), shadowAlgorithm(shadowAlgorithm),
-        camera(camera), scene(scene)
+        camera(camera), scene(scene),
+        storage_allocator( storage_allocator_ )
     {
     }
     RTRTInterface* rtrt_int;
@@ -168,6 +185,9 @@
     ShadowAlgorithm* shadowAlgorithm;
     const Camera* camera;
     const Scene* scene;
+
+    mutable ThreadStorageAllocator *storage_allocator;
+    
   private:
     RenderContext(const RenderContext&);
     RenderContext& operator=(const RenderContext&);

Modified: branches/itanium2/Interface/Fragment.h
==============================================================================
--- branches/itanium2/Interface/Fragment.h      (original)
+++ branches/itanium2/Interface/Fragment.h      Thu Dec  1 01:30:42 2005
@@ -36,7 +36,10 @@
     static const int ConsecutiveX    = 0x01;  // Implies a constant Y:
     static const int ConstantEye = 0x02;
 
+    
///////////////////////////////////////////////////////////////////////////
+    // Constructor    
     Fragment(): flags(0), size(0) {} // empty constructor
+
     // Creates a "Scan-line" fragment.
     Fragment(int which_eye, int xstart, int xend, int y) {
       ASSERTRANGE(xend-xstart, 0, MaxFragmentSize+1);
@@ -52,34 +55,24 @@
        
     ~Fragment() {}
 
+    
///////////////////////////////////////////////////////////////////////////
+    // Element Accessors.    
     void addElement(int x, int y, int which_eye) {
-      ASSERT(size < MaxFragmentSize);
+      // ASSERT(size < MaxFragmentSize);
       data[size].x = x;
       data[size].y = y;
       data[size].which_eye = which_eye;
       size++;
     }
-    // input: a rectangular tile and number of sample locations to generate
-    // output: creates randomly oriented sample locations in given range
-    void createRandom(const int numElements,
-                      const int xstart, const int ystart,
-                      const int xend, const int yend, const int which_eye, 
-                      MT_RNG &myRandomNumber)
-    {
-      size = numElements;
-      flags = ConstantEye;
-      for(int i=0;i<size;i++)
-      {
-        data[i].x = (int)(xstart+myRandomNumber.genfrand()*(xend - xstart));
-        data[i].y = (int)(ystart+myRandomNumber.genfrand()*(yend - ystart));
-
-        if (data[i].x >= xend) data[i].x = (xend - 1);
-        if (data[i].y >= yend) data[i].y = (yend - 1);
-        
-        data[i].which_eye = which_eye;
-      }
+
+    void setElement( int i, int x, int y, int which_eye ) {
+      data[i].x = x;
+      data[i].y = y;
+      data[i].which_eye = which_eye;
     }
-      
+
+    
///////////////////////////////////////////////////////////////////////////
+    // Accessors.
     int getFlags() const {
       return flags;
     }
@@ -133,6 +126,9 @@
       data[which].color = color;
     }
 
+    
///////////////////////////////////////////////////////////////////////////
+    // Fragment Element Structure.
+    
     // Constant number of Elements so that we do not have to
     // dynamically allocate them.
     static const int MaxFragmentSize = 32;
@@ -159,6 +155,10 @@
     // Number of Elements that are currently being used.
     int size;
   };
+
+
+  // Fragment with a dynamic size.
+  
 }
 
 #endif

Modified: branches/itanium2/Interface/RTRTInterface.h
==============================================================================
--- branches/itanium2/Interface/RTRTInterface.h (original)
+++ branches/itanium2/Interface/RTRTInterface.h Thu Dec  1 01:30:42 2005
@@ -125,6 +125,7 @@
     virtual void registerSetupCallback(SetupCallback*) = 0;
     virtual void registerSerialAnimationCallback(CallbackBase_3Data<int, 
int, bool&>*) = 0;
     virtual void registerParallelAnimationCallback(CallbackBase_3Data<int, 
int, bool&>*) = 0;
+    virtual void registerTerminationCallback( CallbackBase_1Data< 
RTRTInterface *> *) = 0;
     
     // Settings
     enum TimeMode {

Modified: branches/itanium2/Model/Cameras/StereoPinholeCamera.cc
==============================================================================
--- branches/itanium2/Model/Cameras/StereoPinholeCamera.cc      (original)
+++ branches/itanium2/Model/Cameras/StereoPinholeCamera.cc      Thu Dec  1 
01:30:42 2005
@@ -108,20 +108,24 @@
   stereo_eye[0] = eye + right;
   stereo_eye[1] = eye - right;
 
-  // Compute the focus point.
-  Point focus_point = eye + (camera_direction * focus_distance);
+  // Compute focus point for each eye.
+  right.normalize();
+  right *= focus_eye_distance;
 
-  for (int i=0;i<2;++i) {
+  Point focus_point[2];
+  focus_point[0] = eye + (camera_direction * focus_distance) + right;
+  focus_point[1] = eye + (camera_direction * focus_distance) - right;   
   
+  for (int i=0;i<2;++i) {
+
     // Compute direction for either eye.
-    direction[i] = focus_point - stereo_eye[i];
+    direction[i] = focus_point[i] - stereo_eye[i];
     
     // Compute v
     v[i] = Cross( direction[i], up );
     v[i].normalize();
     v[i] *= width;
-   
-    
+       
     // Compute u
     u[i] = Cross( v[i], direction[i] );
     u[i].normalize();

Modified: branches/itanium2/Model/Cameras/StereoPinholeCamera.h
==============================================================================
--- branches/itanium2/Model/Cameras/StereoPinholeCamera.h       (original)
+++ branches/itanium2/Model/Cameras/StereoPinholeCamera.h       Thu Dec  1 
01:30:42 2005
@@ -23,13 +23,15 @@
       hfov( fov_ ),
 
       eye_distance( 1 ),
-      focus_distance( 10 )  { setup(); }
+      focus_distance( 10 ),
+      focus_eye_distance( 0.5 ) { setup(); }
 
     StereoPinholeCamera( const Point &eye_, const Point &lookat_, const 
Vector &up_, Real fov_,
-                         Real eye_distance_, Real focus_distance_ ) :
+                         Real eye_distance_, Real focus_distance_, Real 
focus_eye_distance_ ) :
       
                        eye( eye_ ), lookat( lookat_ ), up( up_ ), hfov( fov_ 
),
-      eye_distance( eye_distance_ ), focus_distance( focus_distance_ )  { 
setup(); }
+      eye_distance( eye_distance_ ), focus_distance( focus_distance_ ),
+      focus_eye_distance( focus_eye_distance_ ) { setup(); }
 
     StereoPinholeCamera(const vector<string>& args);
     static Camera* create(const vector<string>& args);
@@ -47,12 +49,13 @@
                virtual void output( std::ostream &os );
          virtual Point project(const Point &point) const;  // project a 3D 
point to the camera image plane
 
-    void set_eye_distance  ( Real eye_distance_ )   { eye_distance = 
eye_distance_; setup(); }
-    void set_focus_distance( Real focus_distance_ ) { focus_distance = 
focus_distance_; setup(); }
+    void set_eye_distance  ( Real eye_distance_ )     { eye_distance = 
eye_distance_; setup(); }
+    void set_focus_distance( Real focus_distance_ )   { focus_distance = 
focus_distance_; setup(); }
+    void set_focus_eye_distance( Real eye_distance_ ) { focus_eye_distance = 
eye_distance_; setup(); }
     
                virtual Point getPosition() const { return eye; }
                virtual Point getLookAt()   const { return lookat; };
-               virtual Vector getUp()       const { return up; };
+               virtual Vector getUp()      const { return up; };
                
                virtual void reset( const Point &eye_, const Vector &up_, 
const Point &lookat_ ) {
 
@@ -76,6 +79,7 @@
     
     Real eye_distance;   // Distance between eyes.
     Real focus_distance; // Distance from camera point that view from both 
eyes cross.
+    Real focus_eye_distance; // Distance between the point each eye is 
focusing on..?
 
     
     // Assume that fov is the same for both eyes.

Modified: branches/itanium2/StandAlone/CMakeLists.txt
==============================================================================
--- branches/itanium2/StandAlone/CMakeLists.txt (original)
+++ branches/itanium2/StandAlone/CMakeLists.txt Thu Dec  1 01:30:42 2005
@@ -10,7 +10,7 @@
 
  TARGET_LINK_LIBRARIES(manta ${CMAKE_THREAD_LIBS_INIT}
                              ${OPENGL_LIBRARIES}
-                            ${X11_LIBRARIES}
+                                              ${X11_LIBRARIES}
                              -lm)
 
 
@@ -40,7 +40,8 @@
 ENDIF(BUILD_V3C1_TOOLS)
 
 IF(SGI_LINUX)
-  ADD_EXECUTABLE(mf_stream_test mf_stream_test.cc)
+  ADD_EXECUTABLE(mf_stream_test mf_stream_test.cc
+                                ../fox/MediaFusionBridge.cc)
   TARGET_LINK_LIBRARIES(mf_stream_test Manta_Engine
     Manta_UserInterface
     Manta_Model

Modified: branches/itanium2/StandAlone/frust-test.cc
==============================================================================
--- branches/itanium2/StandAlone/frust-test.cc  (original)
+++ branches/itanium2/StandAlone/frust-test.cc  Thu Dec  1 01:30:42 2005
@@ -55,7 +55,7 @@
                                NULL,
                                NULL, NULL,
                                NULL, NULL,
-                               NULL,NULL );
+                               NULL,NULL,NULL );
   // Ah, the ray packet
   Point ray_origin(20, 0, 20);
   Point Pn(19,1,2), Pf(2,1,2);

Modified: branches/itanium2/StandAlone/manta_tile_size.pl
==============================================================================
--- branches/itanium2/StandAlone/manta_tile_size.pl     (original)
+++ branches/itanium2/StandAlone/manta_tile_size.pl     Thu Dec  1 01:30:42 
2005
@@ -220,9 +220,10 @@
     }
 } 
 
-print MANTA_IN "-quit\n";
-close MANTA_IN;
+# print MANTA_IN "-quit\n";
 close MANTA_OUT;
+close MANTA_IN;
+
 
 # Produce a plot.
 if ($file ne "-") {
@@ -268,6 +269,7 @@
                "unu save -f nrrd | " .
                "unu reshape -s $size_x $size_y | ". 
                "unu rmap -m $colormap | " .
+               "unu flip -a 2 | " .
                "unu resample -s = 512 512 -k box | ". 
                "unu quantize -b 8 | unu save -f png -o $file_png\n";
 
@@ -280,7 +282,8 @@
     $colormap_png = "$file-colormap.png";
     $command = "cat $colormap | " . 
                "unu save -f nrrd | " .
-               "unu reshape -s 3 1 12 |" .
+               "unu reshape -s 3 1 12 | " .
+               "unu flip -a 2 | " .
                "unu quantize -b 8 | unu save -f png -o $colormap_png\n";
 
     print $command;

Modified: branches/itanium2/StandAlone/mf_stream_test.cc
==============================================================================
--- branches/itanium2/StandAlone/mf_stream_test.cc      (original)
+++ branches/itanium2/StandAlone/mf_stream_test.cc      Thu Dec  1 01:30:42 
2005
@@ -1,34 +1,79 @@
 
 #include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
 #include <GL/glx.h>
 #include <GL/glu.h>
+#include <unistd.h>
+#include <errno.h>
 
 #include <vector>
 #include <string>
 #include <iostream>
 
 #include <Core/Shm/MFStreamData.h>
+#include <fox/MediaFusionBridge.h>
 #include <SCIRun/Core/Exceptions/Exception.h>
 #include <SCIRun/Core/Exceptions/InternalError.h>
+#include <SCIRun/Core/Exceptions/ErrnoException.h>
 #include <SCIRun/Core/Thread/Time.h>
 
 using namespace std;
 using namespace Manta;
 using namespace SCIRun;
-
+using namespace fox_manta;
 
 static Window parent;
 static Window win;
 static Display* dpy;
 static GLXContext cx;
+static int xpipe[2];
+static vector<int> xfds;
+
+static void connection_watch(Display*, XPointer data, int fd, Bool opening, 
XPointer*) {
+
+  // Check to see if a connection is being opened or closed.
+  if(opening) {
+    xfds.push_back( fd );
+  }
+  else {
+    for (vector<int>::iterator i = xfds.begin();i!=xfds.end();++i) {
+      if ((*i) == fd) {
+        xfds.erase( i );
+      }
+    }
+  }
+}
+  
 
 static void createWindow( MFStreamData *stream_data ) {
 
+  // Create the xpipe.
+  if (pipe(xpipe) == -1)
+    throw ErrnoException( "Error obtaining xpipe", errno, __FILE__, __LINE__ 
);
+  
   // Open the display and make sure it has opengl
   dpy = XOpenDisplay(NULL);
   if(!dpy)
     throw new InternalError("Error opening display", __FILE__, __LINE__ );
 
+  // Add a connection watch callback to obtain the file descriptor.
+  if (XAddConnectionWatch( dpy, connection_watch, 0 ) == 0)
+    throw InternalError("XAddConnectionWatch failed", __FILE__, __LINE__ );
+
+  // Check to see if XAddConnectionWatch already executed the callback????
+  if (xfds.size() == 0) {
+    // throw InternalError("XAddConnectionWatch broken", __FILE__, __LINE__ 
);
+    
+    int tmp_pipe[2];
+    if(pipe(tmp_pipe) == -1)
+      throw ErrnoException("tmp_pipe", errno, __FILE__, __LINE__ );
+    
+    for(int i=xpipe[1]+1; i<tmp_pipe[0];i++)
+      xfds.push_back( i );    
+  }
+
+  // Check to make sure opengl is available.
   int error, event;
   if ( !glXQueryExtension( dpy, &error, &event) ) {
     XCloseDisplay(dpy);
@@ -71,8 +116,15 @@
   atts.background_pixmap = None;
   atts.border_pixmap = None;
   atts.border_pixel = 0;
-  atts.colormap=cmap;
-  atts.event_mask=StructureNotifyMask;
+  atts.colormap = cmap;
+  atts.event_mask =
+    StructureNotifyMask |
+    ExposureMask |
+    ButtonPressMask |
+    ButtonReleaseMask |
+    ButtonMotionMask |
+    KeyPressMask |
+    KeyReleaseMask;
 
   parent = RootWindow(dpy, screen);
 
@@ -95,8 +147,8 @@
   }
 
   // Turn off events from this window
-  atts.event_mask = 0;
-  XChangeWindowAttributes(dpy, win, CWEventMask, &atts);
+  // atts.event_mask = 0;
+  // XChangeWindowAttributes(dpy, win, CWEventMask, &atts);
 
   cx = glXCreateContext(dpy, vi, NULL, True);
   XFree(vi);
@@ -167,6 +219,120 @@
   
 }
 
+#define TOKEN_NOOP 1
+#define TOKEN_LOCK 2
+
+void handle_events() {
+
+  // Setup a file handle for reading.
+  fd_set readfds;
+
+  FD_ZERO( &readfds );
+  FD_SET ( xpipe[0], &readfds );
+
+  // Determine the max file descriptor.
+  int max = xpipe[0];
+  for(vector<int>::iterator iter = xfds.begin(); iter != xfds.end(); iter++){
+
+    // Setup each descriptor for reading.
+    FD_SET(*iter, &readfds);
+
+    if(*iter > max) {
+      max = *iter;
+    }
+  }
+#if 0
+  // Wait for something to happen.
+  // int s;
+  // if ((s = select( max+1, &readfds, 0, 0, 0 )) == -1) {
+  //  throw ErrnoException("select", errno, __FILE__, __LINE__ );
+  // }
+
+  // std::cout << "Past select" << std::endl;
+  
+  // Do I have to do that TOKEN stuff?
+  if(FD_ISSET(xpipe[0], &readfds)){
+
+    std::cout << "Token stuff" << std::endl;
+    
+    // Process the pipe...
+    int token;
+    ssize_t s = read(xpipe[0], &token, sizeof(token));
+    if(s != sizeof(token))
+      throw ErrnoException("read pipe", errno, __FILE__, __LINE__ );
+
+    switch(token){
+    case TOKEN_NOOP:
+      break;
+
+    case TOKEN_LOCK:
+      // xlock.unlock();
+      // xsema.down();
+      // xlock.lock();
+      break;
+
+    default:
+      throw InternalError("Unknown token in pipe", __FILE__, __LINE__ );
+    }
+  }
+  
+  // Process xlib events.
+  bool have_events = false;
+  for(vector<int>::iterator iter = xfds.begin(); iter != xfds.end(); iter++){
+    if(FD_ISSET(*iter, &readfds)){
+      XProcessInternalConnection(dpy, *iter);
+      have_events = true;
+    }
+  }
+
+  // If there are no events waiting, return;
+  if (have_events == false) {
+    return;
+  }
+#endif
+  XEvent e;
+  while (XEventsQueued( dpy, QueuedAfterReading )) {
+
+    // Get the next event.
+    XNextEvent( dpy, &e );
+
+    // Check to see if the event is for our window.
+    if (e.xany.window == win) {
+
+      // Decide what to do based on the event type.
+      switch (e.type) {
+      case KeyPress:
+        std::cerr << "KeyPress" << std::endl;
+        break;
+      case KeyRelease:
+        std::cerr << "KeyRelease" << std::endl;        
+        break;
+      case ButtonPress:
+        std::cerr << "ButtonPress" << std::endl;        
+        break;
+      case ButtonRelease:
+        std::cerr << "ButtonRelease" << std::endl;        
+        break;
+      case MotionNotify:
+        std::cerr << "MotionNotify" << std::endl;        
+        break;
+      case ConfigureNotify:
+        std::cerr << "ConfigureNotify" << std::endl;        
+        break;
+      case Expose:
+        std::cerr << "Expose" << std::endl;        
+        break;
+      default:
+        std::cerr << "Unknown x event: " << e.type << std::endl;
+      }
+    }
+    else {
+      std::cout << "Received event for unknown windows: " << e.xany.window 
<< std::endl;
+    }
+    
+  }
+};
+
 int main( int argc, char **argv ) {
 
   int key = 0;
@@ -203,8 +369,16 @@
     if (use_x) {
       createWindow( stream_data );
 
+      // Start a media fusion event thread.
+      MediaFusionBridge mf_events( win,
+                                   parent,
+                                   dpy,
+                                   key );
+      mf_events.startup();
+      
       for(;;) {
-        display( stream_data );
+        handle_events();
+        // display( stream_data );
         SCIRun::Time::waitUntil( SCIRun::Time::currentSeconds()+0.05 );
       };
 
@@ -226,6 +400,9 @@
   // Catch any exceptions.
   catch (SCIRun::Exception *e) {
     std::cerr << "Caught Exception: " << e->message() << std::endl;
+  }
+  catch (SCIRun::Exception &e) {
+    std::cerr << "Caught Exception: " << e.message() << std::endl;
   }
 
   return 1;

Modified: branches/itanium2/fox/FMantaStereo.cc
==============================================================================
--- branches/itanium2/fox/FMantaStereo.cc       (original)
+++ branches/itanium2/fox/FMantaStereo.cc       Thu Dec  1 01:30:42 2005
@@ -43,6 +43,7 @@
   //        Message_Type ID                                   Message_Handler
   FXMAPFUNC(SEL_COMMAND, FMantaStereoDialog::ID_DISTANCE,        
FMantaStereoDialog::onDistance ),
   FXMAPFUNC(SEL_COMMAND, FMantaStereoDialog::ID_FOCUS,           
FMantaStereoDialog::onFocus ),
+  FXMAPFUNC(SEL_COMMAND, FMantaStereoDialog::ID_FOCUS_EYE,       
FMantaStereoDialog::onFocusEye ),
 
 };
 
@@ -62,12 +63,14 @@
 {
 
   FXHorizontalFrame *frame = new FXHorizontalFrame( this );
-
+  new FXLabel( frame, "The \"stereo\" camera must be specified to use stereo 
mode." );
+  
+  frame = new FXHorizontalFrame( this );
   new FXLabel( frame, "Eye distance" );
   distance_spinner = new FXRealSpinner( frame, 5, this, ID_DISTANCE );
   distance_spinner->setRange( 0, 999 );
-  distance_spinner->setIncrement( 0.05 );
-  distance_spinner->setValue( 0.1 );
+  distance_spinner->setIncrement( 0.001 );
+  distance_spinner->setValue( 0.01 );
 
   frame = new FXHorizontalFrame( this );
   new FXLabel( frame, "Focus distance" );
@@ -75,6 +78,13 @@
   focus_spinner->setRange( 0, 999 );
   focus_spinner->setIncrement( 0.05 );
   focus_spinner->setValue( 10.0 );
+
+  frame = new FXHorizontalFrame( this );
+  new FXLabel( frame, "Focus separation" );
+  focus_eye_spinner = new FXRealSpinner( frame, 5, this, ID_FOCUS_EYE );
+  focus_eye_spinner->setRange( 0, 999 );
+  focus_eye_spinner->setIncrement( 0.001 );
+  focus_eye_spinner->setValue( 0.01 );  
   
 }
 
@@ -98,6 +108,16 @@
   return 1;
 }
 
+long FMantaStereoDialog::onFocusEye( FXObject *sender, FXSelector key, void 
*data ) {
+
+  Real focus = focus_spinner->getValue();
+  manta_window->getMantaInterface()->addTransaction("stereo focus eye",
+                                      Callback::create(this, 
&FMantaStereoDialog::mantaSetFocusEye,
+                                                       focus ));
+  
+  return 1;
+}
+
 void FMantaStereoDialog::mantaSetDistance( Real distance_ ) {
 
   int channel = 0;
@@ -119,3 +139,14 @@
     camera->set_focus_distance( focus_ );
   }
 }
+
+void FMantaStereoDialog::mantaSetFocusEye( Real distance_ ) {
+
+  int channel = 0;
+  
+  // Check to make sure that the camera is a stereo camera.
+  StereoPinholeCamera *camera = dynamic_cast<StereoPinholeCamera 
*>(manta_window->getMantaInterface()->getCamera( channel ));
+  if (camera) {
+    camera->set_focus_eye_distance( distance_ );
+  }
+} 

Modified: branches/itanium2/fox/FMantaStereo.h
==============================================================================
--- branches/itanium2/fox/FMantaStereo.h        (original)
+++ branches/itanium2/fox/FMantaStereo.h        Thu Dec  1 01:30:42 2005
@@ -60,11 +60,13 @@
 
     FXRealSpinner *distance_spinner;
     FXRealSpinner *focus_spinner;
+    FXRealSpinner *focus_eye_spinner;
     
   public:
     enum {
       ID_DISTANCE = FXDialogBox::ID_LAST,
       ID_FOCUS,
+      ID_FOCUS_EYE,
       ID_LAST
     };
     
@@ -78,9 +80,11 @@
 
     long onDistance( FXObject *sender, FXSelector key, void *data );
     long onFocus   ( FXObject *sender, FXSelector key, void *data );
+    long onFocusEye( FXObject *sender, FXSelector key, void *data );
 
     void mantaSetDistance( Real distance_ );
     void mantaSetFocus   ( Real focus_ );
+    void mantaSetFocusEye( Real distance_ );
   };
 
 };

Modified: branches/itanium2/fox/FMantaWindow.cc
==============================================================================
--- branches/itanium2/fox/FMantaWindow.cc       (original)
+++ branches/itanium2/fox/FMantaWindow.cc       Thu Dec  1 01:30:42 2005
@@ -29,8 +29,9 @@
   
//////////////////////////////////////////////////////////////////////////////
   //        Message_Type ID                                 Message_Handler
   FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_QUIT,          
FMantaWindow::onQuit ),
+  FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_FAST_QUIT,     
FMantaWindow::onFastQuit ),
   FXMAPFUNC(SEL_COMMAND, 
FMantaWindow::ID_SAVE_BOOKMARKS,FMantaWindow::onSaveBookmarks ),
-  FXMAPFUNC(SEL_COMMAND, FXApp::ID_QUIT,                 
FMantaWindow::onQuit ),
+  FXMAPFUNC(SEL_CLOSE,   0,                              
FMantaWindow::onFastQuit ),
        
   // Control options
   FXMAPFUNC(SEL_CHANGED, FMantaWindow::ID_SPEED_SLIDER,   
FMantaWindow::onSpeedSlider ),
@@ -101,7 +102,9 @@
   // File Menu.
   file_menu = new FXMenuPane( this );
   new FXMenuCommand( file_menu, "Save Bookmarks", 0, this, ID_SAVE_BOOKMARKS 
);
-  new FXMenuCommand( file_menu, "Quit", 0, this, ID_QUIT );
+  new FXMenuSeparator( file_menu );
+  new FXMenuCommand( file_menu, "Safe Quit", 0, this, ID_QUIT );
+  new FXMenuCommand( file_menu, "Fast Quit", 0, this, ID_FAST_QUIT );
   new FXMenuTitle  ( menu_bar, "File", 0, file_menu );
        
   // Camera menu.
@@ -231,18 +234,30 @@
 // Quit the program.
 long FMantaWindow::onQuit( FXObject *sender, FXSelector key, void *data ) {
        
-  // Hard quit.
-  // if (fast_quit) {
-  SCIRun::Thread::exitAll( 0 );
-  //}
-       
+  // Register termination callback.
+  manta_interface->registerTerminationCallback(
+    Callback::create( this, &FMantaWindow::mantaTerminate ) );
+  
   // Add a quit command to manta.
-  // 
manta_interface->addTransaction("Quit",Callback::create(manta_interface,&RTRTInterface::finish));
-  // fast_quit = true;
-       
+  manta_interface->addTransaction("Quit",Callback::create(manta_interface,
+                                                          
&RTRTInterface::changeNumWorkers, 0 ));
+  // Wait until manta terminates.
+  manta_interface->blockUntilFinished();
+  
+  // Quit the fox application.
+  getApp()->exit();  
+  
   return 1;
 };
 
+long FMantaWindow::onFastQuit( FXObject *sender, FXSelector key, void *data 
) {
+
+  // Hard quit all threads.
+  SCIRun::Thread::exitAll( 0 );
+
+  return 1;
+}
+
 long FMantaWindow::onSpeedSlider( FXObject *sender, FXSelector key, void 
*data ) {
 
   // Set the control speed for interaction.
@@ -1146,5 +1161,8 @@
        
 }
 
+void FMantaWindow::mantaTerminate( RTRTInterface *manta_interface ) {
+
 
+}
 

Modified: branches/itanium2/fox/FMantaWindow.h
==============================================================================
--- branches/itanium2/fox/FMantaWindow.h        (original)
+++ branches/itanium2/fox/FMantaWindow.h        Thu Dec  1 01:30:42 2005
@@ -75,6 +75,7 @@
     // Commands for the main window.
     enum {
       ID_QUIT = FXMainWindow::ID_LAST, // Sent when the application must 
quit.
+      ID_FAST_QUIT,                    // Terminate ALL threads immediately
       ID_SPEED_SLIDER,                 // Control speed slider was changed.
       ID_CUTTING_SLIDER,               // Cutting plane slider was changed.
       ID_CUTTING_FLIP,
@@ -151,6 +152,7 @@
                
     // Message handlers.
     long onQuit           ( FXObject *sender, FXSelector key, void *data );
+    long onFastQuit       ( FXObject *sender, FXSelector key, void *data );
     long onSpeedSlider    ( FXObject *sender, FXSelector key, void *data );
     long onCuttingSlider  ( FXObject *sender, FXSelector key, void *data );
     long onCuttingFlip    ( FXObject *sender, FXSelector key, void *data );
@@ -220,6 +222,9 @@
 
     // Unhide all hidden parts.
     void mantaUnHideAll();
+
+    // This methid is called by manta when the last rendering thread exits.
+    void mantaTerminate( RTRTInterface *manta_interface );
   };
 };
 

Modified: branches/itanium2/scenes/boeing777.cc
==============================================================================
--- branches/itanium2/scenes/boeing777.cc       (original)
+++ branches/itanium2/scenes/boeing777.cc       Thu Dec  1 01:30:42 2005
@@ -184,7 +184,7 @@
     kd_material = new Phong( new KDTreeTexture, 
                              new Constant<Color>(Color::white()),
                              phong_exp,
-                             new Constant<ColorComponent>(phong_reflect) );
+                             new Constant<float>(phong_reflect) );
     break;
   };
        




  • [MANTA] r741 - in branches/itanium2: Core/Util Engine/Control Engine/Display Engine/ImageTraversers Engine/ImageTraversers/AFR Interface Model/Cameras StandAlone fox scenes, abe, 12/01/2005

Archive powered by MHonArc 2.6.16.

Top of page