IPoolDataPtr MemoryPool::allocate( const std::size_t size ) { // Try to reuse a buffer available in the MemoryPool IPoolData* pData = getOneAvailableData( size ); if( pData != NULL ) { TUTTLE_LOG_TRACE("[Memory Pool] Reuse a buffer available in the MemoryPool"); pData->setSize( size ); return pData; } // Try to remove unused element in MemoryCache, and reuse the buffer available in the MemoryPool memory::IMemoryCache& memoryCache = core().getMemoryCache(); CACHE_ELEMENT unusedCacheElement = memoryCache.getUnusedWithSize( size ); if( unusedCacheElement.get() != NULL ) { TUTTLE_LOG_TRACE("[Memory Pool] Pop element in the MemoryCache from " << unusedCacheElement->getFullName() << " of size " << size); memoryCache.remove( unusedCacheElement ); pData = getOneAvailableData( size ); if( pData != NULL ) { TUTTLE_LOG_TRACE("[Memory Pool] Reuse a buffer available in the MemoryPool"); pData->setSize( size ); return pData; } } // Try to allocate a new buffer in MemoryPool std::size_t availableSize = getAvailableMemorySize(); if( size > availableSize ) { // Try to release elements from the MemoryCache (make them available to the MemoryPool) TUTTLE_LOG_TRACE("[Memory Pool] Release elements from the MemoryCache"); memoryCache.clearUnused(); availableSize = getAvailableMemorySize(); if( size > availableSize ) { // Release elements from the MemoryPool (make them available to the OS) TUTTLE_LOG_TRACE("[Memory Pool] Release elements from the MemoryPool"); clear(); } availableSize = getAvailableMemorySize(); if( size > availableSize ) { std::stringstream s; s << "[Memory Pool] can't allocate size:" << size << " because memory available is equal to " << availableSize << " bytes"; BOOST_THROW_EXCEPTION( std::length_error( s.str() ) ); } } // Allocate a new buffer in MemoryPool TUTTLE_TLOG( TUTTLE_TRACE, "[Memory Pool] allocate " << size << " bytes" ); return new PoolData( *this, size ); }
void finish_vertex(VertexDescriptor vd, Graph& g) { Vertex& vertex = _graph.instance(vd); TUTTLE_LOG_TRACE("[Time Domain] finish vertex " << vertex); if(vertex.isFake()) return; vertex.getProcessData()._timeDomain = vertex.getProcessNode().computeTimeDomain(); TUTTLE_LOG_TRACE("[Time Domain] min: " << vertex.getProcessData()._timeDomain.min << ", max: " << vertex.getProcessData()._timeDomain.max); }
void finish_vertex(VertexDescriptor vd, Graph& g) { Vertex& vertex = _graph.instance(vd); TUTTLE_LOG_TRACE("[Compute Hash At Time] finish vertex " << vertex); if(vertex.isFake()) return; const std::size_t localHash = vertex.getProcessNode().getLocalHashAtTime(_time); typedef std::map<VertexKey, std::size_t> InputsHash; InputsHash inputsGlobalHash; BOOST_FOREACH(const edge_descriptor& ed, _graph.getOutEdges(vd)) { const Edge& edge = _graph.instance(ed); vertex_descriptor inputVertexDesc = _graph.target(ed); Vertex& inputVertex = _graph.instance(inputVertexDesc); const std::size_t inputGlobalHash = _outNodesHash.getHash(inputVertex.getKey()); // Key is: (clipName, time) VertexKey k(edge.getInAttrName(), edge.getOutTime()); inputsGlobalHash[k] = inputGlobalHash; } // inputGlobalHashes is put into a map to be ordered by clip name // the clipName is unique for each time used std::size_t seed = localHash; BOOST_FOREACH(const typename InputsHash::value_type& inputGlobalHash, inputsGlobalHash) { // TUTTLE_LOG_VAR2( TUTTLE_TRACE, inputGlobalHash.first, inputGlobalHash.second ); boost::hash_combine(seed, inputGlobalHash.first.getName()); // name of the input clip connected boost::hash_combine(seed, inputGlobalHash.second); }
bool WriterPlugin::isIdentity( const OFX::RenderArguments& args, OFX::Clip*& identityClip, OfxTime& identityTime ) { EParamWriterExistingFile existingFile = static_cast<EParamWriterExistingFile>(_paramExistingFile->getValue()); if( existingFile != eParamWriterExistingFile_overwrite ) { const std::string filepath = getAbsoluteFilenameAt( args.time ); const bool fileExists = bfs::exists( filepath ); switch( existingFile ) { case eParamWriterExistingFile_error: { if( fileExists ) BOOST_THROW_EXCEPTION( exception::FileExist(filepath) ); break; } case eParamWriterExistingFile_reader: { BOOST_ASSERT(false); // Not implemented } case eParamWriterExistingFile_skip: { if( fileExists ) { // We declare an empty clip as identity to disable the process of this node. // This is not in the OpenFX standard. So this option only exist on TuttleOFX host. identityClip = NULL; identityTime = 0; TUTTLE_LOG_TRACE("[Plugin Writer] Identity node: " << this->getName() << " at time: " << args.time << ", file already exist:" << filepath); return true; } break; } case eParamWriterExistingFile_overwrite: BOOST_ASSERT(false); } } // little hack for the push button Render if( _oneRender && _oneRenderAtTime == args.time ) { return false; } if( OFX::getImageEffectHostDescription( )->hostIsBackground ) { return false; } if( _paramRenderAlways->getValue( ) ) { return false; } identityClip = _clipSrc; identityTime = args.time; return true; }
void discover_vertex(VertexDescriptor v, Graph& g) { Vertex& vertex = _graph.instance(v); TUTTLE_LOG_TRACE("[Setup 2] discover vertex " << vertex); if(vertex.isFake()) return; vertex.getProcessNode().setup2_reverse(); }
void finish_vertex(VertexDescriptor v, Graph& g) { Vertex& vertex = _graph.instance(v); TUTTLE_LOG_TRACE("[Setup 1] finish vertex " << vertex); if(vertex.isFake()) return; vertex.getProcessNode().setup1(); }
inline void connectClips(TGraph& graph) { BOOST_FOREACH(typename TGraph::edge_descriptor ed, graph.getEdges()) { typename TGraph::Edge& edge = graph.instance(ed); typename TGraph::Vertex& vertexOutput = graph.targetInstance(ed); typename TGraph::Vertex& vertexInput = graph.sourceInstance(ed); TUTTLE_LOG_TRACE("[Connect Clips] " << edge); TUTTLE_LOG_TRACE("[Connect Clips] " << vertexOutput << " -> " << vertexInput); // TUTTLE_LOG_VAR( TUTTLE_TRACE, edge.getInAttrName() ); if(!vertexOutput.isFake() && !vertexInput.isFake()) { INode& outputNode = vertexOutput.getProcessNode(); INode& inputNode = vertexInput.getProcessNode(); inputNode.connect(outputNode, inputNode.getAttribute(edge.getInAttrName())); } } }
void* OfxhHost::fetchSuite(const char* suiteName, const int suiteVersion) { if(strcmp(suiteName, kOfxPropertySuite) == 0 && suiteVersion == 1) { return property::getPropertySuite(suiteVersion); } else if(strcmp(suiteName, kOfxMemorySuite) == 0 && suiteVersion == 1) { return getMemorySuite(suiteVersion); } TUTTLE_LOG_TRACE("Failed to Fetch Unknown Suite: " << suiteName << " " << suiteVersion << "."); return NULL; }
void WriterPlugin::render( const OFX::RenderArguments& args ) { _oneRender = false; TUTTLE_LOG_INFO( " --> " << getAbsoluteFilenameAt( args.time ) ); if( _paramCopyToOutput->getValue() ) { boost::scoped_ptr<OFX::Image> src( _clipSrc->fetchImage( args.time ) ); boost::scoped_ptr<OFX::Image> dst( _clipDst->fetchImage( args.time ) ); // Copy buffer const OfxRectI bounds = dst->getBounds(); TUTTLE_LOG_VAR( TUTTLE_TRACE, bounds ); if( src->isLinearBuffer() && dst->isLinearBuffer() ) { TUTTLE_LOG_TRACE( "isLinearBuffer" ); const std::size_t imageDataBytes = dst->getBoundsImageDataBytes(); TUTTLE_LOG_VAR( TUTTLE_TRACE, imageDataBytes ); if( imageDataBytes ) { void* dataSrcPtr = src->getPixelAddress( bounds.x1, bounds.y1 ); void* dataDstPtr = dst->getPixelAddress( bounds.x1, bounds.y1 ); memcpy( dataDstPtr, dataSrcPtr, imageDataBytes ); } } else { const std::size_t rowBytesToCopy = dst->getBoundsRowDataBytes(); for( int y = bounds.y1; y < bounds.y2; ++y ) { void* dataSrcPtr = src->getPixelAddress( bounds.x1, y ); void* dataDstPtr = dst->getPixelAddress( bounds.x1, y ); memcpy( dataDstPtr, dataSrcPtr, rowBytesToCopy ); } } } }
void INode::setProcessDataAtTime( DataAtTime* dataAtTime ) { TUTTLE_LOG_TRACE( "setProcessDataAtTime \"" << getName() << "\" at " << dataAtTime->_time ); _dataAtTime[dataAtTime->_time] = dataAtTime; }
bool InteractScene::penMotion(const OFX::PenArgs& args) { if(!_mouseDown) return false; if(_creatingSelection) { // create selection TUTTLE_LOG_TRACE("create a selection"); _selectionRect.x2 = args.penPosition.x; _selectionRect.y2 = args.penPosition.y; _hasSelection = false; IsActiveFunctorVector::iterator itActive = _isActive.begin(); for(InteractObjectsVector::iterator it = _objects.begin(), itEnd = _objects.end(); it != itEnd; ++it, ++itActive) { if(!itActive->active()) continue; if(it->isIn(_selectionRect)) { it->setSelected(true); _hasSelection = true; } else { it->setSelected(false); } } return true; } if(_selected.size() == 0) { TUTTLE_LOG_INFOS; return false; } const Point2 penPosition = ofxToGil(args.penPosition); switch(_motionType._mode) { case eMotionTranslate: { translate(penPosition - _beginPenPosition); break; } case eMotionRotate: { if(_manipulator) { rotate(_manipulator->getPosition(), penPosition, penPosition - _beginPenPosition); } break; } case eMotionScale: { if(_manipulator) scale(_manipulator->getPosition(), penPosition - _beginPenPosition); break; } case eMotionNone: { TUTTLE_LOG_INFOS; break; } } return true; }