Merged changes in the trunk up to revision 46787.
[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_NodeProgram_h
24 #define _COM_NodeProgram_h
25
26 class NodeOperation;
27
28 #include "COM_Node.h"
29 #include <string>
30 #include <sstream>
31 #include "COM_MemoryBuffer.h"
32 #include "COM_MemoryProxy.h"
33 #include "COM_SocketReader.h"
34 #include "OCL_opencl.h"
35 #include "list"
36
37 class ReadBufferOperation;
38
39 /**
40   * @brief NodeOperation are contains calculation logic
41   *
42   * Subclasses needs to implement the execution method (defined in SocketReader) to implement logic.
43   * @ingroup Model
44   */
45 class NodeOperation : public NodeBase, public SocketReader {
46 private:
47         /**
48           * @brief the index of the input socket that will be used to determine the resolution
49           */
50         unsigned int resolutionInputSocketIndex;
51
52         /**
53           * @brief is this operation a complex one.
54           *
55           * Complex operations are typically doing many reads to calculate the output of a single pixel.
56           * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
57           */
58         bool complex;
59
60         /**
61           * @brief can this operation be scheduled on an OpenCL device.
62           * @note Only applicable if complex is True
63           */
64         bool openCL;
65
66         /**
67           * @brief mutex reference for very special node initializations
68           * @note only use when you really know what you are doing.
69           * this mutex is used to share data among chunks in the same operation
70           * @see TonemapOperation for an example of usage
71           * @see NodeOperation.initMutex initializes this mutex
72           * @see NodeOperation.deinitMutex deinitializes this mutex
73           * @see NodeOperation.getMutex retrieve a pointer to this mutex.
74           */
75         ThreadMutex mutex;
76
77 public:
78         /**
79           * @brief is this node an operation?
80           * This is true when the instance is of the subclass NodeOperation.
81           * @return [true:false]
82           * @see NodeBase
83           */
84         const int isOperation() const {return true;}
85
86         /**
87           * @brief determine the resolution of this node
88           * @note this method will not set the resolution, this is the responsibility of the caller
89           * @param resolution the result of this operation
90           * @param preferredResolution the preferrable resolution as no resolution could be determined
91           */
92         virtual void determineResolution(unsigned int resolution[], unsigned int preferredResolution[]);
93
94         /**
95           * @brief isOutputOperation determines whether this operation is an output of the ExecutionSystem during rendering or editing.
96           *
97           * Default behaviour if not overriden, this operation will not be evaluated as being an output of the ExecutionSystem.
98           *
99           * @see ExecutionSystem
100           * @group check
101           * @param rendering [true false]
102           *  true: rendering
103           *  false: editing
104           *
105           * @return bool the result of this method
106           */
107         virtual bool isOutputOperation(bool rendering) const {return false;}
108
109         /**
110           * isBufferOperation returns if this is an operation that work directly on buffers.
111           *
112           * there are only 2 implementation where this is true:
113           * @see ReadBufferOperation
114           * @see WriteBufferOperation
115           * for all other operations this will result in false.
116           */
117         virtual int isBufferOperation() {return false;}
118
119         virtual void initExecution();
120         void initMutex();
121         
122         /**
123           * @brief when a chunk is executed by a CPUDevice, this method is called
124           * @ingroup execution
125           * @param rect the rectangle of the chunk (location and size)
126           * @param chunkNumber the chunkNumber to be calculated
127           * @param memoryBuffers all input MemoryBuffer's needed
128           */
129         virtual void executeRegion(rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {}
130
131         /**
132           * @brief when a chunk is executed by an OpenCLDevice, this method is called
133           * @ingroup execution
134           * @note this method is only implemented in WriteBufferOperation
135           * @param context the OpenCL context
136           * @param program the OpenCL program containing all compositor kernels
137           * @param queue the OpenCL command queue of the device the chunk is executed on
138           * @param rect the rectangle of the chunk (location and size)
139           * @param chunkNumber the chunkNumber to be calculated
140           * @param memoryBuffers all input MemoryBuffer's needed
141           */
142         virtual void executeOpenCLRegion(cl_context context, cl_program program, cl_command_queue queue, rcti *rect, unsigned int chunkNumber, MemoryBuffer** memoryBuffers) {}
143
144         /**
145           * @brief custom handle to add new tasks to the OpenCL command queue in order to execute a chunk on an GPUDevice
146           * @ingroup execution
147           * @param context the OpenCL context
148           * @param program the OpenCL program containing all compositor kernels
149           * @param queue the OpenCL command queue of the device the chunk is executed on
150           * @param outputMemoryBuffer the allocated memory buffer in main CPU memory
151           * @param clOutputBuffer the allocated memory buffer in OpenCLDevice memory
152           * @param inputMemoryBuffers all input MemoryBuffer's needed
153           * @param clMemToCleanUp all created cl_mem references must be added to this list. Framework will clean this after execution
154           * @param clKernelsToCleanUp all created cl_kernel references must be added to this list. Framework will clean this after execution
155           */
156         virtual void executeOpenCL(cl_context context,cl_program program, cl_command_queue queue, MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer, MemoryBuffer** inputMemoryBuffers, list<cl_mem> *clMemToCleanUp, list<cl_kernel> *clKernelsToCleanUp) {}
157         virtual void deinitExecution();
158         void deinitMutex();
159
160         /**
161           * @brief set the resolution
162           * @param resolution the resolution to set
163           */
164         void setResolution(unsigned int resolution[]) {this->width = resolution[0];this->height = resolution[1];}
165         void getConnectedInputSockets(vector<InputSocket*> *sockets);
166
167         /**
168           * @brief is this operation complex
169           *
170           * Complex operations are typically doing many reads to calculate the output of a single pixel.
171           * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
172           */
173         const bool isComplex() const {return this->complex;}
174         virtual const bool isSetOperation() const {return false;}
175
176         /**
177           * @brief is this operation of type ReadBufferOperation
178           * @return [true:false]
179           * @see ReadBufferOperation
180           */
181         virtual const bool isReadBufferOperation() const {return false;}
182
183         /**
184           * @brief is this operation of type WriteBufferOperation
185           * @return [true:false]
186           * @see WriteBufferOperation
187           */
188         virtual const bool isWriteBufferOperation() const {return false;}
189
190         /**
191           * @brief is this operation the active viewer output
192           * user can select an ViewerNode to be active (the result of this node will be drawn on the backdrop)
193           * @return [true:false]
194           * @see BaseViewerOperation
195           */
196         virtual const bool isActiveViewerOutput() const {return false;}
197
198         virtual bool determineDependingAreaOfInterest(rcti * input, ReadBufferOperation *readOperation, rcti *output);
199
200         /**
201           * @brief set the index of the input socket that will determine the resolution of this operation
202           * @param index the index to set
203           */
204         void setResolutionInputSocketIndex(unsigned int index);
205
206         /**
207           * @brief get the render priority of this node.
208           * @note only applicable for output operations like ViewerOperation
209           * @return [0:9] 9 is highest priority
210           */
211         virtual const int getRenderPriority() const {return 0;}
212
213         /**
214           * @brief can this NodeOperation be scheduled on an OpenCLDevice
215           * @see WorkScheduler.schedule
216           * @see ExecutionGroup.addOperation
217           */
218         bool isOpenCL() { return this->openCL; }
219         
220         virtual bool isViewerOperation() {return false;}
221 protected:
222         NodeOperation();
223
224         void setWidth(unsigned int width) {this->width = width;}
225         void setHeight(unsigned int height) {this->height = height;}
226         SocketReader *getInputSocketReader(unsigned int inputSocketindex);
227         NodeOperation *getInputOperation(unsigned int inputSocketindex);
228
229         inline ThreadMutex *getMutex() {return &this->mutex;}
230
231         /**
232           * @brief set whether this operation is complex
233           *
234           * Complex operations are typically doing many reads to calculate the output of a single pixel.
235           * Mostly Filter types (Blurs, Convolution, Defocus etc) need this to be set to true.
236           */
237         void setComplex(bool complex) {this->complex = complex;}
238
239         /**
240           * @brief set if this NodeOperation can be scheduled on a OpenCLDevice
241           */
242         void setOpenCL(bool openCL) {this->openCL = openCL;}
243
244
245 };
246
247 #endif