LCOV - code coverage report
Current view: top level - eq/fabric - channel.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 149 199 74.9 %
Date: 2016-07-30 05:04:55 Functions: 26 83 31.3 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2016, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *                          Julio Delgado Mangas <julio.delgadomangas@epfl.ch>
       5             :  *                          Enrique <egparedes@ifi.uzh.ch>
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or modify it under
       8             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       9             :  * by the Free Software Foundation.
      10             :  *
      11             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      12             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      13             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      14             :  * details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             :  */
      20             : 
      21             : #include "channel.h"
      22             : 
      23             : #include "leafVisitor.h"
      24             : #include "log.h"
      25             : #include "task.h"
      26             : 
      27             : #include <co/dataIStream.h>
      28             : #include <co/dataOStream.h>
      29             : 
      30             : namespace eq
      31             : {
      32             : namespace fabric
      33             : {
      34             : namespace
      35             : {
      36             : #define MAKE_ATTR_STRING( attr ) ( std::string("EQ_CHANNEL_") + #attr )
      37         140 : static std::string _iAttributeStrings[] = {
      38             :     MAKE_ATTR_STRING( IATTR_HINT_STATISTICS ),
      39             :     MAKE_ATTR_STRING( IATTR_HINT_SENDTOKEN )
      40          70 : };
      41             : 
      42         140 : static std::string _sAttributeStrings[] = {
      43             :     MAKE_ATTR_STRING( SATTR_DUMP_IMAGE )
      44          70 : };
      45             : }
      46             : 
      47        2461 : template< class W, class C > Channel< W, C >::Channel( W* parent )
      48             :     : _window( parent )
      49             :     , _context( &_data.nativeContext )
      50        2461 :     , _maxSize( Vector2i::ZERO )
      51             : {
      52        2461 :     memset( _iAttributes, 0xff, IATTR_ALL * sizeof( int32_t ));
      53        2461 :     parent->_addChannel( static_cast< C* >( this ));
      54        2461 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      55        2461 : }
      56             : 
      57        1174 : template< class W, class C > Channel< W, C >::Channel( const Channel& from )
      58             :         : Object( from )
      59             :         , _window( from._window )
      60             :         , _data( from._data )
      61             :         , _context( &_data.nativeContext )
      62        1174 :         , _maxSize( from._maxSize )
      63             : {
      64        1174 :     _window->_addChannel( static_cast< C* >( this ));
      65             : 
      66        9392 :     for( int i = 0; i < IATTR_ALL; ++i )
      67        8218 :         _iAttributes[i] = from._iAttributes[i];
      68        8218 :     for( int i = 0; i < SATTR_ALL; ++i )
      69        7044 :         _sAttributes[i] = from._sAttributes[i];
      70        1174 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      71        1174 : }
      72             : 
      73        2825 : template< class W, class C > void Channel< W, C >::init()
      74             : {
      75        2825 :     notifyViewportChanged();
      76        2825 :     unsetDirty( DIRTY_VIEWPORT );
      77        2825 : }
      78             : 
      79        2821 : template< class W, class C > Channel< W, C >::~Channel()
      80             : {
      81        2821 :     _window->_removeChannel( static_cast< C* >( this ));
      82        5642 : }
      83             : 
      84             : template< class W, class C >
      85      103682 : VisitorResult Channel< W, C >::accept( Visitor& visitor )
      86             : {
      87      103682 :     return visitor.visit( static_cast< C* >( this ));
      88             : }
      89             : 
      90             : template< class W, class C >
      91           0 : VisitorResult Channel< W, C >::accept( Visitor& visitor ) const
      92             : {
      93           0 :     return visitor.visit( static_cast< const C* >( this ));
      94             : }
      95             : 
      96             : template< class W, class C >
      97           8 : void Channel< W, C >::backup()
      98             : {
      99           8 :     Object::backup();
     100           8 :     _backup = _data;
     101           8 : }
     102             : 
     103             : template< class W, class C >
     104           8 : void Channel< W, C >::restore()
     105             : {
     106           8 :     _data = _backup;
     107           8 :     Object::restore();
     108           8 :     notifyViewportChanged();
     109           8 :     setDirty( DIRTY_VIEWPORT | DIRTY_MEMBER | DIRTY_FRUSTUM );
     110           8 : }
     111             : 
     112             : template< class W, class C >
     113           2 : void Channel< W, C >::serialize( co::DataOStream& os, const uint64_t dirtyBits )
     114             : {
     115           2 :     LBASSERT( dirtyBits == DIRTY_ALL ||
     116             :               getWindow()->Serializable::isDirty( W::DIRTY_CHANNELS ));
     117           2 :     Object::serialize( os, dirtyBits );
     118           2 :     if( dirtyBits & DIRTY_ATTRIBUTES )
     119           2 :         os << co::Array< int32_t >( _iAttributes, IATTR_ALL )
     120           4 :            << co::Array< std::string >( _sAttributes, SATTR_ALL );
     121           2 :     if( dirtyBits & DIRTY_VIEWPORT )
     122           4 :         os << _data.nativeContext.vp << _data.nativeContext.pvp
     123           4 :            << _data.fixedVP << _maxSize;
     124           2 :     if( dirtyBits & DIRTY_MEMBER )
     125           2 :         os << _data.nativeContext.view << _data.nativeContext.overdraw;
     126           2 :     if( dirtyBits & DIRTY_FRUSTUM )
     127           2 :         os << _data.nativeContext.frustum;
     128           2 :     if( dirtyBits & DIRTY_CAPABILITIES )
     129           2 :         os << _data.capabilities;
     130           2 : }
     131             : 
     132             : template< class W, class C >
     133           1 : void Channel< W, C >::deserialize( co::DataIStream& is,
     134             :                                    const uint64_t dirtyBits )
     135             : {
     136           1 :     Object::deserialize( is, dirtyBits );
     137           1 :     if( dirtyBits & DIRTY_ATTRIBUTES )
     138           1 :         is >> co::Array< int32_t >( _iAttributes, IATTR_ALL )
     139           2 :            >> co::Array< std::string >( _sAttributes, SATTR_ALL );
     140           1 :     if( dirtyBits & DIRTY_VIEWPORT )
     141             :     {
     142             :         // Ignore data from master (server) if we have local changes
     143           1 :         if( !Serializable::isDirty( DIRTY_VIEWPORT ) || isMaster( ))
     144             :         {
     145           2 :             is >> _data.nativeContext.vp >> _data.nativeContext.pvp
     146           2 :                >> _data.fixedVP >> _maxSize;
     147           1 :             notifyViewportChanged();
     148             :         }
     149             :         else // consume unused data
     150           0 :             is.getRemainingBuffer( sizeof( _data.nativeContext.vp ) +
     151             :                                    sizeof( _data.nativeContext.pvp ) +
     152           0 :                                    sizeof( _data.fixedVP ) +sizeof( _maxSize ));
     153             :     }
     154           1 :     if( dirtyBits & DIRTY_MEMBER )
     155           1 :         is >> _data.nativeContext.view  >> _data.nativeContext.overdraw;
     156           1 :     if( dirtyBits & DIRTY_FRUSTUM )
     157           1 :         is >> _data.nativeContext.frustum;
     158           1 :     if( dirtyBits & DIRTY_CAPABILITIES )
     159             :     {
     160           1 :         is >> _data.capabilities;
     161           1 :         updateCapabilities();
     162             :     }
     163           1 : }
     164             : 
     165             : template< class W, class C >
     166       26378 : void Channel< W, C >::setDirty( const uint64_t dirtyBits )
     167             : {
     168       26378 :     Object::setDirty( dirtyBits );
     169       26378 :     _window->setDirty( W::DIRTY_CHANNELS );
     170       26378 : }
     171             : 
     172             : //----------------------------------------------------------------------
     173             : // viewport
     174             : //----------------------------------------------------------------------
     175             : template< class W, class C >
     176         362 : void Channel< W, C >::setPixelViewport( const PixelViewport& pvp )
     177             : {
     178         362 :     LBASSERT( pvp.isValid( ));
     179         362 :     if( !pvp.isValid( ))
     180           0 :         return;
     181             : 
     182         362 :     _data.fixedVP = false;
     183             : 
     184         362 :     if( _data.nativeContext.pvp == pvp && _data.nativeContext.vp.hasArea( ))
     185         320 :         return;
     186             : 
     187          42 :     _data.nativeContext.pvp = pvp;
     188          42 :     _data.nativeContext.vp.invalidate();
     189             : 
     190          42 :     notifyViewportChanged();
     191          42 :     setDirty( DIRTY_VIEWPORT );
     192             : }
     193             : 
     194             : template< class W, class C >
     195        2060 : void Channel< W, C >::setViewport( const Viewport& vp )
     196             : {
     197        2060 :     if( !vp.hasArea( ))
     198           0 :         return;
     199             : 
     200        2060 :     _data.fixedVP = true;
     201             : 
     202        2060 :     if( _data.nativeContext.vp == vp && _data.nativeContext.pvp.hasArea( ))
     203         890 :         return;
     204             : 
     205        1170 :     _data.nativeContext.vp = vp;
     206        1170 :     _data.nativeContext.pvp.invalidate();
     207             : 
     208        1170 :     notifyViewportChanged();
     209        1170 :     setDirty( DIRTY_VIEWPORT );
     210             : }
     211             : 
     212             : template< class W, class C >
     213        4062 : void Channel< W, C >::notifyViewportChanged()
     214             : {
     215        4062 :     if( !_window )
     216         984 :         return;
     217             : 
     218        4062 :     PixelViewport windowPVP = _window->getPixelViewport();
     219        4062 :     if( !windowPVP.isValid( ))
     220         984 :         return;
     221             : 
     222        3078 :     windowPVP.x = 0;
     223        3078 :     windowPVP.y = 0;
     224             : 
     225        3078 :     if( _data.fixedVP ) // update pixel viewport
     226             :     {
     227        3024 :         const PixelViewport oldPVP = _data.nativeContext.pvp;
     228        3024 :         _data.nativeContext.pvp = windowPVP;
     229        3024 :         _data.nativeContext.pvp.apply( _data.nativeContext.vp );
     230        3024 :         if( oldPVP != _data.nativeContext.pvp )
     231        1992 :             setDirty( DIRTY_VIEWPORT );
     232             :     }
     233             :     else           // update viewport
     234             :     {
     235          54 :         const Viewport oldVP = _data.nativeContext.vp;
     236          54 :         _data.nativeContext.vp = _data.nativeContext.pvp / windowPVP;
     237          54 :         if( oldVP != _data.nativeContext.vp )
     238          44 :             setDirty( DIRTY_VIEWPORT );
     239             :     }
     240             : 
     241        3078 :     LBVERB << getName() << " viewport update: " << _data.nativeContext.vp << ":"
     242           0 :            << _data.nativeContext.pvp << std::endl;
     243             : }
     244             : 
     245             : template< class W, class C >
     246           0 : void Channel< W, C >::setNearFar( const float nearPlane, const float farPlane )
     247             : {
     248           0 :     LBASSERT( _context );
     249           0 :     if( _data.nativeContext.frustum.nearPlane() != nearPlane ||
     250           0 :         _data.nativeContext.frustum.farPlane() != farPlane )
     251             :     {
     252           0 :         _data.nativeContext.frustum.adjustNearPlane( nearPlane );
     253           0 :         _data.nativeContext.frustum.farPlane() = farPlane;
     254           0 :         _data.nativeContext.ortho.nearPlane() = nearPlane;
     255           0 :         _data.nativeContext.ortho.farPlane() = farPlane;
     256           0 :         setDirty( DIRTY_FRUSTUM );
     257             :     }
     258             : 
     259           0 :     if( _context == &_data.nativeContext )
     260           0 :         return;
     261             : 
     262           0 :     if( _context->frustum.nearPlane() != nearPlane ||
     263           0 :         _context->frustum.farPlane() != farPlane )
     264             :     {
     265           0 :         _context->frustum.adjustNearPlane( nearPlane );
     266           0 :         _context->frustum.farPlane() = farPlane;
     267           0 :         _context->ortho.nearPlane() = nearPlane;
     268           0 :         _context->ortho.farPlane() = farPlane;
     269             :     }
     270             : }
     271             : 
     272             : template< class W, class C >
     273        1196 : void Channel< W, C >::setViewVersion( const co::ObjectVersion& view )
     274             : {
     275        1196 :     if( _data.nativeContext.view == view )
     276        2382 :         return;
     277          10 :     LBASSERTINFO( view.identifier != 0 ||
     278             :                   _data.nativeContext.view.version <= view.version,
     279             :                   _data.nativeContext.view << " != " << view );
     280             : 
     281          10 :     _data.nativeContext.view = view;
     282          10 :     setDirty( DIRTY_MEMBER );
     283             : }
     284             : 
     285             : template< class W, class C >
     286           2 : uint64_t Channel< W, C >::getCapabilities() const
     287             : {
     288           2 :     return _data.capabilities;
     289             : }
     290             : 
     291             : template< class W, class C >
     292           0 : void Channel< W, C >::setCapabilities( const uint64_t bitmask )
     293             : {
     294           0 :     if ( bitmask == _data.capabilities )
     295           0 :         return;
     296             : 
     297           0 :     _data.capabilities = bitmask;
     298           0 :     setDirty( DIRTY_CAPABILITIES );
     299             : }
     300             : 
     301             : template< class W, class C >
     302           0 : void Channel< W, C >::setMaxSize( const Vector2i& size )
     303             : {
     304           0 :     _maxSize = size;
     305           0 :     setDirty( DIRTY_VIEWPORT );
     306           0 : }
     307             : 
     308             : template< class W, class C >
     309           4 : void Channel< W, C >::setOverdraw( const Vector4i& overdraw )
     310             : {
     311           4 :     if( _data.nativeContext.overdraw == overdraw )
     312           8 :         return;
     313           0 :     _data.nativeContext.overdraw = overdraw;
     314           0 :     setDirty( DIRTY_MEMBER );
     315             : }
     316             : 
     317             : template< class W, class C >
     318           0 : ChannelPath Channel< W, C >::getPath() const
     319             : {
     320           0 :     const W* window = getWindow();
     321           0 :     LBASSERT( window );
     322           0 :     ChannelPath path( window->getPath( ));
     323             : 
     324           0 :     const typename W::Channels& channels = window->getChannels();
     325             :     typename W::Channels::const_iterator i = std::find( channels.begin(),
     326           0 :                                                         channels.end(), this );
     327           0 :     LBASSERT( i != channels.end( ));
     328           0 :     path.channelIndex = std::distance( channels.begin(), i );
     329           0 :     return path;
     330             : }
     331             : 
     332             : 
     333             : template< class W, class C >
     334           0 : int32_t Channel< W, C >::getIAttribute( const IAttribute attr ) const
     335             : {
     336           0 :     LBASSERT( attr < IATTR_ALL );
     337           0 :     return _iAttributes[ attr ];
     338             : }
     339             : 
     340             : template< class W, class C >
     341           0 : const std::string& Channel< W, C >::getSAttribute( const SAttribute attr ) const
     342             : {
     343           0 :     LBASSERT( attr < SATTR_ALL );
     344           0 :     return _sAttributes[ attr ];
     345             : }
     346             : 
     347             : template< class W, class C >
     348        1362 : const std::string& Channel< W, C >::getIAttributeString( const IAttribute attr )
     349             : {
     350        1362 :     return _iAttributeStrings[attr];
     351             : }
     352             : 
     353             : template< class W, class C >
     354         682 : const std::string& Channel< W, C >::getSAttributeString( const SAttribute attr )
     355             : {
     356         682 :     return _sAttributeStrings[attr];
     357             : }
     358             : 
     359             : template< class W, class C >
     360        1414 : std::ostream& operator << ( std::ostream& os,
     361             :                             const Channel< W, C >& channel)
     362             : {
     363        1414 :     if( channel.omitOutput( ))
     364         588 :         return os;
     365             : 
     366         826 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "channel"
     367             :        << std::endl;
     368         826 :     os << "{" << std::endl << lunchbox::indent;
     369             : 
     370         826 :     const std::string& name = channel.getName();
     371         826 :     if( !name.empty( ))
     372         826 :         os << "name     \"" << name << "\"" << std::endl;
     373             : 
     374         826 :     const Viewport& vp = channel.getViewport();
     375         826 :     const PixelViewport& pvp = channel.getPixelViewport();
     376         826 :     if( vp.hasArea() && channel.hasFixedViewport( ))
     377             :     {
     378         820 :         if( pvp.hasArea( ))
     379         338 :             os << "viewport " << pvp << std::endl;
     380         820 :         os << "viewport " << vp << std::endl;
     381             :     }
     382           6 :     else if( pvp.hasArea() && !channel.hasFixedViewport( ))
     383             :     {
     384           6 :         if( vp.hasArea( ))
     385           6 :             os << "viewport " << vp << std::endl;
     386           6 :         os << "viewport " << pvp << std::endl;
     387             :     }
     388             : 
     389         826 :     os << lunchbox::exdent << "}" << std::endl << lunchbox::enableHeader
     390             :        << lunchbox::enableFlush;
     391             : 
     392         826 :     return os;
     393             : }
     394             : 
     395             : }
     396             : }

Generated by: LCOV version 1.11