loadEqualizer.h

00001 
00002 /* Copyright (c) 2008-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #ifndef EQS_LOADEQUALIZER_H
00019 #define EQS_LOADEQUALIZER_H
00020 
00021 #include "../channelListener.h" // base class
00022 #include "equalizer.h"          // base class
00023 
00024 #include <eq/client/range.h>
00025 #include <eq/client/viewport.h>
00026 
00027 #include <deque>
00028 #include <vector>
00029 
00030 namespace eq
00031 {
00032 namespace server
00033 {
00034     class LoadEqualizer;
00035     std::ostream& operator << ( std::ostream& os, const LoadEqualizer* );
00036 
00038     class LoadEqualizer : public Equalizer, protected ChannelListener
00039     {
00040     public:
00041         LoadEqualizer();
00042         LoadEqualizer( const LoadEqualizer& from );
00043         virtual ~LoadEqualizer();
00044         virtual Equalizer* clone() const { return new LoadEqualizer( *this ); }
00045         virtual void toStream( std::ostream& os ) const { os << this; }
00046 
00047         enum Mode
00048         {
00049             MODE_DB = 0,     
00050             MODE_HORIZONTAL, 
00051             MODE_VERTICAL,   
00052             MODE_2D          
00053         };
00054 
00056         void setMode( const Mode mode ) { _mode = mode; }
00057 
00059         Mode getMode() const { return _mode; }
00060 
00062         void setDamping( const float damping ) { _damping = damping; }
00063 
00065         float getDamping() const { return _damping; }
00066 
00068         virtual void notifyUpdatePre( Compound* compound, 
00069                                       const uint32_t frameNumber );
00070 
00072         virtual void notifyLoadData( Channel* channel, 
00073                                      const uint32_t frameNumber, 
00074                                      const uint32_t nStatistics,
00075                                      const eq::Statistic* statistics );
00076 
00077     protected:
00078         virtual void notifyChildAdded( Compound* compound, Compound* child )
00079             { EQASSERT( !_tree ); }
00080         virtual void notifyChildRemove( Compound* compound, Compound* child )
00081             { EQASSERT( !_tree ); }
00082 
00083     private:
00084         Mode  _mode;    
00085         float _damping; 
00086         
00087         struct Node
00088         {
00089             Node() : left(0), right(0), compound(0), splitMode( MODE_VERTICAL )
00090                    , time( 0.0f ), usage( 0.0f ) {}
00091             ~Node() { delete left; delete right; }
00092 
00093             Node*     left;      //<! Left child (only on non-leafs)
00094             Node*     right;     //<! Right child (only on non-leafs)
00095             Compound* compound;  //<! The corresponding child (only on leafs)
00096             LoadEqualizer::Mode splitMode; //<! What to adapt
00097             float     time;      //<! target render time for next frame
00098             float     usage;     //<! total usage of subtree
00099         };
00100         friend std::ostream& operator << ( std::ostream& os, const Node* node );
00101         typedef std::vector< Node* > LBNodeVector;
00102 
00103         Node* _tree; // <! The binary split tree of all children
00104 
00105         struct Data
00106         {
00107             Data() : channel( 0 ), taskID( 0 ), time( -1 ) {}
00108 
00109             Channel*     channel;
00110             uint32_t     taskID;
00111             eq::Viewport vp;
00112             eq::Range    range;
00113             int64_t      time;
00114             float        load;          //<! time/vp.area
00115         };
00116 
00117         typedef std::vector< Data >                  LBDataVector;
00118         typedef std::pair< uint32_t,  LBDataVector > LBFrameData;
00119         
00120         std::deque< LBFrameData > _history;
00121         
00122         //-------------------- Methods --------------------
00124         Node* _buildTree( const CompoundVector& children );
00125 
00127         void _clearTree( Node* node );
00128 
00130         void _checkHistory();
00131         
00133         void _computeSplit();
00134         float _assignTargetTimes( Node* node, const float totalTime, 
00135                                   const float resourceTime );
00136         void _assignLeftoverTime( Node* node, const float time );
00137         void _removeEmpty( LBDataVector& items );
00138         void _computeSplit( Node* node, LBDataVector* sortedData,
00139                             const eq::Viewport& vp, const eq::Range& range );
00140 
00141         static bool _compareX( const Data& data1, const Data& data2 )
00142             { return data1.vp.x < data2.vp.x; }
00143         static bool _compareY( const Data& data1, const Data& data2 )
00144             { return data1.vp.y < data2.vp.y; }
00145         static bool _compareRange( const Data& data1, const Data& data2 )
00146             { return data1.range.start < data2.range.start; }
00147     };
00148 
00149     std::ostream& operator << ( std::ostream& os, const LoadEqualizer::Mode );
00150 }
00151 }
00152 
00153 #endif // EQS_LOADEQUALIZER_H
Generated on Mon Aug 10 18:58:40 2009 for Equalizer 0.9 by  doxygen 1.5.8