LCOV - code coverage report
Current view: top level - eq/fabric - channel.ipp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 171 216 79.2 %
Date: 2014-06-18 Functions: 32 58 55.2 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2010-2013, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                    2010, Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *                    2013, Julio Delgado Mangas <julio.delgadomangas@epfl.ch>
       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 "channel.h"
      21             : 
      22             : #include "leafVisitor.h"
      23             : #include "log.h"
      24             : #include "task.h"
      25             : 
      26             : #include <co/dataIStream.h>
      27             : #include <co/dataOStream.h>
      28             : 
      29             : namespace eq
      30             : {
      31             : namespace fabric
      32             : {
      33             : namespace
      34             : {
      35             : #define MAKE_ATTR_STRING( attr ) ( std::string("EQ_CHANNEL_") + #attr )
      36          42 : static std::string _iAttributeStrings[] = {
      37             :     MAKE_ATTR_STRING( IATTR_HINT_STATISTICS ),
      38             :     MAKE_ATTR_STRING( IATTR_HINT_SENDTOKEN )
      39          21 : };
      40             : 
      41          42 : static std::string _sAttributeStrings[] = {
      42             :     MAKE_ATTR_STRING( SATTR_DUMP_IMAGE )
      43          21 : };
      44             : }
      45             : 
      46             : template< class W, class C >
      47        1661 : Channel< W, C >::Channel( W* parent )
      48             :         : _window( parent )
      49             :         , _context( &_data.nativeContext )
      50             :         , _drawable( FB_WINDOW )
      51        1661 :         , _maxSize( Vector2i::ZERO )
      52             : {
      53        1661 :     memset( _iAttributes, 0xff, IATTR_ALL * sizeof( int32_t ));
      54        1661 :     parent->_addChannel( static_cast< C* >( this ));
      55        1661 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      56        1661 : }
      57             : 
      58             : template< class W, class C >
      59         636 : Channel< W, C >::Channel( const Channel& from )
      60             :         : Object( from )
      61             :         , _window( from._window )
      62             :         , _data( from._data )
      63             :         , _context( &_data.nativeContext )
      64             :         , _drawable( from._drawable )
      65         636 :         , _maxSize( from._maxSize )
      66             : {
      67         636 :     _window->_addChannel( static_cast< C* >( this ));
      68             : 
      69        5088 :     for( int i = 0; i < IATTR_ALL; ++i )
      70        4452 :         _iAttributes[i] = from._iAttributes[i];
      71        4452 :     for( int i = 0; i < SATTR_ALL; ++i )
      72        3816 :         _sAttributes[i] = from._sAttributes[i];
      73         636 :     LBLOG( LOG_INIT ) << "New " << lunchbox::className( this ) << std::endl;
      74         636 : }
      75             : 
      76             : template< class W, class C >
      77        1466 : void Channel< W, C >::init()
      78             : {
      79        1466 :     LBLOG( LOG_INIT ) << "Delete " << lunchbox::className( this ) << std::endl;
      80        1466 :     notifyViewportChanged();
      81        1466 :     unsetDirty( DIRTY_VIEWPORT );
      82        1466 : }
      83             : 
      84             : template< class W, class C >
      85        1485 : Channel< W, C >::~Channel()
      86             : {
      87        1485 :     _window->_removeChannel( static_cast< C* >( this ));
      88        2970 : }
      89             : 
      90             : template< class W, class C >
      91       62283 : VisitorResult Channel< W, C >::accept( Visitor& visitor )
      92             : {
      93       62283 :     return visitor.visit( static_cast< C* >( this ));
      94             : }
      95             : 
      96             : template< class W, class C >
      97           0 : VisitorResult Channel< W, C >::accept( Visitor& visitor ) const
      98             : {
      99           0 :     return visitor.visit( static_cast< const C* >( this ));
     100             : }
     101             : 
     102             : template< class W, class C >
     103          86 : void Channel< W, C >::backup()
     104             : {
     105          86 :     Object::backup();
     106          86 :     _backup = _data;
     107          86 : }
     108             : 
     109             : template< class W, class C >
     110           4 : void Channel< W, C >::restore()
     111             : {
     112           4 :     _data = _backup;
     113           4 :     Object::restore();
     114           4 :     notifyViewportChanged();
     115           4 :     setDirty( DIRTY_VIEWPORT | DIRTY_MEMBER | DIRTY_FRUSTUM );
     116           4 : }
     117             : 
     118             : template< class W, class C >
     119          47 : void Channel< W, C >::serialize( co::DataOStream& os, const uint64_t dirtyBits )
     120             : {
     121          47 :     LBASSERT( dirtyBits == DIRTY_ALL ||
     122             :               getWindow()->Serializable::isDirty( W::DIRTY_CHANNELS ));
     123          47 :     Object::serialize( os, dirtyBits );
     124          47 :     if( dirtyBits & DIRTY_ATTRIBUTES )
     125          15 :         os << co::Array< int32_t >( _iAttributes, IATTR_ALL )
     126          30 :            << co::Array< std::string >( _sAttributes, SATTR_ALL );
     127          47 :     if( dirtyBits & DIRTY_VIEWPORT )
     128          66 :         os << _data.nativeContext.vp << _data.nativeContext.pvp
     129          66 :            << _data.fixedVP << _maxSize;
     130          47 :     if( dirtyBits & DIRTY_MEMBER )
     131          32 :         os << _drawable << _data.nativeContext.view
     132          32 :            << _data.nativeContext.overdraw;
     133          47 :     if( dirtyBits & DIRTY_FRUSTUM )
     134          15 :         os << _data.nativeContext.frustum;
     135          47 :     if( dirtyBits & DIRTY_CAPABILITIES )
     136          15 :         os << _data.capabilities;
     137          47 : }
     138             : 
     139             : template< class W, class C >
     140          31 : void Channel< W, C >::deserialize( co::DataIStream& is,
     141             :                                    const uint64_t dirtyBits )
     142             : {
     143          31 :     Object::deserialize( is, dirtyBits );
     144          31 :     if( dirtyBits & DIRTY_ATTRIBUTES )
     145          15 :         is >> co::Array< int32_t >( _iAttributes, IATTR_ALL )
     146          30 :            >> co::Array< std::string >( _sAttributes, SATTR_ALL );
     147          31 :     if( dirtyBits & DIRTY_VIEWPORT )
     148             :     {
     149             :         // Ignore data from master (server) if we have local changes
     150          28 :         if( !Serializable::isDirty( DIRTY_VIEWPORT ) || isMaster( ))
     151             :         {
     152          56 :             is >> _data.nativeContext.vp >> _data.nativeContext.pvp
     153          56 :                >> _data.fixedVP >> _maxSize;
     154          28 :             notifyViewportChanged();
     155             :         }
     156             :         else // consume unused data
     157           0 :             is.getRemainingBuffer( sizeof( _data.nativeContext.vp ) +
     158             :                                    sizeof( _data.nativeContext.pvp ) +
     159           0 :                                    sizeof( _data.fixedVP ) + sizeof( _maxSize ));
     160             :     }
     161          31 :     if( dirtyBits & DIRTY_MEMBER )
     162          21 :         is >> _drawable >> _data.nativeContext.view
     163          21 :            >> _data.nativeContext.overdraw;
     164          31 :     if( dirtyBits & DIRTY_FRUSTUM )
     165          15 :         is >> _data.nativeContext.frustum;
     166          31 :     if( dirtyBits & DIRTY_CAPABILITIES )
     167             :     {
     168          15 :         is >> _data.capabilities;
     169          15 :         updateCapabilities();
     170             :     }
     171          31 : }
     172             : 
     173             : template< class W, class C >
     174       13752 : void Channel< W, C >::setDirty( const uint64_t dirtyBits )
     175             : {
     176       13752 :     Object::setDirty( dirtyBits );
     177       13752 :     _window->setDirty( W::DIRTY_CHANNELS );
     178       13752 : }
     179             : 
     180             : //----------------------------------------------------------------------
     181             : // viewport
     182             : //----------------------------------------------------------------------
     183             : template< class W, class C >
     184         179 : void Channel< W, C >::setPixelViewport( const PixelViewport& pvp )
     185             : {
     186         179 :     LBASSERT( pvp.isValid( ));
     187         179 :     if( !pvp.isValid( ))
     188           0 :         return;
     189             : 
     190         179 :     _data.fixedVP = false;
     191             : 
     192         179 :     if( _data.nativeContext.pvp == pvp && _data.nativeContext.vp.hasArea( ))
     193         155 :         return;
     194             : 
     195          24 :     _data.nativeContext.pvp = pvp;
     196          24 :     _data.nativeContext.vp.invalidate();
     197             : 
     198          24 :     notifyViewportChanged();
     199          24 :     setDirty( DIRTY_VIEWPORT );
     200             : }
     201             : 
     202             : template< class W, class C >
     203        1073 : void Channel< W, C >::setViewport( const Viewport& vp )
     204             : {
     205        1073 :     if( !vp.hasArea( ))
     206           0 :         return;
     207             : 
     208        1073 :     _data.fixedVP = true;
     209             : 
     210        1073 :     if( _data.nativeContext.vp == vp && _data.nativeContext.pvp.hasArea( ))
     211         491 :         return;
     212             : 
     213         582 :     _data.nativeContext.vp = vp;
     214         582 :     _data.nativeContext.pvp.invalidate();
     215             : 
     216         582 :     notifyViewportChanged();
     217         582 :     setDirty( DIRTY_VIEWPORT );
     218             : }
     219             : 
     220             : template< class W, class C >
     221        2172 : void Channel< W, C >::notifyViewportChanged()
     222             : {
     223        2172 :     if( !_window )
     224         482 :         return;
     225             : 
     226        2172 :     PixelViewport windowPVP = _window->getPixelViewport();
     227        2172 :     if( !windowPVP.isValid( ))
     228         482 :         return;
     229             : 
     230        1690 :     windowPVP.x = 0;
     231        1690 :     windowPVP.y = 0;
     232             : 
     233        1690 :     if( _data.fixedVP ) // update pixel viewport
     234             :     {
     235        1660 :         const PixelViewport oldPVP = _data.nativeContext.pvp;
     236        1660 :         _data.nativeContext.pvp = windowPVP;
     237        1660 :         _data.nativeContext.pvp.apply( _data.nativeContext.vp );
     238        1660 :         if( oldPVP != _data.nativeContext.pvp )
     239        1095 :             setDirty( DIRTY_VIEWPORT );
     240             :     }
     241             :     else           // update viewport
     242             :     {
     243          30 :         const Viewport oldVP = _data.nativeContext.vp;
     244          30 :         _data.nativeContext.vp = _data.nativeContext.pvp / windowPVP;
     245          30 :         if( oldVP != _data.nativeContext.vp )
     246          25 :             setDirty( DIRTY_VIEWPORT );
     247             :     }
     248             : 
     249        1690 :     LBVERB << getName() << " viewport update: " << _data.nativeContext.vp << ":"
     250           0 :            << _data.nativeContext.pvp << std::endl;
     251             : }
     252             : 
     253             : template< class W, class C >
     254           0 : void Channel< W, C >::setNearFar( const float nearPlane, const float farPlane )
     255             : {
     256           0 :     LBASSERT( _context );
     257           0 :     if( _data.nativeContext.frustum.near_plane() != nearPlane ||
     258           0 :         _data.nativeContext.frustum.far_plane() != farPlane )
     259             :     {
     260           0 :         _data.nativeContext.frustum.adjust_near( nearPlane );
     261           0 :         _data.nativeContext.frustum.far_plane() = farPlane;
     262           0 :         _data.nativeContext.ortho.near_plane()  = nearPlane;
     263           0 :         _data.nativeContext.ortho.far_plane()   = farPlane;
     264           0 :         setDirty( DIRTY_FRUSTUM );
     265             :     }
     266             : 
     267           0 :     if( _context == &_data.nativeContext )
     268           0 :         return;
     269             : 
     270           0 :     if( _context->frustum.near_plane() != nearPlane ||
     271           0 :         _context->frustum.far_plane() != farPlane )
     272             :     {
     273           0 :         _context->frustum.adjust_near( nearPlane );
     274           0 :         _context->frustum.far_plane() = farPlane;
     275           0 :         _context->ortho.near_plane() = nearPlane;
     276           0 :         _context->ortho.far_plane()  = farPlane;
     277             :     }
     278             : }
     279             : 
     280             : template< class W, class C >
     281          44 : void Channel< W, C >::setDrawable( const uint32_t drawable )
     282             : {
     283          44 :     _drawable = drawable;
     284          44 :     setDirty( DIRTY_MEMBER );
     285          44 : }
     286             : 
     287             : template< class W, class C >
     288         812 : void Channel< W, C >::setViewVersion( const co::ObjectVersion& view )
     289             : {
     290         812 :     if( _data.nativeContext.view == view )
     291        1482 :         return;
     292         142 :     LBASSERTINFO( view.identifier != 0 ||
     293             :                   _data.nativeContext.view.version <= view.version,
     294             :                   _data.nativeContext.view << " != " << view );
     295             : 
     296         142 :     _data.nativeContext.view = view;
     297         142 :     setDirty( DIRTY_MEMBER );
     298             : }
     299             : 
     300             : template< class W, class C >
     301        1248 : uint64_t Channel< W, C >::getCapabilities() const
     302             : {
     303        1248 :     return _data.capabilities;
     304             : }
     305             : 
     306             : template< class W, class C >
     307           0 : void Channel< W, C >::setCapabilities( const uint64_t bitmask )
     308             : {
     309           0 :     if ( bitmask == _data.capabilities )
     310           0 :         return;
     311             : 
     312           0 :     _data.capabilities = bitmask;
     313           0 :     setDirty( DIRTY_CAPABILITIES );
     314             : }
     315             : 
     316             : template< class W, class C >
     317           0 : void Channel< W, C >::setMaxSize( const Vector2i& size )
     318             : {
     319           0 :     _maxSize = size;
     320           0 :     setDirty( DIRTY_VIEWPORT );
     321           0 : }
     322             : 
     323             : template< class W, class C >
     324         368 : void Channel< W, C >::setOverdraw( const Vector4i& overdraw )
     325             : {
     326         368 :     if( _data.nativeContext.overdraw == overdraw )
     327         736 :         return;
     328           0 :     _data.nativeContext.overdraw = overdraw;
     329           0 :     setDirty( DIRTY_MEMBER );
     330             : }
     331             : 
     332             : template< class W, class C >
     333           0 : ChannelPath Channel< W, C >::getPath() const
     334             : {
     335           0 :     const W* window = getWindow();
     336           0 :     LBASSERT( window );
     337           0 :     ChannelPath path( window->getPath( ));
     338             : 
     339           0 :     const typename W::Channels& channels = window->getChannels();
     340             :     typename W::Channels::const_iterator i = std::find( channels.begin(),
     341           0 :                                                         channels.end(), this );
     342           0 :     LBASSERT( i != channels.end( ));
     343           0 :     path.channelIndex = std::distance( channels.begin(), i );
     344           0 :     return path;
     345             : }
     346             : 
     347             : 
     348             : template< class W, class C >
     349          32 : int32_t Channel< W, C >::getIAttribute( const IAttribute attr ) const
     350             : {
     351          32 :     LBASSERT( attr < IATTR_ALL );
     352          32 :     return _iAttributes[ attr ];
     353             : }
     354             : 
     355             : template< class W, class C >
     356           6 : std::string Channel< W, C >::getSAttribute( const SAttribute attr ) const
     357             : {
     358           6 :     LBASSERT( attr < SATTR_ALL );
     359           6 :     return _sAttributes[ attr ];
     360             : }
     361             : 
     362             : template< class W, class C >
     363         711 : const std::string& Channel< W, C >::getIAttributeString( const IAttribute attr )
     364             : {
     365         711 :     return _iAttributeStrings[attr];
     366             : }
     367             : 
     368             : template< class W, class C >
     369         356 : const std::string& Channel< W, C >::getSAttributeString( const SAttribute attr )
     370             : {
     371         356 :     return _sAttributeStrings[attr];
     372             : }
     373             : 
     374             : template< class W, class C >
     375         860 : std::ostream& operator << ( std::ostream& os,
     376             :                             const Channel< W, C >& channel)
     377             : {
     378         860 :     if( channel.omitOutput( ))
     379         410 :         return os;
     380             : 
     381         450 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "channel"
     382             :        << std::endl;
     383         450 :     os << "{" << std::endl << lunchbox::indent;
     384             : 
     385         450 :     const std::string& name = channel.getName();
     386         450 :     if( !name.empty( ))
     387         450 :         os << "name     \"" << name << "\"" << std::endl;
     388             : 
     389         450 :     const Viewport& vp = channel.getViewport();
     390         450 :     const PixelViewport& pvp = channel.getPixelViewport();
     391         450 :     if( vp.isValid( ) && channel.hasFixedViewport( ))
     392             :     {
     393         446 :         if( pvp.hasArea( ))
     394         164 :             os << "viewport " << pvp << std::endl;
     395         446 :         os << "viewport " << vp << std::endl;
     396             :     }
     397           4 :     else if( pvp.hasArea( ))
     398             :     {
     399           4 :         if( vp != Viewport::FULL && vp.isValid( ))
     400           4 :             os << "viewport " << vp << std::endl;
     401           4 :         os << "viewport " << pvp << std::endl;
     402             :     }
     403             : 
     404             : 
     405         450 :     const uint32_t drawable = channel.getDrawable();
     406         450 :     if( drawable != C::FB_WINDOW )
     407             :     {
     408          22 :         os << "drawable [";
     409             : 
     410          22 :         if ((drawable & C::FBO_COLOR) != 0 )
     411             :         {
     412          22 :            os << " FBO_COLOR";
     413             :         }
     414             : 
     415          22 :         if ((drawable & C::FBO_DEPTH) != 0)
     416             :         {
     417          22 :            os << " FBO_DEPTH";
     418             :         }
     419          22 :         if ((drawable & C::FBO_STENCIL) != 0)
     420             :         {
     421           0 :            os << " FBO_STENCIL";
     422             :         }
     423             : 
     424          22 :         os << " ]" << std::endl;
     425             :     }
     426         450 :     os << lunchbox::exdent << "}" << std::endl << lunchbox::enableHeader
     427             :        << lunchbox::enableFlush;
     428             : 
     429         450 :     return os;
     430             : }
     431             : 
     432             : }
     433             : }

Generated by: LCOV version 1.10