code cleanup: spelling
[blender.git] / source / blender / compositor / intern / COM_NodeOperation.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #ifndef _COM_NodeOperation_h
24 #define _COM_NodeOperation_h
25 class OpenCLDevice;
26 #include "COM_Node.h"
27 #include <string>
28 #include <sstream>
29 #include "COM_MemoryBuffer.h"
30 #include "COM_MemoryProxy.h"
31 #include "COM_SocketReader.h"
32 #include "OCL_opencl.h"
33 #include "list"
34 #include "BLI_threads.h"
35
36 #include "BLI_math_color.h"
37 #include "BLI_math_vector.h"
38
39 class ReadBufferOperation;
40
41 /**
42  * @brief NodeOperation are contains calculation logic
43  *
44  * Subclasses needs to implement the execution method (defined in SocketReader) to implement logic.
45  * @ingroup Model
46  */
47 class NodeOperation : public NodeBase, public SocketReader {
48 private:
49         /**
50          * @brief the index of the input socket that will be used to determine the resolution
51          */
52         unsigned int m_resolutionInputSocketIndex;
53
54         /**
55          * @brief is this operation a complex one.
56          *
57          * Complex operations are typically doing many reads to calculate the output of a single pixel.
58          * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
59          */
60         bool m_complex;
61
62         /**
63          * @brief can this operation be scheduled on an OpenCL device.
64          * @note Only applicable if complex is True
65          */
66         bool m_openCL;
67
68         /**
69          * @brief mutex reference for very special node initializations
70          * @note only use when you really know what you are doing.
71          * this mutex is used to share data among chunks in the same operation
72          * @see TonemapOperation for an example of usage
73          * @see NodeOperation.initMutex initializes this mutex
74          * @see NodeOperation.deinitMutex deinitializes this mutex
75          * @see NodeOperation.getMutex retrieve a pointer to this mutex.
76          */
77         ThreadMutex m_mutex;
78         
79         /**
80          * @brief reference to the editing bNodeTree only used for break callback
81          */
82         const bNodeTree *m_btree;
83
84 public:
85         /**
86          * @brief is this node an operation?
87          * This is true when the instance is of the subclass NodeOperation.
88          * @return [true:false]
89          * @see NodeBase
90          */
91         const bool isOperation() const { return true; }
92
93         /**
94          * @brief determine the resolution of this node
95          * @note this method will not set the resolution, this is the responsibility of the caller
96          * @param resolution the result of this operation
97          * @param preferredResolution the preferable resolution as no resolution could be determined
98          */
99         virtual void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
100
101         /**
102          * @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing.
103          *
104          * Default behaviour if not overridden, this operation will not be evaluated as being an output of the ExecutionSystem.
105          *
106          * @see ExecutionSystem
107          * @group check
108          * @param rendering [true false]
109          *  true: rendering
110          *  false: editing
111          *
112          * @return bool the result of this method
113          */
114         virtual bool isOutputOperation(bool rendering) const { return false; }
115
116         /**
117          * isBufferOperation returns if this is an operation that work directly on buffers.
118          *
119          * there are only 2 implementation where this is true:
120          * @see ReadBufferOperation
121          * @see WriteBufferOperation
122          * for all other operations this will result in false.
123          */
124         virtual int isBufferOperation() { return false; }
125         virtual int isSingleThreaded() { return false; }
126
127         void setbNodeTree(const bNodeTree *tree) { this->m_btree = tree; }
128         virtual void initExecution();
129         
130         /**
131          * @brief when a chunk is executed by a CPUDevice, this method is called
132          * @ingroup execution
133          * @param rect the rectangle of the chunk (location and size)
134          * @param chunkNumber the chunkNumber to be calculated
135          * @param memoryBuffers all input MemoryBuffer's needed
136          */
137         virtual void executeRegion(rcti *rect, unsigned int chunkNumber) {}
138
139         /**
140          * @brief when a chunk is executed by an OpenCLDevice, this method is called
141          * @ingroup execution
142          * @note this method is only implemented in WriteBufferOperation
143          * @param context the OpenCL context
144          * @param program the OpenCL program containing all compositor kernels
145          * @param queue the OpenCL command queue of the device the chunk is executed on
146          * @param rect the rectangle of the chunk (location and size)
147          * @param chunkNumber the chunkNumber to be calculated
148          * @param memoryBuffers all input MemoryBuffer's needed
149          * @param outputBuffer the outputbuffer to write to
150          */
151         virtual void executeOpenCLRegion(OpenCLDevice *device, rcti *rect,
152                                          unsigned int chunkNumber, MemoryBuffer **memoryBuffers, MemoryBuffer *outputBuffer) {}
153
154         /**
155          * @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice
156          * @ingroup execution
157          * @param context the OpenCL context
158          * @param program the OpenCL program containing all compositor kernels
159          * @param queue the OpenCL command queue of the device the chunk is executed on
160          * @param outputMemoryBuffer the allocated memory buffer in main CPU memory
161          * @param clOutputBuffer the allocated memory buffer in OpenCLDevice memory
162          * @param inputMemoryBuffers all input MemoryBuffer's needed
163          * @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution
164          * @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution
165          */
166         virtual void executeOpenCL(OpenCLDevice *device, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {}
167         virtual void deinitExecution();
168
169         bool isResolutionSet() {
170                 return this->m_width != 0 && this->m_height != 0;
171         }
172
173         /**
174          * @brief set the resolution
175          * @param resolution the resolution to set
176          */
177         void setResolution(unsigned int resolution[2]) {
178                 if (!isResolutionSet()) {
179                         this->m_width = resolution[0];
180                         this->m_height = resolution[1];
181                 }
182         }
183         
184
185         void getConnectedInputSockets(vector<InputSocket *> *sockets);
186
187         /**
188          * @brief is this operation complex
189          *
190          * Complex operations are typically doing many reads to calculate the output of a single pixel.
191          * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
192          */
193         const bool isComplex() const { return this->m_complex; }
194         virtual const bool isSetOperation() const { return false; }
195
196         /**
197          * @brief is this operation of type ReadBufferOperation
198          * @return [true:false]
199          * @see ReadBufferOperation
200          */
201         virtual const bool isReadBufferOperation() const { return false; }
202
203         /**
204          * @brief is this operation of type WriteBufferOperation
205          * @return [true:false]
206          * @see WriteBufferOperation
207          */
208         virtual const bool isWriteBufferOperation() const { return false; }
209
210         /**
211          * @brief is this operation the active viewer output
212          * user can select an ViewerNode to be active (the result of this node will be drawn on the backdrop)
213          * @return [true:false]
214          * @see BaseViewerOperation
215          */
216         virtual const bool isActiveViewerOutput() const { return false; }
217
218         virtual bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
219
220         /**
221          * @brief set the index of the input socket that will determine the resolution of this operation
222          * @param index the index to set
223          */
224         void setResolutionInputSocketIndex(unsigned int index);
225
226         /**
227          * @brief get the render priority of this node.
228          * @note only applicable for output operations like ViewerOperation
229          * @return CompositorPriority
230          */
231         virtual const CompositorPriority getRenderPriority() const { return COM_PRIORITY_LOW; }
232
233         /**
234          * @brief can this NodeOperation be scheduled on an OpenCLDevice
235          * @see WorkScheduler.schedule
236          * @see ExecutionGroup.addOperation
237          */
238         bool isOpenCL() { return this->m_openCL; }
239         
240         virtual bool isViewerOperation() { return false; }
241         virtual bool isPreviewOperation() { return false; }
242         
243         inline bool isBreaked() {
244                 return this->m_btree->test_break(this->m_btree->tbh);
245         }
246
247 protected:
248         NodeOperation();
249
250         void setWidth(unsigned int width) { this->m_width = width; }
251         void setHeight(unsigned int height) { this->m_height = height; }
252         SocketReader *getInputSocketReader(unsigned int inputSocketindex);
253         NodeOperation *getInputOperation(unsigned int inputSocketindex);
254
255         void deinitMutex();
256         void initMutex();
257         void lockMutex();
258         void unlockMutex();
259         
260
261         /**
262          * @brief set whether this operation is complex
263          *
264          * Complex operations are typically doing many reads to calculate the output of a single pixel.
265          * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
266          */
267         void setComplex(bool complex) { this->m_complex = complex; }
268
269         /**
270          * @brief set if this NodeOperation can be scheduled on a OpenCLDevice
271          */
272         void setOpenCL(bool openCL) { this->m_openCL = openCL; }
273
274 #ifdef WITH_CXX_GUARDEDALLOC
275         MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
276 #endif
277 };
278
279 #endif