Line data Source code
1 :
2 : /* Copyright (c) 2005-2017, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Cedric Stalder <cedric Stalder@gmail.com>
4 : * Daniel Nachbaur <danielnachbaur@gmail.com>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef EQSERVER_NODE_H
21 : #define EQSERVER_NODE_H
22 :
23 : #include "config.h" // used in inline method
24 : #include "state.h" // enum
25 : #include "types.h"
26 :
27 : #include <eq/fabric/node.h> // base class
28 :
29 : #include <co/barrier.h>
30 : #include <co/bufferConnection.h>
31 : #include <co/connectionDescription.h>
32 : #include <co/node.h>
33 :
34 : #include <vector>
35 :
36 : namespace eq
37 : {
38 : namespace server
39 : {
40 : /** The node. */
41 : class Node : public fabric::Node<Config, Node, Pipe, NodeVisitor>
42 : {
43 : public:
44 : /** Construct a new Node. */
45 : EQSERVER_API explicit Node(Config* parent);
46 :
47 : virtual ~Node();
48 :
49 : /** @name Data Access. */
50 : //@{
51 : ServerPtr getServer();
52 : ConstServerPtr getServer() const;
53 :
54 8 : co::NodePtr getNode() const { return _node; }
55 2 : void setNode(co::NodePtr node) { _node = node; }
56 498 : void setHost(const std::string& host) { _host = host; }
57 380 : const std::string& getHost() const { return _host; }
58 : Channel* getChannel(const ChannelPath& path);
59 :
60 : /** @return the state of this node. */
61 20 : State getState() const { return _state.get(); }
62 : /** @internal */
63 0 : void setState(const State state) { _state = state; }
64 : co::CommandQueue* getMainThreadQueue();
65 : co::CommandQueue* getCommandThreadQueue();
66 :
67 : /** Increase node activition count. */
68 : void activate();
69 :
70 : /** Decrease node activition count. */
71 : void deactivate();
72 :
73 : /** @return if this pipe is actively used for rendering. */
74 30 : bool isActive() const { return (_active != 0); }
75 : /** @return if this node is running. */
76 14 : bool isRunning() const { return _state == STATE_RUNNING; }
77 : /** @return if this node is stopped. */
78 2 : bool isStopped() const { return _state == STATE_STOPPED; }
79 : /**
80 : * Add additional tasks this pipe, and all its parents, might
81 : * potentially execute.
82 : */
83 : void addTasks(const uint32_t tasks);
84 :
85 : /** The last drawing channel for this entity. */
86 4 : void setLastDrawPipe(const Pipe* pipe) { _lastDrawPipe = pipe; }
87 4 : const Pipe* getLastDrawPipe() const { return _lastDrawPipe; }
88 : /** @return the number of the last finished frame. @internal */
89 6 : uint32_t getFinishedFrame() const { return _finishedFrame; }
90 : //@}
91 :
92 : /**
93 : * @name Operations
94 : */
95 : //@{
96 : /** Connect the render slave node process. */
97 : bool connect();
98 :
99 : /** Launch the render slave node process. */
100 : bool launch();
101 :
102 : /** Synchronize the connection of a render slave launch. */
103 : bool syncLaunch(const lunchbox::Clock& time);
104 :
105 : /** Start initializing this entity. */
106 : void configInit(const uint128_t& initID, const uint32_t frameNumber);
107 :
108 : /** Sync initialization of this entity. */
109 : bool syncConfigInit();
110 :
111 : /** Start exiting this entity. */
112 : void configExit();
113 :
114 : /** Sync exit of this entity. */
115 : bool syncConfigExit();
116 :
117 : /**
118 : * Trigger the rendering of a new frame for this node.
119 : *
120 : * @param frameID a per-frame identifier passed to all rendering
121 : * methods.
122 : * @param frameNumber the number of the frame.
123 : */
124 : void update(const uint128_t& frameID, const uint32_t frameNumber);
125 :
126 : /**
127 : * Flush the processing of frames, including frameNumber.
128 : *
129 : * @param frameNumber the number of the frame.
130 : */
131 : void flushFrames(const uint32_t frameNumber);
132 :
133 : /** Synchronize the completion of the rendering of a frame. */
134 : void finishFrame(const uint32_t frame);
135 : //@}
136 :
137 : /**
138 : * @name Barrier Cache
139 : *
140 : * Caches barriers for which this node is the master.
141 : */
142 : //@{
143 : /**
144 : * Get a new barrier of height 0.
145 : *
146 : * @return the barrier.
147 : */
148 : co::Barrier* getBarrier();
149 :
150 : /**
151 : * Release a barrier server by this node.
152 : *
153 : * @param barrier the barrier.
154 : */
155 : void releaseBarrier(co::Barrier* barrier);
156 :
157 : /** Change the latency on all objects (barrier) */
158 : void changeLatency(const uint32_t latency);
159 : //@}
160 :
161 : co::ObjectOCommand send(const uint32_t cmd);
162 : co::ObjectOCommand send(const uint32_t cmd, const uint128_t& id);
163 : EventOCommand sendError(const uint32_t error);
164 :
165 : void flushSendBuffer();
166 :
167 : /**
168 : * Add a new description how this node can be reached.
169 : *
170 : * @param desc the connection description.
171 : */
172 588 : void addConnectionDescription(co::ConnectionDescriptionPtr desc)
173 : {
174 588 : _connectionDescriptions.push_back(desc);
175 588 : }
176 :
177 : /**
178 : * Remove a connection description.
179 : *
180 : * @param cd the connection description.
181 : * @return true if the connection description was removed, false otherwise.
182 : */
183 : EQSERVER_API bool removeConnectionDescription(
184 : co::ConnectionDescriptionPtr cd);
185 :
186 : /** @return the vector of connection descriptions. */
187 382 : const co::ConnectionDescriptions& getConnectionDescriptions() const
188 : {
189 382 : return _connectionDescriptions;
190 : }
191 :
192 : /** @name Attributes */
193 : //@{
194 : /** String attributes. */
195 : enum SAttribute
196 : {
197 : SATTR_LAUNCH_COMMAND, //!< the command to launch the node
198 : SATTR_LAST,
199 : SATTR_ALL = SATTR_LAST + 5
200 : };
201 :
202 : /** Character attributes. */
203 : enum CAttribute
204 : {
205 : CATTR_LAUNCH_COMMAND_QUOTE, //!< The character to quote arguments
206 : CATTR_LAST,
207 : CATTR_ALL = CATTR_LAST + 5
208 : };
209 :
210 : /** @internal Set a string integer attribute. */
211 : EQSERVER_API void setSAttribute(const SAttribute attr,
212 : const std::string& value);
213 :
214 : /** @internal Set a character integer attribute. */
215 : void setCAttribute(const CAttribute attr, const char value);
216 :
217 : /** @return the value of a node string attribute. @version 1.0 */
218 : const std::string& getSAttribute(const SAttribute attr) const;
219 :
220 : /** @return the value of a node string attribute. @version 1.0 */
221 : char getCAttribute(const CAttribute attr) const;
222 :
223 : /** @internal @return the name of a node string attribute. */
224 : static const std::string& getSAttributeString(const SAttribute attr);
225 : /** @internal @return the name of a node character attribute. */
226 : static const std::string& getCAttributeString(const CAttribute attr);
227 : //@}
228 :
229 : void output(std::ostream& os) const; //!< @internal
230 :
231 : protected:
232 : /** @sa co::Object::attach. */
233 : virtual void attach(const uint128_t& id, const uint32_t instanceID);
234 :
235 : private:
236 : /** String attributes. */
237 : std::string _sAttributes[SATTR_ALL];
238 :
239 : /** Character attributes. */
240 : char _cAttributes[CATTR_ALL];
241 :
242 : std::string _host; // The host name to launch this node
243 :
244 : /** Number of activations for this node. */
245 : uint32_t _active;
246 :
247 : /** The network node on which this Equalizer node is running. */
248 : co::NodePtr _node;
249 :
250 : /** The list of descriptions on how this node is reachable. */
251 : co::ConnectionDescriptions _connectionDescriptions;
252 :
253 : typedef std::unordered_map<uint32_t, co::uint128_t> FrameIDHash;
254 : /** The frame identifiers non-finished frames. */
255 : FrameIDHash _frameIDs;
256 :
257 : /** The number of the last finished frame. */
258 : uint32_t _finishedFrame;
259 :
260 : /** The number of the last flushed frame (frame finish command sent). */
261 : uint32_t _flushedFrame;
262 :
263 : /** The current state for state change synchronization. */
264 : lunchbox::Monitor<State> _state;
265 :
266 : /** The cached barriers. */
267 : std::vector<co::Barrier*> _barriers;
268 :
269 : /** Task commands for the current operation. */
270 : co::BufferConnectionPtr _bufferedTasks;
271 :
272 : /** The last draw pipe for this entity */
273 : const Pipe* _lastDrawPipe;
274 :
275 : struct Private;
276 : Private* _private; // placeholder for binary-compatible changes
277 :
278 : /**
279 : * Compose and execute the launch command by expanding the variables in
280 : * the launch command string.
281 : *
282 : * @param description the connection description.
283 : * @return true on success, false otherwise
284 : */
285 : bool _launch(const std::string& hostname) const;
286 : std::string _createLaunchCommand() const;
287 : std::string _createRemoteCommand() const;
288 :
289 : uint32_t _getFinishLatency() const;
290 : void _finish(const uint32_t currentFrame);
291 :
292 : /** flush cached barriers. */
293 : void _flushBarriers();
294 :
295 : /** Send the frame finish command for the given frame number. */
296 : void _sendFrameFinish(const uint32_t frameNumber);
297 :
298 : /* ICommand handler functions. */
299 : bool _cmdConfigInitReply(co::ICommand& command);
300 : bool _cmdConfigExitReply(co::ICommand& command);
301 : bool _cmdFrameFinishReply(co::ICommand& command);
302 : };
303 : }
304 : }
305 : #endif // EQSERVER_NODE_H
|