This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/compositor/intern/COM_ExecutionSystem.h

258 lines
8.8 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
*/
class ExecutionGroup;
#ifndef _COM_ExecutionSystem_h
#define _COM_ExecutionSystem_h
#include "DNA_color_types.h"
#include "DNA_node_types.h"
#include <vector>
#include "COM_Node.h"
#include "COM_SocketConnection.h"
#include "BKE_text.h"
#include "COM_ExecutionGroup.h"
#include "COM_NodeOperation.h"
using namespace std;
/**
* @page execution Execution model
* In order to get to an efficient model for execution, several steps are being done. these steps are explained below.
*
* @section EM_Step1 Step 1: translating blender node system to the new compsitor system
* Blenders node structure is based on C structs (DNA). These structs are not efficient in the new architecture.
* We want to use classes in order to simplify the system.
* during this step the blender node_tree is evaluated and converted to a CPP node system.
*
* @see ExecutionSystem
* @see Converter.convert
* @see Node
*
* @section EM_Step2 Step2: translating nodes to operations
* Ungrouping the GroupNodes. Group nodes are node_tree's in node_tree's.
* The new system only supports a single level of node_tree. We will 'flatten' the system in a single level.
* @see GroupNode
* @see ExecutionSystemHelper.ungroup
*
* Every node has the ability to convert itself to operations. The node itself is responsible to create a correct
* NodeOperation setup based on its internal settings.
* Most Node only need to convert it to its NodeOperation. Like a ColorToBWNode doesn't check anything,
* but replaces itself with a ConvertColorToBWOperation.
* More complex nodes can use different NodeOperation based on settings; like MixNode.
* based on the selected Mixtype a different operation will be used.
* for more information see the page about creating new Nodes. [@subpage newnode]
*
* @see ExecutionSystem.convertToOperations
* @see Node.convertToOperations
* @see NodeOperation base class for all operations in the system
*
* @section EM_Step3 Step3: add additional conversions to the operation system
* - Data type conversions: the system has 3 data types COM_DT_VALUE, COM_DT_VECTOR, COM_DT_COLOR.
* The user can connect a Value socket to a color socket.
* As values are ordered differently than colors a conversion happens.
*
* - Image size conversions: the system can automatically convert when resolutions do not match.
* An InputSocket has a resize mode. This can be any of the following settings.
* - [@ref InputSocketResizeMode.COM_SC_CENTER]: The center of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_WIDTH]: The width of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT_HEIGHT]: the height of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_FIT]: The width, or the height of both images are aligned to make sure that it fits.
* - [@ref InputSocketResizeMode.COM_SC_STRETCH]: The width and the height of both images are aligned
* - [@ref InputSocketResizeMode.COM_SC_NO_RESIZE]: bottom left of the images are aligned.
*
* @see Converter.convertDataType Datatype conversions
* @see Converter.convertResolution Image size conversions
*
* @section EM_Step4 Step4: group operations in executions groups
* ExecutionGroup are groups of operations that are calculated as being one bigger operation.
* All operations will be part of an ExecutionGroup.
* Complex nodes will be added to separate groups. Between ExecutionGroup's the data will be stored in MemoryBuffers.
* ReadBufferOperations and WriteBufferOperations are added where needed.
*
* <pre>
*
* +------------------------------+ +----------------+
* | ExecutionGroup A | |ExecutionGroup B| ExecutionGroup
* | +----------+ +----------+| |+----------+ |
* /----->| Operation|---->| Operation|-\ /--->| Operation|-\ | NodeOperation
* | | | A | | B ||| | || C | | |
* | | | cFFA | /->| cFFA ||| | || cFFA | | |
* | | +----------+ | +----------+|| | |+----------+ | |
* | +---------------|--------------+v | +-------------v--+
* +-*----+ +---*--+ +--*-*--+ +--*----+
* |inputA| |inputB| |outputA| |outputB| MemoryBuffer
* |cFAA | |cFAA | |cFAA | |cFAA |
* +------+ +------+ +-------+ +-------+
* </pre>
* @see ExecutionSystem.groupOperations method doing this step
* @see ExecutionSystem.addReadWriteBufferOperations
* @see NodeOperation.isComplex
* @see ExecutionGroup class representing the ExecutionGroup
*/
/**
* @brief the ExecutionSystem contains the whole compositor tree.
*/
class ExecutionSystem {
private:
/**
* @brief the context used during execution
*/
CompositorContext m_context;
/**
* @brief vector of nodes
*/
vector<Node *> m_nodes;
/**
* @brief vector of operations
*/
vector<NodeOperation *> m_operations;
/**
* @brief vector of groups
*/
vector<ExecutionGroup *> m_groups;
/**
* @brief vector of connections
*/
vector<SocketConnection *> m_connections;
private: //methods
/**
* @brief add ReadBufferOperation and WriteBufferOperation around an operation
* @param operation the operation to add the bufferoperations around.
*/
void addReadWriteBufferOperations(NodeOperation *operation);
/**
* find all execution group with output nodes
*/
void findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const;
/**
* find all execution group with output nodes
*/
void findOutputExecutionGroup(vector<ExecutionGroup *> *result) const;
public:
/**
* @brief Create a new ExecutionSystem and initialize it with the
* editingtree.
*
* @param editingtree [bNodeTree *]
* @param rendering [true false]
*/
ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool rendering, bool fastcalculation,
const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
/**
* Destructor
*/
~ExecutionSystem();
/**
* @brief execute this system
* - initialize the NodeOperation's and ExecutionGroup's
* - schedule the output ExecutionGroup's based on their priority
* - deinitialize the ExecutionGroup's and NodeOperation's
*/
void execute();
/**
* @brief Add an operation to the operation list
*
* @param operation the operation to add
*/
void addOperation(NodeOperation *operation);
/**
* Add an editor link to the system. convert it to an socketconnection (CPP-representative)
* this converted socket is returned.
*/
SocketConnection *addNodeLink(bNodeLink *bNodeLink);
void addSocketConnection(SocketConnection *connection);
/**
* Remove a socket connection from the system.
*/
void removeSocketConnection(SocketConnection *connection);
/**
* @brief Convert all nodes to operations
*/
void convertToOperations();
/**
* @brief group operations in ExecutionGroup's
* @see ExecutionGroup
*/
void groupOperations();
/**
* @brief get the reference to the compositor context
*/
CompositorContext &getContext() { return this->m_context; }
/**
* @brief get the reference to the compositor nodes
*/
vector<Node *> &getNodes() { return this->m_nodes; }
/**
* @brief get the reference to the compositor connections
*/
vector<SocketConnection *>& getConnections() { return this->m_connections; }
/**
* @brief get the reference to the list of execution groups
*/
vector<ExecutionGroup *>& getExecutionGroups() { return this->m_groups; }
/**
* @brief get the reference to the list of operations
*/
vector<NodeOperation *>& getOperations() { return this->m_operations; }
private:
/**
* @brief determine the actual data types of all sockets
* @param nodes list of nodes or operations to do the data type determination
*/
void determineActualSocketDataTypes(vector<NodeBase *> &nodes);
void executeGroups(CompositorPriority priority);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionSystem")
#endif
};
#endif /* _COM_ExecutionSystem_h */