This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp
Jeroen Bakker be1b5f82ce * optimized threading
* break out with glare node
 * Added OpenCL kernels compatible with AMD still need some testing.
2012-06-13 12:34:56 +00:00

340 lines
9.9 KiB
C++

/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor:
* Jeroen Bakker
* Monique Dewanchand
*/
#include "COM_ExecutionSystemHelper.h"
#include "PIL_time.h"
#include "BKE_node.h"
#include "COM_Converter.h"
#include <sstream>
#include "COM_NodeOperation.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeBase.h"
#include "COM_WorkScheduler.h"
#include "COM_ReadBufferOperation.h"
#include "stdio.h"
#include "COM_GroupNode.h"
#include "COM_WriteBufferOperation.h"
#include "COM_ReadBufferOperation.h"
#include "COM_ViewerBaseOperation.h"
Node *ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_start, bNodeTree * tree, bNode *groupnode)
{
vector<Node*>& nodes = system.getNodes();
vector<SocketConnection*>& links = system.getConnections();
Node *mainnode = NULL;
const bNode * activeGroupNode = system.getContext().getActivegNode();
bool isActiveGroup = activeGroupNode == groupnode;
/* add all nodes of the tree to the node list */
bNode *node = (bNode*)tree->nodes.first;
while (node != NULL) {
Node *execnode = addNode(nodes, node, isActiveGroup);
if (node->type == CMP_NODE_COMPOSITE) {
mainnode = execnode;
}
node = (bNode*)node->next;
}
NodeRange node_range(nodes.begin()+nodes_start, nodes.end());
/* add all nodelinks of the tree to the link list */
bNodeLink *nodelink = (bNodeLink*)tree->links.first;
while (nodelink != NULL) {
addNodeLink(node_range, links, nodelink);
nodelink = (bNodeLink*)nodelink->next;
}
/* Expand group nodes */
for (unsigned int i=nodes_start; i < nodes.size(); ++i) {
Node *execnode = nodes[i];
if (execnode->isGroupNode()) {
GroupNode * groupNode = (GroupNode*)execnode;
groupNode->ungroup(system);
}
}
return mainnode;
}
void ExecutionSystemHelper::addNode(vector<Node*>& nodes, Node *node)
{
nodes.push_back(node);
}
Node *ExecutionSystemHelper::addNode(vector<Node*>& nodes, bNode *bNode, bool inActiveGroup)
{
Converter converter;
Node * node;
node = converter.convert(bNode);
node->setIsInActiveGroup(inActiveGroup);
if (node != NULL) {
addNode(nodes, node);
return node;
}
return NULL;
}
void ExecutionSystemHelper::addOperation(vector<NodeOperation*>& operations, NodeOperation *operation)
{
operations.push_back(operation);
}
void ExecutionSystemHelper::addExecutionGroup(vector<ExecutionGroup*>& executionGroups, ExecutionGroup *executionGroup)
{
executionGroups.push_back(executionGroup);
}
void ExecutionSystemHelper::findOutputNodeOperations(vector<NodeOperation*>* result, vector<NodeOperation*>& operations, bool rendering)
{
unsigned int index;
for (index = 0 ; index < operations.size() ; index ++) {
NodeOperation *operation = operations[index];
if (operation->isOutputOperation(rendering)) {
result->push_back(operation);
}
}
}
static InputSocket *find_input(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket)
{
if (bnode != NULL) {
for (NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node *node = *it;
if (node->getbNode() == bnode)
return node->findInputSocketBybNodeSocket(bsocket);
}
}
else {
for (NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node *node = *it;
if (node->isProxyNode()) {
InputSocket *proxySocket = node->getInputSocket(0);
if (proxySocket->getbNodeSocket()==bsocket)
return proxySocket;
}
}
}
return NULL;
}
static OutputSocket *find_output(NodeRange &node_range, bNode *bnode, bNodeSocket *bsocket)
{
if (bnode != NULL) {
for (NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node *node = *it;
if (node->getbNode() == bnode)
return node->findOutputSocketBybNodeSocket(bsocket);
}
}
else {
for (NodeIterator it=node_range.first; it!=node_range.second; ++it) {
Node *node = *it;
if (node->isProxyNode()) {
OutputSocket *proxySocket = node->getOutputSocket(0);
if (proxySocket->getbNodeSocket()==bsocket)
return proxySocket;
}
}
}
return NULL;
}
SocketConnection *ExecutionSystemHelper::addNodeLink(NodeRange &node_range, vector<SocketConnection*>& links, bNodeLink *bNodeLink)
{
/// @note: cyclic lines will be ignored. This has been copied from node.c
if (bNodeLink->tonode != 0 && bNodeLink->fromnode != 0) {
if (!(bNodeLink->fromnode->level >= bNodeLink->tonode->level && bNodeLink->tonode->level!=0xFFF)) { // only add non cyclic lines! so execution will procede
return NULL;
}
}
InputSocket *inputSocket = find_input(node_range, bNodeLink->tonode, bNodeLink->tosock);
OutputSocket *outputSocket = find_output(node_range, bNodeLink->fromnode, bNodeLink->fromsock);
if (inputSocket == NULL || outputSocket == NULL) {
return NULL;
}
if (inputSocket->isConnected()) {
return NULL;
}
SocketConnection *connection = addLink(links, outputSocket, inputSocket);
return connection;
}
SocketConnection *ExecutionSystemHelper::addLink(vector<SocketConnection*>& links, OutputSocket *fromSocket, InputSocket *toSocket)
{
SocketConnection * newconnection = new SocketConnection();
newconnection->setFromSocket(fromSocket);
newconnection->setToSocket(toSocket);
fromSocket->addConnection(newconnection);
toSocket->setConnection(newconnection);
links.push_back(newconnection);
return newconnection;
}
void ExecutionSystemHelper::debugDump(ExecutionSystem *system)
{
Node *node;
NodeOperation *operation;
ExecutionGroup *group;
SocketConnection *connection;
int tot, tot2;
printf("-- BEGIN COMPOSITOR DUMP --\r\n");
printf("digraph compositorexecution {\r\n");
tot = system->getNodes().size();
for (int i = 0 ; i < tot ; i ++) {
node = system->getNodes()[i];
printf("// NODE: %s\r\n", node->getbNode()->typeinfo->name);
}
tot = system->getOperations().size();
for (int i = 0 ; i < tot ; i ++) {
operation = system->getOperations()[i];
printf("// OPERATION: %p\r\n", operation);
printf("\t\"O_%p\"", operation);
printf(" [shape=record,label=\"{");
tot2 = operation->getNumberOfInputSockets();
if (tot2 != 0) {
printf("{");
for (int j = 0 ; j < tot2 ; j ++) {
InputSocket *socket = operation->getInputSocket(j);
if (j != 0) {
printf("|");
}
printf("<IN_%p>", socket);
switch (socket->getActualDataType()) {
case COM_DT_VALUE:
printf("Value");
break;
case COM_DT_VECTOR:
printf("Vector");
break;
case COM_DT_COLOR:
printf("Color");
break;
case COM_DT_UNKNOWN:
printf("Unknown");
break;
}
}
printf("}");
printf("|");
}
if (operation->isViewerOperation()) {
ViewerBaseOperation * viewer = (ViewerBaseOperation*)operation;
if (viewer->isActiveViewerOutput()) {
printf("Active viewer");
} else {
printf("Viewer");
}
}
else if (operation->isOutputOperation(system->getContext().isRendering())) {
printf("Output");
}
else if (operation->isSetOperation()) {
printf("Set");
}
else if (operation->isReadBufferOperation()) {
printf("ReadBuffer");
}
else if (operation->isWriteBufferOperation()) {
printf("WriteBuffer");
}
else {
printf("O_%p", operation);
}
printf(" (%d,%d)", operation->getWidth(), operation->getHeight());
tot2 = operation->getNumberOfOutputSockets();
if (tot2 != 0) {
printf("|");
printf("{");
for (int j = 0 ; j < tot2 ; j ++) {
OutputSocket *socket = operation->getOutputSocket(j);
if (j != 0) {
printf("|");
}
printf("<OUT_%p>", socket);
switch (socket->getActualDataType()) {
case COM_DT_VALUE:
printf("Value");
break;
case COM_DT_VECTOR:
printf("Vector");
break;
case COM_DT_COLOR:
printf("Color");
break;
case COM_DT_UNKNOWN:
printf("Unknown");
break;
}
}
printf("}");
}
printf("}\"]");
printf("\r\n");
}
tot = system->getExecutionGroups().size();
for (int i = 0 ; i < tot ; i ++) {
group = system->getExecutionGroups()[i];
printf("// GROUP: %d\r\n", i);
printf("subgraph {\r\n");
printf("// OUTPUTOPERATION: %p\r\n", group->getOutputNodeOperation());
printf(" O_%p\r\n", group->getOutputNodeOperation());
printf("}\r\n");
}
tot = system->getOperations().size();
for (int i = 0 ; i < tot ; i ++) {
operation = system->getOperations()[i];
if (operation->isReadBufferOperation()) {
ReadBufferOperation * read = (ReadBufferOperation*)operation;
WriteBufferOperation * write = read->getMemoryProxy()->getWriteBufferOperation();
printf("\t\"O_%p\" -> \"O_%p\" [style=dotted]\r\n", write, read);
}
}
tot = system->getConnections().size();
for (int i = 0 ; i < tot ; i ++) {
connection = system->getConnections()[i];
printf("// CONNECTION: %p.%p -> %p.%p\r\n", connection->getFromNode(), connection->getFromSocket(), connection->getToNode(), connection->getToSocket());
printf("\t\"O_%p\":\"OUT_%p\" -> \"O_%p\":\"IN_%p\"", connection->getFromNode(), connection->getFromSocket(), connection->getToNode(), connection->getToSocket());
if (!connection->isValid()) {
printf(" [color=red]");
}
else {
switch (connection->getFromSocket()->getActualDataType()) {
case COM_DT_VALUE:
printf(" [color=grey]");
break;
case COM_DT_VECTOR:
printf(" [color=blue]");
break;
case COM_DT_COLOR:
printf(" [color=orange]");
break;
case COM_DT_UNKNOWN:
printf(" [color=black]");
break;
}
}
printf("\r\n");
}
printf("}\r\n");
printf("-- END COMPOSITOR DUMP --\r\n");
}