diff options
Diffstat (limited to 'source/blender/compositor/intern/COM_NodeOperationBuilder.cpp')
-rw-r--r-- | source/blender/compositor/intern/COM_NodeOperationBuilder.cpp | 953 |
1 files changed, 482 insertions, 471 deletions
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp index 37a1d7c005f..0f331a25ed9 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cpp @@ -39,12 +39,10 @@ extern "C" { #include "COM_NodeOperationBuilder.h" /* own include */ -NodeOperationBuilder::NodeOperationBuilder(const CompositorContext *context, bNodeTree *b_nodetree) : - m_context(context), - m_current_node(NULL), - m_active_viewer(NULL) +NodeOperationBuilder::NodeOperationBuilder(const CompositorContext *context, bNodeTree *b_nodetree) + : m_context(context), m_current_node(NULL), m_active_viewer(NULL) { - m_graph.from_bNodeTree(*context, b_nodetree); + m_graph.from_bNodeTree(*context, b_nodetree); } NodeOperationBuilder::~NodeOperationBuilder() @@ -53,208 +51,215 @@ NodeOperationBuilder::~NodeOperationBuilder() void NodeOperationBuilder::convertToOperations(ExecutionSystem *system) { - /* interface handle for nodes */ - NodeConverter converter(this); + /* interface handle for nodes */ + NodeConverter converter(this); - for (int index = 0; index < m_graph.nodes().size(); index++) { - Node *node = (Node *)m_graph.nodes()[index]; + for (int index = 0; index < m_graph.nodes().size(); index++) { + Node *node = (Node *)m_graph.nodes()[index]; - m_current_node = node; + m_current_node = node; - DebugInfo::node_to_operations(node); - node->convertToOperations(converter, *m_context); - } + DebugInfo::node_to_operations(node); + node->convertToOperations(converter, *m_context); + } - m_current_node = NULL; + m_current_node = NULL; - /* The input map constructed by nodes maps operation inputs to node inputs. - * Inverting yields a map of node inputs to all connected operation inputs, - * so multiple operations can use the same node input. - */ - OpInputInverseMap inverse_input_map; - for (InputSocketMap::const_iterator it = m_input_map.begin(); it != m_input_map.end(); ++it) - inverse_input_map[it->second].push_back(it->first); + /* The input map constructed by nodes maps operation inputs to node inputs. + * Inverting yields a map of node inputs to all connected operation inputs, + * so multiple operations can use the same node input. + */ + OpInputInverseMap inverse_input_map; + for (InputSocketMap::const_iterator it = m_input_map.begin(); it != m_input_map.end(); ++it) + inverse_input_map[it->second].push_back(it->first); - for (NodeGraph::Links::const_iterator it = m_graph.links().begin(); it != m_graph.links().end(); ++it) { - const NodeGraph::Link &link = *it; - NodeOutput *from = link.getFromSocket(); - NodeInput *to = link.getToSocket(); + for (NodeGraph::Links::const_iterator it = m_graph.links().begin(); it != m_graph.links().end(); + ++it) { + const NodeGraph::Link &link = *it; + NodeOutput *from = link.getFromSocket(); + NodeInput *to = link.getToSocket(); - NodeOperationOutput *op_from = find_operation_output(m_output_map, from); - const OpInputs &op_to_list = find_operation_inputs(inverse_input_map, to); - if (!op_from || op_to_list.empty()) { - /* XXX allow this? error/debug message? */ - //BLI_assert(false); - /* XXX note: this can happen with certain nodes (e.g. OutputFile) - * which only generate operations in certain circumstances (rendering) - * just let this pass silently for now ... - */ - continue; - } + NodeOperationOutput *op_from = find_operation_output(m_output_map, from); + const OpInputs &op_to_list = find_operation_inputs(inverse_input_map, to); + if (!op_from || op_to_list.empty()) { + /* XXX allow this? error/debug message? */ + //BLI_assert(false); + /* XXX note: this can happen with certain nodes (e.g. OutputFile) + * which only generate operations in certain circumstances (rendering) + * just let this pass silently for now ... + */ + continue; + } - for (OpInputs::const_iterator it = op_to_list.begin(); it != op_to_list.end(); ++it) { - NodeOperationInput *op_to = *it; - addLink(op_from, op_to); - } - } + for (OpInputs::const_iterator it = op_to_list.begin(); it != op_to_list.end(); ++it) { + NodeOperationInput *op_to = *it; + addLink(op_from, op_to); + } + } - add_operation_input_constants(); + add_operation_input_constants(); - resolve_proxies(); + resolve_proxies(); - add_datatype_conversions(); + add_datatype_conversions(); - determineResolutions(); + determineResolutions(); - /* surround complex ops with read/write buffer */ - add_complex_operation_buffers(); + /* surround complex ops with read/write buffer */ + add_complex_operation_buffers(); - /* links not available from here on */ - /* XXX make m_links a local variable to avoid confusion! */ - m_links.clear(); + /* links not available from here on */ + /* XXX make m_links a local variable to avoid confusion! */ + m_links.clear(); - prune_operations(); + prune_operations(); - /* ensure topological (link-based) order of nodes */ - /*sort_operations();*/ /* not needed yet */ + /* ensure topological (link-based) order of nodes */ + /*sort_operations();*/ /* not needed yet */ - /* create execution groups */ - group_operations(); + /* create execution groups */ + group_operations(); - /* transfer resulting operations to the system */ - system->set_operations(m_operations, m_groups); + /* transfer resulting operations to the system */ + system->set_operations(m_operations, m_groups); } void NodeOperationBuilder::addOperation(NodeOperation *operation) { - m_operations.push_back(operation); + m_operations.push_back(operation); } -void NodeOperationBuilder::mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket) +void NodeOperationBuilder::mapInputSocket(NodeInput *node_socket, + NodeOperationInput *operation_socket) { - BLI_assert(m_current_node); - BLI_assert(node_socket->getNode() == m_current_node); + BLI_assert(m_current_node); + BLI_assert(node_socket->getNode() == m_current_node); - /* note: this maps operation sockets to node sockets. - * for resolving links the map will be inverted first in convertToOperations, - * to get a list of links for each node input socket. - */ - m_input_map[operation_socket] = node_socket; + /* note: this maps operation sockets to node sockets. + * for resolving links the map will be inverted first in convertToOperations, + * to get a list of links for each node input socket. + */ + m_input_map[operation_socket] = node_socket; } -void NodeOperationBuilder::mapOutputSocket(NodeOutput *node_socket, NodeOperationOutput *operation_socket) +void NodeOperationBuilder::mapOutputSocket(NodeOutput *node_socket, + NodeOperationOutput *operation_socket) { - BLI_assert(m_current_node); - BLI_assert(node_socket->getNode() == m_current_node); + BLI_assert(m_current_node); + BLI_assert(node_socket->getNode() == m_current_node); - m_output_map[node_socket] = operation_socket; + m_output_map[node_socket] = operation_socket; } void NodeOperationBuilder::addLink(NodeOperationOutput *from, NodeOperationInput *to) { - if (to->isConnected()) - return; + if (to->isConnected()) + return; - m_links.push_back(Link(from, to)); + m_links.push_back(Link(from, to)); - /* register with the input */ - to->setLink(from); + /* register with the input */ + to->setLink(from); } void NodeOperationBuilder::removeInputLink(NodeOperationInput *to) { - for (Links::iterator it = m_links.begin(); it != m_links.end(); ++it) { - Link &link = *it; - if (link.to() == to) { - /* unregister with the input */ - to->setLink(NULL); + for (Links::iterator it = m_links.begin(); it != m_links.end(); ++it) { + Link &link = *it; + if (link.to() == to) { + /* unregister with the input */ + to->setLink(NULL); - m_links.erase(it); - return; - } - } + m_links.erase(it); + return; + } + } } -NodeInput *NodeOperationBuilder::find_node_input(const InputSocketMap &map, NodeOperationInput *op_input) +NodeInput *NodeOperationBuilder::find_node_input(const InputSocketMap &map, + NodeOperationInput *op_input) { - InputSocketMap::const_iterator it = map.find(op_input); - return (it != map.end() ? it->second : NULL); + InputSocketMap::const_iterator it = map.find(op_input); + return (it != map.end() ? it->second : NULL); } -const NodeOperationBuilder::OpInputs &NodeOperationBuilder::find_operation_inputs(const OpInputInverseMap &map, NodeInput *node_input) +const NodeOperationBuilder::OpInputs &NodeOperationBuilder::find_operation_inputs( + const OpInputInverseMap &map, NodeInput *node_input) { - static const OpInputs empty_list; - OpInputInverseMap::const_iterator it = map.find(node_input); - return (it != map.end() ? it->second : empty_list); + static const OpInputs empty_list; + OpInputInverseMap::const_iterator it = map.find(node_input); + return (it != map.end() ? it->second : empty_list); } -NodeOperationOutput *NodeOperationBuilder::find_operation_output(const OutputSocketMap &map, NodeOutput *node_output) +NodeOperationOutput *NodeOperationBuilder::find_operation_output(const OutputSocketMap &map, + NodeOutput *node_output) { - OutputSocketMap::const_iterator it = map.find(node_output); - return (it != map.end() ? it->second : NULL); + OutputSocketMap::const_iterator it = map.find(node_output); + return (it != map.end() ? it->second : NULL); } PreviewOperation *NodeOperationBuilder::make_preview_operation() const { - BLI_assert(m_current_node); + BLI_assert(m_current_node); - if (!(m_current_node->getbNode()->flag & NODE_PREVIEW)) - return NULL; - /* previews only in the active group */ - if (!m_current_node->isInActiveGroup()) - return NULL; - /* do not calculate previews of hidden nodes */ - if (m_current_node->getbNode()->flag & NODE_HIDDEN) - return NULL; + if (!(m_current_node->getbNode()->flag & NODE_PREVIEW)) + return NULL; + /* previews only in the active group */ + if (!m_current_node->isInActiveGroup()) + return NULL; + /* do not calculate previews of hidden nodes */ + if (m_current_node->getbNode()->flag & NODE_HIDDEN) + return NULL; - bNodeInstanceHash *previews = m_context->getPreviewHash(); - if (previews) { - PreviewOperation *operation = new PreviewOperation(m_context->getViewSettings(), m_context->getDisplaySettings()); - operation->setbNodeTree(m_context->getbNodeTree()); - operation->verifyPreview(previews, m_current_node->getInstanceKey()); - return operation; - } + bNodeInstanceHash *previews = m_context->getPreviewHash(); + if (previews) { + PreviewOperation *operation = new PreviewOperation(m_context->getViewSettings(), + m_context->getDisplaySettings()); + operation->setbNodeTree(m_context->getbNodeTree()); + operation->verifyPreview(previews, m_current_node->getInstanceKey()); + return operation; + } - return NULL; + return NULL; } void NodeOperationBuilder::addPreview(NodeOperationOutput *output) { - PreviewOperation *operation = make_preview_operation(); - if (operation) { - addOperation(operation); + PreviewOperation *operation = make_preview_operation(); + if (operation) { + addOperation(operation); - addLink(output, operation->getInputSocket(0)); - } + addLink(output, operation->getInputSocket(0)); + } } void NodeOperationBuilder::addNodeInputPreview(NodeInput *input) { - PreviewOperation *operation = make_preview_operation(); - if (operation) { - addOperation(operation); + PreviewOperation *operation = make_preview_operation(); + if (operation) { + addOperation(operation); - mapInputSocket(input, operation->getInputSocket(0)); - } + mapInputSocket(input, operation->getInputSocket(0)); + } } void NodeOperationBuilder::registerViewer(ViewerOperation *viewer) { - if (m_active_viewer) { - if (m_current_node->isInActiveGroup()) { - /* deactivate previous viewer */ - m_active_viewer->setActive(false); + if (m_active_viewer) { + if (m_current_node->isInActiveGroup()) { + /* deactivate previous viewer */ + m_active_viewer->setActive(false); - m_active_viewer = viewer; - viewer->setActive(true); - } - } - else { - if (m_current_node->getbNodeTree() == m_context->getbNodeTree()) { - m_active_viewer = viewer; - viewer->setActive(true); - } - } + m_active_viewer = viewer; + viewer->setActive(true); + } + } + else { + if (m_current_node->getbNodeTree() == m_context->getbNodeTree()) { + m_active_viewer = viewer; + viewer->setActive(true); + } + } } /**************************** @@ -263,430 +268,436 @@ void NodeOperationBuilder::registerViewer(ViewerOperation *viewer) void NodeOperationBuilder::add_datatype_conversions() { - Links convert_links; - for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { - const Link &link = *it; + Links convert_links; + for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { + const Link &link = *it; - /* proxy operations can skip data type conversion */ - NodeOperation *from_op = &link.from()->getOperation(); - NodeOperation *to_op = &link.to()->getOperation(); - if (!(from_op->useDatatypeConversion() || to_op->useDatatypeConversion())) - continue; + /* proxy operations can skip data type conversion */ + NodeOperation *from_op = &link.from()->getOperation(); + NodeOperation *to_op = &link.to()->getOperation(); + if (!(from_op->useDatatypeConversion() || to_op->useDatatypeConversion())) + continue; - if (link.from()->getDataType() != link.to()->getDataType()) - convert_links.push_back(link); - } - for (Links::const_iterator it = convert_links.begin(); it != convert_links.end(); ++it) { - const Link &link = *it; - NodeOperation *converter = Converter::convertDataType(link.from(), link.to()); - if (converter) { - addOperation(converter); + if (link.from()->getDataType() != link.to()->getDataType()) + convert_links.push_back(link); + } + for (Links::const_iterator it = convert_links.begin(); it != convert_links.end(); ++it) { + const Link &link = *it; + NodeOperation *converter = Converter::convertDataType(link.from(), link.to()); + if (converter) { + addOperation(converter); - removeInputLink(link.to()); - addLink(link.from(), converter->getInputSocket(0)); - addLink(converter->getOutputSocket(0), link.to()); - } - } + removeInputLink(link.to()); + addLink(link.from(), converter->getInputSocket(0)); + addLink(converter->getOutputSocket(0), link.to()); + } + } } void NodeOperationBuilder::add_operation_input_constants() { - /* Note: unconnected inputs cached first to avoid modifying - * m_operations while iterating over it - */ - typedef std::vector<NodeOperationInput*> Inputs; - Inputs pending_inputs; - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { - NodeOperation *op = *it; - for (int k = 0; k < op->getNumberOfInputSockets(); ++k) { - NodeOperationInput *input = op->getInputSocket(k); - if (!input->isConnected()) - pending_inputs.push_back(input); - } - } - for (Inputs::const_iterator it = pending_inputs.begin(); it != pending_inputs.end(); ++it) { - NodeOperationInput *input = *it; - add_input_constant_value(input, find_node_input(m_input_map, input)); - } -} - -void NodeOperationBuilder::add_input_constant_value(NodeOperationInput *input, NodeInput *node_input) -{ - switch (input->getDataType()) { - case COM_DT_VALUE: { - float value; - if (node_input && node_input->getbNodeSocket()) - value = node_input->getEditorValueFloat(); - else - value = 0.0f; - - SetValueOperation *op = new SetValueOperation(); - op->setValue(value); - addOperation(op); - addLink(op->getOutputSocket(), input); - break; - } - case COM_DT_COLOR: { - float value[4]; - if (node_input && node_input->getbNodeSocket()) - node_input->getEditorValueColor(value); - else - zero_v4(value); - - SetColorOperation *op = new SetColorOperation(); - op->setChannels(value); - addOperation(op); - addLink(op->getOutputSocket(), input); - break; - } - case COM_DT_VECTOR: { - float value[3]; - if (node_input && node_input->getbNodeSocket()) - node_input->getEditorValueVector(value); - else - zero_v3(value); - - SetVectorOperation *op = new SetVectorOperation(); - op->setVector(value); - addOperation(op); - addLink(op->getOutputSocket(), input); - break; - } - } + /* Note: unconnected inputs cached first to avoid modifying + * m_operations while iterating over it + */ + typedef std::vector<NodeOperationInput *> Inputs; + Inputs pending_inputs; + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { + NodeOperation *op = *it; + for (int k = 0; k < op->getNumberOfInputSockets(); ++k) { + NodeOperationInput *input = op->getInputSocket(k); + if (!input->isConnected()) + pending_inputs.push_back(input); + } + } + for (Inputs::const_iterator it = pending_inputs.begin(); it != pending_inputs.end(); ++it) { + NodeOperationInput *input = *it; + add_input_constant_value(input, find_node_input(m_input_map, input)); + } +} + +void NodeOperationBuilder::add_input_constant_value(NodeOperationInput *input, + NodeInput *node_input) +{ + switch (input->getDataType()) { + case COM_DT_VALUE: { + float value; + if (node_input && node_input->getbNodeSocket()) + value = node_input->getEditorValueFloat(); + else + value = 0.0f; + + SetValueOperation *op = new SetValueOperation(); + op->setValue(value); + addOperation(op); + addLink(op->getOutputSocket(), input); + break; + } + case COM_DT_COLOR: { + float value[4]; + if (node_input && node_input->getbNodeSocket()) + node_input->getEditorValueColor(value); + else + zero_v4(value); + + SetColorOperation *op = new SetColorOperation(); + op->setChannels(value); + addOperation(op); + addLink(op->getOutputSocket(), input); + break; + } + case COM_DT_VECTOR: { + float value[3]; + if (node_input && node_input->getbNodeSocket()) + node_input->getEditorValueVector(value); + else + zero_v3(value); + + SetVectorOperation *op = new SetVectorOperation(); + op->setVector(value); + addOperation(op); + addLink(op->getOutputSocket(), input); + break; + } + } } void NodeOperationBuilder::resolve_proxies() { - Links proxy_links; - for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { - const Link &link = *it; - /* don't replace links from proxy to proxy, since we may need them for replacing others! */ - if (link.from()->getOperation().isProxyOperation() && - !link.to()->getOperation().isProxyOperation()) - { - proxy_links.push_back(link); - } - } - - for (Links::const_iterator it = proxy_links.begin(); it != proxy_links.end(); ++it) { - const Link &link = *it; - - NodeOperationInput *to = link.to(); - NodeOperationOutput *from = link.from(); - do { - /* walk upstream bypassing the proxy operation */ - from = from->getOperation().getInputSocket(0)->getLink(); - } while (from && from->getOperation().isProxyOperation()); - - removeInputLink(to); - /* we may not have a final proxy input link, - * in that case it just gets dropped - */ - if (from) - addLink(from, to); - } + Links proxy_links; + for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { + const Link &link = *it; + /* don't replace links from proxy to proxy, since we may need them for replacing others! */ + if (link.from()->getOperation().isProxyOperation() && + !link.to()->getOperation().isProxyOperation()) { + proxy_links.push_back(link); + } + } + + for (Links::const_iterator it = proxy_links.begin(); it != proxy_links.end(); ++it) { + const Link &link = *it; + + NodeOperationInput *to = link.to(); + NodeOperationOutput *from = link.from(); + do { + /* walk upstream bypassing the proxy operation */ + from = from->getOperation().getInputSocket(0)->getLink(); + } while (from && from->getOperation().isProxyOperation()); + + removeInputLink(to); + /* we may not have a final proxy input link, + * in that case it just gets dropped + */ + if (from) + addLink(from, to); + } } void NodeOperationBuilder::determineResolutions() { - /* determine all resolutions of the operations (Width/Height) */ - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { - NodeOperation *op = *it; - - if (op->isOutputOperation(m_context->isRendering()) && !op->isPreviewOperation()) { - unsigned int resolution[2] = {0, 0}; - unsigned int preferredResolution[2] = {0, 0}; - op->determineResolution(resolution, preferredResolution); - op->setResolution(resolution); - } - } - - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { - NodeOperation *op = *it; - - if (op->isOutputOperation(m_context->isRendering()) && op->isPreviewOperation()) { - unsigned int resolution[2] = {0, 0}; - unsigned int preferredResolution[2] = {0, 0}; - op->determineResolution(resolution, preferredResolution); - op->setResolution(resolution); - } - } - - /* add convert resolution operations when needed */ - { - Links convert_links; - for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { - const Link &link = *it; - - if (link.to()->getResizeMode() != COM_SC_NO_RESIZE) { - NodeOperation &from_op = link.from()->getOperation(); - NodeOperation &to_op = link.to()->getOperation(); - if (from_op.getWidth() != to_op.getWidth() || from_op.getHeight() != to_op.getHeight()) - convert_links.push_back(link); - } - } - for (Links::const_iterator it = convert_links.begin(); it != convert_links.end(); ++it) { - const Link &link = *it; - Converter::convertResolution(*this, link.from(), link.to()); - } - } -} - -NodeOperationBuilder::OpInputs NodeOperationBuilder::cache_output_links(NodeOperationOutput *output) const -{ - OpInputs inputs; - for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { - const Link &link = *it; - if (link.from() == output) - inputs.push_back(link.to()); - } - return inputs; -} - -WriteBufferOperation *NodeOperationBuilder::find_attached_write_buffer_operation(NodeOperationOutput *output) const -{ - for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { - const Link &link = *it; - if (link.from() == output) { - NodeOperation &op = link.to()->getOperation(); - if (op.isWriteBufferOperation()) - return (WriteBufferOperation *)(&op); - } - } - return NULL; + /* determine all resolutions of the operations (Width/Height) */ + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { + NodeOperation *op = *it; + + if (op->isOutputOperation(m_context->isRendering()) && !op->isPreviewOperation()) { + unsigned int resolution[2] = {0, 0}; + unsigned int preferredResolution[2] = {0, 0}; + op->determineResolution(resolution, preferredResolution); + op->setResolution(resolution); + } + } + + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { + NodeOperation *op = *it; + + if (op->isOutputOperation(m_context->isRendering()) && op->isPreviewOperation()) { + unsigned int resolution[2] = {0, 0}; + unsigned int preferredResolution[2] = {0, 0}; + op->determineResolution(resolution, preferredResolution); + op->setResolution(resolution); + } + } + + /* add convert resolution operations when needed */ + { + Links convert_links; + for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { + const Link &link = *it; + + if (link.to()->getResizeMode() != COM_SC_NO_RESIZE) { + NodeOperation &from_op = link.from()->getOperation(); + NodeOperation &to_op = link.to()->getOperation(); + if (from_op.getWidth() != to_op.getWidth() || from_op.getHeight() != to_op.getHeight()) + convert_links.push_back(link); + } + } + for (Links::const_iterator it = convert_links.begin(); it != convert_links.end(); ++it) { + const Link &link = *it; + Converter::convertResolution(*this, link.from(), link.to()); + } + } +} + +NodeOperationBuilder::OpInputs NodeOperationBuilder::cache_output_links( + NodeOperationOutput *output) const +{ + OpInputs inputs; + for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { + const Link &link = *it; + if (link.from() == output) + inputs.push_back(link.to()); + } + return inputs; +} + +WriteBufferOperation *NodeOperationBuilder::find_attached_write_buffer_operation( + NodeOperationOutput *output) const +{ + for (Links::const_iterator it = m_links.begin(); it != m_links.end(); ++it) { + const Link &link = *it; + if (link.from() == output) { + NodeOperation &op = link.to()->getOperation(); + if (op.isWriteBufferOperation()) + return (WriteBufferOperation *)(&op); + } + } + return NULL; } void NodeOperationBuilder::add_input_buffers(NodeOperation * /*operation*/, NodeOperationInput *input) { - if (!input->isConnected()) - return; + if (!input->isConnected()) + return; - NodeOperationOutput *output = input->getLink(); - if (output->getOperation().isReadBufferOperation()) { - /* input is already buffered, no need to add another */ - return; - } + NodeOperationOutput *output = input->getLink(); + if (output->getOperation().isReadBufferOperation()) { + /* input is already buffered, no need to add another */ + return; + } - /* this link will be replaced below */ - removeInputLink(input); + /* this link will be replaced below */ + removeInputLink(input); - /* check of other end already has write operation, otherwise add a new one */ - WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output); - if (!writeoperation) { - writeoperation = new WriteBufferOperation(output->getDataType()); - writeoperation->setbNodeTree(m_context->getbNodeTree()); - addOperation(writeoperation); + /* check of other end already has write operation, otherwise add a new one */ + WriteBufferOperation *writeoperation = find_attached_write_buffer_operation(output); + if (!writeoperation) { + writeoperation = new WriteBufferOperation(output->getDataType()); + writeoperation->setbNodeTree(m_context->getbNodeTree()); + addOperation(writeoperation); - addLink(output, writeoperation->getInputSocket(0)); + addLink(output, writeoperation->getInputSocket(0)); - writeoperation->readResolutionFromInputSocket(); - } + writeoperation->readResolutionFromInputSocket(); + } - /* add readbuffer op for the input */ - ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType()); - readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); - this->addOperation(readoperation); + /* add readbuffer op for the input */ + ReadBufferOperation *readoperation = new ReadBufferOperation(output->getDataType()); + readoperation->setMemoryProxy(writeoperation->getMemoryProxy()); + this->addOperation(readoperation); - addLink(readoperation->getOutputSocket(), input); + addLink(readoperation->getOutputSocket(), input); - readoperation->readResolutionFromWriteBuffer(); + readoperation->readResolutionFromWriteBuffer(); } -void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, NodeOperationOutput *output) +void NodeOperationBuilder::add_output_buffers(NodeOperation *operation, + NodeOperationOutput *output) { - /* cache connected sockets, so we can safely remove links first before replacing them */ - OpInputs targets = cache_output_links(output); - if (targets.empty()) - return; + /* cache connected sockets, so we can safely remove links first before replacing them */ + OpInputs targets = cache_output_links(output); + if (targets.empty()) + return; - WriteBufferOperation *writeOperation = NULL; - for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) { - NodeOperationInput *target = *it; + WriteBufferOperation *writeOperation = NULL; + for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) { + NodeOperationInput *target = *it; - /* try to find existing write buffer operation */ - if (target->getOperation().isWriteBufferOperation()) { - BLI_assert(writeOperation == NULL); /* there should only be one write op connected */ - writeOperation = (WriteBufferOperation *)(&target->getOperation()); - } - else { - /* remove all links to other nodes */ - removeInputLink(target); - } - } + /* try to find existing write buffer operation */ + if (target->getOperation().isWriteBufferOperation()) { + BLI_assert(writeOperation == NULL); /* there should only be one write op connected */ + writeOperation = (WriteBufferOperation *)(&target->getOperation()); + } + else { + /* remove all links to other nodes */ + removeInputLink(target); + } + } - /* if no write buffer operation exists yet, create a new one */ - if (!writeOperation) { - writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType()); - writeOperation->setbNodeTree(m_context->getbNodeTree()); - addOperation(writeOperation); + /* if no write buffer operation exists yet, create a new one */ + if (!writeOperation) { + writeOperation = new WriteBufferOperation(operation->getOutputSocket()->getDataType()); + writeOperation->setbNodeTree(m_context->getbNodeTree()); + addOperation(writeOperation); - addLink(output, writeOperation->getInputSocket(0)); - } + addLink(output, writeOperation->getInputSocket(0)); + } - writeOperation->readResolutionFromInputSocket(); + writeOperation->readResolutionFromInputSocket(); - /* add readbuffer op for every former connected input */ - for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) { - NodeOperationInput *target = *it; - if (&target->getOperation() == writeOperation) - continue; /* skip existing write op links */ + /* add readbuffer op for every former connected input */ + for (OpInputs::const_iterator it = targets.begin(); it != targets.end(); ++it) { + NodeOperationInput *target = *it; + if (&target->getOperation() == writeOperation) + continue; /* skip existing write op links */ - ReadBufferOperation *readoperation = new ReadBufferOperation(operation->getOutputSocket()->getDataType()); - readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); - addOperation(readoperation); + ReadBufferOperation *readoperation = new ReadBufferOperation( + operation->getOutputSocket()->getDataType()); + readoperation->setMemoryProxy(writeOperation->getMemoryProxy()); + addOperation(readoperation); - addLink(readoperation->getOutputSocket(), target); + addLink(readoperation->getOutputSocket(), target); - readoperation->readResolutionFromWriteBuffer(); - } + readoperation->readResolutionFromWriteBuffer(); + } } void NodeOperationBuilder::add_complex_operation_buffers() { - /* note: complex ops and get cached here first, since adding operations - * will invalidate iterators over the main m_operations - */ - Operations complex_ops; - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) - if ((*it)->isComplex()) - complex_ops.push_back(*it); + /* note: complex ops and get cached here first, since adding operations + * will invalidate iterators over the main m_operations + */ + Operations complex_ops; + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) + if ((*it)->isComplex()) + complex_ops.push_back(*it); - for (Operations::const_iterator it = complex_ops.begin(); it != complex_ops.end(); ++it) { - NodeOperation *op = *it; + for (Operations::const_iterator it = complex_ops.begin(); it != complex_ops.end(); ++it) { + NodeOperation *op = *it; - DebugInfo::operation_read_write_buffer(op); + DebugInfo::operation_read_write_buffer(op); - for (int index = 0; index < op->getNumberOfInputSockets(); index++) - add_input_buffers(op, op->getInputSocket(index)); + for (int index = 0; index < op->getNumberOfInputSockets(); index++) + add_input_buffers(op, op->getInputSocket(index)); - for (int index = 0; index < op->getNumberOfOutputSockets(); index++) - add_output_buffers(op, op->getOutputSocket(index)); - } + for (int index = 0; index < op->getNumberOfOutputSockets(); index++) + add_output_buffers(op, op->getOutputSocket(index)); + } } -typedef std::set<NodeOperation*> Tags; +typedef std::set<NodeOperation *> Tags; static void find_reachable_operations_recursive(Tags &reachable, NodeOperation *op) { - if (reachable.find(op) != reachable.end()) - return; - reachable.insert(op); + if (reachable.find(op) != reachable.end()) + return; + reachable.insert(op); - for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { - NodeOperationInput *input = op->getInputSocket(i); - if (input->isConnected()) - find_reachable_operations_recursive(reachable, &input->getLink()->getOperation()); - } + for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { + NodeOperationInput *input = op->getInputSocket(i); + if (input->isConnected()) + find_reachable_operations_recursive(reachable, &input->getLink()->getOperation()); + } - /* associated write-buffer operations are executed as well */ - if (op->isReadBufferOperation()) { - ReadBufferOperation *read_op = (ReadBufferOperation *)op; - MemoryProxy *memproxy = read_op->getMemoryProxy(); - find_reachable_operations_recursive(reachable, memproxy->getWriteBufferOperation()); - } + /* associated write-buffer operations are executed as well */ + if (op->isReadBufferOperation()) { + ReadBufferOperation *read_op = (ReadBufferOperation *)op; + MemoryProxy *memproxy = read_op->getMemoryProxy(); + find_reachable_operations_recursive(reachable, memproxy->getWriteBufferOperation()); + } } void NodeOperationBuilder::prune_operations() { - Tags reachable; - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { - NodeOperation *op = *it; + Tags reachable; + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { + NodeOperation *op = *it; - /* output operations are primary executed operations */ - if (op->isOutputOperation(m_context->isRendering())) - find_reachable_operations_recursive(reachable, op); - } + /* output operations are primary executed operations */ + if (op->isOutputOperation(m_context->isRendering())) + find_reachable_operations_recursive(reachable, op); + } - /* delete unreachable operations */ - Operations reachable_ops; - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { - NodeOperation *op = *it; + /* delete unreachable operations */ + Operations reachable_ops; + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { + NodeOperation *op = *it; - if (reachable.find(op) != reachable.end()) - reachable_ops.push_back(op); - else - delete op; - } - /* finally replace the operations list with the pruned list */ - m_operations = reachable_ops; + if (reachable.find(op) != reachable.end()) + reachable_ops.push_back(op); + else + delete op; + } + /* finally replace the operations list with the pruned list */ + m_operations = reachable_ops; } /* topological (depth-first) sorting of operations */ -static void sort_operations_recursive(NodeOperationBuilder::Operations &sorted, Tags &visited, NodeOperation *op) +static void sort_operations_recursive(NodeOperationBuilder::Operations &sorted, + Tags &visited, + NodeOperation *op) { - if (visited.find(op) != visited.end()) - return; - visited.insert(op); + if (visited.find(op) != visited.end()) + return; + visited.insert(op); - for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { - NodeOperationInput *input = op->getInputSocket(i); - if (input->isConnected()) - sort_operations_recursive(sorted, visited, &input->getLink()->getOperation()); - } + for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { + NodeOperationInput *input = op->getInputSocket(i); + if (input->isConnected()) + sort_operations_recursive(sorted, visited, &input->getLink()->getOperation()); + } - sorted.push_back(op); + sorted.push_back(op); } void NodeOperationBuilder::sort_operations() { - Operations sorted; - sorted.reserve(m_operations.size()); - Tags visited; + Operations sorted; + sorted.reserve(m_operations.size()); + Tags visited; - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) - sort_operations_recursive(sorted, visited, *it); + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) + sort_operations_recursive(sorted, visited, *it); - m_operations = sorted; + m_operations = sorted; } static void add_group_operations_recursive(Tags &visited, NodeOperation *op, ExecutionGroup *group) { - if (visited.find(op) != visited.end()) - return; - visited.insert(op); + if (visited.find(op) != visited.end()) + return; + visited.insert(op); - if (!group->addOperation(op)) - return; + if (!group->addOperation(op)) + return; - /* add all eligible input ops to the group */ - for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { - NodeOperationInput *input = op->getInputSocket(i); - if (input->isConnected()) - add_group_operations_recursive(visited, &input->getLink()->getOperation(), group); - } + /* add all eligible input ops to the group */ + for (int i = 0; i < op->getNumberOfInputSockets(); ++i) { + NodeOperationInput *input = op->getInputSocket(i); + if (input->isConnected()) + add_group_operations_recursive(visited, &input->getLink()->getOperation(), group); + } } ExecutionGroup *NodeOperationBuilder::make_group(NodeOperation *op) { - ExecutionGroup *group = new ExecutionGroup(); - m_groups.push_back(group); + ExecutionGroup *group = new ExecutionGroup(); + m_groups.push_back(group); - Tags visited; - add_group_operations_recursive(visited, op, group); + Tags visited; + add_group_operations_recursive(visited, op, group); - return group; + return group; } void NodeOperationBuilder::group_operations() { - for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { - NodeOperation *op = *it; - - if (op->isOutputOperation(m_context->isRendering())) { - ExecutionGroup *group = make_group(op); - group->setOutputExecutionGroup(true); - } - - /* add new groups for associated memory proxies where needed */ - if (op->isReadBufferOperation()) { - ReadBufferOperation *read_op = (ReadBufferOperation *)op; - MemoryProxy *memproxy = read_op->getMemoryProxy(); - - if (memproxy->getExecutor() == NULL) { - ExecutionGroup *group = make_group(memproxy->getWriteBufferOperation()); - memproxy->setExecutor(group); - } - } - } + for (Operations::const_iterator it = m_operations.begin(); it != m_operations.end(); ++it) { + NodeOperation *op = *it; + + if (op->isOutputOperation(m_context->isRendering())) { + ExecutionGroup *group = make_group(op); + group->setOutputExecutionGroup(true); + } + + /* add new groups for associated memory proxies where needed */ + if (op->isReadBufferOperation()) { + ReadBufferOperation *read_op = (ReadBufferOperation *)op; + MemoryProxy *memproxy = read_op->getMemoryProxy(); + + if (memproxy->getExecutor() == NULL) { + ExecutionGroup *group = make_group(memproxy->getWriteBufferOperation()); + memproxy->setExecutor(group); + } + } + } } |