Line data Source code
1 :
2 : /* Copyright (c) 2008-2015, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 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/fabric/range.h> // member
26 : #include <eq/fabric/viewport.h> // member
27 :
28 : #include <deque>
29 : #include <vector>
30 :
31 : namespace eq
32 : {
33 : namespace server
34 : {
35 : std::ostream& operator << ( std::ostream& os, const LoadEqualizer* );
36 :
37 : /** Adapts the 2D tiling or DB range of the attached compound's children. */
38 : class LoadEqualizer : public Equalizer, protected ChannelListener
39 : {
40 : public:
41 : EQSERVER_API LoadEqualizer();
42 : explicit LoadEqualizer( const fabric::Equalizer& from );
43 : virtual ~LoadEqualizer();
44 94 : void toStream( std::ostream& os ) const final { os << this; }
45 :
46 : /** @sa CompoundListener::notifyUpdatePre */
47 : void notifyUpdatePre( Compound* compound,
48 : const uint32_t frameNumber ) final;
49 :
50 : /** @sa ChannelListener::notifyLoadData */
51 : void notifyLoadData( Channel* channel,
52 : uint32_t frameNumber,
53 : const Statistics& statistics,
54 : const Viewport& region ) final;
55 :
56 0 : uint32_t getType() const final { return fabric::LOAD_EQUALIZER; }
57 :
58 : protected:
59 708 : void notifyChildAdded( Compound*, Compound* ) override
60 708 : { LBASSERT( !_tree ); }
61 0 : void notifyChildRemove( Compound*, Compound* ) override
62 0 : { LBASSERT( !_tree ); }
63 :
64 : private:
65 : struct Node
66 : {
67 0 : Node() : left(0), right(0), compound(0), mode( MODE_VERTICAL )
68 : , resources( 0.0f ), split( 0.5f ), boundaryf( 0.0f )
69 0 : , resistancef( 0.0f ) {}
70 0 : ~Node() { delete left; delete right; }
71 :
72 : Node* left; //<! Left child (only on non-leafs)
73 : Node* right; //<! Right child (only on non-leafs)
74 : Compound* compound; //<! The corresponding child (only on leafs)
75 : LoadEqualizer::Mode mode; //<! What to adapt
76 : float resources; //<! total amount of resources of subtree
77 : float split; //<! 0..1 global (vp, range) split
78 : float boundaryf;
79 : Vector2i boundary2i;
80 : float resistancef;
81 : Vector2i resistance2i;
82 : Vector2i maxSize;
83 : };
84 : friend std::ostream& operator << ( std::ostream& os, const Node* node );
85 : typedef std::vector< Node* > LBNodes;
86 :
87 : Node* _tree; // <! The binary split tree of all children
88 :
89 : struct Data
90 : {
91 0 : Data() : channel( 0 ), taskID( 0 ), destTaskID( 0 )
92 0 : , time( -1 ), assembleTime( 0 ) {}
93 : Channel* channel;
94 : uint32_t taskID;
95 : uint32_t destTaskID;
96 : Viewport vp;
97 : Range range;
98 : int64_t time;
99 : int64_t assembleTime;
100 : };
101 :
102 : typedef std::vector< Data > LBDatas;
103 : typedef std::pair< uint32_t, LBDatas > LBFrameData;
104 :
105 : std::deque< LBFrameData > _history;
106 :
107 : //-------------------- Methods --------------------
108 : /** @return true if we have a valid LB tree */
109 : Node* _buildTree( const Compounds& children );
110 :
111 : /** Setup assembly with the compound dest value */
112 : void _updateAssembleTime( Data& data, const Statistic& stat );
113 :
114 : /** Clear the tree, does not delete the nodes. */
115 : void _clearTree( Node* node );
116 :
117 : /** get the total time used by the rendering. */
118 : int64_t _getTotalTime();
119 :
120 : /** get the assembly time used by the compound which use
121 : the destination Channel. */
122 : int64_t _getAssembleTime( );
123 :
124 : /** Obsolete _history so that front-most item is youngest available. */
125 : void _checkHistory();
126 :
127 : /** Update all node fields influencing the split */
128 : void _update( Node* node, const Viewport& vp, const Range& range );
129 : void _updateLeaf( Node* node );
130 : void _updateNode( Node* node, const Viewport& vp, const Range& range );
131 :
132 : /** Adjust the split of each node based on the front-most _history. */
133 : void _computeSplit();
134 : void _removeEmpty( LBDatas& items );
135 :
136 : void _computeSplit( Node* node, const float time, LBDatas* sortedData,
137 : const Viewport& vp, const Range& range );
138 : void _assign( Compound* compound, const Viewport& vp,
139 : const Range& range );
140 :
141 : /** Get the resource for all children compound. */
142 : float _getTotalResources( ) const;
143 :
144 0 : static bool _compareX( const Data& data1, const Data& data2 )
145 0 : { return data1.vp.x < data2.vp.x; }
146 0 : static bool _compareY( const Data& data1, const Data& data2 )
147 0 : { return data1.vp.y < data2.vp.y; }
148 0 : static bool _compareRange( const Data& data1, const Data& data2 )
149 0 : { return data1.range.start < data2.range.start; }
150 : };
151 : }
152 : }
153 :
154 : #endif // EQS_LOADEQUALIZER_H
|