void Channel::frameAssemble( const eq::uint128_t& frameID ) { if( stopRendering( )) return; if( _isDone( )) return; Accum& accum = _accum[ lunchbox::getIndexOfLastBit( getEye()) ]; if( getPixelViewport() != _currentPVP ) { accum.transfer = true; if( accum.buffer && !accum.buffer->usesFBO( )) { LBWARN << "Current viewport different from view viewport, " << "idle anti-aliasing not implemented." << std::endl; accum.step = 0; } eq::Channel::frameAssemble( frameID ); return; } // else accum.transfer = true; const eq::Frames& frames = getInputFrames(); for( eq::Frames::const_iterator i = frames.begin(); i != frames.end(); ++i ) { eq::Frame* frame = *i; const eq::SubPixel& curSubPixel = frame->getSubPixel(); if( curSubPixel != eq::SubPixel::ALL ) accum.transfer = false; accum.stepsDone = LB_MAX( accum.stepsDone, frame->getSubPixel().size*frame->getPeriod( )); } applyBuffer(); applyViewport(); setupAssemblyState(); try { eq::Compositor::assembleFrames( getInputFrames(), this, accum.buffer ); } catch( const co::Exception& e ) { LBWARN << e.what() << std::endl; } resetAssemblyState(); }
void Channel::frameAssemble( const eq::uint128_t& frameID ) { const bool composeOnly = (_drawRange == eq::Range::ALL); eq::FrameData* data = _frame.getData(); _startAssemble(); const eq::Frames& frames = getInputFrames(); eq::PixelViewport coveredPVP; eq::Frames dbFrames; eq::Zoom zoom( eq::Zoom::NONE ); // Make sure all frames are ready and gather some information on them for( eq::Frames::const_iterator i = frames.begin(); i != frames.end(); ++i ) { eq::Frame* frame = *i; { eq::ChannelStatistics stat( eq::Statistic::CHANNEL_FRAME_WAIT_READY, this ); frame->waitReady( ); } const eq::Range& range = frame->getRange(); if( range == eq::Range::ALL ) // 2D frame, assemble directly eq::Compositor::assembleFrame( frame, this ); else { dbFrames.push_back( frame ); zoom = frame->getZoom(); _expandPVP( coveredPVP, frame->getImages(), frame->getOffset() ); } } coveredPVP.intersect( getPixelViewport( )); if( dbFrames.empty( )) { resetAssemblyState(); return; } // calculate correct frames sequence if( !composeOnly && coveredPVP.hasArea( )) { _frame.clear(); data->setRange( _drawRange ); dbFrames.push_back( &_frame ); } _orderFrames( dbFrames ); // check if current frame is in proper position, read back if not if( !composeOnly ) { if( _bgColor == eq::Vector3f::ZERO && dbFrames.front() == &_frame ) dbFrames.erase( dbFrames.begin( )); else if( coveredPVP.hasArea()) { eq::Window::ObjectManager* glObjects = getObjectManager(); _frame.setOffset( eq::Vector2i( 0, 0 )); _frame.setZoom( zoom ); data->setPixelViewport( coveredPVP ); _frame.readback( glObjects, getDrawableConfig( )); clearViewport( coveredPVP ); // offset for assembly _frame.setOffset( eq::Vector2i( coveredPVP.x, coveredPVP.y )); } } // blend DB frames in order try { eq::Compositor::assembleFramesSorted( dbFrames, this, 0, true /*blendAlpha*/ ); } catch( eq::Exception e ) { EQWARN << e << std::endl; } resetAssemblyState(); // Update range _drawRange = getRange(); }