00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "compound.h"
00019
00020 #include "canvas.h"
00021 #include "channel.h"
00022 #include "colorMask.h"
00023 #include "compoundExitVisitor.h"
00024 #include "compoundInitVisitor.h"
00025 #include "compoundListener.h"
00026 #include "compoundUpdateDataVisitor.h"
00027 #include "compoundUpdateInputVisitor.h"
00028 #include "compoundUpdateOutputVisitor.h"
00029 #include "config.h"
00030 #include "equalizers/equalizer.h"
00031 #include "frame.h"
00032 #include "frameData.h"
00033 #include "global.h"
00034 #include "layout.h"
00035 #include "log.h"
00036 #include "paths.h"
00037 #include "segment.h"
00038 #include "swapBarrier.h"
00039 #include "view.h"
00040
00041 #include <eq/base/base.h>
00042 #include <eq/base/stdExt.h>
00043 #include <eq/client/colorMask.h>
00044 #include <eq/client/global.h>
00045 #include <eq/client/packets.h>
00046 #include <eq/client/windowSystem.h>
00047 #include <eq/net/session.h>
00048
00049 #include <algorithm>
00050 #include <math.h>
00051 #include <vector>
00052
00053 #include "compoundActivateVisitor.h"
00054
00055 using namespace eq::base;
00056 using namespace std;
00057 using namespace stde;
00058
00059 namespace eq
00060 {
00061 namespace server
00062 {
00063 #define MAKE_ATTR_STRING( attr ) ( string("EQ_COMPOUND_") + #attr )
00064 std::string Compound::_iAttributeStrings[IATTR_ALL] = {
00065 MAKE_ATTR_STRING( IATTR_STEREO_MODE ),
00066 MAKE_ATTR_STRING( IATTR_STEREO_ANAGLYPH_LEFT_MASK ),
00067 MAKE_ATTR_STRING( IATTR_STEREO_ANAGLYPH_RIGHT_MASK ),
00068 MAKE_ATTR_STRING( IATTR_HINT_OFFSET ),
00069 MAKE_ATTR_STRING( IATTR_FILL1 ),
00070 MAKE_ATTR_STRING( IATTR_FILL2 )
00071 };
00072
00073 Compound::Compound()
00074 : _config( 0 )
00075 , _parent( 0 )
00076 , _active( false )
00077 , _usage( 1.0f )
00078 , _taskID( 0 )
00079 , _frustum( _data.frustumData )
00080 , _swapBarrier( 0 )
00081 {
00082 EQINFO << "New Compound @" << (void*)this << endl;
00083 }
00084
00085
00086 Compound::Compound( const Compound& from, Config* config, Compound* parent )
00087 : _name( from._name )
00088 , _config( 0 )
00089 , _parent( 0 )
00090 , _active( false )
00091 , _usage( from._usage )
00092 , _taskID( from._taskID )
00093 , _data( from._data )
00094 , _frustum( from._frustum, _data.frustumData )
00095 , _swapBarrier( 0 )
00096 {
00097 EQASSERTINFO( (config && !parent) || (!config && parent),
00098 "Either config or parent has to be given" );
00099
00100 if( config )
00101 config->addCompound( this );
00102 else
00103 {
00104 EQASSERT( parent );
00105 parent->addChild( this );
00106 }
00107
00108 if( from._data.channel )
00109 {
00110 const Channel* oldChannel = from._data.channel;
00111 const ChannelPath path = oldChannel->getPath();
00112
00113 _data.channel = getConfig()->getChannel( path );
00114 EQASSERT( _data.channel );
00115 }
00116
00117 for( CompoundVector::const_iterator i = from._children.begin();
00118 i != from._children.end(); ++i )
00119 {
00120 new Compound( **i, 0, this );
00121 }
00122
00123 for( EqualizerVector::const_iterator i = from._equalizers.begin();
00124 i != from._equalizers.end(); ++i )
00125 {
00126 addEqualizer( (*i)->clone( ));
00127 }
00128
00129 if( from._swapBarrier )
00130 _swapBarrier = new SwapBarrier( *from._swapBarrier );
00131
00132 for( FrameVector::const_iterator i = from._inputFrames.begin();
00133 i != from._inputFrames.end(); ++i )
00134 {
00135 addInputFrame( new Frame( **i ));
00136 }
00137
00138 for( FrameVector::const_iterator i = from._outputFrames.begin();
00139 i != from._outputFrames.end(); ++i )
00140 {
00141 addOutputFrame( new Frame( **i ));
00142 }
00143 }
00144
00145 Compound::~Compound()
00146 {
00147 delete _swapBarrier;
00148 _swapBarrier = 0;
00149
00150 for( EqualizerVector::const_iterator i = _equalizers.begin();
00151 i != _equalizers.end(); ++i )
00152 {
00153 Equalizer* equalizer = *i;
00154 equalizer->attach( 0 );
00155 delete equalizer;
00156 }
00157 _equalizers.clear();
00158
00159 for( CompoundVector::const_iterator i = _children.begin();
00160 i != _children.end(); ++i )
00161 {
00162 Compound* compound = *i;
00163 delete compound;
00164 }
00165 _children.clear();
00166
00167 if( _config )
00168 _config->removeCompound( this );
00169
00170 _config = 0;
00171
00172 for( FrameVector::const_iterator i = _inputFrames.begin();
00173 i != _inputFrames.end(); ++i )
00174 {
00175 Frame* frame = *i;
00176
00177 frame->_compound = 0;
00178 delete frame;
00179 }
00180 _inputFrames.clear();
00181
00182 for( FrameVector::const_iterator i = _outputFrames.begin();
00183 i != _outputFrames.end(); ++i )
00184 {
00185 Frame* frame = *i;
00186
00187 frame->_compound = 0;
00188 delete frame;
00189 }
00190 _outputFrames.clear();
00191
00192 _parent = 0;
00193 }
00194
00195 Compound::InheritData::InheritData()
00196 : channel( 0 )
00197 , overdraw( Vector4i::ZERO )
00198 , buffers( eq::Frame::BUFFER_UNDEFINED )
00199 , eyes( EYE_UNDEFINED )
00200 , tasks( eq::TASK_DEFAULT )
00201 , period( EQ_UNDEFINED_UINT32 )
00202 , phase( EQ_UNDEFINED_UINT32 )
00203 , maxFPS( numeric_limits< float >::max( ))
00204 , active( true )
00205 {
00206 const Global* global = Global::instance();
00207 for( int i=0; i<IATTR_ALL; ++i )
00208 iAttributes[i] =
00209 global->getCompoundIAttribute( static_cast< IAttribute >( i ));
00210 }
00211
00212 void Compound::addChild( Compound* child )
00213 {
00214 _children.push_back( child );
00215 EQASSERT( !child->_parent );
00216 child->_parent = this;
00217 _fireChildAdded( child );
00218 }
00219
00220 bool Compound::removeChild( Compound* child )
00221 {
00222 CompoundVector::iterator i = find( _children.begin(), _children.end(),
00223 child );
00224 if( i == _children.end( ))
00225 return false;
00226
00227 _fireChildRemove( child );
00228 _children.erase( i );
00229 child->_parent = 0;
00230 return true;
00231 }
00232
00233 Compound* Compound::getNext() const
00234 {
00235 if( !_parent )
00236 return 0;
00237
00238 vector<Compound*>& siblings = _parent->_children;
00239 vector<Compound*>::iterator result = find( siblings.begin(),
00240 siblings.end(), this);
00241
00242 if( result == siblings.end() )
00243 return 0;
00244 result++;
00245 if( result == siblings.end() )
00246 return 0;
00247
00248 return *result;
00249 }
00250
00251 Node* Compound::getNode()
00252 {
00253 Channel* channel = getChannel();
00254 return channel ? channel->getNode() : 0;
00255 }
00256
00257 void Compound::setChannel( Channel* channel )
00258 {
00259 _data.channel = channel;
00260 }
00261
00262 const Channel* Compound::getChannel() const
00263 {
00264 if( _data.channel )
00265 return _data.channel;
00266 if( _parent )
00267 return _parent->getChannel();
00268 return 0;
00269 }
00270
00271 Channel* Compound::getChannel()
00272 {
00273 if( _data.channel )
00274 return _data.channel;
00275 if( _parent )
00276 return _parent->getChannel();
00277 return 0;
00278 }
00279
00280 Window* Compound::getWindow()
00281 {
00282 Channel* channel = getChannel();
00283 if( channel )
00284 return channel->getWindow();
00285 return 0;
00286 }
00287
00288 const Window* Compound::getWindow() const
00289 {
00290 const Channel* channel = getChannel();
00291 if( channel )
00292 return channel->getWindow();
00293 return 0;
00294 }
00295
00296 Pipe* Compound::getPipe()
00297 {
00298 Channel* channel = getChannel();
00299 if( channel )
00300 return channel->getPipe();
00301 return 0;
00302 }
00303
00304 const Pipe* Compound::getPipe() const
00305 {
00306 const Channel* channel = getChannel();
00307 if( channel )
00308 return channel->getPipe();
00309 return 0;
00310 }
00311
00312 void Compound::addEqualizer( Equalizer* equalizer )
00313 {
00314 if( equalizer )
00315 equalizer->attach( this );
00316
00317 _equalizers.push_back( equalizer );
00318 }
00319
00320 bool Compound::isActive() const
00321 {
00322 const Channel* channel = getChannel();
00323 if( channel )
00324 return _inherit.active && channel->isActive();
00325
00326 return _inherit.active;
00327 }
00328
00329
00330
00331
00332 void Compound::addListener( CompoundListener* listener )
00333 {
00334 _listeners.push_back( listener );
00335 }
00336
00337 void Compound::removeListener( CompoundListener* listener )
00338 {
00339 CompoundListeners::iterator i = find( _listeners.begin(), _listeners.end(),
00340 listener );
00341 if( i != _listeners.end( ))
00342 _listeners.erase( i );
00343 }
00344
00345 void Compound::fireUpdatePre( const uint32_t frameNumber )
00346 {
00347 CHECK_THREAD( _serverThread );
00348
00349 for( CompoundListeners::const_iterator i = _listeners.begin();
00350 i != _listeners.end(); ++i )
00351
00352 (*i)->notifyUpdatePre( this, frameNumber );
00353 }
00354
00355 void Compound::_fireChildAdded( Compound* child )
00356 {
00357 CHECK_THREAD( _serverThread );
00358
00359 for( CompoundListeners::const_iterator i = _listeners.begin();
00360 i != _listeners.end(); ++i )
00361
00362 (*i)->notifyChildAdded( this, child );
00363 }
00364
00365 void Compound::_fireChildRemove( Compound* child )
00366 {
00367 CHECK_THREAD( _serverThread );
00368
00369 for( CompoundListeners::const_iterator i = _listeners.begin();
00370 i != _listeners.end(); ++i )
00371
00372 (*i)->notifyChildRemove( this, child );
00373 }
00374
00375
00376
00377
00378 void Compound::setSwapBarrier( SwapBarrier* barrier )
00379 {
00380 if( barrier && barrier->getName().empty( ))
00381 {
00382 const Compound* root = getRoot();
00383 const string& rootName = root->getName();
00384 if( rootName.empty( ))
00385 barrier->setName( "barrier" );
00386 else
00387 barrier->setName( "barrier." + rootName );
00388 }
00389
00390 _swapBarrier = barrier;
00391 }
00392
00393 void Compound::addInputFrame( Frame* frame )
00394 {
00395 EQASSERT( frame );
00396 if( frame->getName().empty() )
00397 _setDefaultFrameName( frame );
00398 _inputFrames.push_back( frame );
00399 frame->_compound = this;
00400 }
00401 void Compound::addOutputFrame( Frame* frame )
00402 {
00403 if( frame->getName().empty() )
00404 _setDefaultFrameName( frame );
00405 _outputFrames.push_back( frame );
00406 frame->_compound = this;
00407 }
00408
00409 void Compound::_setDefaultFrameName( Frame* frame )
00410 {
00411 for( Compound* compound = this; compound; compound = compound->getParent())
00412 {
00413 if( !compound->getName().empty( ))
00414 {
00415 frame->setName( "frame." + compound->getName( ));
00416 return;
00417 }
00418
00419 const Channel* channel = compound->getChannel();
00420 if( channel && !channel->getName().empty( ))
00421 {
00422 frame->setName( "frame." + channel->getName( ));
00423 return;
00424 }
00425 }
00426 frame->setName( "frame" );
00427 }
00428
00429 bool Compound::isDestination() const
00430 {
00431 if( !getChannel( ))
00432 return false;
00433
00434 if( !getParent( ))
00435 return true;
00436
00437 for( const Compound* compound = getParent(); compound;
00438 compound = compound->getParent())
00439 {
00440 if( compound->getChannel() )
00441 return false;
00442 }
00443
00444 return true;
00445 }
00446
00447
00448
00449 void Compound::setWall( const eq::Wall& wall )
00450 {
00451 _frustum.setWall( wall );
00452 EQVERB << "Wall: " << _data.frustumData << endl;
00453 }
00454
00455 void Compound::setProjection( const eq::Projection& projection )
00456 {
00457 _frustum.setProjection( projection );
00458 EQVERB << "Projection: " << _data.frustumData << endl;
00459 }
00460
00461 void Compound::updateFrustum()
00462 {
00463 if( !isDestination( ))
00464 return;
00465
00466 Channel* channel = getChannel();
00467 if( !channel )
00468 return;
00469
00470 const Segment* segment = channel->getSegment();
00471 const View* view = channel->getView();
00472 if( !segment || !view )
00473 return;
00474
00475 if( view->getCurrentType() != Frustum::TYPE_NONE )
00476 {
00477
00478
00479 const Viewport& segmentVP = segment->getViewport();
00480 const Viewport& viewVP = view->getViewport();
00481 const Viewport coverage = viewVP.getCoverage( segmentVP );
00482
00483 Wall wall( view->getWall( ));
00484
00485 wall.apply( coverage );
00486 _updateOverdraw( wall );
00487
00488 switch( view->getCurrentType( ))
00489 {
00490 case Frustum::TYPE_WALL:
00491 setWall( wall );
00492 EQLOG( LOG_VIEW ) << "Compound wall: " << wall << std::endl;
00493 return;
00494
00495 case Frustum::TYPE_PROJECTION:
00496 {
00497 Projection projection( view->getProjection( ));
00498 projection = wall;
00499 setProjection( projection );
00500 EQLOG( LOG_VIEW ) << "Compound projection: " << projection
00501 << std::endl;
00502 return;
00503 }
00504
00505 default:
00506 EQUNIMPLEMENTED;
00507 }
00508 }
00509
00510 if( segment->getCurrentType() != Frustum::TYPE_NONE )
00511 {
00512
00513
00514 const Channel* outputChannel = segment->getChannel();
00515 EQASSERT( outputChannel );
00516
00517 const Viewport& outputVP = outputChannel->getViewport();
00518 const Viewport& channelVP = channel->getViewport();
00519 const Viewport coverage = outputVP.getCoverage( channelVP );
00520
00521 Wall wall( segment->getWall( ));
00522
00523 wall.apply( coverage );
00524 _updateOverdraw( wall );
00525
00526 switch( segment->getCurrentType( ))
00527 {
00528 case Frustum::TYPE_WALL:
00529 {
00530 setWall( wall );
00531 EQLOG( LOG_VIEW ) << "Compound wall: " << wall << std::endl;
00532 return;
00533 }
00534
00535 case Frustum::TYPE_PROJECTION:
00536 {
00537 Projection projection( segment->getProjection( ));
00538 projection = wall;
00539 setProjection( projection );
00540 EQLOG( LOG_VIEW ) << "Compound projection: " << projection
00541 << std::endl;
00542 return;
00543 }
00544 default:
00545 EQUNIMPLEMENTED;
00546 }
00547 }
00548 }
00549
00550 void Compound::_updateOverdraw( Wall& wall )
00551 {
00552 Channel* channel = getChannel();
00553 EQASSERT( channel );
00554 if( !channel )
00555 return;
00556
00557 const Segment* segment = channel->getSegment();
00558 const View* view = channel->getView();
00559 EQASSERT( segment && view );
00560 if( !segment || !view )
00561 return;
00562
00563 const Viewport& segmentVP = segment->getViewport();
00564 const Viewport& viewVP = view->getViewport();
00565 const Vector2i& overdraw = view->getOverdraw();
00566 Vector4i channelOverdraw( Vector4i::ZERO );
00567
00568
00569 if( overdraw.x() && viewVP.x < segmentVP.x )
00570 channelOverdraw.x() = overdraw.x();
00571
00572 if( overdraw.x() && viewVP.getXEnd() > segmentVP.getXEnd( ))
00573 channelOverdraw.z() = overdraw.x();
00574
00575 if( overdraw.y() && viewVP.y < segmentVP.y )
00576 channelOverdraw.y() = overdraw.y();
00577
00578 if( overdraw.y() && viewVP.getYEnd() > segmentVP.getYEnd( ))
00579 channelOverdraw.w() = overdraw.y();
00580
00581
00582 const Vector2i& maxSize = channel->getMaxSize();
00583 if( maxSize != Vector2i::ZERO )
00584 {
00585 const PixelViewport& channelPVP = channel->getPixelViewport();
00586
00587 const int32_t xOverdraw = channelOverdraw.x() + channelOverdraw.z();
00588 const int32_t xSize = xOverdraw + channelPVP.w;
00589 if( xSize > maxSize.x( ))
00590 {
00591 const uint32_t maxOverdraw = maxSize.x() - channelPVP.w;
00592 const float ratio = static_cast< float >( maxOverdraw ) /
00593 static_cast< float >( xOverdraw );
00594 channelOverdraw.x() = static_cast< int >(
00595 channelOverdraw.x() * ratio + .5f );
00596 channelOverdraw.z() = maxOverdraw - channelOverdraw.x();
00597 }
00598
00599 const int32_t yOverdraw = channelOverdraw.y() + channelOverdraw.w();
00600 const int32_t ySize = yOverdraw + channelPVP.h;
00601 if( ySize > maxSize.y( ))
00602 {
00603 const uint32_t maxOverdraw = maxSize.y() - channelPVP.h;
00604 const float ratio = static_cast< float >( maxOverdraw ) /
00605 static_cast< float >( yOverdraw );
00606 channelOverdraw.y() = static_cast< int >(
00607 channelOverdraw.y() * ratio +.5f );
00608 channelOverdraw.w() = maxOverdraw - channelOverdraw.y();
00609 }
00610 }
00611
00612
00613 if( channelOverdraw.x() > 0 )
00614 {
00615 const PixelViewport& pvp = channel->getPixelViewport();
00616 const float ratio = static_cast<float>( pvp.w + channelOverdraw.x( )) /
00617 static_cast<float>( pvp.w );
00618 wall.resizeLeft( ratio );
00619 }
00620
00621 if( channelOverdraw.z() > 0 )
00622 {
00623 const PixelViewport& pvp = channel->getPixelViewport();
00624 const float ratio = static_cast<float>( pvp.w + channelOverdraw.x( ) +
00625 channelOverdraw.z( )) /
00626 static_cast<float>( pvp.w + channelOverdraw.x( ));
00627 wall.resizeRight( ratio );
00628 }
00629
00630 if( channelOverdraw.y() > 0 )
00631 {
00632 const PixelViewport& pvp = channel->getPixelViewport();
00633 const float ratio = static_cast<float>( pvp.h + channelOverdraw.y( )) /
00634 static_cast<float>( pvp.h );
00635 wall.resizeBottom( ratio );
00636 }
00637
00638 if( channelOverdraw.w() > 0 )
00639 {
00640 const PixelViewport& pvp = channel->getPixelViewport();
00641 const float ratio = static_cast<float>( pvp.h + + channelOverdraw.y( ) +
00642 channelOverdraw.w( )) /
00643 static_cast<float>( pvp.h + channelOverdraw.y( ));
00644 wall.resizeTop( ratio );
00645 }
00646
00647 channel->setOverdraw( channelOverdraw );
00648 }
00649
00650
00651
00652
00653 namespace
00654 {
00655 template< class C >
00656 VisitorResult _accept( C* compound, CompoundVisitor& visitor )
00657 {
00658 if( compound->isLeaf( ))
00659 return visitor.visitLeaf( compound );
00660
00661 C* current = compound;
00662 VisitorResult result = TRAVERSE_CONTINUE;
00663
00664 while( true )
00665 {
00666 C* parent = current->getParent();
00667 C* next = current->getNext();
00668
00669 const CompoundVector& children = current->getChildren();
00670 C* child = children.empty() ? 0 : children[0];
00671
00672
00673 if ( !child )
00674 {
00675 switch( visitor.visitLeaf( current ))
00676 {
00677 case TRAVERSE_TERMINATE:
00678 return TRAVERSE_TERMINATE;
00679
00680 case TRAVERSE_PRUNE:
00681 result = TRAVERSE_PRUNE;
00682 current = next;
00683 break;
00684
00685 case TRAVERSE_CONTINUE:
00686 current = next;
00687 break;
00688
00689 default:
00690 EQASSERTINFO( 0, "Unreachable" );
00691 }
00692 }
00693 else
00694 {
00695 switch( visitor.visitPre( current ))
00696 {
00697 case TRAVERSE_TERMINATE:
00698 return TRAVERSE_TERMINATE;
00699
00700 case TRAVERSE_PRUNE:
00701 result = TRAVERSE_PRUNE;
00702 current = next;
00703 break;
00704
00705 case TRAVERSE_CONTINUE:
00706 current = child;
00707 break;
00708
00709 default:
00710 EQASSERTINFO( 0, "Unreachable" );
00711 }
00712 }
00713
00714
00715 if( !current && !parent ) return TRAVERSE_CONTINUE;
00716
00717 while( !current )
00718 {
00719 current = parent;
00720 parent = current->getParent();
00721 next = current->getNext();
00722
00723 switch( visitor.visitPost( current ))
00724 {
00725 case TRAVERSE_TERMINATE:
00726 return TRAVERSE_TERMINATE;
00727
00728 case TRAVERSE_PRUNE:
00729 result = TRAVERSE_PRUNE;
00730 break;
00731
00732 case TRAVERSE_CONTINUE:
00733 break;
00734
00735 default:
00736 EQASSERTINFO( 0, "Unreachable" );
00737 }
00738
00739 if ( current == compound )
00740 return result;
00741
00742 current = next;
00743 }
00744 }
00745 return result;
00746 }
00747 }
00748
00749 VisitorResult Compound::accept( CompoundVisitor& visitor )
00750 {
00751 return _accept( this, visitor );
00752 }
00753
00754 VisitorResult Compound::accept( CompoundVisitor& visitor ) const
00755 {
00756 return _accept( this, visitor );
00757 }
00758
00759
00760
00761
00762
00763 void Compound::activate()
00764 {
00765 EQASSERT( isDestination( ));
00766
00767 CompoundActivateVisitor activator( true );
00768 accept( activator );
00769 }
00770
00771 void Compound::deactivate()
00772 {
00773 EQASSERT( isDestination( ));
00774
00775 CompoundActivateVisitor deactivator( false );
00776 accept( deactivator );
00777 }
00778
00779 void Compound::init()
00780 {
00781 CompoundInitVisitor initVisitor;
00782 accept( initVisitor );
00783 }
00784
00785 void Compound::exit()
00786 {
00787 CompoundExitVisitor visitor;
00788 accept( visitor );
00789 }
00790
00791
00792
00793
00794 void Compound::update( const uint32_t frameNumber )
00795 {
00796 CompoundUpdateDataVisitor updateDataVisitor( frameNumber );
00797 accept( updateDataVisitor );
00798
00799 CompoundUpdateOutputVisitor updateOutputVisitor( frameNumber );
00800 accept( updateOutputVisitor );
00801
00802 const hash_map<std::string, Frame*>& outputFrames =
00803 updateOutputVisitor.getOutputFrames();
00804 CompoundUpdateInputVisitor updateInputVisitor( outputFrames );
00805 accept( updateInputVisitor );
00806
00807 const BarrierMap& swapBarriers = updateOutputVisitor.getSwapBarriers();
00808
00809 for( hash_map<string, net::Barrier*>::const_iterator i =
00810 swapBarriers.begin(); i != swapBarriers.end(); ++i )
00811 {
00812 net::Barrier* barrier = i->second;
00813 if( barrier->getHeight() > 1 )
00814 barrier->commit();
00815 }
00816 }
00817
00818 void Compound::updateInheritData( const uint32_t frameNumber )
00819 {
00820 _data.pixel.validate();
00821 _data.subpixel.validate();
00822 _data.zoom.validate();
00823
00824 if( !_parent )
00825 {
00826 _inherit = _data;
00827 _inherit.zoom = eq::Zoom::NONE;
00828
00829 if( _inherit.eyes == EYE_UNDEFINED )
00830 _inherit.eyes = EYE_CYCLOP_BIT;
00831
00832 if( _inherit.period == EQ_UNDEFINED_UINT32 )
00833 _inherit.period = 1;
00834
00835 if( _inherit.phase == EQ_UNDEFINED_UINT32 )
00836 _inherit.phase = 0;
00837
00838 if( _inherit.channel )
00839 _updateInheritPVP();
00840
00841 if( _inherit.buffers == eq::Frame::BUFFER_UNDEFINED )
00842 _inherit.buffers = eq::Frame::BUFFER_COLOR;
00843
00844 if( _inherit.iAttributes[IATTR_STEREO_MODE] == eq::UNDEFINED )
00845 _inherit.iAttributes[IATTR_STEREO_MODE] = eq::QUAD;
00846
00847 if( _inherit.iAttributes[IATTR_STEREO_ANAGLYPH_LEFT_MASK] ==
00848 eq::UNDEFINED )
00849 {
00850 _inherit.iAttributes[IATTR_STEREO_ANAGLYPH_LEFT_MASK] =
00851 COLOR_MASK_RED;
00852 }
00853 if( _inherit.iAttributes[IATTR_STEREO_ANAGLYPH_RIGHT_MASK] ==
00854 eq::UNDEFINED )
00855 {
00856 _inherit.iAttributes[IATTR_STEREO_ANAGLYPH_RIGHT_MASK] =
00857 COLOR_MASK_GREEN | COLOR_MASK_BLUE;
00858 }
00859 }
00860 else
00861 {
00862 _inherit = _parent->_inherit;
00863
00864 if( !_inherit.channel )
00865 _inherit.channel = _data.channel;
00866
00867 if( _data.frustumData.isValid( ))
00868 _inherit.frustumData = _data.frustumData;
00869
00870 _inherit.range.apply( _data.range );
00871 _inherit.pixel.apply( _data.pixel );
00872 _inherit.subpixel.apply( _data.subpixel );
00873
00874 if( _data.eyes != EYE_UNDEFINED )
00875 _inherit.eyes = _data.eyes;
00876
00877 if( _data.period != EQ_UNDEFINED_UINT32 )
00878 _inherit.period = _data.period;
00879
00880 if( _data.phase != EQ_UNDEFINED_UINT32 )
00881 _inherit.phase = _data.phase;
00882
00883 _inherit.maxFPS = _data.maxFPS;
00884
00885 if ( _inherit.pvp.isValid( ))
00886 {
00887 EQASSERT( _data.vp.isValid( ));
00888 _inherit.pvp.apply( _data.vp );
00889
00890
00891
00892
00893 const Viewport vp = _inherit.pvp.getSubVP( _parent->_inherit.pvp );
00894 _inherit.vp.apply( vp );
00895
00896 _updateInheritOverdraw();
00897 }
00898 else if( _inherit.channel )
00899 {
00900 _updateInheritPVP();
00901 _inherit.vp.apply( _data.vp );
00902 }
00903
00904 if( _data.buffers != eq::Frame::BUFFER_UNDEFINED )
00905 _inherit.buffers = _data.buffers;
00906
00907 if( _data.iAttributes[IATTR_STEREO_MODE] != eq::UNDEFINED )
00908 _inherit.iAttributes[IATTR_STEREO_MODE] =
00909 _data.iAttributes[IATTR_STEREO_MODE];
00910
00911 if( _data.iAttributes[IATTR_STEREO_ANAGLYPH_LEFT_MASK] != eq::UNDEFINED)
00912 _inherit.iAttributes[IATTR_STEREO_ANAGLYPH_LEFT_MASK] =
00913 _data.iAttributes[IATTR_STEREO_ANAGLYPH_LEFT_MASK];
00914
00915 if( _data.iAttributes[IATTR_STEREO_ANAGLYPH_RIGHT_MASK] !=eq::UNDEFINED)
00916 _inherit.iAttributes[IATTR_STEREO_ANAGLYPH_RIGHT_MASK] =
00917 _data.iAttributes[IATTR_STEREO_ANAGLYPH_RIGHT_MASK];
00918 }
00919
00920 if( _inherit.pvp.isValid( ))
00921 {
00922 _inherit.pvp.apply( _data.pixel );
00923
00924
00925 const eq::PixelViewport unzoomedPVP( _inherit.pvp );
00926 _inherit.pvp.apply( _data.zoom );
00927
00928
00929
00930 const Zoom zoom = _inherit.pvp.getZoom( unzoomedPVP );
00931 _inherit.zoom *= zoom;
00932 }
00933
00934
00935 if( frameNumber != 0 &&
00936 ( !_inherit.pvp.hasArea() || !_inherit.range.hasData( )) )
00937 {
00938
00939
00940 _inherit.tasks = eq::TASK_NONE;
00941 }
00942 else if( _data.tasks == eq::TASK_DEFAULT )
00943 {
00944 if( isLeaf( ))
00945 _inherit.tasks = eq::TASK_ALL;
00946 else
00947 _inherit.tasks = eq::TASK_ASSEMBLE | eq::TASK_READBACK;
00948 }
00949 else
00950 _inherit.tasks = _data.tasks;
00951
00952 if( isDestination() && getChannel()->getView( ))
00953 _inherit.tasks |= eq::TASK_VIEW;
00954 else
00955 _inherit.tasks &= ~eq::TASK_VIEW;
00956
00957
00958 _inherit.active = (( frameNumber % _inherit.period ) == _inherit.phase);
00959 }
00960
00961 void Compound::_updateInheritPVP()
00962 {
00963 const PixelViewport oldPVP( _inherit.pvp );
00964
00965 const Channel* channel = _inherit.channel;
00966 const View* view = channel->getView();
00967
00968 _inherit.pvp = channel->getPixelViewport( );
00969
00970 if( !view || !_inherit.pvp.isValid( ))
00971 {
00972 EQASSERT( channel->getOverdraw() == Vector4i::ZERO );
00973 return;
00974 }
00975 EQASSERT( channel == getChannel( ));
00976
00977
00978 const Vector4i& overdraw = channel->getOverdraw();
00979 _inherit.pvp.w += overdraw.x() + overdraw.z();
00980 _inherit.pvp.h += overdraw.y() + overdraw.w();
00981
00982 if( oldPVP != _inherit.pvp )
00983 {
00984 updateFrustum();
00985 EQASSERT( overdraw == channel->getOverdraw( ));
00986 }
00987
00988 _inherit.overdraw = overdraw;
00989 }
00990
00991 void Compound::_updateInheritOverdraw()
00992 {
00993 const PixelViewport& pvp = _inherit.pvp;
00994 const PixelViewport& parentPVP = _parent->_inherit.pvp;
00995
00996 _inherit.overdraw.x() -= pvp.x - parentPVP.x;
00997 _inherit.overdraw.y() -= pvp.y - parentPVP.y;
00998 _inherit.overdraw.z() -= parentPVP.getXEnd() - pvp.getXEnd();
00999 _inherit.overdraw.w() -= parentPVP.getYEnd() - pvp.getYEnd();
01000
01001 _inherit.overdraw.x() = EQ_MAX( _inherit.overdraw.x(), 0 );
01002 _inherit.overdraw.y() = EQ_MAX( _inherit.overdraw.y(), 0 );
01003 _inherit.overdraw.z() = EQ_MAX( _inherit.overdraw.z(), 0 );
01004 _inherit.overdraw.w() = EQ_MAX( _inherit.overdraw.w(), 0 );
01005
01006 _inherit.overdraw.x() = EQ_MIN( _inherit.overdraw.x(), pvp.w );
01007 _inherit.overdraw.y() = EQ_MIN( _inherit.overdraw.y(), pvp.h );
01008 _inherit.overdraw.z() = EQ_MIN( _inherit.overdraw.z(), pvp.w );
01009 _inherit.overdraw.w() = EQ_MIN( _inherit.overdraw.w(), pvp.h );
01010
01011 EQASSERTINFO( pvp.w >= _inherit.overdraw.x() + _inherit.overdraw.z(),
01012 pvp.w << " < " <<
01013 _inherit.overdraw.x() + _inherit.overdraw.z( ));
01014 EQASSERTINFO( pvp.h >= _inherit.overdraw.y() + _inherit.overdraw.w(),
01015 pvp.h << " < " <<
01016 _inherit.overdraw.y() + _inherit.overdraw.w( ));
01017 }
01018
01019 std::ostream& operator << (std::ostream& os, const Compound* compound)
01020 {
01021 if( !compound )
01022 return os;
01023
01024 os << disableFlush << "compound" << endl;
01025 os << "{" << endl << indent;
01026
01027 const std::string& name = compound->getName();
01028 if( !name.empty( ))
01029 os << "name \"" << name << "\"" << endl;
01030
01031 const Channel* channel = compound->getChannel();
01032 if( channel )
01033 {
01034 Compound* parent = compound->getParent();
01035 if( !parent || parent->getChannel() != channel )
01036 {
01037 const std::string& channelName = channel->getName();
01038 const Config* config = compound->getConfig();
01039 EQASSERT( config );
01040
01041 if( !channelName.empty() &&
01042 config->findChannel( channelName ) == channel )
01043 {
01044 os << "channel \"" << channelName << "\"" << endl;
01045 }
01046 else
01047 {
01048 const Segment* segment = channel->getSegment();
01049 const View* view = channel->getView();
01050
01051 if( view && segment )
01052 {
01053 os << "channel ( ";
01054
01055 const std::string& segmentName = segment->getName();
01056 if( !segmentName.empty() &&
01057 config->findSegment( segmentName ) == segment )
01058 {
01059 const Canvas* canvas = segment->getCanvas();
01060 const std::string& canvasName = canvas->getName();
01061 if( !canvasName.empty() &&
01062 config->findCanvas( canvasName ) == canvas )
01063 {
01064 os << "canvas \"" << canvasName << "\" ";
01065 }
01066 else
01067 os << canvas->getPath() << ' ';
01068
01069 os << "segment \"" << segmentName << "\" ";
01070 }
01071 else
01072 os << segment->getPath() << ' ';
01073
01074 const std::string& viewName = view->getName();
01075 if( !viewName.empty() &&
01076 config->findView( viewName ) == view )
01077 {
01078 const Layout* layout = view->getLayout();
01079 const std::string& layoutName = layout->getName();
01080 if( !layoutName.empty() &&
01081 config->findLayout( layoutName ) == layout )
01082 {
01083 os << "layout \"" << layoutName << "\" ";
01084 }
01085 else
01086 os << layout->getPath() << ' ';
01087
01088 os << "view \"" << viewName << '\"';
01089 }
01090 else
01091 os << view->getPath();
01092
01093 os << " )" << endl;
01094 }
01095 else
01096 os << "channel ( " << channel->getPath() << " )" << endl;
01097 }
01098 }
01099 }
01100
01101 const uint32_t tasks = compound->getTasks();
01102 if( tasks != eq::TASK_DEFAULT )
01103 {
01104 os << "task [";
01105 if( tasks & eq::TASK_CLEAR ) os << " CLEAR";
01106 if( tasks & eq::TASK_CULL ) os << " CULL";
01107 if( compound->isLeaf() &&
01108 ( tasks & eq::TASK_DRAW )) os << " DRAW";
01109 if( tasks & eq::TASK_ASSEMBLE ) os << " ASSEMBLE";
01110 if( tasks & eq::TASK_READBACK ) os << " READBACK";
01111 os << " ]" << endl;
01112 }
01113
01114 const uint32_t buffers = compound->getBuffers();
01115 if( buffers != eq::Frame::BUFFER_UNDEFINED )
01116 {
01117 os << "buffers [";
01118 if( buffers & eq::Frame::BUFFER_COLOR ) os << " COLOR";
01119 if( buffers & eq::Frame::BUFFER_DEPTH ) os << " DEPTH";
01120 os << " ]" << endl;
01121 }
01122
01123 const eq::Viewport& vp = compound->getViewport();
01124 if( vp.isValid() && vp != eq::Viewport::FULL )
01125 os << "viewport " << vp << endl;
01126
01127 const eq::Range& range = compound->getRange();
01128 if( range.isValid() && range != eq::Range::ALL )
01129 os << range << endl;
01130
01131 const eq::Pixel& pixel = compound->getPixel();
01132 if( pixel.isValid() && pixel != eq::Pixel::ALL )
01133 os << pixel << endl;
01134
01135 const eq::SubPixel& subpixel = compound->getSubPixel();
01136 if( subpixel.isValid() && subpixel != eq::SubPixel::ALL )
01137 os << subpixel << endl;
01138
01139 const eq::Zoom& zoom = compound->getZoom();
01140 if( zoom.isValid() && zoom != eq::Zoom::NONE )
01141 os << zoom << endl;
01142
01143 const uint32_t eye = compound->getEyes();
01144 if( eye )
01145 {
01146 os << "eye [ ";
01147 if( eye & Compound::EYE_CYCLOP_BIT )
01148 os << "CYCLOP ";
01149 if( eye & Compound::EYE_LEFT_BIT )
01150 os << "LEFT ";
01151 if( eye & Compound::EYE_RIGHT_BIT )
01152 os << "RIGHT ";
01153 os << "]" << endl;
01154 }
01155
01156 const uint32_t period = compound->getPeriod();
01157 const uint32_t phase = compound->getPhase();
01158 if( period != EQ_UNDEFINED_UINT32 )
01159 os << "period " << period << " ";
01160
01161 if( phase != EQ_UNDEFINED_UINT32 )
01162 os << "phase " << phase;
01163
01164 if( period != EQ_UNDEFINED_UINT32 || phase != EQ_UNDEFINED_UINT32 )
01165 os << endl;
01166
01167
01168 bool attrPrinted = false;
01169
01170 for( Compound::IAttribute i = static_cast< Compound::IAttribute >( 0 );
01171 i<Compound::IATTR_ALL;
01172 i = static_cast< Compound::IAttribute >( static_cast<uint32_t>( i )+1))
01173 {
01174 const int value = compound->getIAttribute( i );
01175 if( value == Global::instance()->getCompoundIAttribute( i ))
01176 continue;
01177
01178 if( !attrPrinted )
01179 {
01180 os << endl << "attributes" << endl;
01181 os << "{" << endl << indent;
01182 attrPrinted = true;
01183 }
01184
01185 os << ( i==Compound::IATTR_STEREO_MODE ?
01186 "stereo_mode " :
01187 i==Compound::IATTR_STEREO_ANAGLYPH_LEFT_MASK ?
01188 "stereo_anaglyph_left_mask " :
01189 i==Compound::IATTR_STEREO_ANAGLYPH_RIGHT_MASK ?
01190 "stereo_anaglyph_right_mask " : "ERROR" );
01191
01192 switch( i )
01193 {
01194 case Compound::IATTR_STEREO_MODE:
01195 os << static_cast<eq::IAttrValue>( value ) << endl;
01196 break;
01197
01198 case Compound::IATTR_STEREO_ANAGLYPH_LEFT_MASK:
01199 case Compound::IATTR_STEREO_ANAGLYPH_RIGHT_MASK:
01200 os << ColorMask( value ) << endl;
01201 break;
01202
01203 default:
01204 EQASSERTINFO( 0, "unimplemented" );
01205 }
01206 }
01207
01208 if( attrPrinted )
01209 os << exdent << "}" << endl << endl;
01210
01211 switch( compound->getFrustumType( ))
01212 {
01213 case eq::Frustum::TYPE_WALL:
01214 os << compound->getWall() << endl;
01215 break;
01216 case eq::Frustum::TYPE_PROJECTION:
01217 os << compound->getProjection() << endl;
01218 break;
01219 default:
01220 break;
01221 }
01222
01223 const EqualizerVector& equalizers = compound->getEqualizers();
01224 for( EqualizerVector::const_iterator i = equalizers.begin();
01225 i != equalizers.end(); ++i )
01226 {
01227 os << *i;
01228 }
01229
01230 const CompoundVector& children = compound->getChildren();
01231 if( !children.empty( ))
01232 {
01233 os << endl;
01234 for( CompoundVector::const_iterator i = children.begin();
01235 i != children.end(); ++i )
01236
01237 os << *i;
01238 }
01239
01240 const FrameVector& inputFrames = compound->getInputFrames();
01241 for( FrameVector::const_iterator i = inputFrames.begin();
01242 i != inputFrames.end(); ++i )
01243
01244 os << "input" << *i;
01245
01246 const FrameVector& outputFrames = compound->getOutputFrames();
01247 for( FrameVector::const_iterator i = outputFrames.begin();
01248 i != outputFrames.end(); ++i )
01249
01250 os << "output" << *i;
01251
01252 os << compound->getSwapBarrier();
01253
01254 os << exdent << "}" << endl << enableFlush;
01255 return os;
01256 }
01257
01258 }
01259 }