Line data Source code
1 :
2 : /* Copyright (c) 2005-2013, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2010, Cedric Stalder <cedric.stalder@gmail.com>
4 : * 2011, 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/client/frame.h>
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 Compound( Config* parent );
53 :
54 : /** Construct a new compound child. */
55 : EQSERVER_API 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 6783 : 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 16490 : const Compounds& getChildren() const { return _children; }
103 :
104 : /** @return the parent compound. */
105 42763 : Compound* getParent() const { return _parent; }
106 :
107 : /** @return the root of the compound tree. */
108 5760 : Compound* getRoot()
109 5760 : { return _parent ? _parent->getRoot() : this; }
110 997 : const Compound* getRoot() const
111 997 : { return _parent ? _parent->getRoot() : this; }
112 :
113 : /** @return true if this is the top-most compound. */
114 1363 : bool isRoot() const { return _parent==0; }
115 :
116 : /** @return the next sibling, or 0. */
117 : Compound* getNext() const;
118 :
119 1305 : Config* getConfig() { return getRoot()->_config; }
120 997 : const Config* getConfig() const { return getRoot()->_config; }
121 :
122 : Node* getNode();
123 : ServerPtr getServer();
124 :
125 172 : void setName( const std::string& name ) { _name = name; }
126 2333 : 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 2202 : 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 184 : 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 276 : void enableTask( const fabric::Task task ) { _data.tasks |= task; }
181 :
182 : /** @return the tasks executed by this compound. */
183 1876 : 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 147 : 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::Frame::Buffer buffer )
200 : { _data.buffers |= buffer; }
201 :
202 : /** @return the image buffers used by this compound. */
203 1876 : uint32_t getBuffers() const { return _data.buffers; }
204 :
205 159 : void setViewport( const Viewport& vp ) { _data.vp = vp; }
206 1876 : const Viewport& getViewport() const { return _data.vp; }
207 :
208 410 : void setRange( const Range& range ) { _data.range = range; }
209 1876 : const Range& getRange() const { return _data.range; }
210 :
211 34 : void setPeriod( const uint32_t period ) { _data.period = period; }
212 1876 : uint32_t getPeriod() const { return _data.period; }
213 :
214 34 : void setPhase( const uint32_t phase ) { _data.phase = phase; }
215 1876 : uint32_t getPhase() const { return _data.phase; }
216 :
217 46 : void setPixel( const Pixel& pixel ) { _data.pixel = pixel; }
218 1876 : const Pixel& getPixel() const { return _data.pixel; }
219 :
220 33 : void setSubPixel( const SubPixel& subpixel )
221 33 : { _data.subpixel = subpixel; }
222 1876 : const SubPixel& getSubPixel() const { return _data.subpixel; }
223 :
224 2 : void setZoom( const Zoom& zoom ) { _data.zoom = zoom; }
225 1876 : 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 872 : void setTaskID( const uint32_t id ) { _taskID = id; }
235 13 : 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 2079 : 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 1909 : 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 2378 : 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 1988 : 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 2360 : const TileQueues& getOutputTileQueues() const
307 2360 : { return _outputTileQueues; }
308 :
309 : /** @return true if the compound is a tile compound. */
310 7 : bool hasTiles() const
311 7 : { return !_outputTileQueues.empty() || !_inputTileQueues.empty(); }
312 : //@}
313 :
314 : /**
315 : * @name Inherit data access needed during channel update.
316 : *
317 : * Inherit data are the actual, as opposed to configured, attributes and
318 : * data used by the compound. The inherit data is updated at the
319 : * beginning of each update().
320 : */
321 : //@{
322 9 : uint32_t getInheritBuffers() const { return _inherit.buffers; }
323 22 : const PixelViewport& getInheritPixelViewport() const
324 22 : { return _inherit.pvp; }
325 13 : const Vector4i& getInheritOverdraw() const
326 13 : { return _inherit.overdraw; }
327 39 : const Viewport& getInheritViewport() const { return _inherit.vp; }
328 22 : const Range& getInheritRange() const { return _inherit.range; }
329 48 : const Pixel& getInheritPixel() const { return _inherit.pixel; }
330 22 : const SubPixel& getInheritSubPixel() const
331 22 : { return _inherit.subpixel; }
332 31 : const Zoom& getInheritZoom() const { return _inherit.zoom; }
333 22 : uint32_t getInheritPeriod() const { return _inherit.period; }
334 22 : uint32_t getInheritPhase() const { return _inherit.phase; }
335 9 : float getInheritMaxFPS() const { return _inherit.maxFPS; }
336 26 : int32_t getInheritIAttribute( const IAttribute attr ) const
337 26 : { return _inherit.iAttributes[attr]; }
338 65 : const FrustumData& getInheritFrustumData() const
339 65 : { return _inherit.frustumData; }
340 379 : uint32_t getInheritTasks() const { return _inherit.tasks; }
341 0 : uint32_t getInheritEyes() const { return _inherit.eyes; }
342 408 : Channel* getInheritChannel() { return _inherit.channel; }
343 65 : const Channel* getInheritChannel() const { return _inherit.channel; }
344 :
345 : /** @return true if the task is set, false if not. */
346 747 : bool testInheritTask( const fabric::Task task ) const
347 747 : { return (_inherit.tasks & task); }
348 :
349 : /** Delete an inherit task, if it was set. */
350 116 : void unsetInheritTask( const fabric::Task task )
351 116 : { _inherit.tasks &= ~task; }
352 :
353 : /** @return true if the eye pass is actived, false if not. */
354 90 : bool testInheritEye( const Eye eye ) const
355 90 : { return (_inherit.eyes & eye); }
356 : //@}
357 :
358 : /** @name Frustum Operations */
359 : //@{
360 : /**
361 : * Set the compound's frustum using a wall description.
362 : *
363 : * @param wall the wall description.
364 : */
365 : EQSERVER_API void setWall( const Wall& wall );
366 :
367 : /** @return the last specified wall description. */
368 14 : const Wall& getWall() const { return _frustum.getWall(); }
369 :
370 : /**
371 : * Set the compound's frustum using a projection description
372 : *
373 : * @param projection the projection description.
374 : */
375 : EQSERVER_API void setProjection( const Projection& projection );
376 :
377 : /** @return the last specified projection description. */
378 0 : const Projection& getProjection() const
379 0 : { return _frustum.getProjection(); }
380 :
381 : /** @return the type of the latest specified frustum. */
382 1876 : Frustum::Type getFrustumType() const
383 1876 : { return _frustum.getCurrentType(); }
384 :
385 : /** @return the frustum of this compound. */
386 0 : Frustum& getFrustum() { return _frustum; }
387 :
388 : /** @return the frustum of this compound. */
389 : const Frustum& getFrustum() const { return _frustum; }
390 :
391 : /** Update the frustum from the view or segment. */
392 : void updateFrustum( const Vector3f& eye, const float ratio );
393 :
394 : /** compute the frustum of the given context */
395 : void computeFrustum( RenderContext& context,
396 : const fabric::Eye eye ) const;
397 :
398 : /** compute the frustum for a given viewport */
399 : void computeTileFrustum( Frustumf& frustum, const fabric::Eye eye,
400 : Viewport vp, bool ortho ) const;
401 :
402 : /** @return the bitwise OR of the eye values. */
403 1986 : uint32_t getEyes() const { return _data.eyes; }
404 :
405 : /**
406 : * Set the eyes to be used by the compound.
407 : *
408 : * Previously set eyes are overwritten.
409 : *
410 : * @param eyes the compound eyes.
411 : */
412 378 : void setEyes( const uint32_t eyes ) { _data.eyes = eyes; }
413 :
414 : /**
415 : * Add eyes to be used by the compound.
416 : *
417 : * Previously set eyes are preserved.
418 : *
419 : * @param eyes the compound eyes.
420 : */
421 180 : void enableEye( const uint32_t eyes ) { _data.eyes |= eyes; }
422 : //@}
423 :
424 : /** @name Compound Operations. */
425 : //@{
426 : /**
427 : * Traverse the compound and all children using a compound visitor.
428 : *
429 : * @param visitor the visitor.
430 : * @return the result of the visitor traversal.
431 : */
432 : EQSERVER_API VisitorResult accept( CompoundVisitor& visitor ) const;
433 : /** Non-const version of accept(). */
434 : EQSERVER_API VisitorResult accept( CompoundVisitor& visitor );
435 :
436 : /** @internal Activate the given eyes for the the compound tree. */
437 : void activate( const uint32_t eyes );
438 :
439 : /** @internal Deactivate the given eyes for the the compound tree. */
440 : void deactivate( const uint32_t eyes );
441 :
442 : /**
443 : * @return if the compound is activated for selected eye
444 : and current (DPlex).
445 : *
446 : * @param eye eye which will be tested.
447 : */
448 : bool isInheritActive( const Eye eye ) const;
449 :
450 : /** @return true if the compound is activated for any later eye pass. */
451 : bool isLastInheritEye( const Eye eye ) const;
452 :
453 : /**
454 : * @return true if the compound is active and the compound's channel is
455 : * running.
456 : */
457 : bool isActive() const;
458 :
459 : /** Initialize this compound. */
460 : void init();
461 :
462 : /** Exit this compound. */
463 : void exit();
464 :
465 : /** Initialize the default tasks of this compound. */
466 : void updateInheritTasks();
467 :
468 : /** Register all distributed objects (frames) */
469 : void register_();
470 :
471 : /** Deregister all distributed objects (frames) */
472 : void deregister();
473 :
474 : /** Back up all relevant compound data. */
475 : void backup();
476 :
477 : /** Restore all relevant compound data. */
478 : void restore();
479 :
480 : /**
481 : * Updates this compound.
482 : *
483 : * The compound's parameters for the next frame are computed.
484 : */
485 : void update( const uint32_t frameNumber );
486 :
487 : /** Update the inherit data of this compound. */
488 : void updateInheritData( const uint32_t frameNumber );
489 : //@}
490 :
491 : /** @name Compound listener interface. */
492 : //@{
493 : /** Register a compound listener. */
494 : void addListener( CompoundListener* listener );
495 : /** Deregister a compound listener. */
496 : void removeListener( CompoundListener* listener );
497 :
498 : /** Notify all listeners that the compound is about to be updated. */
499 : void fireUpdatePre( const uint32_t frameNumber );
500 : //@}
501 :
502 : /**
503 : * @name Attributes
504 : */
505 : //@{
506 14 : void setIAttribute( const IAttribute attr, const int32_t value )
507 14 : { _data.iAttributes[attr] = value; }
508 9380 : int32_t getIAttribute( const IAttribute attr ) const
509 9380 : { return _data.iAttributes[attr]; }
510 : static const std::string& getIAttributeString( const IAttribute attr );
511 : //@}
512 :
513 : typedef stde::hash_map<std::string, co::Barrier*> BarrierMap;
514 : typedef BarrierMap::const_iterator BarrierMapCIter;
515 :
516 : typedef stde::hash_map<std::string, Frame*> FrameMap;
517 : typedef FrameMap::const_iterator FrameMapCIter;
518 :
519 : typedef stde::hash_map<std::string, TileQueue*> TileQueueMap;
520 :
521 : private:
522 : //-------------------- Members --------------------
523 : std::string _name;
524 :
525 : /**
526 : * The config the compound is attached to, only set on root
527 : * compounds.
528 : */
529 : friend class Config;
530 : Config* const _config;
531 :
532 : Compound* const _parent;
533 : Compounds _children;
534 :
535 : /** Percentage the resource should be used. */
536 : float _usage;
537 :
538 : /** Unique identifier for channel tasks. */
539 : uint32_t _taskID;
540 :
541 1631 : struct Data
542 : {
543 : Data();
544 :
545 : Channel* channel;
546 : Viewport vp;
547 : PixelViewport pvp;
548 : Vector4i overdraw;
549 : Range range;
550 : Pixel pixel;
551 : SubPixel subpixel;
552 : FrustumData frustumData;
553 : Zoom zoom;
554 : uint32_t buffers;
555 : uint32_t eyes;
556 : uint32_t tasks;
557 : uint32_t period;
558 : uint32_t phase;
559 : int32_t iAttributes[IATTR_ALL];
560 : float maxFPS;
561 :
562 : // compound activation per eye
563 : uint32_t active[ fabric::NUM_EYES ];
564 :
565 : union // placeholder for binary-compatible changes
566 : {
567 : char dummy[16];
568 : };
569 : };
570 :
571 : Data _data;
572 : Data _backup;
573 : Data _inherit;
574 :
575 : /** The frustum description of this compound. */
576 : Frustum _frustum;
577 :
578 : typedef std::vector< CompoundListener* > CompoundListeners;
579 : CompoundListeners _listeners;
580 :
581 : Equalizers _equalizers;
582 :
583 : SwapBarrierPtr _swapBarrier;
584 :
585 : Frames _inputFrames;
586 : Frames _outputFrames;
587 :
588 : TileQueues _inputTileQueues;
589 : TileQueues _outputTileQueues;
590 :
591 : struct Private;
592 : Private* _private; // placeholder for binary-compatible changes
593 :
594 4910 : LB_TS_VAR( _serverThread );
595 :
596 : //-------------------- Methods --------------------
597 : void _addChild( Compound* child );
598 : bool _removeChild( Compound* child );
599 :
600 : void _updateOverdraw( Wall& wall );
601 : void _updateInheritRoot();
602 : void _updateInheritNode();
603 : void _updateInheritPVP();
604 : void _updateInheritOverdraw();
605 : void _updateInheritStereo();
606 : void _updateInheritActive( const uint32_t frameNumber );
607 :
608 : void _setDefaultFrameName( Frame* frame );
609 : void _setDefaultTileQueueName( TileQueue* tileQueue );
610 :
611 : void _fireChildAdded( Compound* child );
612 : void _fireChildRemove( Compound* child );
613 :
614 : void _computePerspective( RenderContext& context,
615 : const Vector3f& eye ) const;
616 : void _computeOrtho( RenderContext& context, const Vector3f& eye ) const;
617 : Vector3f _getEyePosition( const fabric::Eye eye ) const;
618 : const Matrix4f& _getInverseHeadMatrix() const;
619 : void _computeFrustumCorners( Frustumf& frustum,
620 : const FrustumData& frustumData, const Vector3f& eye,
621 : const bool ortho, const Viewport* const vp = 0 ) const;
622 : };
623 :
624 : std::ostream& operator << ( std::ostream& os, const Compound& compound );
625 : }
626 : }
627 : #endif // EQSERVER_COMPOUND_H
|