LCOV - code coverage report
Current view: top level - eq/server - pipe.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 117 162 72.2 %
Date: 2016-09-29 05:02:09 Functions: 21 26 80.8 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2013, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2010, 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             : #include "pipe.h"
      20             : 
      21             : #include "channel.h"
      22             : #include "config.h"
      23             : #include "global.h"
      24             : #include "log.h"
      25             : #include "node.h"
      26             : #include "nodeFactory.h"
      27             : #include "window.h"
      28             : 
      29             : #include <eq/fabric/commands.h>
      30             : #include <eq/fabric/elementVisitor.h>
      31             : #include <eq/fabric/paths.h>
      32             : 
      33             : #include <co/objectICommand.h>
      34             : 
      35             : namespace eq
      36             : {
      37             : namespace server
      38             : {
      39             : 
      40             : typedef fabric::Pipe< Node, Pipe, Window, PipeVisitor > Super;
      41             : typedef co::CommandFunc<Pipe> PipeFunc;
      42             : 
      43        1146 : Pipe::Pipe( Node* parent )
      44             :         : Super( parent )
      45             :         , _active( 0 )
      46             :         , _state( STATE_STOPPED )
      47        1146 :         , _lastDrawWindow( 0 )
      48             : {
      49        1146 :     const Global* global = Global::instance();
      50        3438 :     for( unsigned i = 0; i < IATTR_LAST; ++i )
      51             :     {
      52        2292 :         const IAttribute attr = static_cast< IAttribute >( i );
      53        2292 :         setIAttribute( attr, global->getPipeIAttribute( attr ));
      54             :     }
      55        1146 : }
      56             : 
      57        2288 : Pipe::~Pipe()
      58             : {
      59        2288 : }
      60             : 
      61           4 : void Pipe::attach( const uint128_t& id, const uint32_t instanceID )
      62             : {
      63           4 :     Super::attach( id, instanceID );
      64             : 
      65           4 :     co::CommandQueue* cmdQ = getCommandThreadQueue();
      66             :     registerCommand( fabric::CMD_OBJECT_SYNC,
      67           4 :                      PipeFunc( this, &Pipe::_cmdSync ), cmdQ );
      68             :     registerCommand( fabric::CMD_PIPE_CONFIG_INIT_REPLY,
      69           4 :                      PipeFunc( this, &Pipe::_cmdConfigInitReply ), cmdQ );
      70             :     registerCommand( fabric::CMD_PIPE_CONFIG_EXIT_REPLY,
      71           4 :                      PipeFunc( this, &Pipe::_cmdConfigExitReply ), cmdQ );
      72           4 : }
      73             : 
      74           0 : void Pipe::removeChild( const uint128_t& id )
      75             : {
      76           0 :     LBASSERT( getConfig()->isRunning( ));
      77             : 
      78           0 :     Window* window = _findWindow( id );
      79           0 :     LBASSERT( window );
      80           0 :     if( window )
      81           0 :         window->postDelete();
      82           0 : }
      83             : 
      84          16 : ServerPtr Pipe::getServer()
      85             : {
      86          16 :     Node* node = getNode();
      87          16 :     LBASSERT( node );
      88          16 :     return ( node ? node->getServer() : 0);
      89             : }
      90             : 
      91           0 : ConstServerPtr Pipe::getServer() const
      92             : {
      93           0 :     const Node* node = getNode();
      94           0 :     LBASSERT( node );
      95           0 :     return node ? node->getServer() : 0;
      96             : }
      97             : 
      98         588 : Config* Pipe::getConfig()
      99             : {
     100         588 :     Node* node = getNode();
     101         588 :     LBASSERT( node );
     102         588 :     return ( node ? node->getConfig() : 0);
     103             : }
     104             : 
     105           0 : const Config* Pipe::getConfig() const
     106             : {
     107           0 :     const Node* node = getNode();
     108           0 :     LBASSERT( node );
     109           0 :     return ( node ? node->getConfig() : 0);
     110             : }
     111             : 
     112          12 : co::CommandQueue* Pipe::getMainThreadQueue()
     113             : {
     114          12 :     Node* node = getNode();
     115          12 :     LBASSERT( node );
     116          12 :     return node->getMainThreadQueue();
     117             : }
     118             : 
     119          16 : co::CommandQueue* Pipe::getCommandThreadQueue()
     120             : {
     121          16 :     Node* node = getNode();
     122          16 :     LBASSERT( node );
     123          16 :     return node->getCommandThreadQueue();
     124             : }
     125             : 
     126           0 : Channel* Pipe::getChannel( const ChannelPath& path )
     127             : {
     128           0 :     const Windows& windows = getWindows();
     129           0 :     LBASSERTINFO( windows.size() > path.windowIndex,
     130             :                   "Path " << path << " for " << *this );
     131             : 
     132           0 :     if( windows.size() <= path.windowIndex )
     133           0 :         return 0;
     134             : 
     135           0 :     return windows[ path.windowIndex ]->getChannel( path );
     136             : }
     137             : 
     138           2 : void Pipe::activate()
     139             : {
     140           2 :     Node* node = getNode();
     141           2 :     LBASSERT( node );
     142             : 
     143           2 :     ++_active;
     144           2 :     if( node )
     145           2 :         node->activate();
     146             : 
     147           2 :     LBLOG( LOG_VIEW ) << "activate: " << _active << std::endl;
     148           2 : }
     149             : 
     150           2 : void Pipe::deactivate()
     151             : {
     152           2 :     LBASSERT( _active != 0 );
     153             : 
     154           2 :     Node* node = getNode();
     155           2 :     LBASSERT( node );
     156             : 
     157           2 :     --_active;
     158           2 :     if( node )
     159           2 :         node->deactivate();
     160             : 
     161           2 :     LBLOG( LOG_VIEW ) << "deactivate: " << _active << std::endl;
     162           2 : };
     163             : 
     164           4 : void Pipe::addTasks( const uint32_t tasks )
     165             : {
     166           4 :     Node* node = getNode();
     167           4 :     LBASSERT( node );
     168           4 :     setTasks( getTasks() | tasks );
     169           4 :     node->addTasks( tasks );
     170           4 : }
     171             : 
     172           6 : co::ObjectOCommand Pipe::send( const uint32_t cmd )
     173             : {
     174           6 :     return getNode()->send( cmd, getID( ));
     175             : }
     176             : 
     177             : //===========================================================================
     178             : // Operations
     179             : //===========================================================================
     180             : 
     181             : //---------------------------------------------------------------------------
     182             : // init
     183             : //---------------------------------------------------------------------------
     184           2 : void Pipe::configInit( const uint128_t& initID, const uint32_t frameNumber )
     185             : {
     186           2 :     LBASSERT( _state == STATE_STOPPED );
     187           2 :     _state = STATE_INITIALIZING;
     188             : 
     189           2 :     LBLOG( LOG_INIT ) << "Create pipe" << std::endl;
     190           2 :     getNode()->send( fabric::CMD_NODE_CREATE_PIPE, getNode()->getID( ))
     191           4 :             << getID() << isThreaded();
     192             : 
     193           2 :     LBLOG( LOG_INIT ) << "Init pipe" << std::endl;
     194           2 :     send( fabric::CMD_PIPE_CONFIG_INIT ) << initID << frameNumber;
     195           2 : }
     196             : 
     197           2 : bool Pipe::syncConfigInit()
     198             : {
     199           2 :     LBASSERT( _state == STATE_INITIALIZING || _state == STATE_INIT_SUCCESS ||
     200             :               _state == STATE_INIT_FAILED );
     201             : 
     202           2 :     _state.waitNE( STATE_INITIALIZING );
     203             : 
     204           2 :     if( _state == STATE_INIT_SUCCESS )
     205             :     {
     206           0 :         _state = STATE_RUNNING;
     207           0 :         return true;
     208             :     }
     209             : 
     210           2 :     LBWARN << "Pipe initialization failed" << std::endl;
     211           2 :     configExit();
     212           2 :     return false;
     213             : }
     214             : 
     215             : //---------------------------------------------------------------------------
     216             : // exit
     217             : //---------------------------------------------------------------------------
     218           2 : void Pipe::configExit()
     219             : {
     220           2 :     if( _state == STATE_EXITING )
     221           2 :         return;
     222             : 
     223           2 :     LBASSERT( _state == STATE_RUNNING || _state == STATE_INIT_FAILED );
     224           2 :     _state = STATE_EXITING;
     225             : 
     226           2 :     LBLOG( LOG_INIT ) << "Exit pipe" << std::endl;
     227           2 :     send( fabric::CMD_PIPE_CONFIG_EXIT );
     228             : }
     229             : 
     230           2 : bool Pipe::syncConfigExit()
     231             : {
     232           2 :     LBASSERT( _state == STATE_EXITING || _state == STATE_EXIT_SUCCESS ||
     233             :               _state == STATE_EXIT_FAILED );
     234             : 
     235           2 :     _state.waitNE( STATE_EXITING );
     236           2 :     const bool success = ( _state == STATE_EXIT_SUCCESS );
     237           2 :     LBASSERT( success || _state == STATE_EXIT_FAILED );
     238             : 
     239           2 :     _state = isActive() ? STATE_FAILED : STATE_STOPPED;
     240           2 :     setTasks( fabric::TASK_NONE );
     241           2 :     return success;
     242             : }
     243             : 
     244             : //---------------------------------------------------------------------------
     245             : // update
     246             : //---------------------------------------------------------------------------
     247           0 : void Pipe::update( const uint128_t& frameID, const uint32_t frameNumber )
     248             : {
     249           0 :     if( !isRunning( ))
     250           0 :         return;
     251             : 
     252           0 :     LBASSERT( isActive( ))
     253           0 :     send( fabric::CMD_PIPE_FRAME_START_CLOCK );
     254             : 
     255             :     send( fabric::CMD_PIPE_FRAME_START )
     256           0 :             << getVersion() << frameID << frameNumber;
     257           0 :     LBLOG( LOG_TASKS ) << "TASK pipe start frame " << frameNumber << " id "
     258           0 :                        << frameID << std::endl;
     259             : 
     260           0 :     const Windows& windows = getWindows();
     261           0 :     for( Windows::const_iterator i = windows.begin(); i != windows.end(); ++i )
     262           0 :         (*i)->updateDraw( frameID, frameNumber );
     263             : 
     264           0 :     for( Windows::const_iterator i = windows.begin(); i != windows.end(); ++i )
     265           0 :         (*i)->updatePost( frameID, frameNumber );
     266             : 
     267           0 :     if( !_lastDrawWindow ) // no FrameDrawFinish sent
     268             :     {
     269           0 :         send( fabric::CMD_PIPE_FRAME_DRAW_FINISH ) << frameID << frameNumber;
     270           0 :         LBLOG( LOG_TASKS ) << "TASK pipe draw finish " << getName()
     271           0 :                            << " frame " << frameNumber
     272           0 :                            << " id " << frameID << std::endl;
     273             :     }
     274           0 :     _lastDrawWindow = 0;
     275             : 
     276           0 :     send( fabric::CMD_PIPE_FRAME_FINISH ) << frameID << frameNumber;
     277             : 
     278           0 :     LBLOG( LOG_TASKS ) << "TASK pipe finish frame " << frameNumber
     279           0 :                        << " id " << frameID << std::endl;
     280             : }
     281             : 
     282             : 
     283             : 
     284             : //===========================================================================
     285             : // command handling
     286             : //===========================================================================
     287           2 : bool Pipe::_cmdConfigInitReply( co::ICommand& cmd )
     288             : {
     289           2 :     co::ObjectICommand command( cmd );
     290           2 :     const bool result = command.read< bool >();
     291             : 
     292           2 :     LBVERB << "handle pipe configInit reply " << command << " result " << result
     293           2 :            << std::endl;
     294             : 
     295           2 :     _state = result ? STATE_INIT_SUCCESS : STATE_INIT_FAILED;
     296           2 :     return true;
     297             : }
     298             : 
     299           2 : bool Pipe::_cmdConfigExitReply( co::ICommand& cmd )
     300             : {
     301           2 :     co::ObjectICommand command( cmd );
     302           2 :     LBVERB << "handle pipe configExit reply " << command << std::endl;
     303             : 
     304           2 :     _state = command.read< bool >() ? STATE_EXIT_SUCCESS : STATE_EXIT_FAILED;
     305           2 :     return true;
     306             : }
     307             : 
     308         574 : void Pipe::output( std::ostream& os ) const
     309             : {
     310         574 :     bool attrPrinted   = false;
     311        3444 :     for( IAttribute i = static_cast<IAttribute>( 0 );
     312        1722 :          i < IATTR_LAST;
     313             :          i = static_cast<IAttribute>( static_cast<uint32_t>( i )+1))
     314             :     {
     315        1148 :         const int value = getIAttribute( i );
     316        1148 :         if( value == Global::instance()->getPipeIAttribute( i ))
     317        1138 :             continue;
     318             : 
     319          10 :         if( !attrPrinted )
     320             :         {
     321          10 :             os << std::endl << "attributes" << std::endl;
     322          10 :             os << "{" << std::endl << lunchbox::indent;
     323          10 :             attrPrinted = true;
     324             :         }
     325             : 
     326             :         os << ( i == IATTR_HINT_THREAD ? "hint_thread "                   :
     327             :                 i == IATTR_HINT_AFFINITY ? "hint_affinity "               :
     328          10 :                     "ERROR" )
     329          10 :            << static_cast< fabric::IAttribute >( value ) << std::endl;
     330             :     }
     331             : 
     332         574 :     if( attrPrinted )
     333          10 :         os << lunchbox::exdent << "}" << std::endl;
     334         574 : }
     335             : 
     336             : }
     337             : }
     338             : 
     339             : #include "../fabric/pipe.ipp"
     340             : template class eq::fabric::Pipe< eq::server::Node, eq::server::Pipe,
     341             :                                  eq::server::Window, eq::server::PipeVisitor >;
     342             : 
     343             : /** @cond IGNORE */
     344             : template std::ostream& eq::fabric::operator << ( std::ostream&,
     345          84 :                                                  const eq::server::Super& );
     346             : /** @endcond */

Generated by: LCOV version 1.11