Line data Source code
1 :
2 : /* Copyright (c) 2005-2017, 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 EQ_NODE_H
20 : #define EQ_NODE_H
21 :
22 : #include <eq/api.h>
23 : #include <eq/fabric/eventType.h> // EventType enum
24 : #include <eq/fabric/node.h> // base class
25 : #include <eq/types.h>
26 : #include <eq/visitorResult.h> // enum
27 :
28 : #include <co/types.h>
29 :
30 : namespace eq
31 : {
32 : namespace detail
33 : {
34 : class Node;
35 : }
36 :
37 : /**
38 : * A Node represents a single computer in the cluster.
39 : *
40 : * Each node is executed in a separate process. Each process has only its local
41 : * node instantiated, that is, it has at most instance of a Node and does not
42 : * see other node instances. The application process may not have a node, which
43 : * is the case when it does not contribute to the rendering.
44 : *
45 : * The eq::Node is not to be confused with the co::Node which represents the
46 : * process in the underlying peer-to-peer network layer. The eq::Client and
47 : * eq::Server are co::Nodes representing the local client and Equalizer server,
48 : * respectively.
49 : *
50 : * @sa fabric::Node
51 : */
52 : class Node : public fabric::Node<Config, Node, Pipe, NodeVisitor>
53 : {
54 : public:
55 : /** Construct a new node. @version 1.0 */
56 : EQ_API explicit Node(Config* parent);
57 :
58 : /** Destruct the node. @version 1.0 */
59 : EQ_API virtual ~Node();
60 :
61 : /** @return the parent client node. @version 1.0 */
62 : EQ_API ClientPtr getClient();
63 :
64 : /** @return the parent server node. @version 1.0 */
65 : EQ_API ServerPtr getServer();
66 :
67 : EQ_API co::CommandQueue* getMainThreadQueue(); //!< @internal
68 : EQ_API co::CommandQueue* getCommandThreadQueue(); //!< @internal
69 : co::CommandQueue* getTransmitterQueue(); //!< @internal
70 :
71 : /** @internal node thread only. */
72 : uint32_t getCurrentFrame() const;
73 :
74 : /**
75 : * @internal
76 : * Get a network barrier.
77 : *
78 : * @param barrier the barrier identifier and version.
79 : * @return the barrier.
80 : */
81 : co::Barrier* getBarrier(const co::ObjectVersion& barrier);
82 :
83 : /**
84 : * @internal
85 : * Get a frame data instance.
86 : *
87 : * @param frameDataVersion the frame data identifier and version.
88 : * @return the frame.
89 : */
90 : FrameDataPtr getFrameData(const co::ObjectVersion& frameDataVersion);
91 :
92 : /** @internal Release the frame data instance. */
93 : void releaseFrameData(FrameDataPtr data);
94 :
95 : /** @internal Wait for the node to be initialized. */
96 : EQ_API void waitInitialized() const;
97 :
98 : /**
99 : * @return true if this node is running, false otherwise.
100 : * @version 1.0
101 : */
102 : EQ_API bool isRunning() const;
103 :
104 : /**
105 : * @return true if this node is stopped, false otherwise.
106 : * @version 1.0
107 : */
108 : EQ_API bool isStopped() const;
109 :
110 : /**
111 : * Wait for a frame to be started.
112 : *
113 : * Used by the pipe task methods to implement the current thread
114 : * synchronization model.
115 : *
116 : * @param frameNumber the frame number.
117 : * @sa releaseFrame()
118 : * @version 1.0
119 : */
120 : EQ_API void waitFrameStarted(const uint32_t frameNumber) const;
121 :
122 : /** @internal @return the number of the last finished frame. */
123 : uint32_t getFinishedFrame() const;
124 :
125 : /**
126 : * Send an error event to the application node.
127 : *
128 : * @param error the error code.
129 : * @version 1.7.1
130 : */
131 : EQ_API EventOCommand sendError(const uint32_t error);
132 :
133 : /**
134 : * Process a received spacemouse event.
135 : *
136 : * The task of this method is to update the node as necessary, and send it
137 : * to the application using Config::sendEvent().
138 : *
139 : * @param event the received event.
140 : * @return true if the event was handled, false if not.
141 : * @version 1.5.2
142 : */
143 : EQ_API virtual bool processEvent(AxisEvent& event);
144 : EQ_API virtual bool processEvent(ButtonEvent& event);
145 : EQ_API virtual bool processEvent(Statistic& event);
146 :
147 : /** @internal @sa Serializable::setDirty() */
148 : EQ_API void setDirty(const uint64_t bits) override;
149 :
150 : /** @internal */
151 : EQ_API void dirtyClientExit();
152 :
153 : protected:
154 : /** @internal */
155 : EQ_API
156 : void attach(const uint128_t& id, const uint32_t instanceID) override;
157 :
158 : /** @name Actions */
159 : //@{
160 : /**
161 : * Start a frame by unlocking all child resources.
162 : *
163 : * @param frameNumber the frame to start.
164 : * @version 1.0
165 : */
166 : EQ_API void startFrame(const uint32_t frameNumber);
167 :
168 : /**
169 : * Signal the completion of a frame to the parent.
170 : *
171 : * @param frameNumber the frame to end.
172 : * @version 1.0
173 : */
174 : EQ_API void releaseFrame(const uint32_t frameNumber);
175 :
176 : /**
177 : * Release the local synchronization of the parent for a frame.
178 : *
179 : * @param frameNumber the frame to release.
180 : * @version 1.0
181 : */
182 : EQ_API void releaseFrameLocal(const uint32_t frameNumber);
183 : //@}
184 :
185 : /**
186 : * @name Callbacks
187 : *
188 : * The callbacks are called by Equalizer during rendering to execute
189 : * various actions.
190 : */
191 : //@{
192 :
193 : /**
194 : * Initialize this node.
195 : *
196 : * @param initID the init identifier.
197 : * @version 1.0
198 : */
199 : EQ_API virtual bool configInit(const uint128_t& initID);
200 :
201 : /** Exit this node. @version 1.0 */
202 : EQ_API virtual bool configExit();
203 :
204 : /**
205 : * Start rendering a frame.
206 : *
207 : * Called once at the beginning of each frame, to start the node's frame
208 : * and to do per-frame updates of node-specific data. This method has to
209 : * call startFrame(). Immediately releases local synchronization if the
210 : * thread model is async.
211 : *
212 : * @param frameID the per-frame identifier.
213 : * @param frameNumber the frame to start.
214 : * @sa startFrame(), Config::beginFrame()
215 : * @version 1.0
216 : */
217 : EQ_API virtual void frameStart(const uint128_t& frameID,
218 : const uint32_t frameNumber);
219 :
220 : /**
221 : * Finish rendering a frame.
222 : *
223 : * Called once at the end of each frame, to end the frame and to do
224 : * per-frame updates of node-specific data. This method has to call
225 : * releaseFrame().
226 : *
227 : * @param frameID the per-frame identifier.
228 : * @param frameNumber the frame to finish.
229 : * @sa endFrame(), Config::finishFrame()
230 : * @version 1.0
231 : */
232 : EQ_API virtual void frameFinish(const uint128_t& frameID,
233 : const uint32_t frameNumber);
234 :
235 : /**
236 : * Finish drawing.
237 : *
238 : * Called once per frame after the last draw operation. Waits for the
239 : * pipes to release the local synchonization and releases the node's
240 : * local synchronization if the thread model is draw_sync (the default).
241 : *
242 : * @param frameID the per-frame identifier.
243 : * @param frameNumber the frame finished with draw.
244 : * @sa Pipe::waitFrameLocal(), releaseFrameLocal()
245 : * @version 1.0
246 : */
247 : EQ_API virtual void frameDrawFinish(const uint128_t& frameID,
248 : const uint32_t frameNumber);
249 :
250 : /**
251 : * Finish all rendering tasks.
252 : *
253 : * Called once per frame after all frame tasks. Waits for the pipes to
254 : * release the local synchonization and releases the node's local
255 : * synchronization if the thread model is local_sync.
256 : *
257 : * Note that frameFinish is called after the latency is exhausted and
258 : * synchronizes pipe thread execution.
259 : *
260 : * @param frameID the per-frame identifier.
261 : * @param frameNumber the frame finished with draw.
262 : * @sa Pipe::waitFrameLocal(), releaseFrameLocal()
263 : * @version 1.0
264 : */
265 : EQ_API virtual void frameTasksFinish(const uint128_t& frameID,
266 : const uint32_t frameNumber);
267 : //@}
268 :
269 : private:
270 : detail::Node* const _impl;
271 :
272 : void _setAffinity();
273 :
274 : void _finishFrame(const uint32_t frameNumber) const;
275 : void _frameFinish(const uint128_t& frameID, const uint32_t frameNumber);
276 :
277 : void _flushObjects();
278 :
279 : /** The command functions. */
280 : bool _cmdCreatePipe(co::ICommand& command);
281 : bool _cmdDestroyPipe(co::ICommand& command);
282 : bool _cmdConfigInit(co::ICommand& command);
283 : bool _cmdConfigExit(co::ICommand& command);
284 : bool _cmdFrameStart(co::ICommand& command);
285 : bool _cmdFrameFinish(co::ICommand& command);
286 : bool _cmdFrameDrawFinish(co::ICommand& command);
287 : bool _cmdFrameTasksFinish(co::ICommand& command);
288 : bool _cmdFrameDataTransmit(co::ICommand& command);
289 : bool _cmdFrameDataReady(co::ICommand& command);
290 : bool _cmdSetAffinity(co::ICommand& command);
291 :
292 2 : LB_TS_VAR(_nodeThread);
293 : };
294 : }
295 :
296 : #endif // EQ_NODE_H
|