loadEqualizer.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef EQS_LOADEQUALIZER_H
00019 #define EQS_LOADEQUALIZER_H
00020
00021 #include "../channelListener.h"
00022 #include "equalizer.h"
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;
00094 Node* right;
00095 Compound* compound;
00096 LoadEqualizer::Mode splitMode;
00097 float time;
00098 float usage;
00099 };
00100 friend std::ostream& operator << ( std::ostream& os, const Node* node );
00101 typedef std::vector< Node* > LBNodeVector;
00102
00103 Node* _tree;
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;
00115 };
00116
00117 typedef std::vector< Data > LBDataVector;
00118 typedef std::pair< uint32_t, LBDataVector > LBFrameData;
00119
00120 std::deque< LBFrameData > _history;
00121
00122
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