Line data Source code
1 :
2 : /* Copyright (c) 2008-2013, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2010, Cedric Stalder <cedric.stalder@gmail.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #ifndef EQS_LOADEQUALIZER_H
20 : #define EQS_LOADEQUALIZER_H
21 :
22 : #include "../channelListener.h" // base class
23 : #include "equalizer.h" // base class
24 :
25 : #include <eq/client/types.h>
26 : #include <eq/fabric/range.h> // member
27 : #include <eq/fabric/viewport.h> // member
28 :
29 : #include <deque>
30 : #include <vector>
31 :
32 : namespace eq
33 : {
34 : namespace server
35 : {
36 : std::ostream& operator << ( std::ostream& os, const LoadEqualizer* );
37 :
38 : /** Adapts the 2D tiling or DB range of the attached compound's children. */
39 : class LoadEqualizer : public Equalizer, protected ChannelListener
40 : {
41 : public:
42 : EQSERVER_API LoadEqualizer();
43 : LoadEqualizer( const fabric::Equalizer& from );
44 : virtual ~LoadEqualizer();
45 142 : virtual void toStream( std::ostream& os ) const { os << this; }
46 :
47 : /** @sa CompoundListener::notifyUpdatePre */
48 : virtual void notifyUpdatePre( Compound* compound,
49 : const uint32_t frameNumber );
50 :
51 : /** @sa ChannelListener::notifyLoadData */
52 : virtual void notifyLoadData( Channel* channel,
53 : const uint32_t frameNumber,
54 : const Statistics& statistics,
55 : const Viewport& region );
56 :
57 0 : virtual uint32_t getType() const { return fabric::LOAD_EQUALIZER; }
58 :
59 : protected:
60 384 : void notifyChildAdded( Compound*, Compound* ) override
61 384 : { LBASSERT( !_tree ); }
62 0 : void notifyChildRemove( Compound*, Compound* ) override
63 0 : { LBASSERT( !_tree ); }
64 :
65 : private:
66 : struct Node
67 : {
68 0 : Node() : left(0), right(0), compound(0), mode( MODE_VERTICAL )
69 : , resources( 0.0f ), split( 0.5f ), boundaryf( 0.0f )
70 0 : , resistancef( 0.0f ) {}
71 0 : ~Node() { delete left; delete right; }
72 :
73 : Node* left; //<! Left child (only on non-leafs)
74 : Node* right; //<! Right child (only on non-leafs)
75 : Compound* compound; //<! The corresponding child (only on leafs)
76 : LoadEqualizer::Mode mode; //<! What to adapt
77 : float resources; //<! total amount of resources of subtree
78 : float split; //<! 0..1 global (vp, range) split
79 : float boundaryf;
80 : Vector2i boundary2i;
81 : float resistancef;
82 : Vector2i resistance2i;
83 : Vector2i maxSize;
84 : };
85 : friend std::ostream& operator << ( std::ostream& os, const Node* node );
86 : typedef std::vector< Node* > LBNodes;
87 :
88 : Node* _tree; // <! The binary split tree of all children
89 :
90 : struct Data
91 : {
92 42 : Data() : channel( 0 ), taskID( 0 ), destTaskID( 0 )
93 42 : , time( -1 ), assembleTime( 0 ) {}
94 : Channel* channel;
95 : uint32_t taskID;
96 : uint32_t destTaskID;
97 : eq::Viewport vp;
98 : eq::Range range;
99 : int64_t time;
100 : int64_t assembleTime;
101 : };
102 :
103 : typedef std::vector< Data > LBDatas;
104 : typedef std::pair< uint32_t, LBDatas > LBFrameData;
105 :
106 : std::deque< LBFrameData > _history;
107 :
108 : //-------------------- Methods --------------------
109 : /** @return true if we have a valid LB tree */
110 : Node* _buildTree( const Compounds& children );
111 :
112 : /** Setup assembly with the compound dest value */
113 : void _updateAssembleTime( Data& data, const Statistic& stat );
114 :
115 : /** Clear the tree, does not delete the nodes. */
116 : void _clearTree( Node* node );
117 :
118 : /** get the total time used by the rendering. */
119 : int64_t _getTotalTime();
120 :
121 : /** get the assembly time used by the compound which use
122 : the destination Channel. */
123 : int64_t _getAssembleTime( );
124 :
125 : /** Obsolete _history so that front-most item is youngest available. */
126 : void _checkHistory();
127 :
128 : /** Update all node fields influencing the split */
129 : void _update( Node* node, const Viewport& vp, const Range& range );
130 : void _updateLeaf( Node* node );
131 : void _updateNode( Node* node, const Viewport& vp, const Range& range );
132 :
133 : /** Adjust the split of each node based on the front-most _history. */
134 : void _computeSplit();
135 : void _removeEmpty( LBDatas& items );
136 :
137 : void _computeSplit( Node* node, const float time, LBDatas* sortedData,
138 : const eq::Viewport& vp, const eq::Range& range );
139 : void _assign( Compound* compound, const Viewport& vp,
140 : const Range& range );
141 :
142 : /** Get the resource for all children compound. */
143 : float _getTotalResources( ) const;
144 :
145 0 : static bool _compareX( const Data& data1, const Data& data2 )
146 0 : { return data1.vp.x < data2.vp.x; }
147 0 : static bool _compareY( const Data& data1, const Data& data2 )
148 0 : { return data1.vp.y < data2.vp.y; }
149 0 : static bool _compareRange( const Data& data1, const Data& data2 )
150 0 : { return data1.range.start < data2.range.start; }
151 : };
152 : }
153 : }
154 :
155 : #endif // EQS_LOADEQUALIZER_H
|