Line data Source code
1 :
2 : /* Copyright (c) 2005-2016, 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_COMPOUND_H
21 : #define EQSERVER_COMPOUND_H
22 :
23 : #include "channel.h" // used in inline method
24 : #include "frustum.h" // member
25 : #include "frustumData.h" // member
26 : #include "visitorResult.h" // enum
27 : #include "types.h"
28 :
29 : #include <eq/fabric/frame.h> // enum Frame::Buffer
30 : #include <eq/fabric/projection.h> // used in inline method
31 : #include <eq/fabric/range.h> // member
32 : #include <eq/fabric/subPixel.h> // member
33 : #include <eq/fabric/swapBarrier.h> // RefPtr member
34 : #include <eq/fabric/task.h> // enum
35 : #include <eq/fabric/viewport.h> // member
36 : #include <eq/fabric/wall.h> // used in inline method
37 : #include <eq/fabric/zoom.h> // member
38 : #include <co/barrier.h>
39 : #include <lunchbox/thread.h>
40 : #include <iostream>
41 : #include <vector>
42 :
43 : namespace eq
44 : {
45 : namespace server
46 : {
47 : /** The compound form the tree describing the rendering task setup. */
48 : class Compound
49 : {
50 : public:
51 : /** Construct a new root compound. */
52 : EQSERVER_API explicit Compound( Config* parent );
53 :
54 : /** Construct a new compound child. */
55 : EQSERVER_API explicit Compound( Compound* parent );
56 :
57 : /** Destruct the compound and all children. */
58 : virtual ~Compound();
59 :
60 : /** The color mask bits, used for anaglyphic stereo. */
61 : enum ColorMask
62 : {
63 : COLOR_MASK_NONE = 0,
64 : COLOR_MASK_RED = 0x02,
65 : COLOR_MASK_GREEN = 0x04,
66 : COLOR_MASK_BLUE = 0x08,
67 : COLOR_MASK_ALL = 0xff
68 : };
69 :
70 : /**
71 : * @name Attributes
72 : */
73 : //@{
74 : // Note: also update string array initialization in compound.cpp
75 : enum IAttribute
76 : {
77 : IATTR_STEREO_MODE,
78 : IATTR_STEREO_ANAGLYPH_LEFT_MASK,
79 : IATTR_STEREO_ANAGLYPH_RIGHT_MASK,
80 : IATTR_FILL1,
81 : IATTR_FILL2,
82 : IATTR_ALL
83 : };
84 :
85 : /**
86 : * @name Data Access
87 : */
88 : //@{
89 : /** Reparent the given child to this compound. */
90 : EQSERVER_API void adopt( Compound* child );
91 :
92 : /** @return if the compound is a leaf compound. */
93 2316 : bool isLeaf() const { return _children.empty(); }
94 :
95 : /** @return true if this is the top-most compound with a channel. */
96 : bool isDestination() const;
97 :
98 : /** @return if the compound has the destination channel. */
99 : bool hasDestinationChannel() const;
100 :
101 : /** @return the children of this compound. */
102 7942 : const Compounds& getChildren() const { return _children; }
103 :
104 : /** @return the parent compound. */
105 16448 : Compound* getParent() const { return _parent; }
106 :
107 : /** @return the root of the compound tree. */
108 1968 : Compound* getRoot()
109 1968 : { return _parent ? _parent->getRoot() : this; }
110 1444 : const Compound* getRoot() const
111 1444 : { return _parent ? _parent->getRoot() : this; }
112 :
113 : /** @return true if this is the top-most compound. */
114 4 : bool isRoot() const { return _parent==0; }
115 :
116 : /** @return the next sibling, or 0. */
117 : Compound* getNext() const;
118 :
119 24 : Config* getConfig() { return getRoot()->_config; }
120 1444 : const Config* getConfig() const { return getRoot()->_config; }
121 :
122 : Node* getNode();
123 : ServerPtr getServer();
124 :
125 16 : void setName( const std::string& name ) { _name = name; }
126 2812 : const std::string& getName() const { return _name; }
127 :
128 : /**
129 : * Set the channel of this compound.
130 : *
131 : * The compound uses the channel for all rendering operations executed
132 : * by this compound. The compound's swap barrier will be updated with
133 : * the segment's swap barrier if this compound becomes a destination
134 : * compound.
135 : *
136 : * @param channel the channel.
137 : */
138 : EQSERVER_API void setChannel( Channel* channel );
139 :
140 : /**
141 : * Return the channel of this compound.
142 : *
143 : * Note that the channel is inherited, that is, if this compound has no
144 : * channel, the parent's channel is returned.
145 : *
146 : * @return the channel of this compound.
147 : */
148 : EQSERVER_API Channel* getChannel();
149 : EQSERVER_API const Channel* getChannel() const;
150 :
151 : Window* getWindow();
152 : const Window* getWindow() const;
153 :
154 : Pipe* getPipe();
155 : const Pipe* getPipe() const;
156 :
157 : /** Attach a load balancer to this compound. */
158 : EQSERVER_API void addEqualizer( Equalizer* equalizer );
159 :
160 : /** Get the attached load balancers. */
161 2054 : const Equalizers& getEqualizers() const { return _equalizers; }
162 :
163 : /**
164 : * Set the tasks to be executed by the compound, overwriting previous
165 : * tasks.
166 : *
167 : * Tasks define which actions are executed by the compound, and provide
168 : * a flexible way of configuring the decomposition and recomposition. A
169 : * separate html design document describes them in depth.
170 : *
171 : * @param tasks the compound tasks.
172 : */
173 376 : void setTasks( const uint32_t tasks ) { _data.tasks = tasks; }
174 :
175 : /**
176 : * Add a task to be executed by the compound, preserving previous tasks.
177 : *
178 : * @param task the compound task to add.
179 : */
180 568 : void enableTask( const fabric::Task task ) { _data.tasks |= task; }
181 :
182 : /** @return the tasks executed by this compound. */
183 2054 : uint32_t getTasks() const { return _data.tasks; }
184 :
185 : /**
186 : * Set the image buffers to be used by the compound during
187 : * recomposition, overwriting previous buffers.
188 : *
189 : * @param buffers the compound image buffers.
190 : */
191 204 : void setBuffers( const uint32_t buffers ) { _data.buffers = buffers; }
192 :
193 : /**
194 : * Add a image buffer to be used by the compound, preserving previous
195 : * buffers.
196 : *
197 : * @param buffer the compound image buffer to add.
198 : */
199 : void enableBuffer( const eq::fabric::Frame::Buffer buffer )
200 : { _data.buffers |= buffer; }
201 :
202 : /** @return the image buffers used by this compound. */
203 2054 : uint32_t getBuffers() const { return _data.buffers; }
204 :
205 256 : void setViewport( const Viewport& vp ) { _data.vp = vp; }
206 2054 : const Viewport& getViewport() const { return _data.vp; }
207 :
208 724 : void setRange( const Range& range ) { _data.range = range; }
209 2054 : const Range& getRange() const { return _data.range; }
210 :
211 68 : void setPeriod( const uint32_t period ) { _data.period = period; }
212 2054 : uint32_t getPeriod() const { return _data.period; }
213 :
214 68 : void setPhase( const uint32_t phase ) { _data.phase = phase; }
215 2054 : uint32_t getPhase() const { return _data.phase; }
216 :
217 92 : void setPixel( const Pixel& pixel ) { _data.pixel = pixel; }
218 2054 : const Pixel& getPixel() const { return _data.pixel; }
219 :
220 44 : void setSubPixel( const SubPixel& subPixel )
221 44 : { _data.subPixel = subPixel; }
222 2054 : const SubPixel& getSubPixel() const { return _data.subPixel; }
223 :
224 4 : void setZoom( const Zoom& zoom ) { _data.zoom = zoom; }
225 2054 : const Zoom& getZoom() const { return _data.zoom; }
226 :
227 0 : void setMaxFPS( const float fps ) { _data.maxFPS = fps; }
228 : float getMaxFPS() const { return _data.maxFPS; }
229 :
230 0 : void setUsage( const float usage )
231 0 : { LBASSERT( usage >= 0.f ); _usage = usage; }
232 0 : float getUsage() const { return _usage; }
233 :
234 4 : void setTaskID( const uint32_t id ) { _taskID = id; }
235 0 : uint32_t getTaskID() const { return _taskID; }
236 : //@}
237 :
238 : /** @name IO object access. */
239 : //@{
240 : /**
241 : * Set a swap barrier.
242 : *
243 : * Windows of compounds with the same swap barrier name will enter a
244 : * barrier before executing Window::swap. Setting an empty string
245 : * disables the swap barrier.
246 : *
247 : * @param barrier the swap barrier.
248 : */
249 : void setSwapBarrier( SwapBarrierPtr barrier );
250 :
251 : /** @return the current swap barrier. */
252 2254 : SwapBarrierConstPtr getSwapBarrier() const { return _swapBarrier; }
253 :
254 : /**
255 : * Add a new input frame for this compound.
256 : *
257 : * @param frame the input frame.
258 : */
259 : EQSERVER_API void addInputFrame( Frame* frame );
260 :
261 : /** @return the vector of input frames. */
262 2054 : const Frames& getInputFrames() const {return _inputFrames; }
263 :
264 : /**
265 : * Add a new output frame for this compound.
266 : *
267 : * @param frame the output frame.
268 : */
269 : EQSERVER_API void addOutputFrame( Frame* frame );
270 :
271 : /** @return the vector of output frames. */
272 2058 : const Frames& getOutputFrames() const { return _outputFrames; }
273 :
274 : /**
275 : * Add a new input tile queue for this compound.
276 : *
277 : * @param tileQueue the input tile queue.
278 : */
279 : EQSERVER_API void addInputTileQueue( TileQueue* tileQueue );
280 :
281 : /**
282 : * Remove an input tile queue from this compound.
283 : *
284 : * @param tileQueue the input tile queue.
285 : */
286 : EQSERVER_API void removeInputTileQueue( TileQueue* tileQueue );
287 :
288 : /** @return the vector of input tile queues. */
289 2054 : const TileQueues& getInputTileQueues() const { return _inputTileQueues;}
290 :
291 : /**
292 : * Add a new output tile queue for this compound.
293 : *
294 : * @param queue the output tile queue.
295 : */
296 : EQSERVER_API void addOutputTileQueue( TileQueue* queue );
297 :
298 : /**
299 : * Remove an output tile queue from this compound.
300 : *
301 : * @param tileQueue the output tile queue.
302 : */
303 : EQSERVER_API void removeOutputTileQueue( TileQueue* tileQueue );
304 :
305 : /** @return the vector of output tile queues. */
306 2058 : const TileQueues& getOutputTileQueues() const { return _outputTileQueues; }
307 :
308 : /** @return true if the compound is a tile compound. */
309 0 : bool hasTiles() const
310 0 : { return !_outputTileQueues.empty() || !_inputTileQueues.empty(); }
311 : //@}
312 :
313 : /**
314 : * @name Inherit data access needed during channel update.
315 : *
316 : * Inherit data are the actual, as opposed to configured, attributes and
317 : * data used by the compound. The inherit data is updated at the
318 : * beginning of each update().
319 : */
320 : //@{
321 : RenderContext setupRenderContext( Eye eye ) const;
322 0 : uint32_t getInheritBuffers() const { return _inherit.buffers; }
323 0 : const PixelViewport& getInheritPixelViewport() const { return _inherit.pvp;}
324 : const Range& getInheritRange() const { return _inherit.range; }
325 0 : const Pixel& getInheritPixel() const { return _inherit.pixel; }
326 : const SubPixel& getInheritSubPixel() const { return _inherit.subPixel; }
327 0 : const Zoom& getInheritZoom() const { return _inherit.zoom; }
328 0 : uint32_t getInheritPeriod() const { return _inherit.period; }
329 : uint32_t getInheritPhase() const { return _inherit.phase; }
330 0 : float getInheritMaxFPS() const { return _inherit.maxFPS; }
331 0 : int32_t getInheritIAttribute( const IAttribute attr ) const
332 0 : { return _inherit.iAttributes[attr]; }
333 4 : uint32_t getInheritTasks() const { return _inherit.tasks; }
334 0 : uint32_t getInheritEyes() const { return _inherit.eyes; }
335 0 : Channel* getInheritChannel() { return _inherit.channel; }
336 0 : const Channel* getInheritChannel() const { return _inherit.channel; }
337 :
338 : /** @return true if the task is set, false if not. */
339 0 : bool testInheritTask( const fabric::Task task ) const
340 0 : { return (_inherit.tasks & task); }
341 :
342 : /** Delete an inherit task, if it was set. */
343 0 : void unsetInheritTask( const fabric::Task task ) { _inherit.tasks &= ~task;}
344 :
345 : /** @return true if the eye pass is actived, false if not. */
346 4 : bool testInheritEye( const Eye eye ) const { return (_inherit.eyes & eye); }
347 : //@}
348 :
349 : /** @name Frustum Operations */
350 : //@{
351 : /**
352 : * Set the compound's frustum using a wall description.
353 : *
354 : * @param wall the wall description.
355 : */
356 : EQSERVER_API void setWall( const Wall& wall );
357 :
358 : /** @return the last specified wall description. */
359 28 : const Wall& getWall() const { return _frustum.getWall(); }
360 :
361 : /**
362 : * Set the compound's frustum using a projection description
363 : *
364 : * @param projection the projection description.
365 : */
366 : EQSERVER_API void setProjection( const Projection& projection );
367 :
368 : /** @return the last specified projection description. */
369 0 : const Projection& getProjection() const
370 0 : { return _frustum.getProjection(); }
371 :
372 : /** @return the type of the latest specified frustum. */
373 2054 : Frustum::Type getFrustumType() const
374 2054 : { return _frustum.getCurrentType(); }
375 :
376 : /** @return the frustum of this compound. */
377 0 : Frustum& getFrustum() { return _frustum; }
378 :
379 : /** @return the frustum of this compound. */
380 : const Frustum& getFrustum() const { return _frustum; }
381 :
382 : /** Update the frustum from the view or segment. */
383 : void updateFrustum( const Vector3f& eye, const float ratio );
384 :
385 : /** compute the frustum for a given viewport */
386 : void computeTileFrustum( Frustumf& frustum, const fabric::Eye eye,
387 : Viewport vp, bool ortho ) const;
388 :
389 : /** @return the bitwise OR of the eye values. */
390 2058 : uint32_t getEyes() const { return _data.eyes; }
391 :
392 : /**
393 : * Set the eyes to be used by the compound.
394 : *
395 : * Previously set eyes are overwritten.
396 : *
397 : * @param eyes the compound eyes.
398 : */
399 216 : void setEyes( const uint32_t eyes ) { _data.eyes = eyes; }
400 :
401 : /**
402 : * Add eyes to be used by the compound.
403 : *
404 : * Previously set eyes are preserved.
405 : *
406 : * @param eyes the compound eyes.
407 : */
408 360 : void enableEye( const uint32_t eyes ) { _data.eyes |= eyes; }
409 : //@}
410 :
411 : /** @name Compound Operations. */
412 : //@{
413 : /**
414 : * Traverse the compound and all children using a compound visitor.
415 : *
416 : * @param visitor the visitor.
417 : * @return the result of the visitor traversal.
418 : */
419 : EQSERVER_API VisitorResult accept( CompoundVisitor& visitor ) const;
420 : /** Non-const version of accept(). */
421 : EQSERVER_API VisitorResult accept( CompoundVisitor& visitor );
422 :
423 : /** @internal Activate the given eyes for the the compound tree. */
424 : void activate( const uint32_t eyes );
425 :
426 : /** @internal Deactivate the given eyes for the the compound tree. */
427 : void deactivate( const uint32_t eyes );
428 :
429 : /**
430 : * @return if the compound is activated for selected eye
431 : and current (DPlex).
432 : *
433 : * @param eye eye which will be tested.
434 : */
435 : bool isInheritActive( const Eye eye ) const;
436 :
437 : /** @return true if the compound is activated for any later eye pass. */
438 : bool isLastInheritEye( const Eye eye ) const;
439 :
440 : /**
441 : * @return true if the compound is active and the compound's channel is
442 : * running.
443 : */
444 : bool isActive() const;
445 :
446 : /** Initialize this compound. */
447 : void init();
448 :
449 : /** Exit this compound. */
450 : void exit();
451 :
452 : /** Initialize the default tasks of this compound. */
453 : void updateInheritTasks();
454 :
455 : /** Register all distributed objects (frames) */
456 : void register_();
457 :
458 : /** Deregister all distributed objects (frames) */
459 : void deregister();
460 :
461 : /** Back up all relevant compound data. */
462 : void backup();
463 :
464 : /** Restore all relevant compound data. */
465 : void restore();
466 :
467 : /**
468 : * Updates this compound.
469 : *
470 : * The compound's parameters for the next frame are computed.
471 : */
472 : void update( const uint32_t frameNumber );
473 :
474 : /** Update the inherit data of this compound. */
475 : void updateInheritData( const uint32_t frameNumber );
476 : //@}
477 :
478 : /** @name Compound listener interface. */
479 : //@{
480 : /** Register a compound listener. */
481 : void addListener( CompoundListener* listener );
482 : /** Deregister a compound listener. */
483 : void removeListener( CompoundListener* listener );
484 :
485 : /** Notify all listeners that the compound is about to be updated. */
486 : void fireUpdatePre( const uint32_t frameNumber );
487 : //@}
488 :
489 : /**
490 : * @name Attributes
491 : */
492 : //@{
493 28 : void setIAttribute( const IAttribute attr, const int32_t value )
494 28 : { _data.iAttributes[attr] = value; }
495 10270 : int32_t getIAttribute( const IAttribute attr ) const
496 10270 : { return _data.iAttributes[attr]; }
497 : static const std::string& getIAttributeString( const IAttribute attr );
498 : //@}
499 :
500 : typedef stde::hash_map<std::string, co::Barrier*> BarrierMap;
501 : typedef BarrierMap::const_iterator BarrierMapCIter;
502 :
503 : typedef stde::hash_map<std::string, Frame*> FrameMap;
504 : typedef FrameMap::const_iterator FrameMapCIter;
505 :
506 : typedef stde::hash_map<std::string, TileQueue*> TileQueueMap;
507 :
508 : private:
509 : //-------------------- Members --------------------
510 : std::string _name;
511 :
512 : /**
513 : * The config the compound is attached to, only set on root
514 : * compounds.
515 : */
516 : friend class Config;
517 : Config* const _config;
518 :
519 : Compound* const _parent;
520 : Compounds _children;
521 :
522 : /** Percentage the resource should be used. */
523 : float _usage;
524 :
525 : /** Unique identifier for channel tasks. */
526 : uint32_t _taskID;
527 :
528 12 : struct Data
529 : {
530 : Data();
531 :
532 : Channel* channel;
533 : Viewport vp;
534 : PixelViewport pvp;
535 : Vector4i overdraw;
536 : Range range;
537 : Pixel pixel;
538 : SubPixel subPixel;
539 : FrustumData frustumData;
540 : Zoom zoom;
541 : uint32_t buffers;
542 : uint32_t eyes;
543 : uint32_t tasks;
544 : uint32_t period;
545 : uint32_t phase;
546 : int32_t iAttributes[IATTR_ALL];
547 : float maxFPS;
548 :
549 : // compound activation per eye
550 : uint32_t active[ fabric::NUM_EYES ];
551 :
552 : union // placeholder for binary-compatible changes
553 : {
554 : char dummy[16];
555 : };
556 : };
557 :
558 : Data _data;
559 : Data _backup;
560 : Data _inherit;
561 :
562 : /** The frustum description of this compound. */
563 : Frustum _frustum;
564 :
565 : typedef std::vector< CompoundListener* > CompoundListeners;
566 : CompoundListeners _listeners;
567 :
568 : Equalizers _equalizers;
569 :
570 : SwapBarrierPtr _swapBarrier;
571 :
572 : Frames _inputFrames;
573 : Frames _outputFrames;
574 :
575 : TileQueues _inputTileQueues;
576 : TileQueues _outputTileQueues;
577 :
578 : struct Private;
579 : Private* _private; // placeholder for binary-compatible changes
580 :
581 8200 : LB_TS_VAR( _serverThread );
582 :
583 : //-------------------- Methods --------------------
584 : void _addChild( Compound* child );
585 : bool _removeChild( Compound* child );
586 :
587 : void _updateOverdraw( Wall& wall );
588 : void _updateInheritRoot();
589 : void _updateInheritNode();
590 : void _updateInheritPVP();
591 : void _updateInheritOverdraw();
592 : void _updateInheritStereo();
593 : void _updateInheritActive( const uint32_t frameNumber );
594 :
595 : void _setDefaultFrameName( Frame* frame );
596 : void _setDefaultTileQueueName( TileQueue* tileQueue );
597 :
598 : void _fireChildAdded( Compound* child );
599 : void _fireChildRemove( Compound* child );
600 :
601 : void _computeFrustum( RenderContext& context ) const;
602 : void _computePerspective( RenderContext& context,
603 : const Vector3f& eye ) const;
604 : void _computeOrtho( RenderContext& context, const Vector3f& eye ) const;
605 : Vector3f _getEyePosition( const fabric::Eye eye ) const;
606 : const Matrix4f& _getInverseHeadMatrix() const;
607 : void _computeFrustumCorners( Frustumf& frustum,
608 : const FrustumData& frustumData, const Vector3f& eye,
609 : const bool ortho, const Viewport* const vp = 0 ) const;
610 : };
611 :
612 : std::ostream& operator << ( std::ostream& os, const Compound& compound );
613 : }
614 : }
615 : #endif // EQSERVER_COMPOUND_H
|