LCOV - code coverage report
Current view: top level - eq/server - pipe.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 138 162 85.2 %
Date: 2014-06-18 Functions: 23 26 88.5 %

          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         588 : Pipe::Pipe( Node* parent )
      44             :         : Super( parent )
      45             :         , _active( 0 )
      46             :         , _state( STATE_STOPPED )
      47         588 :         , _lastDrawWindow( 0 )
      48             : {
      49         588 :     const Global* global = Global::instance();
      50        2352 :     for( unsigned i = 0; i < IATTR_LAST; ++i )
      51             :     {
      52        1764 :         const IAttribute attr = static_cast< IAttribute >( i );
      53        1764 :         setIAttribute( attr, global->getPipeIAttribute( attr ));
      54             :     }
      55         588 : }
      56             : 
      57        1174 : Pipe::~Pipe()
      58             : {
      59        1174 : }
      60             : 
      61          23 : void Pipe::attach( const uint128_t& id, const uint32_t instanceID )
      62             : {
      63          23 :     Super::attach( id, instanceID );
      64             : 
      65          23 :     co::CommandQueue* cmdQ = getCommandThreadQueue();
      66             :     registerCommand( fabric::CMD_OBJECT_SYNC,
      67          23 :                      PipeFunc( this, &Pipe::_cmdSync ), cmdQ );
      68             :     registerCommand( fabric::CMD_PIPE_CONFIG_INIT_REPLY,
      69          23 :                      PipeFunc( this, &Pipe::_cmdConfigInitReply ), cmdQ );
      70             :     registerCommand( fabric::CMD_PIPE_CONFIG_EXIT_REPLY,
      71          23 :                      PipeFunc( this, &Pipe::_cmdConfigExitReply ), cmdQ );
      72          23 : }
      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         132 : ServerPtr Pipe::getServer()
      85             : {
      86         132 :     Node* node = getNode();
      87         132 :     LBASSERT( node );
      88         132 :     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         349 : Config* Pipe::getConfig()
      99             : {
     100         349 :     Node* node = getNode();
     101         349 :     LBASSERT( node );
     102         349 :     return ( node ? node->getConfig() : 0);
     103             : }
     104             : 
     105           7 : const Config* Pipe::getConfig() const
     106             : {
     107           7 :     const Node* node = getNode();
     108           7 :     LBASSERT( node );
     109           7 :     return ( node ? node->getConfig() : 0);
     110             : }
     111             : 
     112         109 : co::CommandQueue* Pipe::getMainThreadQueue()
     113             : {
     114         109 :     Node* node = getNode();
     115         109 :     LBASSERT( node );
     116         109 :     return node->getMainThreadQueue();
     117             : }
     118             : 
     119         132 : co::CommandQueue* Pipe::getCommandThreadQueue()
     120             : {
     121         132 :     Node* node = getNode();
     122         132 :     LBASSERT( node );
     123         132 :     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          22 : void Pipe::activate()
     139             : {
     140          22 :     Node* node = getNode();
     141          22 :     LBASSERT( node );
     142             : 
     143          22 :     ++_active;
     144          22 :     if( node )
     145          22 :         node->activate();
     146             : 
     147          22 :     LBLOG( LOG_VIEW ) << "activate: " << _active << std::endl;
     148          22 : }
     149             : 
     150          22 : void Pipe::deactivate()
     151             : {
     152          22 :     LBASSERT( _active != 0 );
     153             : 
     154          22 :     Node* node = getNode();
     155          22 :     LBASSERT( node );
     156             : 
     157          22 :     --_active;
     158          22 :     if( node )
     159          22 :         node->deactivate();
     160             : 
     161          22 :     LBLOG( LOG_VIEW ) << "deactivate: " << _active << std::endl;
     162          22 : };
     163             : 
     164         348 : void Pipe::addTasks( const uint32_t tasks )
     165             : {
     166         348 :     Node* node = getNode();
     167         348 :     LBASSERT( node );
     168         348 :     setTasks( getTasks() | tasks );
     169         348 :     node->addTasks( tasks );
     170         348 : }
     171             : 
     172          66 : co::ObjectOCommand Pipe::send( const uint32_t cmd )
     173             : {
     174          66 :     return getNode()->send( cmd, getID( ));
     175             : }
     176             : 
     177             : //===========================================================================
     178             : // Operations
     179             : //===========================================================================
     180             : 
     181             : //---------------------------------------------------------------------------
     182             : // init
     183             : //---------------------------------------------------------------------------
     184          15 : void Pipe::configInit( const uint128_t& initID, const uint32_t frameNumber )
     185             : {
     186          15 :     LBASSERT( _state == STATE_STOPPED );
     187          15 :     _state = STATE_INITIALIZING;
     188             : 
     189          15 :     LBLOG( LOG_INIT ) << "Create pipe" << std::endl;
     190          15 :     getNode()->send( fabric::CMD_NODE_CREATE_PIPE, getNode()->getID( ))
     191          30 :             << getID() << isThreaded();
     192             : 
     193          15 :     LBLOG( LOG_INIT ) << "Init pipe" << std::endl;
     194          15 :     send( fabric::CMD_PIPE_CONFIG_INIT ) << initID << frameNumber;
     195          15 : }
     196             : 
     197          15 : bool Pipe::syncConfigInit()
     198             : {
     199          15 :     LBASSERT( _state == STATE_INITIALIZING || _state == STATE_INIT_SUCCESS ||
     200             :               _state == STATE_INIT_FAILED );
     201             : 
     202          15 :     _state.waitNE( STATE_INITIALIZING );
     203             : 
     204          15 :     if( _state == STATE_INIT_SUCCESS )
     205             :     {
     206          15 :         _state = STATE_RUNNING;
     207          15 :         return true;
     208             :     }
     209             : 
     210           0 :     LBWARN << "Pipe initialization failed" << std::endl;
     211           0 :     configExit();
     212           0 :     return false;
     213             : }
     214             : 
     215             : //---------------------------------------------------------------------------
     216             : // exit
     217             : //---------------------------------------------------------------------------
     218          15 : void Pipe::configExit()
     219             : {
     220          15 :     if( _state == STATE_EXITING )
     221          15 :         return;
     222             : 
     223          15 :     LBASSERT( _state == STATE_RUNNING || _state == STATE_INIT_FAILED );
     224          15 :     _state = STATE_EXITING;
     225             : 
     226          15 :     LBLOG( LOG_INIT ) << "Exit pipe" << std::endl;
     227          15 :     send( fabric::CMD_PIPE_CONFIG_EXIT );
     228             : }
     229             : 
     230          15 : bool Pipe::syncConfigExit()
     231             : {
     232          15 :     LBASSERT( _state == STATE_EXITING || _state == STATE_EXIT_SUCCESS ||
     233             :               _state == STATE_EXIT_FAILED );
     234             : 
     235          15 :     _state.waitNE( STATE_EXITING );
     236          15 :     const bool success = ( _state == STATE_EXIT_SUCCESS );
     237          15 :     LBASSERT( success || _state == STATE_EXIT_FAILED );
     238             : 
     239          15 :     _state = isActive() ? STATE_FAILED : STATE_STOPPED;
     240          15 :     setTasks( fabric::TASK_NONE );
     241          15 :     return success;
     242             : }
     243             : 
     244             : //---------------------------------------------------------------------------
     245             : // update
     246             : //---------------------------------------------------------------------------
     247           7 : void Pipe::update( const uint128_t& frameID, const uint32_t frameNumber )
     248             : {
     249           7 :     if( !isRunning( ))
     250           7 :         return;
     251             : 
     252           7 :     LBASSERT( isActive( ))
     253           7 :     send( fabric::CMD_PIPE_FRAME_START_CLOCK );
     254             : 
     255             :     send( fabric::CMD_PIPE_FRAME_START )
     256           7 :             << getVersion() << frameID << frameNumber;
     257           7 :     LBLOG( LOG_TASKS ) << "TASK pipe start frame " << frameNumber << " id "
     258           7 :                        << frameID << std::endl;
     259             : 
     260           7 :     const Windows& windows = getWindows();
     261          14 :     for( Windows::const_iterator i = windows.begin(); i != windows.end(); ++i )
     262           7 :         (*i)->updateDraw( frameID, frameNumber );
     263             : 
     264          14 :     for( Windows::const_iterator i = windows.begin(); i != windows.end(); ++i )
     265           7 :         (*i)->updatePost( frameID, frameNumber );
     266             : 
     267           7 :     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           7 :     _lastDrawWindow = 0;
     275             : 
     276           7 :     send( fabric::CMD_PIPE_FRAME_FINISH ) << frameID << frameNumber;
     277             : 
     278           7 :     LBLOG( LOG_TASKS ) << "TASK pipe finish frame " << frameNumber
     279           7 :                        << " id " << frameID << std::endl;
     280             : }
     281             : 
     282             : 
     283             : 
     284             : //===========================================================================
     285             : // command handling
     286             : //===========================================================================
     287          15 : bool Pipe::_cmdConfigInitReply( co::ICommand& cmd )
     288             : {
     289          15 :     co::ObjectICommand command( cmd );
     290          15 :     const bool result = command.read< bool >();
     291             : 
     292          15 :     LBVERB << "handle pipe configInit reply " << command << " result " << result
     293          15 :            << std::endl;
     294             : 
     295          15 :     _state = result ? STATE_INIT_SUCCESS : STATE_INIT_FAILED;
     296          15 :     return true;
     297             : }
     298             : 
     299          15 : bool Pipe::_cmdConfigExitReply( co::ICommand& cmd )
     300             : {
     301          15 :     co::ObjectICommand command( cmd );
     302          15 :     LBVERB << "handle pipe configExit reply " << command << std::endl;
     303             : 
     304          15 :     _state = command.read< bool >() ? STATE_EXIT_SUCCESS : STATE_EXIT_FAILED;
     305          15 :     return true;
     306             : }
     307             : 
     308         326 : void Pipe::output( std::ostream& os ) const
     309             : {
     310         326 :     bool attrPrinted   = false;
     311        2608 :     for( IAttribute i = static_cast<IAttribute>( 0 );
     312        1304 :          i < IATTR_LAST;
     313             :          i = static_cast<IAttribute>( static_cast<uint32_t>( i )+1))
     314             :     {
     315         978 :         const int value = getIAttribute( i );
     316         978 :         if( value == Global::instance()->getPipeIAttribute( i ))
     317         973 :             continue;
     318             : 
     319           5 :         if( !attrPrinted )
     320             :         {
     321           5 :             os << std::endl << "attributes" << std::endl;
     322           5 :             os << "{" << std::endl << lunchbox::indent;
     323           5 :             attrPrinted = true;
     324             :         }
     325             : 
     326             :         os << ( i == IATTR_HINT_THREAD ? "hint_thread "                   :
     327             :                 i == IATTR_HINT_CUDA_GL_INTEROP ? "hint_cuda_GL_interop " :
     328             :                 i == IATTR_HINT_AFFINITY ? "hint_affinity "               :
     329           5 :                     "ERROR" )
     330           5 :            << static_cast< fabric::IAttribute >( value ) << std::endl;
     331             :     }
     332             : 
     333         326 :     if( attrPrinted )
     334           5 :         os << lunchbox::exdent << "}" << std::endl;
     335         326 : }
     336             : 
     337             : }
     338             : }
     339             : 
     340             : #include "../fabric/pipe.ipp"
     341             : template class eq::fabric::Pipe< eq::server::Node, eq::server::Pipe,
     342             :                                  eq::server::Window, eq::server::PipeVisitor >;
     343             : 
     344             : /** @cond IGNORE */
     345             : template std::ostream& eq::fabric::operator << ( std::ostream&,
     346          27 :                                                  const eq::server::Super& );
     347             : /** @endcond */

Generated by: LCOV version 1.10