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