diff options
Diffstat (limited to 'source/blender/compositor/intern/COM_ExecutionSystem.cpp')
-rw-r--r-- | source/blender/compositor/intern/COM_ExecutionSystem.cpp | 230 |
1 files changed, 13 insertions, 217 deletions
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index 088232481d0..7c08188db90 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -29,15 +29,11 @@ extern "C" { } #include "COM_Converter.h" +#include "COM_NodeOperationBuilder.h" #include "COM_NodeOperation.h" #include "COM_ExecutionGroup.h" -#include "COM_NodeBase.h" #include "COM_WorkScheduler.h" #include "COM_ReadBufferOperation.h" -#include "COM_GroupNode.h" -#include "COM_WriteBufferOperation.h" -#include "COM_ReadBufferOperation.h" -#include "COM_ExecutionSystemHelper.h" #include "COM_Debug.h" #include "BKE_global.h" @@ -63,14 +59,15 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin this->m_context.setRendering(rendering); this->m_context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL)); - ExecutionSystemHelper::addbNodeTree(*this, 0, editingtree, NODE_INSTANCE_KEY_BASE); - this->m_context.setRenderData(rd); this->m_context.setViewSettings(viewSettings); this->m_context.setDisplaySettings(displaySettings); - this->convertToOperations(); - this->groupOperations(); /* group operations in ExecutionGroups */ + { + NodeOperationBuilder builder(&m_context, editingtree); + builder.convertToOperations(this); + } + unsigned int index; unsigned int resolution[2]; @@ -107,16 +104,6 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editin ExecutionSystem::~ExecutionSystem() { unsigned int index; - for (index = 0; index < this->m_connections.size(); index++) { - SocketConnection *connection = this->m_connections[index]; - delete connection; - } - this->m_connections.clear(); - for (index = 0; index < this->m_nodes.size(); index++) { - Node *node = this->m_nodes[index]; - delete node; - } - this->m_nodes.clear(); for (index = 0; index < this->m_operations.size(); index++) { NodeOperation *operation = this->m_operations[index]; delete operation; @@ -129,14 +116,19 @@ ExecutionSystem::~ExecutionSystem() this->m_groups.clear(); } +void ExecutionSystem::set_operations(const Operations &operations, const Groups &groups) +{ + m_operations = operations; + m_groups = groups; +} + void ExecutionSystem::execute() { DebugInfo::execute_started(this); unsigned int order = 0; for (vector<NodeOperation *>::iterator iter = this->m_operations.begin(); iter != this->m_operations.end(); ++iter) { - NodeBase *node = *iter; - NodeOperation *operation = (NodeOperation *) node; + NodeOperation *operation = *iter; if (operation->isReadBufferOperation()) { ReadBufferOperation *readOperation = (ReadBufferOperation *)operation; readOperation->setOffset(order); @@ -196,202 +188,6 @@ void ExecutionSystem::executeGroups(CompositorPriority priority) } } -void ExecutionSystem::addOperation(NodeOperation *operation) -{ - ExecutionSystemHelper::addOperation(this->m_operations, operation); - DebugInfo::operation_added(operation); -} - -void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) -{ - DebugInfo::operation_read_write_buffer(operation); - - // for every input add write and read operation if input is not a read operation - // only add read operation to other links when they are attached to buffered operations. - unsigned int index; - for (index = 0; index < operation->getNumberOfInputSockets(); index++) { - InputSocket *inputsocket = operation->getInputSocket(index); - if (inputsocket->isConnected()) { - SocketConnection *connection = inputsocket->getConnection(); - NodeOperation *otherEnd = (NodeOperation *)connection->getFromNode(); - if (!otherEnd->isReadBufferOperation()) { - // check of other end already has write operation - OutputSocket *fromsocket = connection->getFromSocket(); - WriteBufferOperation *writeoperation = fromsocket->findAttachedWriteBufferOperation(); - if (writeoperation == NULL) { - writeoperation = new WriteBufferOperation(); - writeoperation->setbNodeTree(this->getContext().getbNodeTree()); - this->addOperation(writeoperation); - ExecutionSystemHelper::addLink(this->getConnections(), fromsocket, writeoperation->getInputSocket(0)); - writeoperation->readResolutionFromInputSocket(); - } - ReadBufferOperation *readoperation = new ReadBufferOperation(); - readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); - connection->setFromSocket(readoperation->getOutputSocket()); - readoperation->getOutputSocket()->addConnection(connection); - readoperation->readResolutionFromWriteBuffer(); - this->addOperation(readoperation); - } - } - } - /* - * link the outputsocket to a write operation - * link the writeoperation to a read operation - * link the read operation to the next node. - */ - OutputSocket *outputsocket = operation->getOutputSocket(); - if (outputsocket->isConnected()) { - WriteBufferOperation *writeOperation = NULL; - /* try to find existing write buffer operation first */ - for (index = 0; index < outputsocket->getNumberOfConnections(); index++) { - SocketConnection *connection = outputsocket->getConnection(index); - NodeBase *otherEnd = connection->getToNode(); - if (otherEnd->isOperation()) { - NodeOperation *otherEndOp = (NodeOperation *)otherEnd; - if (otherEndOp->isWriteBufferOperation()) { - writeOperation = (WriteBufferOperation *)otherEndOp; - break; - } - } - } - /* if no write buffer operation exists yet, create a new one */ - if (!writeOperation) { - writeOperation = new WriteBufferOperation(); - writeOperation->setbNodeTree(this->getContext().getbNodeTree()); - this->addOperation(writeOperation); - ExecutionSystemHelper::addLink(this->getConnections(), outputsocket, writeOperation->getInputSocket(0)); - } - writeOperation->readResolutionFromInputSocket(); - - for (index = 0; index < outputsocket->getNumberOfConnections(); index++) { - SocketConnection *connection = outputsocket->getConnection(index); - /* skip existing connections to write buffer operation */ - if (connection->getToNode() == writeOperation) - continue; - - ReadBufferOperation *readoperation = new ReadBufferOperation(); - readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); - connection->setFromSocket(readoperation->getOutputSocket()); - readoperation->getOutputSocket()->addConnection(connection); - readoperation->readResolutionFromWriteBuffer(); - this->addOperation(readoperation); - } - } -} - -#ifndef NDEBUG -/* if this fails, there are still connection to/from this node, - * which have not been properly relinked to operations! - */ -static void debug_check_node_connections(Node *node) -{ - /* note: connected inputs are not checked here, - * it would break quite a lot and such inputs are ignored later anyway - */ -#if 0 - for (int i = 0; i < node->getNumberOfInputSockets(); ++i) { - BLI_assert(!node->getInputSocket(i)->isConnected()); - } -#endif - for (int i = 0; i < node->getNumberOfOutputSockets(); ++i) { - BLI_assert(!node->getOutputSocket(i)->isConnected()); - } -} -#else -/* stub */ -#define debug_check_node_connections(node) -#endif - -void ExecutionSystem::convertToOperations() -{ - unsigned int index; - - for (index = 0; index < this->m_nodes.size(); index++) { - Node *node = (Node *)this->m_nodes[index]; - DebugInfo::node_to_operations(node); - node->convertToOperations(this, &this->m_context); - - debug_check_node_connections(node); - } - - for (index = 0; index < this->m_connections.size(); index++) { - SocketConnection *connection = this->m_connections[index]; - if (connection->isValid()) { - if (connection->getFromSocket()->getDataType() != connection->getToSocket()->getDataType()) { - Converter::convertDataType(connection, this); - } - } - } - - // determine all resolutions of the operations (Width/Height) - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; - if (operation->isOutputOperation(this->m_context.isRendering()) && !operation->isPreviewOperation()) { - unsigned int resolution[2] = {0, 0}; - unsigned int preferredResolution[2] = {0, 0}; - operation->determineResolution(resolution, preferredResolution); - operation->setResolution(resolution); - } - } - for (index = 0; index < this->m_operations.size(); index++) { - NodeOperation *operation = this->m_operations[index]; - if (operation->isOutputOperation(this->m_context.isRendering()) && operation->isPreviewOperation()) { - unsigned int resolution[2] = {0, 0}; - unsigned int preferredResolution[2] = {0, 0}; - operation->determineResolution(resolution, preferredResolution); - operation->setResolution(resolution); - } - } - - // add convert resolution operations when needed. - for (index = 0; index < this->m_connections.size(); index++) { - SocketConnection *connection = this->m_connections[index]; - if (connection->isValid()) { - if (connection->needsResolutionConversion()) { - Converter::convertResolution(connection, this); - } - } - } -} - -void ExecutionSystem::groupOperations() -{ - vector<NodeOperation *> outputOperations; - NodeOperation *operation; - unsigned int index; - // surround complex operations with ReadBufferOperation and WriteBufferOperation - for (index = 0; index < this->m_operations.size(); index++) { - operation = this->m_operations[index]; - if (operation->isComplex()) { - this->addReadWriteBufferOperations(operation); - } - } - ExecutionSystemHelper::findOutputNodeOperations(&outputOperations, this->getOperations(), this->m_context.isRendering()); - for (vector<NodeOperation *>::iterator iter = outputOperations.begin(); iter != outputOperations.end(); ++iter) { - operation = *iter; - ExecutionGroup *group = new ExecutionGroup(); - group->addOperation(this, operation); - group->setOutputExecutionGroup(true); - ExecutionSystemHelper::addExecutionGroup(this->getExecutionGroups(), group); - } -} - -void ExecutionSystem::addSocketConnection(SocketConnection *connection) -{ - this->m_connections.push_back(connection); -} - -void ExecutionSystem::removeSocketConnection(SocketConnection *connection) -{ - for (vector<SocketConnection *>::iterator it = m_connections.begin(); it != m_connections.end(); ++it) { - if (*it == connection) { - this->m_connections.erase(it); - return; - } - } -} - - void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const { unsigned int index; |