/*! In case of attached mode, the current context must be reset to context for client \param [in] event Event sent to server */ void CContextClient::sendEvent(CEventClient& event) { list<int> ranks = event.getRanks(); if (!event.isEmpty()) { list<int> sizes = event.getSizes(); // We force the getBuffers call to be non-blocking on the servers list<CBufferOut*> buffList; bool couldBuffer = getBuffers(ranks, sizes, buffList, !CXios::isClient); if (couldBuffer) { event.send(timeLine, sizes, buffList); checkBuffers(ranks); if (isAttachedModeEnabled()) // couldBuffer is always true in attached mode { waitEvent(ranks); CContext::setCurrent(context->getId()); } } else { tmpBufferedEvent.ranks = ranks; tmpBufferedEvent.sizes = sizes; for (list<int>::const_iterator it = sizes.begin(); it != sizes.end(); it++) tmpBufferedEvent.buffers.push_back(new CBufferOut(*it)); event.send(timeLine, tmpBufferedEvent.sizes, tmpBufferedEvent.buffers); } } timeLine++; }
/*! * Send the temporarily buffered event (if any). * * \return true if a temporarily buffered event could be sent, false otherwise */ bool CContextClient::sendTemporarilyBufferedEvent() { bool couldSendTmpBufferedEvent = false; if (hasTemporarilyBufferedEvent()) { list<CBufferOut*> buffList; if (getBuffers(tmpBufferedEvent.ranks, tmpBufferedEvent.sizes, buffList, true)) // Non-blocking call { list<CBufferOut*>::iterator it, itBuffer; for (it = tmpBufferedEvent.buffers.begin(), itBuffer = buffList.begin(); it != tmpBufferedEvent.buffers.end(); it++, itBuffer++) (*itBuffer)->put((char*)(*it)->start(), (*it)->count()); checkBuffers(tmpBufferedEvent.ranks); tmpBufferedEvent.clear(); couldSendTmpBufferedEvent = true; } } return couldSendTmpBufferedEvent; }
Images FrameData::startReadback( const Frame& frame, util::ObjectManager& glObjects, const DrawableConfig& config, const PixelViewports& regions ) { if( _impl->data.buffers == Frame::BUFFER_NONE ) return Images(); const Zoom& zoom = frame.getZoom(); if( !zoom.isValid( )) { LBWARN << "Invalid zoom factor, skipping frame" << std::endl; return Images(); } const eq::PixelViewport& framePVP = getPixelViewport(); const PixelViewport absPVP = framePVP + frame.getOffset(); if( !absPVP.isValid( )) return Images(); Images images; // readback the whole screen when using textures if( getType() == eq::Frame::TYPE_TEXTURE ) { Image* image = newImage( getType(), config ); if( image->startReadback( getBuffers(), absPVP, zoom, glObjects )) images.push_back( image ); image->setOffset( 0, 0 ); return images; } //else read only required regions #if 0 // TODO: issue #85: move automatic ROI detection to eq::Channel PixelViewports regions; if( _impl->data.buffers & Frame::BUFFER_DEPTH && zoom == Zoom::NONE ) regions = _impl->roiFinder->findRegions( _impl->data.buffers, absPVP, zoom, frame.getAssemblyStage(), frame.getFrameID(), glObjects); else regions.push_back( absPVP ); #endif LBASSERT( getType() == eq::Frame::TYPE_MEMORY ); const eq::Pixel& pixel = getPixel(); for( uint32_t i = 0; i < regions.size(); ++i ) { PixelViewport pvp = regions[ i ] + frame.getOffset(); pvp.intersect( absPVP ); if( !pvp.hasArea( )) continue; Image* image = newImage( getType(), config ); if( image->startReadback( getBuffers(), pvp, zoom, glObjects )) images.push_back( image ); pvp -= frame.getOffset(); pvp.apply( zoom ); image->setOffset( (pvp.x - framePVP.x) * pixel.w, (pvp.y - framePVP.y) * pixel.h ); } return images; }
/*! Requests the buffer to reduce its capacity to fit the data currently contained in the stream. */ void SendBuffer::squeeze() { for (RawSendBuffer & buffer : getBuffers()) { buffer.squeeze(); } }