LCOV - code coverage report
Current view: top level - eq/fabric - channel.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 154 200 77.0 %
Date: 2017-12-16 05:07:20 Functions: 30 80 37.5 %

          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         100 : static std::string _iAttributeStrings[] = {
      38         100 :     MAKE_ATTR_STRING(IATTR_HINT_STATISTICS),
      39         150 :     MAKE_ATTR_STRING(IATTR_HINT_SENDTOKEN)};
      40             : 
      41         100 : static std::string _sAttributeStrings[] = {MAKE_ATTR_STRING(SATTR_DUMP_IMAGE)};
      42             : }
      43             : 
      44             : template <class W, class C>
      45        1652 : Channel<W, C>::Channel(W* parent)
      46             :     : _window(parent)
      47        1652 :     , _context(&_data.nativeContext)
      48             : {
      49        1652 :     memset(_iAttributes, 0xff, IATTR_ALL * sizeof(int32_t));
      50        1652 :     parent->_addChannel(static_cast<C*>(this));
      51        1652 :     LBLOG(LOG_INIT) << "New " << lunchbox::className(this) << std::endl;
      52        1652 : }
      53             : 
      54             : template <class W, class C>
      55        1224 : Channel<W, C>::Channel(const Channel& from)
      56             :     : Object(from)
      57        1224 :     , _window(from._window)
      58             :     , _data(from._data)
      59        2448 :     , _context(&_data.nativeContext)
      60             : {
      61        1224 :     _window->_addChannel(static_cast<C*>(this));
      62             : 
      63        9792 :     for (int i = 0; i < IATTR_ALL; ++i)
      64        8568 :         _iAttributes[i] = from._iAttributes[i];
      65        8568 :     for (int i = 0; i < SATTR_ALL; ++i)
      66        7344 :         _sAttributes[i] = from._sAttributes[i];
      67        1224 :     LBLOG(LOG_INIT) << "New " << lunchbox::className(this) << std::endl;
      68        1224 : }
      69             : 
      70             : template <class W, class C>
      71        2872 : void Channel<W, C>::init()
      72             : {
      73        2872 :     notifyViewportChanged();
      74        2872 :     unsetDirty(DIRTY_VIEWPORT | DIRTY_PIXELVIEWPORT);
      75        2872 : }
      76             : 
      77             : template <class W, class C>
      78        2872 : Channel<W, C>::~Channel()
      79             : {
      80        2872 :     _window->_removeChannel(static_cast<C*>(this));
      81        5744 : }
      82             : 
      83             : template <class W, class C>
      84      113400 : VisitorResult Channel<W, C>::accept(Visitor& visitor)
      85             : {
      86      113400 :     return visitor.visit(static_cast<C*>(this));
      87             : }
      88             : 
      89             : template <class W, class C>
      90           0 : VisitorResult Channel<W, C>::accept(Visitor& visitor) const
      91             : {
      92           0 :     return visitor.visit(static_cast<const C*>(this));
      93             : }
      94             : 
      95             : template <class W, class C>
      96          18 : void Channel<W, C>::backup()
      97             : {
      98          18 :     Object::backup();
      99          18 :     _backup = _data;
     100          18 : }
     101             : 
     102             : template <class W, class C>
     103           0 : void Channel<W, C>::restore()
     104             : {
     105           0 :     _data = _backup;
     106           0 :     Object::restore();
     107           0 :     notifyViewportChanged();
     108           0 :     setDirty(DIRTY_VIEWPORT | DIRTY_PIXELVIEWPORT | DIRTY_MEMBER |
     109             :              DIRTY_FRUSTUM);
     110           0 : }
     111             : 
     112             : template <class W, class C>
     113          13 : void Channel<W, C>::serialize(co::DataOStream& os, const uint64_t dirtyBits)
     114             : {
     115          13 :     LBASSERT(dirtyBits == DIRTY_ALL ||
     116             :              getWindow()->Serializable::isDirty(W::DIRTY_CHANNELS));
     117          13 :     Object::serialize(os, dirtyBits);
     118          13 :     if (dirtyBits & DIRTY_ATTRIBUTES)
     119           4 :         os << co::Array<int32_t>(_iAttributes, IATTR_ALL)
     120           8 :            << co::Array<std::string>(_sAttributes, SATTR_ALL);
     121          13 :     if (dirtyBits & DIRTY_VIEWPORT)
     122           4 :         os << _data.nativeContext.vp << _data.fixedVP;
     123          13 :     if (dirtyBits & DIRTY_PIXELVIEWPORT)
     124           7 :         os << _data.nativeContext.pvp << _data.fixedVP;
     125          13 :     if (dirtyBits & DIRTY_MEMBER)
     126          10 :         os << _data.nativeContext.view << _data.nativeContext.overdraw;
     127          13 :     if (dirtyBits & DIRTY_FRUSTUM)
     128           4 :         os << _data.nativeContext.frustum;
     129          13 :     if (dirtyBits & DIRTY_CAPABILITIES)
     130           4 :         os << _data.capabilities;
     131          13 : }
     132             : 
     133             : template <class W, class C>
     134           7 : void Channel<W, C>::deserialize(co::DataIStream& is, const uint64_t dirtyBits)
     135             : {
     136           7 :     Object::deserialize(is, dirtyBits);
     137           7 :     if (dirtyBits & DIRTY_ATTRIBUTES)
     138           2 :         is >> co::Array<int32_t>(_iAttributes, IATTR_ALL) >>
     139             :             co::Array<std::string>(_sAttributes, SATTR_ALL);
     140           7 :     if (dirtyBits & DIRTY_VIEWPORT)
     141             :     {
     142             :         // Ignore data from master (server) if we have local changes
     143           2 :         if (!Serializable::isDirty(DIRTY_VIEWPORT) || isMaster())
     144             :         {
     145           2 :             is >> _data.nativeContext.vp >> _data.fixedVP;
     146           2 :             notifyViewportChanged();
     147             :         }
     148             :         else // consume unused data
     149           0 :             is.getRemainingBuffer(sizeof(_data.nativeContext.vp) +
     150             :                                   sizeof(_data.fixedVP));
     151             :     }
     152           7 :     if (dirtyBits & DIRTY_PIXELVIEWPORT)
     153             :     {
     154             :         // Ignore data from master (server) if we have local changes
     155           5 :         if (!Serializable::isDirty(DIRTY_PIXELVIEWPORT) || isMaster())
     156             :         {
     157           5 :             is >> _data.nativeContext.pvp >> _data.fixedVP;
     158           5 :             notifyViewportChanged();
     159             :         }
     160             :         else // consume unused data
     161           0 :             is.getRemainingBuffer(sizeof(_data.nativeContext.pvp) +
     162             :                                   sizeof(_data.fixedVP));
     163             :     }
     164           7 :     if (dirtyBits & DIRTY_MEMBER)
     165           4 :         is >> _data.nativeContext.view >> _data.nativeContext.overdraw;
     166           7 :     if (dirtyBits & DIRTY_FRUSTUM)
     167           2 :         is >> _data.nativeContext.frustum;
     168           7 :     if (dirtyBits & DIRTY_CAPABILITIES)
     169             :     {
     170           2 :         is >> _data.capabilities;
     171           2 :         updateCapabilities();
     172             :     }
     173           7 : }
     174             : 
     175             : template <class W, class C>
     176       26479 : void Channel<W, C>::setDirty(const uint64_t dirtyBits)
     177             : {
     178       26479 :     Object::setDirty(dirtyBits);
     179       26479 :     _window->setDirty(W::DIRTY_CHANNELS);
     180       26479 : }
     181             : 
     182             : //----------------------------------------------------------------------
     183             : // viewport
     184             : //----------------------------------------------------------------------
     185             : template <class W, class C>
     186         392 : void Channel<W, C>::setPixelViewport(const PixelViewport& pvp)
     187             : {
     188         392 :     LBASSERT(pvp.isValid());
     189         392 :     if (!pvp.isValid())
     190           0 :         return;
     191             : 
     192         392 :     _data.fixedVP = false;
     193             : 
     194         392 :     if (_data.nativeContext.pvp == pvp && _data.nativeContext.vp.hasArea())
     195         350 :         return;
     196             : 
     197          42 :     _data.nativeContext.pvp = pvp;
     198          42 :     _data.nativeContext.vp.invalidate();
     199             : 
     200          42 :     notifyViewportChanged();
     201          42 :     setDirty(DIRTY_PIXELVIEWPORT);
     202             : }
     203             : 
     204             : template <class W, class C>
     205        2110 : void Channel<W, C>::setViewport(const Viewport& vp)
     206             : {
     207        2110 :     if (!vp.hasArea())
     208           0 :         return;
     209             : 
     210        2110 :     _data.fixedVP = true;
     211             : 
     212        2110 :     if (_data.nativeContext.vp == vp && _data.nativeContext.pvp.hasArea())
     213         954 :         return;
     214             : 
     215        1156 :     _data.nativeContext.vp = vp;
     216        1156 :     _data.nativeContext.pvp.invalidate();
     217             : 
     218        1156 :     notifyViewportChanged();
     219        1156 :     setDirty(DIRTY_VIEWPORT);
     220             : }
     221             : 
     222             : template <class W, class C>
     223        4080 : void Channel<W, C>::notifyViewportChanged()
     224             : {
     225        4080 :     if (!_window)
     226         906 :         return;
     227             : 
     228        4080 :     PixelViewport windowPVP = _window->getPixelViewport();
     229        4080 :     if (!windowPVP.isValid())
     230         906 :         return;
     231             : 
     232        3174 :     windowPVP.x = 0;
     233        3174 :     windowPVP.y = 0;
     234             : 
     235        3174 :     if (_data.fixedVP) // update pixel viewport
     236             :     {
     237        3120 :         const PixelViewport oldPVP = _data.nativeContext.pvp;
     238        3120 :         _data.nativeContext.pvp = windowPVP;
     239        3120 :         _data.nativeContext.pvp.apply(_data.nativeContext.vp);
     240        3120 :         if (oldPVP != _data.nativeContext.pvp)
     241        2055 :             setDirty(DIRTY_PIXELVIEWPORT);
     242             :     }
     243             :     else // update viewport
     244             :     {
     245          54 :         const Viewport oldVP = _data.nativeContext.vp;
     246          54 :         _data.nativeContext.vp = _data.nativeContext.pvp / windowPVP;
     247          54 :         if (oldVP != _data.nativeContext.vp)
     248          44 :             setDirty(DIRTY_VIEWPORT);
     249             :     }
     250             : 
     251        3174 :     LBVERB << getName() << " viewport update: " << _data.nativeContext.vp << ":"
     252           0 :            << _data.nativeContext.pvp << std::endl;
     253             : }
     254             : 
     255             : template <class W, class C>
     256           0 : void Channel<W, C>::setNearFar(const float nearPlane, const float farPlane)
     257             : {
     258           0 :     LBASSERT(_context);
     259           0 :     if (_data.nativeContext.frustum.nearPlane() != nearPlane ||
     260           0 :         _data.nativeContext.frustum.farPlane() != farPlane)
     261             :     {
     262           0 :         _data.nativeContext.frustum.adjustNearPlane(nearPlane);
     263           0 :         _data.nativeContext.frustum.farPlane() = farPlane;
     264           0 :         _data.nativeContext.ortho.nearPlane() = nearPlane;
     265           0 :         _data.nativeContext.ortho.farPlane() = farPlane;
     266           0 :         setDirty(DIRTY_FRUSTUM);
     267             :     }
     268             : 
     269           0 :     if (_context == &_data.nativeContext)
     270           0 :         return;
     271             : 
     272           0 :     if (_context->frustum.nearPlane() != nearPlane ||
     273           0 :         _context->frustum.farPlane() != farPlane)
     274             :     {
     275           0 :         _context->frustum.adjustNearPlane(nearPlane);
     276           0 :         _context->frustum.farPlane() = farPlane;
     277           0 :         _context->ortho.nearPlane() = nearPlane;
     278           0 :         _context->ortho.farPlane() = farPlane;
     279             :     }
     280             : }
     281             : 
     282             : template <class W, class C>
     283        1300 : void Channel<W, C>::setViewVersion(const co::ObjectVersion& view)
     284             : {
     285        1300 :     if (_data.nativeContext.view == view)
     286        1250 :         return;
     287          50 :     LBASSERTINFO(view.identifier != 0 ||
     288             :                      _data.nativeContext.view.version <= view.version,
     289             :                  _data.nativeContext.view << " != " << view);
     290             : 
     291          50 :     _data.nativeContext.view = view;
     292          50 :     setDirty(DIRTY_MEMBER);
     293             : }
     294             : 
     295             : template <class W, class C>
     296         650 : uint64_t Channel<W, C>::getCapabilities() const
     297             : {
     298         650 :     return _data.capabilities;
     299             : }
     300             : 
     301             : template <class W, class C>
     302           0 : void Channel<W, C>::setCapabilities(const uint64_t bitmask)
     303             : {
     304           0 :     if (bitmask == _data.capabilities)
     305           0 :         return;
     306             : 
     307           0 :     _data.capabilities = bitmask;
     308           0 :     setDirty(DIRTY_CAPABILITIES);
     309             : }
     310             : 
     311             : template <class W, class C>
     312         118 : void Channel<W, C>::setOverdraw(const Vector4i& overdraw)
     313             : {
     314         118 :     if (_data.nativeContext.overdraw == overdraw)
     315         118 :         return;
     316           0 :     _data.nativeContext.overdraw = overdraw;
     317           0 :     setDirty(DIRTY_MEMBER);
     318             : }
     319             : 
     320             : template <class W, class C>
     321           0 : ChannelPath Channel<W, C>::getPath() const
     322             : {
     323           0 :     const W* window = getWindow();
     324           0 :     LBASSERT(window);
     325           0 :     ChannelPath path(window->getPath());
     326             : 
     327           0 :     const typename W::Channels& channels = window->getChannels();
     328             :     typename W::Channels::const_iterator i =
     329           0 :         std::find(channels.begin(), channels.end(), this);
     330           0 :     LBASSERT(i != channels.end());
     331           0 :     path.channelIndex = std::distance(channels.begin(), i);
     332           0 :     return path;
     333             : }
     334             : 
     335             : template <class W, class C>
     336           9 : int32_t Channel<W, C>::getIAttribute(const IAttribute attr) const
     337             : {
     338           9 :     LBASSERT(attr < IATTR_ALL);
     339           9 :     return _iAttributes[attr];
     340             : }
     341             : 
     342             : template <class W, class C>
     343           1 : const std::string& Channel<W, C>::getSAttribute(const SAttribute attr) const
     344             : {
     345           1 :     LBASSERT(attr < SATTR_ALL);
     346           1 :     return _sAttributes[attr];
     347             : }
     348             : 
     349             : template <class W, class C>
     350        1222 : const std::string& Channel<W, C>::getIAttributeString(const IAttribute attr)
     351             : {
     352        1222 :     return _iAttributeStrings[attr];
     353             : }
     354             : 
     355             : template <class W, class C>
     356         612 : const std::string& Channel<W, C>::getSAttributeString(const SAttribute attr)
     357             : {
     358         612 :     return _sAttributeStrings[attr];
     359             : }
     360             : 
     361             : template <class W, class C>
     362        1462 : std::ostream& operator<<(std::ostream& os, const Channel<W, C>& channel)
     363             : {
     364        1462 :     if (channel.omitOutput())
     365         632 :         return os;
     366             : 
     367         830 :     os << lunchbox::disableFlush << lunchbox::disableHeader << "channel"
     368             :        << std::endl;
     369         830 :     os << "{" << std::endl << lunchbox::indent;
     370             : 
     371         830 :     const std::string& name = channel.getName();
     372         830 :     if (!name.empty())
     373         830 :         os << "name     \"" << name << "\"" << std::endl;
     374             : 
     375         830 :     const Viewport& vp = channel.getViewport();
     376         830 :     const PixelViewport& pvp = channel.getPixelViewport();
     377         830 :     if (vp.hasArea() && channel.hasFixedViewport())
     378             :     {
     379         824 :         if (pvp.hasArea())
     380         368 :             os << "viewport " << pvp << std::endl;
     381         824 :         os << "viewport " << vp << std::endl;
     382             :     }
     383           6 :     else if (pvp.hasArea() && !channel.hasFixedViewport())
     384             :     {
     385           6 :         if (vp.hasArea())
     386           6 :             os << "viewport " << vp << std::endl;
     387           6 :         os << "viewport " << pvp << std::endl;
     388             :     }
     389             : 
     390        1660 :     os << lunchbox::exdent << "}" << std::endl
     391         830 :        << lunchbox::enableHeader << lunchbox::enableFlush;
     392             : 
     393         830 :     return os;
     394             : }
     395             : }
     396             : }

Generated by: LCOV version 1.11