LCOV - code coverage report
Current view: top level - eq/server - pipe.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 145 165 87.9 %
Date: 2017-12-16 05:07:20 Functions: 24 26 92.3 %

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

Generated by: LCOV version 1.11