LCOV - code coverage report
Current view: top level - eq/server - window.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 125 273 45.8 %
Date: 2016-07-30 05:04:55 Functions: 22 33 66.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2005-2015, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Cedric Stalder <cedric.stalder@gmail.com>
       4             :  *                          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             : #include "window.h"
      21             : 
      22             : #include "global.h"
      23             : #include "channel.h"
      24             : #include "config.h"
      25             : #include "compound.h"
      26             : #include "log.h"
      27             : #include "node.h"
      28             : #include "nodeFactory.h"
      29             : #include "pipe.h"
      30             : 
      31             : #include <eq/fabric/commands.h>
      32             : #include <eq/fabric/elementVisitor.h>
      33             : #include <eq/fabric/leafVisitor.h>
      34             : #include <eq/fabric/paths.h>
      35             : #include <co/objectICommand.h>
      36             : 
      37             : #include <boost/foreach.hpp>
      38             : 
      39             : namespace eq
      40             : {
      41             : namespace server
      42             : {
      43             : typedef fabric::Window< Pipe, Window, Channel > Super;
      44             : typedef co::CommandFunc<Window> WindowFunc;
      45             : 
      46        1494 : Window::Window( Pipe* parent )
      47             :         : Super( parent )
      48             :         , _active( 0 )
      49             :         , _state( STATE_STOPPED )
      50        1494 :         , _maxFPS( std::numeric_limits< float >::max( ))
      51             :         , _nvSwapBarrier( 0 )
      52             :         , _nvNetBarrier( 0 )
      53             :         , _lastDrawChannel( 0 )
      54             :         , _swapFinish( false )
      55        2988 :         , _swap( false )
      56             : {
      57        1494 :     const Global* global = Global::instance();
      58       32868 :     for( unsigned i = 0; i < WindowSettings::IATTR_ALL; ++i )
      59             :     {
      60       31374 :         const WindowSettings::IAttribute attr = static_cast< WindowSettings::IAttribute >( i );
      61       31374 :         setIAttribute( attr, global->getWindowIAttribute( attr ));
      62             :     }
      63        1494 : }
      64             : 
      65        2984 : Window::~Window()
      66             : {
      67        2984 : }
      68             : 
      69           4 : void Window::attach( const uint128_t& id, const uint32_t instanceID )
      70             : {
      71           4 :     Super::attach( id, instanceID );
      72             : 
      73           4 :     co::CommandQueue* cmdQ = getCommandThreadQueue();
      74             :     registerCommand( fabric::CMD_OBJECT_SYNC,
      75           4 :                      WindowFunc( this, &Window::_cmdSync ), cmdQ );
      76             :     registerCommand( fabric::CMD_WINDOW_CONFIG_INIT_REPLY,
      77           4 :                      WindowFunc( this, &Window::_cmdConfigInitReply ), cmdQ );
      78             :     registerCommand( fabric::CMD_WINDOW_CONFIG_EXIT_REPLY,
      79           4 :                      WindowFunc( this, &Window::_cmdConfigExitReply ), cmdQ );
      80           4 : }
      81             : 
      82           0 : void Window::removeChild( const uint128_t& id )
      83             : {
      84           0 :     LBASSERT( getConfig()->isRunning( ));
      85             : 
      86           0 :     Channel* channel = _findChannel( id );
      87           0 :     LBASSERT( channel );
      88           0 :     if( channel )
      89           0 :         channel->postDelete();
      90           0 : }
      91             : 
      92           0 : void Window::postDelete()
      93             : {
      94           0 :     _state = State( _state.get() | STATE_DELETE );
      95           0 :     getConfig()->postNeedsFinish();
      96             : 
      97           0 :     const Channels& channels = getChannels();
      98           0 :     for( Channels::const_iterator i = channels.begin(); i!=channels.end(); ++i )
      99             :     {
     100           0 :         (*i)->postDelete();
     101             :     }
     102           0 : }
     103             : 
     104           0 : const Node* Window::getNode() const
     105             : {
     106           0 :     const Pipe* pipe = getPipe();
     107           0 :     LBASSERT( pipe );
     108           0 :     return ( pipe ? pipe->getNode() : 0 );
     109             : }
     110             : 
     111          10 : Node* Window::getNode()
     112             : {
     113          10 :     Pipe* pipe = getPipe();
     114          10 :     LBASSERT( pipe );
     115          10 :     return ( pipe ? pipe->getNode() : 0 );
     116             : }
     117             : 
     118           0 : const Config* Window::getConfig() const
     119             : {
     120           0 :     const Pipe* pipe = getPipe();
     121           0 :     LBASSERT( pipe );
     122           0 :     return ( pipe ? pipe->getConfig() : 0);
     123             : }
     124             : 
     125         588 : Config* Window::getConfig()
     126             : {
     127         588 :     Pipe* pipe = getPipe();
     128         588 :     LBASSERT( pipe );
     129         588 :     return ( pipe ? pipe->getConfig() : 0);
     130             : }
     131             : 
     132          12 : ServerPtr Window::getServer()
     133             : {
     134          12 :     Pipe* pipe = getPipe();
     135          12 :     LBASSERT( pipe );
     136          12 :     return ( pipe ? pipe->getServer() : 0 );
     137             : }
     138             : 
     139           8 : co::CommandQueue* Window::getMainThreadQueue()
     140             : {
     141           8 :     Pipe* pipe = getPipe();
     142           8 :     LBASSERT( pipe );
     143           8 :     return pipe->getMainThreadQueue();
     144             : }
     145             : 
     146          12 : co::CommandQueue* Window::getCommandThreadQueue()
     147             : {
     148          12 :     Pipe* pipe = getPipe();
     149          12 :     LBASSERT( pipe );
     150          12 :     return pipe->getCommandThreadQueue();
     151             : }
     152             : 
     153           0 : Channel* Window::getChannel( const ChannelPath& path )
     154             : {
     155           0 :     const Channels& channels = getChannels();
     156           0 :     LBASSERT( channels.size() > path.channelIndex );
     157             : 
     158           0 :     if( channels.size() <= path.channelIndex )
     159           0 :         return 0;
     160             : 
     161           0 :     return channels[ path.channelIndex ];
     162             : }
     163             : 
     164           2 : void Window::activate()
     165             : {
     166           2 :     Pipe* pipe = getPipe();
     167           2 :     LBASSERT( pipe );
     168             : 
     169           2 :     ++_active;
     170           2 :     pipe->activate();
     171             : 
     172           2 :     LBLOG( LOG_VIEW ) << "activate: " << _active << std::endl;
     173           2 : }
     174             : 
     175           2 : void Window::deactivate()
     176             : {
     177           2 :     LBASSERT( _active != 0 );
     178           2 :     Pipe* pipe = getPipe();
     179           2 :     LBASSERT( pipe );
     180             : 
     181           2 :     --_active;
     182           2 :     pipe->deactivate();
     183             : 
     184           2 :     LBLOG( LOG_VIEW ) << "deactivate: " << _active << std::endl;
     185           2 : }
     186             : 
     187           4 : void Window::addTasks( const uint32_t tasks )
     188             : {
     189           4 :     Pipe* pipe = getPipe();
     190           4 :     LBASSERT( pipe );
     191           4 :     setTasks( getTasks() | tasks );
     192           4 :     pipe->addTasks( tasks );
     193           4 : }
     194             : 
     195             : //---------------------------------------------------------------------------
     196             : // swap barrier operations
     197             : //---------------------------------------------------------------------------
     198           0 : void Window::_resetSwapBarriers()
     199             : {
     200           0 :     Node* node = getNode();
     201           0 :     LBASSERT( node );
     202             : 
     203           0 :     BOOST_FOREACH( co::Barrier* barrier, _masterBarriers )
     204             :     {
     205           0 :         node->releaseBarrier( barrier );
     206             :     }
     207             : 
     208           0 :     _nvNetBarrier = 0;
     209           0 :     _masterBarriers.clear();
     210           0 :     _barriers.clear();
     211           0 : }
     212             : 
     213           0 : co::Barrier* Window::joinSwapBarrier( co::Barrier* barrier )
     214             : {
     215           0 :     _swapFinish = true;
     216             : 
     217           0 :     if( !barrier )
     218             :     {
     219           0 :         Node* node = getNode();
     220           0 :         barrier = node->getBarrier();
     221           0 :         barrier->increase();
     222             : 
     223           0 :         _masterBarriers.push_back( barrier );
     224           0 :         _barriers.push_back( barrier );
     225           0 :         return barrier;
     226             :     }
     227             : 
     228           0 :     co::BarriersCIter i = lunchbox::find( _barriers, barrier );
     229           0 :     if( i != _barriers.end( )) // Issue #39: window already has this barrier
     230           0 :         return barrier;
     231             : 
     232           0 :     LBASSERT( getPipe() );
     233           0 :     const Windows& windows = getPipe()->getWindows();
     234           0 :     bool beforeSelf = true;
     235             : 
     236             :     // Check if another window in the same thread is using the swap barrier
     237           0 :     for( WindowsCIter j = windows.begin(); j != windows.end(); ++j )
     238             :     {
     239           0 :         Window* window = *j;
     240           0 :         if( window == this ) // skip self
     241             :         {
     242           0 :             beforeSelf = false;
     243           0 :             continue;
     244             :         }
     245             : 
     246           0 :         co::Barriers& barriers = window->_barriers;
     247           0 :         co::BarriersIter k = lunchbox::find( barriers, barrier );
     248           0 :         if( k == barriers.end( ))
     249           0 :             continue;
     250             : 
     251           0 :         if( beforeSelf ) // some earlier window will do the barrier for us
     252           0 :             return barrier;
     253             : 
     254             :         // else we will do the barrier, remove from later window
     255           0 :         barriers.erase( k );
     256           0 :         _barriers.push_back( barrier );
     257           0 :         return barrier;
     258             :     }
     259             : 
     260             :     // No other window on this pipe does the barrier yet
     261           0 :     barrier->increase();
     262           0 :     _barriers.push_back( barrier );
     263           0 :     return barrier;
     264             : }
     265             : 
     266           0 : co::Barrier* Window::joinNVSwapBarrier( SwapBarrierConstPtr swapBarrier,
     267             :                                         co::Barrier* netBarrier )
     268             : {
     269           0 :     LBASSERTINFO( !_nvSwapBarrier,
     270             :                   "Only one NV_swap_group barrier per window allowed" );
     271             : 
     272           0 :     _nvSwapBarrier = swapBarrier;
     273           0 :     _nvNetBarrier = netBarrier;
     274             :     // no _swapFinish = true since NV_swap_group takes care of this
     275             : 
     276           0 :     if( !_nvNetBarrier )
     277             :     {
     278           0 :         Node* node = getNode();
     279           0 :         _nvNetBarrier = node->getBarrier();
     280           0 :         _masterBarriers.push_back( _nvNetBarrier );
     281             :     }
     282             : 
     283           0 :     _nvNetBarrier->increase();
     284           0 :     _barriers.push_back( _nvNetBarrier );
     285           0 :     return _nvNetBarrier;
     286             : }
     287             : 
     288             : 
     289           6 : co::ObjectOCommand Window::send( const uint32_t cmd )
     290             : {
     291           6 :     return getNode()->send( cmd, getID( ));
     292             : }
     293             : 
     294             : //===========================================================================
     295             : // Operations
     296             : //===========================================================================
     297             : //---------------------------------------------------------------------------
     298             : // init
     299             : //---------------------------------------------------------------------------
     300           2 : void Window::configInit( const uint128_t& initID, const uint32_t /*frame*/ )
     301             : {
     302           2 :     LBASSERT( !needsDelete( ));
     303           2 :     LBASSERT( _state == STATE_STOPPED );
     304           2 :     _state = STATE_INITIALIZING;
     305             : 
     306           2 :     LBLOG( LOG_INIT ) << "Create Window" << std::endl;
     307           2 :     getPipe()->send( fabric::CMD_PIPE_CREATE_WINDOW ) << getID();
     308             : 
     309           2 :     LBLOG( LOG_INIT ) << "Init Window" << std::endl;
     310           2 :     send( fabric::CMD_WINDOW_CONFIG_INIT ) << initID;
     311           2 :     LBLOG( LOG_TASKS ) << "TASK window configInit  " << " id " << getID()
     312           2 :                        << std::endl;
     313           2 : }
     314             : 
     315           2 : bool Window::syncConfigInit()
     316             : {
     317           2 :     LBASSERT( !needsDelete( ));
     318           2 :     LBASSERT( _state == STATE_INITIALIZING || _state == STATE_INIT_SUCCESS ||
     319             :               _state == STATE_INIT_FAILED );
     320             : 
     321           2 :     _state.waitNE( STATE_INITIALIZING );
     322             : 
     323           2 :     if( _state == STATE_INIT_SUCCESS )
     324             :     {
     325           0 :         _state = STATE_RUNNING;
     326           0 :         return true;
     327             :     }
     328             : 
     329           2 :     configExit();
     330           2 :     return false;
     331             : }
     332             : 
     333             : //---------------------------------------------------------------------------
     334             : // exit
     335             : //---------------------------------------------------------------------------
     336           2 : void Window::configExit()
     337             : {
     338           2 :     if( _state & STATE_EXITING )
     339           2 :         return;
     340             : 
     341           2 :     LBASSERT( isRunning() || _state == STATE_INIT_FAILED );
     342           4 :     _state =
     343           4 :         State( needsDelete() ? STATE_EXITING | STATE_DELETE : STATE_EXITING );
     344             : 
     345           2 :     LBLOG( LOG_INIT ) << "Exit Window" << std::endl;
     346           2 :     send( fabric::CMD_WINDOW_CONFIG_EXIT );
     347             : }
     348             : 
     349           2 : bool Window::syncConfigExit()
     350             : {
     351           2 :     _state.waitNE( STATE_EXITING, State( STATE_EXITING | STATE_DELETE ));
     352           2 :     const bool success = ( _state & STATE_EXIT_SUCCESS );
     353           2 :     LBASSERT( success || _state & STATE_EXIT_FAILED );
     354             : 
     355             :     // EXIT_FAILED -> STOPPED transition
     356           2 :     uint32_t state = needsDelete() ? STATE_DELETE : 0;
     357           2 :     state |= ( isActive() ? STATE_FAILED : STATE_STOPPED );
     358           2 :     _state = State( state );
     359           2 :     _nvSwapBarrier = 0;
     360           2 :     return success;
     361             : }
     362             : 
     363             : //---------------------------------------------------------------------------
     364             : // update
     365             : //---------------------------------------------------------------------------
     366           0 : void Window::updateDraw( const uint128_t& frameID, const uint32_t frameNumber )
     367             : {
     368           0 :     if( !isRunning( ))
     369           0 :         return;
     370             : 
     371           0 :     LBASSERT( isActive( ))
     372             : 
     373             :     send( fabric::CMD_WINDOW_FRAME_START )
     374           0 :             << getVersion() << frameID << frameNumber;
     375           0 :     LBLOG( LOG_TASKS ) << "TASK window start frame " << frameNumber
     376           0 :                        << " id " << frameID << std::endl;
     377             : 
     378           0 :     const Channels& channels = getChannels();
     379           0 :     _swap = false;
     380             : 
     381           0 :     for( ChannelsCIter i = channels.begin(); i != channels.end(); ++i )
     382             :     {
     383           0 :         Channel* channel = *i;
     384           0 :         if( channel->update( frameID, frameNumber ))
     385           0 :             _swap = true;
     386             :     }
     387             : 
     388           0 :     if( _lastDrawChannel )
     389           0 :         _lastDrawChannel = 0;
     390             :     else // no FrameDrawFinish sent
     391             :     {
     392           0 :         send( fabric::CMD_WINDOW_FRAME_DRAW_FINISH ) << frameID << frameNumber;
     393           0 :         LBLOG( LOG_TASKS ) << "TASK window draw finish " << getName()
     394           0 :                            << " frame " << frameNumber
     395           0 :                            << " id " << frameID << std::endl;
     396             :     }
     397             : 
     398           0 :     if( _swapFinish )
     399             :     {
     400           0 :         send( fabric::CMD_WINDOW_FLUSH );
     401           0 :         LBLOG( LOG_TASKS ) << "TASK flush " << std::endl;
     402             :     }
     403             : }
     404             : 
     405           0 : void Window::updatePost( const uint128_t& frameID,
     406             :                          const uint32_t frameNumber )
     407             : {
     408           0 :     if( !isRunning( ))
     409           0 :         return;
     410             : 
     411           0 :     LBASSERT( isActive( ))
     412           0 :     _updateSwap( frameNumber );
     413             : 
     414           0 :     send( fabric::CMD_WINDOW_FRAME_FINISH ) << frameID << frameNumber;
     415           0 :     LBLOG( LOG_TASKS ) << "TASK window finish frame " << frameNumber
     416           0 :                        << " id " << frameID << std::endl;
     417             : }
     418             : 
     419           0 : void Window::_updateSwap( const uint32_t frameNumber )
     420             : {
     421           0 :     if( _swapFinish )
     422             :     {
     423           0 :         send( fabric::CMD_WINDOW_FINISH );
     424           0 :         LBLOG( LOG_TASKS ) << "TASK finish " << frameNumber << std::endl;
     425           0 :         _swapFinish = false;
     426             :     }
     427             : 
     428           0 :     if( _maxFPS < std::numeric_limits< float >::max( ))
     429             :     {
     430           0 :         const float minFrameTime = 1000.0f / _maxFPS;
     431           0 :         send( fabric::CMD_WINDOW_THROTTLE_FRAMERATE ) << minFrameTime;
     432           0 :         LBLOG( LOG_TASKS ) << "TASK Throttle framerate  "
     433           0 :                                << minFrameTime << std::endl;
     434             : 
     435           0 :         _maxFPS = std::numeric_limits< float >::max();
     436             :     }
     437             : 
     438           0 :     for( co::BarriersCIter i = _barriers.begin(); i != _barriers.end(); ++i )
     439             :     {
     440           0 :         const co::Barrier* barrier = *i;
     441           0 :         if( barrier->getHeight() <= 1 )
     442             :         {
     443           0 :             LBVERB << "Ignoring swap barrier of height " << barrier->getHeight()
     444           0 :                    << std::endl;
     445           0 :             continue;
     446             :         }
     447             : 
     448           0 :         send( fabric::CMD_WINDOW_BARRIER ) << co::ObjectVersion( barrier );
     449           0 :         LBLOG( LOG_TASKS ) << "TASK barrier  barrier "
     450           0 :                            << co::ObjectVersion( barrier ) << std::endl;
     451             :     }
     452             : 
     453           0 :     if( _nvNetBarrier )
     454             :     {
     455           0 :         if( _nvNetBarrier->getHeight() <= 1 )
     456             :         {
     457           0 :             LBWARN << "Ignoring NV swap barrier of height "
     458           0 :                    << _nvNetBarrier->getHeight() << std::endl;
     459             :         }
     460             :         else
     461             :         {
     462           0 :             LBASSERT( _nvSwapBarrier );
     463           0 :             LBASSERT( _nvSwapBarrier->isNvSwapBarrier( ));
     464             :             // Entering the NV_swap_group. The _nvNetBarrier is also part of
     465             :             // _barriers, which means that the pre-join was already sync'ed
     466             :             // with a barrier.
     467             : 
     468             :             // Now enter the swap group and post-sync with the barrier again.
     469             :             send( fabric::CMD_WINDOW_NV_BARRIER )
     470           0 :                     << co::ObjectVersion( _nvNetBarrier )
     471           0 :                     << _nvSwapBarrier->getNVSwapGroup()
     472           0 :                     << _nvSwapBarrier->getNVSwapBarrier();
     473             :         }
     474             :     }
     475             : 
     476           0 :     _resetSwapBarriers();
     477             : 
     478           0 :     if( _swap )
     479             :     {
     480           0 :         send( fabric::CMD_WINDOW_SWAP );
     481           0 :         LBLOG( LOG_TASKS ) << "TASK swap  " << frameNumber << std::endl;
     482             :     }
     483           0 : }
     484             : 
     485             : //===========================================================================
     486             : // command handling
     487             : //===========================================================================
     488           2 : bool Window::_cmdConfigInitReply( co::ICommand& cmd )
     489             : {
     490           2 :     co::ObjectICommand command( cmd );
     491           2 :     LBVERB << "handle window configInit reply " << command << std::endl;
     492             : 
     493           2 :     LBASSERT( !needsDelete( ));
     494           2 :     _state = command.read< bool >() ? STATE_INIT_SUCCESS : STATE_INIT_FAILED;
     495           2 :     return true;
     496             : }
     497             : 
     498           2 : bool Window::_cmdConfigExitReply( co::ICommand& cmd )
     499             : {
     500           2 :     co::ObjectICommand command( cmd );
     501           2 :     LBVERB << "handle window configExit reply " << command << std::endl;
     502             : 
     503           2 :     if( command.read< bool >( ))
     504           4 :         _state = State( needsDelete() ?
     505           2 :                         STATE_EXIT_SUCCESS|STATE_DELETE : STATE_EXIT_SUCCESS );
     506             :     else
     507           0 :         _state = State( needsDelete() ?
     508           0 :                         STATE_EXIT_FAILED | STATE_DELETE : STATE_EXIT_FAILED );
     509           2 :     return true;
     510             : }
     511             : 
     512         748 : void Window::output( std::ostream& os ) const
     513             : {
     514         748 :     bool attrPrinted   = false;
     515             : 
     516       32912 :     for( WindowSettings::IAttribute i = static_cast<WindowSettings::IAttribute>( 0 );
     517       16456 :          i < WindowSettings::IATTR_LAST;
     518             :          i = static_cast<WindowSettings::IAttribute>( static_cast<uint32_t>( i )+1))
     519             :     {
     520       15708 :         const int value = getIAttribute( i );
     521       15708 :         if( value == Global::instance()->getWindowIAttribute( i ))
     522       15522 :             continue;
     523             : 
     524         186 :         if( !attrPrinted )
     525             :         {
     526         138 :             os << std::endl << "attributes" << std::endl;
     527         138 :             os << "{" << std::endl << lunchbox::indent;
     528         138 :             attrPrinted = true;
     529             :         }
     530             : 
     531             :         os << ( i == WindowSettings::IATTR_HINT_CORE_PROFILE ?
     532             :                     "hint_core_profile  " :
     533             :                 i == WindowSettings::IATTR_HINT_OPENGL_MAJOR ?
     534             :                     "hint_opengl_major  " :
     535             :                 i == WindowSettings::IATTR_HINT_OPENGL_MINOR ?
     536             :                     "hint_opengl_minor  " :
     537             :                 i == WindowSettings::IATTR_HINT_STEREO ?
     538             :                     "hint_stereo        " :
     539             :                 i == WindowSettings::IATTR_HINT_DOUBLEBUFFER ?
     540             :                     "hint_doublebuffer  " :
     541             :                 i == WindowSettings::IATTR_HINT_FULLSCREEN ?
     542             :                     "hint_fullscreen    " :
     543             :                 i == WindowSettings::IATTR_HINT_DECORATION ?
     544             :                     "hint_decoration    " :
     545             :                 i == WindowSettings::IATTR_HINT_SWAPSYNC ?
     546             :                     "hint_swapsync      " :
     547             :                 i == WindowSettings::IATTR_HINT_DRAWABLE ?
     548             :                     "hint_drawable      " :
     549             :                 i == WindowSettings::IATTR_HINT_STATISTICS ?
     550             :                     "hint_statistics    " :
     551             :                 i == WindowSettings::IATTR_HINT_SCREENSAVER ?
     552             :                     "hint_screensaver   " :
     553             :                 i == WindowSettings::IATTR_HINT_GRAB_POINTER ?
     554             :                     "hint_grab_pointer  " :
     555             :                 i == WindowSettings::IATTR_PLANES_COLOR ?
     556             :                     "planes_color       " :
     557             :                 i == WindowSettings::IATTR_PLANES_ALPHA ?
     558             :                     "planes_alpha       " :
     559             :                 i == WindowSettings::IATTR_PLANES_DEPTH ?
     560             :                     "planes_depth       " :
     561             :                 i == WindowSettings::IATTR_PLANES_STENCIL ?
     562             :                     "planes_stencil     " :
     563             :                 i == WindowSettings::IATTR_PLANES_ACCUM ?
     564             :                     "planes_accum       " :
     565             :                 i == WindowSettings::IATTR_PLANES_ACCUM_ALPHA ?
     566             :                     "planes_accum_alpha " :
     567             :                 i == WindowSettings::IATTR_PLANES_SAMPLES ?
     568         186 :                     "planes_samples     " : "ERROR" )
     569         186 :            << static_cast< fabric::IAttribute >( value ) << std::endl;
     570             :     }
     571             : 
     572         748 :     if( attrPrinted )
     573         138 :         os << lunchbox::exdent << "}" << std::endl << std::endl;
     574         748 : }
     575             : 
     576             : }
     577             : }
     578             : 
     579             : #include "../fabric/window.ipp"
     580             : template class eq::fabric::Window< eq::server::Pipe, eq::server::Window,
     581             :                                    eq::server::Channel >;
     582             : 
     583             : /** @cond IGNORE */
     584             : template std::ostream& eq::fabric::operator << ( std::ostream&,
     585          84 :                                                  const eq::server::Super& );
     586             : /** @endcond */

Generated by: LCOV version 1.11