LCOV - code coverage report
Current view: top level - eq/server - compoundUpdateOutputVisitor.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 79 162 48.8 %
Date: 2014-06-18 Functions: 8 10 80.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2007-2014, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *               2011-2012, Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "compoundUpdateOutputVisitor.h"
      20             : 
      21             : #include "config.h"
      22             : #include "frame.h"
      23             : #include "frameData.h"
      24             : #include "server.h"
      25             : #include "tileQueue.h"
      26             : #include "window.h"
      27             : 
      28             : #include "tiles/zigzagStrategy.h"
      29             : 
      30             : #include <eq/client/log.h>
      31             : #include <eq/fabric/iAttribute.h>
      32             : #include <eq/fabric/tile.h>
      33             : 
      34             : namespace eq
      35             : {
      36             : namespace server
      37             : {
      38          72 : CompoundUpdateOutputVisitor::CompoundUpdateOutputVisitor(
      39             :     const uint32_t frameNumber )
      40          72 :         : _frameNumber( frameNumber )
      41          72 : {}
      42             : 
      43         171 : VisitorResult CompoundUpdateOutputVisitor::visit( Compound* compound )
      44             : {
      45         171 :     if( !compound->isActive( ))
      46          68 :         return TRAVERSE_PRUNE;
      47             : 
      48         103 :     _updateQueues( compound );
      49         103 :     _updateFrames( compound );
      50         103 :     _updateSwapBarriers( compound );
      51             : 
      52         103 :     return TRAVERSE_CONTINUE;
      53             : }
      54             : 
      55         103 : void CompoundUpdateOutputVisitor::_updateQueues( Compound* compound )
      56             : {
      57         103 :     const TileQueues& queues = compound->getOutputTileQueues();
      58         103 :     for( TileQueuesCIter i = queues.begin(); i != queues.end(); ++i )
      59             :     {
      60             :         //----- Check uniqueness of output queue name
      61           0 :         TileQueue* queue  = *i;
      62           0 :         const std::string& name   = queue->getName();
      63             : 
      64           0 :         if( _outputTileQueues.find( name ) != _outputTileQueues.end( ))
      65             :         {
      66           0 :             LBWARN << "Multiple output queues of the same name are unsupported"
      67           0 :                 << ", ignoring output queue " << name << std::endl;
      68           0 :             queue->unsetData();
      69           0 :             continue;
      70             :         }
      71             : 
      72           0 :         queue->cycleData( _frameNumber, compound );
      73             : 
      74             :         //----- Generate tile task commands
      75           0 :         _generateTiles( queue, compound );
      76           0 :         _outputTileQueues[name] = queue;
      77             :     }
      78         103 : }
      79             : 
      80         103 : void CompoundUpdateOutputVisitor::_updateFrames( Compound* compound )
      81             : {
      82         103 :     const Frames& outputFrames = compound->getOutputFrames();
      83         103 :     if( outputFrames.empty( ))
      84          94 :         compound->unsetInheritTask( fabric::TASK_READBACK );
      85             : 
      86         103 :     const Channel* channel = compound->getChannel();
      87         103 :     if( !compound->testInheritTask( fabric::TASK_READBACK ) || !channel )
      88         197 :         return;
      89             : 
      90          18 :     for( FramesCIter i = outputFrames.begin(); i != outputFrames.end(); ++i )
      91             :     {
      92             :         //----- Check uniqueness of output frame name
      93           9 :         Frame*             frame  = *i;
      94           9 :         const std::string& name   = frame->getName();
      95             : 
      96           9 :         if( _outputFrames.find( name ) != _outputFrames.end())
      97             :         {
      98           0 :             LBWARN << "Multiple output frames of the same name are unsupported"
      99           0 :                    << ", ignoring output frame " << name << std::endl;
     100           0 :             frame->unsetData();
     101           0 :             continue;
     102             :         }
     103             : 
     104             :         //----- compute readback area
     105           9 :         const Viewport& frameVP = frame->getViewport();
     106           9 :         const PixelViewport& inheritPVP = compound->getInheritPixelViewport();
     107           9 :         PixelViewport framePVP( inheritPVP );
     108           9 :         framePVP.apply( frameVP );
     109             : 
     110           9 :         if( !framePVP.hasArea( )) // output frame has no pixels
     111             :         {
     112           0 :             LBINFO << "Skipping output frame " << name << ", no pixels"
     113           0 :                    << std::endl;
     114           0 :             frame->unsetData();
     115           0 :             continue;
     116             :         }
     117             : 
     118             :         //----- Create new frame datas
     119             :         // * one frame data used for each eye pass
     120             :         // * data is set only on master frame data (will copy to all others)
     121           9 :         frame->cycleData( _frameNumber, compound );
     122           9 :         FrameData* frameData = frame->getMasterData();
     123           9 :         LBASSERT( frameData );
     124             : 
     125           9 :         LBLOG( LOG_ASSEMBLY )
     126           0 :             << lunchbox::disableFlush << "Output frame \"" << name << "\" id "
     127           9 :             << frame->getID() << " v" << frame->getVersion()+1
     128           0 :             << " data id " << frameData->getID() << " v"
     129           9 :             << frameData->getVersion() + 1 << " on channel \""
     130           0 :             << channel->getName() << "\" tile pos " << framePVP.x << ", "
     131          27 :             << framePVP.y;
     132             : 
     133             :         //----- Set frame data parameters:
     134             :         // 1) offset is position wrt destination view, used only by input frames
     135           9 :         const bool tiled = !compound->getInputTileQueues().empty();
     136             :         frameData->setOffset( tiled ? Vector2i( 0 , 0 ) :
     137           9 :                                       Vector2i( framePVP.x, framePVP.y ));
     138             : 
     139             :         // 2) pvp is area within channel
     140           9 :         framePVP.x = static_cast< int32_t >( frameVP.x * inheritPVP.w );
     141           9 :         framePVP.y = static_cast< int32_t >( frameVP.y * inheritPVP.h );
     142           9 :         frameData->setPixelViewport( framePVP );
     143             : 
     144             :         // 3) image buffers and storage type
     145           9 :         uint32_t buffers = frame->getBuffers();
     146             : 
     147           9 :         frameData->setType( frame->getType() );
     148             :         frameData->setBuffers( buffers == eq::Frame::BUFFER_UNDEFINED ?
     149           9 :                                    compound->getInheritBuffers() : buffers );
     150             : 
     151             :         // 4) (source) render context
     152           9 :         frameData->setRange( compound->getInheritRange( ));
     153           9 :         frameData->setPixel( compound->getInheritPixel( ));
     154           9 :         frameData->setSubPixel( compound->getInheritSubPixel( ));
     155           9 :         frameData->setPeriod( compound->getInheritPeriod( ));
     156           9 :         frameData->setPhase( compound->getInheritPhase( ));
     157             : 
     158             :         //----- Set frame parameters:
     159             :         // 1) offset is position wrt window, i.e., the channel position
     160           9 :         if( compound->getInheritChannel() == channel )
     161           0 :             frame->setOffset( Vector2i( inheritPVP.x, inheritPVP.y ));
     162             :         else
     163             :         {
     164           9 :             const PixelViewport& nativePVP = channel->getPixelViewport();
     165           9 :             frame->setOffset( Vector2i( nativePVP.x, nativePVP.y ));
     166             :         }
     167             : 
     168             :         // 2) zoom
     169           9 :         _updateZoom( compound, frame );
     170             : 
     171             :         //----- Commit
     172           9 :         frame->commitData();
     173             : 
     174           9 :         _outputFrames[name] = frame;
     175           9 :         LBLOG( LOG_ASSEMBLY )
     176           0 :             << " buffers " << frameData->getBuffers() << " read area "
     177           0 :             << framePVP << " readback " << frame->getZoom() << " assemble "
     178           9 :             << frameData->getZoom()<< lunchbox::enableFlush << std::endl ;
     179             :     }
     180             : }
     181             : 
     182           0 : void CompoundUpdateOutputVisitor::_generateTiles( TileQueue* queue,
     183             :                                                   Compound* compound )
     184             : {
     185           0 :     const Vector2i& tileSize = queue->getTileSize();
     186           0 :     const PixelViewport pvp = compound->getInheritPixelViewport();
     187           0 :     if( !pvp.hasArea( ))
     188           0 :         return;
     189             : 
     190           0 :     const Vector2i dim( pvp.w / tileSize.x() + ((pvp.w%tileSize.x()) ? 1 : 0),
     191           0 :                         pvp.h / tileSize.y() + ((pvp.h%tileSize.y()) ? 1 : 0));
     192             : 
     193           0 :     std::vector< Vector2i > tiles;
     194           0 :     tiles.reserve( dim.x() * dim.y() );
     195             : 
     196           0 :     tiles::generateZigzag( tiles, dim );
     197           0 :     _addTilesToQueue( queue, compound, tiles );
     198             : }
     199             : 
     200           0 : void CompoundUpdateOutputVisitor::_addTilesToQueue( TileQueue* queue,
     201             :                                                     Compound* compound,
     202             :                                          const std::vector< Vector2i >& tiles )
     203             : {
     204             : 
     205           0 :     const Vector2i& tileSize = queue->getTileSize();
     206           0 :     PixelViewport pvp = compound->getInheritPixelViewport();
     207           0 :     const double xFraction = 1.0 / pvp.w;
     208           0 :     const double yFraction = 1.0 / pvp.h;
     209             : 
     210           0 :     for( std::vector< Vector2i >::const_iterator i = tiles.begin();
     211           0 :          i != tiles.end(); ++i )
     212             :     {
     213           0 :         const Vector2i& tile = *i;
     214           0 :         PixelViewport tilePVP( tile.x() * tileSize.x(), tile.y() * tileSize.y(),
     215           0 :                                tileSize.x(), tileSize.y( ));
     216             : 
     217           0 :         if ( tilePVP.x + tileSize.x() > pvp.w ) // no full tile
     218           0 :             tilePVP.w = pvp.w - tilePVP.x;
     219             : 
     220           0 :         if ( tilePVP.y + tileSize.y() > pvp.h ) // no full tile
     221           0 :             tilePVP.h = pvp.h - tilePVP.y;
     222             : 
     223           0 :         const Viewport tileVP( tilePVP.x * xFraction, tilePVP.y * yFraction,
     224           0 :                                tilePVP.w * xFraction, tilePVP.h * yFraction );
     225             : 
     226           0 :         for( fabric::Eye eye = fabric::EYE_CYCLOP; eye < fabric::EYES_ALL;
     227           0 :              eye = fabric::Eye(eye<<1) )
     228             :         {
     229           0 :             if ( !(compound->getInheritEyes() & eye) ||
     230           0 :                  !compound->isInheritActive( eye ))
     231             :             {
     232           0 :                 continue;
     233             :             }
     234             : 
     235           0 :             Tile tileItem( tilePVP, tileVP );
     236             :             compound->computeTileFrustum( tileItem.frustum, eye, tileItem.vp,
     237           0 :                                           false );
     238             :             compound->computeTileFrustum( tileItem.ortho, eye, tileItem.vp,
     239           0 :                                           true );
     240           0 :             queue->addTile( tileItem, eye );
     241           0 :         }
     242             :     }
     243           0 : }
     244             : 
     245           9 : void CompoundUpdateOutputVisitor::_updateZoom( const Compound* compound,
     246             :                                                Frame* frame )
     247             : {
     248           9 :     Zoom zoom = frame->getNativeZoom();
     249           9 :     Zoom zoom_1;
     250             : 
     251           9 :     if( !zoom.isValid( )) // if zoom is not set, auto-calculate from parent
     252             :     {
     253           9 :         zoom_1 = compound->getInheritZoom();
     254           9 :         LBASSERT( zoom_1.isValid( ));
     255           9 :         zoom.x() = 1.0f / zoom_1.x();
     256           9 :         zoom.y() = 1.0f / zoom_1.y();
     257             :     }
     258             :     else
     259             :     {
     260           0 :         zoom_1.x() = 1.0f / zoom.x();
     261           0 :         zoom_1.y() = 1.0f / zoom.y();
     262             :     }
     263             : 
     264           9 :     if( frame->getType( ) == eq::Frame::TYPE_TEXTURE )
     265             :     {
     266           0 :         FrameData* frameData = frame->getMasterData();
     267           0 :         frameData->setZoom( zoom_1 ); // textures are zoomed by input frame
     268           0 :         frame->setZoom( Zoom::NONE );
     269             :     }
     270             :     else
     271             :     {
     272           9 :         Zoom inputZoom;
     273             :         /* Output frames downscale pixel data during readback, and upscale it on
     274             :          * the input frame by setting the input frame's inherit zoom. */
     275           9 :         if( zoom.x() > 1.0f )
     276             :         {
     277           0 :             inputZoom.x() = zoom_1.x();
     278           0 :             zoom.x()      = 1.f;
     279             :         }
     280           9 :         if( zoom.y() > 1.0f )
     281             :         {
     282           0 :             inputZoom.y() = zoom_1.y();
     283           0 :             zoom.y()      = 1.f;
     284             :         }
     285             : 
     286           9 :         FrameData* frameData = frame->getMasterData();
     287           9 :         frameData->setZoom( inputZoom );
     288           9 :         frame->setZoom( zoom );
     289             :     }
     290           9 : }
     291             : 
     292         103 : void CompoundUpdateOutputVisitor::_updateSwapBarriers( Compound* compound )
     293             : {
     294         103 :     SwapBarrierConstPtr swapBarrier = compound->getSwapBarrier();
     295         103 :     if( !swapBarrier )
     296         103 :         return;
     297             : 
     298           0 :     Window* window = compound->getWindow();
     299           0 :     LBASSERT( window );
     300           0 :     if( !window )
     301           0 :         return;
     302             : 
     303           0 :     if( swapBarrier->isNvSwapBarrier( ))
     304             :     {
     305           0 :         if( !window->hasNVSwapBarrier( ))
     306             :         {
     307           0 :             const std::string name( "__NV_swap_group_protection_barrier__" );
     308           0 :             _swapBarriers[name] =
     309           0 :                 window->joinNVSwapBarrier( swapBarrier, _swapBarriers[name] );
     310             :         }
     311             :     }
     312             :     else
     313             :     {
     314           0 :         const std::string& name = swapBarrier->getName();
     315           0 :         _swapBarriers[name] = window->joinSwapBarrier( _swapBarriers[name] );
     316           0 :     }
     317             : }
     318             : 
     319             : }
     320          27 : }
     321             : 

Generated by: LCOV version 1.10