compoundUpdateOutputVisitor.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "compoundUpdateOutputVisitor.h"
00019
00020 #include "frame.h"
00021 #include "frameData.h"
00022 #include "swapBarrier.h"
00023 #include "window.h"
00024
00025 #include <eq/client/log.h>
00026
00027 using namespace std;
00028 using namespace stde;
00029 using namespace eq::base;
00030
00031 namespace eq
00032 {
00033 namespace server
00034 {
00035 CompoundUpdateOutputVisitor::CompoundUpdateOutputVisitor(
00036 const uint32_t frameNumber )
00037 : _frameNumber( frameNumber )
00038 {}
00039
00040 VisitorResult CompoundUpdateOutputVisitor::visit( Compound* compound )
00041 {
00042 if( !compound->isActive( ))
00043 return TRAVERSE_PRUNE;
00044
00045 _updateOutput( compound );
00046 _updateSwapBarriers( compound );
00047
00048 return TRAVERSE_CONTINUE;
00049 }
00050
00051 void CompoundUpdateOutputVisitor::_updateOutput( Compound* compound )
00052 {
00053 const std::vector< Frame* >& outputFrames = compound->getOutputFrames();
00054 const Channel* channel = compound->getChannel();
00055
00056 if( !compound->testInheritTask( eq::TASK_READBACK ) || !channel )
00057 return;
00058
00059 if( outputFrames.empty( ))
00060 {
00061 compound->unsetInheritTask( eq::TASK_READBACK );
00062 return;
00063 }
00064
00065 for( vector<Frame*>::const_iterator i = outputFrames.begin();
00066 i != outputFrames.end(); ++i )
00067 {
00068
00069 Frame* frame = *i;
00070 const std::string& name = frame->getName();
00071
00072 if( _outputFrames.find( name ) != _outputFrames.end())
00073 {
00074 EQWARN << "Multiple output frames of the same name are unsupported"
00075 << ", ignoring output frame " << name << endl;
00076 frame->unsetData();
00077 continue;
00078 }
00079
00080
00081 const eq::Viewport& frameVP = frame->getViewport();
00082 const eq::PixelViewport& inheritPVP=compound->getInheritPixelViewport();
00083 eq::PixelViewport framePVP = inheritPVP.getSubPVP( frameVP );
00084
00085 if( !framePVP.hasArea( ))
00086 {
00087 EQINFO << "Skipping output frame " << name << ", no pixels" << endl;
00088 frame->unsetData();
00089 continue;
00090 }
00091
00092
00093
00094
00095 frame->cycleData( _frameNumber, compound->getInheritEyes( ));
00096 FrameData* frameData = frame->getMasterData();
00097 EQASSERT( frameData );
00098
00099 EQLOG( eq::LOG_ASSEMBLY )
00100 << disableFlush << "Output frame \"" << name << "\" id "
00101 << frame->getID() << " v" << frame->getVersion()+1
00102 << " data id " << frameData->getID() << " v"
00103 << frameData->getVersion() + 1 << " on channel \""
00104 << channel->getName() << "\" tile pos " << framePVP.x << ", "
00105 << framePVP.y;
00106
00107
00108
00109 frameData->setOffset( Vector2i( framePVP.x, framePVP.y ));
00110
00111
00112 framePVP.x = (int32_t)(frameVP.x * inheritPVP.w);
00113 framePVP.y = (int32_t)(frameVP.y * inheritPVP.h);
00114 frameData->setPixelViewport( framePVP );
00115
00116
00117 uint32_t buffers = frame->getBuffers();
00118
00119 frameData->setType( frame->getType() );
00120 frameData->setBuffers( buffers == eq::Frame::BUFFER_UNDEFINED ?
00121 compound->getInheritBuffers() : buffers );
00122
00123
00124 frameData->setRange( compound->getInheritRange( ));
00125 frameData->setPixel( compound->getInheritPixel( ));
00126
00127
00128
00129 if( compound->getInheritChannel() == channel ||
00130 compound->getIAttribute( Compound::IATTR_HINT_OFFSET ) == eq::ON )
00131 {
00132 frame->setInheritOffset( Vector2i( inheritPVP.x, inheritPVP.y ));
00133 }
00134 else
00135 {
00136 const eq::PixelViewport& nativePVP = channel->getPixelViewport();
00137 frame->setInheritOffset( Vector2i( nativePVP.x, nativePVP.y ));
00138 }
00139
00140
00141 _updateZoom( compound, frame );
00142
00143
00144 frame->commitData();
00145 frame->commit();
00146
00147 _outputFrames[name] = frame;
00148 EQLOG( eq::LOG_ASSEMBLY )
00149 << " buffers " << frameData->getBuffers() << " read area "
00150 << framePVP << " readback " << frame->getInheritZoom()
00151 << " assemble " << frameData->getZoom() << endl << enableFlush;
00152 }
00153 }
00154
00155 void CompoundUpdateOutputVisitor::_updateZoom( const Compound* compound,
00156 Frame* frame )
00157 {
00158 eq::Zoom zoom = frame->getZoom();
00159 eq::Zoom zoom_1;
00160
00161 if( !zoom.isValid( ))
00162 {
00163 zoom_1 = compound->getInheritZoom();
00164 EQASSERT( zoom_1.isValid( ));
00165 zoom.x() = 1.0f / zoom_1.x();
00166 zoom.y() = 1.0f / zoom_1.y();
00167 }
00168 else
00169 {
00170 zoom_1.x() = 1.0f / zoom.x();
00171 zoom_1.y() = 1.0f / zoom.y();
00172 }
00173
00174 if( frame->getType( ) == eq::Frame::TYPE_TEXTURE )
00175 {
00176 FrameData* frameData = frame->getMasterData();
00177 frameData->setZoom( zoom_1 );
00178 frame->setInheritZoom( eq::Zoom( ));
00179 }
00180 else
00181 {
00182 eq::Zoom inputZoom;
00183
00184
00185 if( zoom.x() > 1.0f )
00186 {
00187 inputZoom.x() = zoom_1.x();
00188 zoom.x() = 1.f;
00189 }
00190 if( zoom.y() > 1.0f )
00191 {
00192 inputZoom.y() = zoom_1.y();
00193 zoom.y() = 1.f;
00194 }
00195
00196 FrameData* frameData = frame->getMasterData();
00197 frameData->setZoom( inputZoom );
00198 frame->setInheritZoom( zoom );
00199 }
00200 }
00201
00202 void CompoundUpdateOutputVisitor::_updateSwapBarriers( Compound* compound )
00203 {
00204 const SwapBarrier* swapBarrier = compound->getSwapBarrier();
00205 if( !swapBarrier )
00206 return;
00207
00208 Window* window = compound->getWindow();
00209 EQASSERT( window );
00210 if( !window )
00211 return;
00212
00213 if( swapBarrier->isNvSwapBarrier( ))
00214 {
00215 if( !window->hasNVSwapBarrier( ))
00216 {
00217 const std::string name( "__NV_swap_group_protection_barrier__" );
00218 _swapBarriers[name] =
00219 window->joinNVSwapBarrier( swapBarrier, _swapBarriers[name] );
00220 }
00221 }
00222 else
00223 {
00224 const std::string& name = swapBarrier->getName();
00225 _swapBarriers[name] = window->joinSwapBarrier( _swapBarriers[name] );
00226 }
00227 }
00228
00229 }
00230 }