* Added new dilate/erode function
[blender.git] / source / blender / compositor / COM_compositor.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  #ifdef __cplusplus
24  extern "C" {
25  #endif
26
27 #include "DNA_node_types.h"
28
29 /**
30   * @defgroup Model The data model of the compositor
31   * @defgroup Memory The memory management stuff
32   * @defgroup Execution The execution logic
33   * @defgroup Conversion Conversion logic
34   * @defgroup Node All nodes of the compositor
35   * @defgroup Operation All operations of the compositor
36   *
37   * @mainpage Introduction of the Blender Compositor
38   *
39   * @section bcomp Blender compositor
40   * This project redesigns the interals of Blender's compositor. The project has been executed in 2011 by At Mind.
41   * At Mind is a technology company located in Amsterdam, The Netherlands.
42   * The project has been crowdfunded. This code has been released under GPL2 to be used in Blender.
43   *
44   * @section goals The goals of the project
45   * the new compositor has 2 goals.
46   *   - Make a faster compositor (speed of calculation)
47   *   - Make the compositor work faster for you (workflow)
48   *
49   * @section speed Faster compositor
50   * The speedup has been done by making better use of the hardware Blenders is working on. The previous compositor only
51   * used a single threaded model to calculate a node. The only exception to this is the Defocus node.
52   * Only when it is possible to calculate two full nodes in parallel a second thread was used.
53   * Current workstations have 8-16 threads available, and most of the time these are idle.
54   *
55   * In the new compositor we want to use as much of threads as possible. Even new OpenCL capable GPU-hardware can be
56   * used for calculation.
57   *
58   * @section workflow Work faster
59   * The previous compositor only showed the final image. The compositor could wait a long time before seeing the result
60   * of his work. The new compositor will work in a way that it will focus on getting information back to the user.
61   * It will prioritise its work to get earlier user feedback.
62   *
63   * @page memory Memory model
64   * The main issue is the type of memory model to use. Blender is used by consumers and professionals.
65   * Ranging from low-end machines to very high-end machines.
66   * The system should work on high-end machines and on low-end machines.
67   *
68   *
69   * @page executing Executing
70   * @section prepare Prepare execution
71   *
72   * during the preparation of the execution All ReadBufferOperation will receive an offset.
73   * This offset is used during execution as an optimization trick
74   * Next all operations will be initialized for execution @see NodeOperation.initExecution
75   * Next all ExecutionGroup's will be initialized for execution @see ExecutionGroup.initExecution
76   * this all is controlled from @see ExecutionSystem.execute
77   *
78   * @section priority Render priority
79   * Render priority is an priority of an output node. A user has a different need of Render priorities of output nodes
80   * than during editing.
81   * for example. the Active ViewerNode has top priority during editing, but during rendering a CompositeNode has.
82   * All NodeOperation has a setting for their renderpriority, but only for output NodeOperation these have effect.
83   * In ExecutionSystem.execute all priorities are checked. For every priority the ExecutionGroup's are check if the
84   * priority do match.
85   * When match the ExecutionGroup will be executed (this happens in serial)
86   *
87   * @see ExecutionSystem.execute control of the Render priority
88   * @see NodeOperation.getRenderPriority receive the render priority
89   * @see ExecutionGroup.execute the main loop to execute a whole ExecutionGroup
90   *
91   * @section order Chunk order
92   *
93   * When a ExecutionGroup is executed, first the order of chunks are determined.
94   * The settings are stored in the ViewerNode inside the ExecutionGroup. ExecutionGroups that have no viewernode,
95   * will use a default one.
96   * There are several possible chunk orders
97   *  - [@ref OrderOfChunks.COM_TO_CENTER_OUT]: Start calculating from a configurable point and order by nearest chunk
98   *  - [@ref OrderOfChunks.COM_TO_RANDOM]: Randomize all chunks.
99   *  - [@ref OrderOfChunks.COM_TO_TOP_DOWN]: Start calculation from the bottom to the top of the image
100   *  - [@ref OrderOfChunks.COM_TO_RULE_OF_THIRDS]: Experimental order based on 9 hotspots in the image
101   *
102   * When the chunkorder is determined, the first few chunks will be checked if they can be scheduled.
103   * Chunks can have three states:
104   *  - [@ref ChunkExecutionState.COM_ES_NOT_SCHEDULED]: Chunk is not yet scheduled, or dependacies are not met
105   *  - [@ref ChunkExecutionState.COM_ES_SCHEDULED]: All dependacies are met, chunk is scheduled, but not finished
106   *  - [@ref ChunkExecutionState.COM_ES_EXECUTED]: Chunk is finished
107   *
108   * @see ExecutionGroup.execute
109   * @see ViewerBaseOperation.getChunkOrder
110   * @see OrderOfChunks
111   *
112   * @section interest Area of interest
113   * An ExecutionGroup can have dependancies to other ExecutionGroup's. Data passing from one ExecutionGroup to another
114   * one are stored in 'chunks'.
115   * If not all input chunks are available the chunk execution will not be scheduled.
116   * <pre>
117   * +-------------------------------------+              +--------------------------------------+
118   * | ExecutionGroup A                    |              | ExecutionGroup B                     |
119   * | +----------------+  +-------------+ |              | +------------+   +-----------------+ |
120   * | | NodeOperation a|  | WriteBuffer | |              | | ReadBuffer |   | ViewerOperation | |
121   * | |                *==* Operation   | |              | | Operation  *===*                 | |
122   * | |                |  |             | |              | |            |   |                 | |
123   * | +----------------+  +-------------+ |              | +------------+   +-----------------+ |
124   * |                                |    |              |   |                                  |
125   * +--------------------------------|----+              +---|----------------------------------+
126   *                                  |                       |
127   *                                  |                       |
128   *                                +---------------------------+
129   *                                | MemoryProxy               |
130   *                                | +----------+  +---------+ |
131   *                                | | Chunk a  |  | Chunk b | |
132   *                                | |          |  |         | |
133   *                                | +----------+  +---------+ |
134   *                                |                           |
135   *                                +---------------------------+
136   * </pre>
137   *
138   * In the above example ExecutionGroup B has an outputoperation (ViewerOperation) and is being executed.
139   * The first chunk is evaluated [@ref ExecutionGroup.scheduleChunkWhenPossible],
140   * but not all input chunks are available. The relevant ExecutionGroup (that can calculate the missing chunks;
141   * ExecutionGroup A) is asked to calculate the area ExecutionGroup B is missing.
142   * [@ref ExecutionGroup.scheduleAreaWhenPossible]
143   * ExecutionGroup B checks what chunks the area spans, and tries to schedule these chunks.
144   * If all input data is available these chunks are scheduled [@ref ExecutionGroup.scheduleChunk]
145   *
146   * <pre>
147   *
148   * +-------------------------+        +----------------+                           +----------------+
149   * | ExecutionSystem.execute |        | ExecutionGroup |                           | ExecutionGroup |
150   * +-------------------------+        | (B)            |                           | (A)            |
151   *            O                       +----------------+                           +----------------+
152   *            O                                |                                            |
153   *            O       ExecutionGroup.execute   |                                            |
154   *            O------------------------------->O                                            |
155   *            .                                O                                            |
156   *            .                                O-------\                                    |
157   *            .                                .       | ExecutionGroup.scheduleChunkWhenPossible
158   *            .                                .  O----/ (*)                                |
159   *            .                                .  O                                         |
160   *            .                                .  O                                         |
161   *            .                                .  O  ExecutionGroup.scheduleAreaWhenPossible|
162   *            .                                .  O---------------------------------------->O
163   *            .                                .  .                                         O----------\ ExecutionGroup.scheduleChunkWhenPossible
164   *            .                                .  .                                         .          | (*)
165   *            .                                .  .                                         .  O-------/
166   *            .                                .  .                                         .  O
167   *            .                                .  .                                         .  O
168   *            .                                .  .                                         .  O-------\ ExecutionGroup.scheduleChunk
169   *            .                                .  .                                         .  .       |
170   *            .                                .  .                                         .  .  O----/
171   *            .                                .  .                                         .  O<=O
172   *            .                                .  .                                         O<=O
173   *            .                                .  .                                         O
174   *            .                                .  O<========================================O
175   *            .                                .  O                                         |
176   *            .                                O<=O                                         |
177   *            .                                O                                            |
178   *            .                                O                                            |
179   * </pre>
180   *
181   * This happens until all chunks of (ExecutionGroup B) are finished executing or the user break's the process.
182   *
183   * NodeOperation like the ScaleOperation can influence the area of interest by reimplementing the
184   * [@ref NodeOperation.determineAreaOfInterest] method
185   *
186   * <pre>
187   *
188   * +--------------------------+                             +---------------------------------+
189   * | ExecutionGroup A         |                             | ExecutionGroup B                |
190   * |                          |                             |                                 |
191   * +--------------------------+                             +---------------------------------+
192   *           Needed chunks from ExecutionGroup A               |   Chunk of ExecutionGroup B (to be evaluated)
193   *            +-------+ +-------+                              |                  +--------+
194   *            |Chunk 1| |Chunk 2|               +----------------+                |Chunk 1 |
195   *            |       | |       |               | ScaleOperation |                |        |
196   *            +-------+ +-------+               +----------------+                +--------+
197   *
198   *            +-------+ +-------+
199   *            |Chunk 3| |Chunk 4|
200   *            |       | |       |
201   *            +-------+ +-------+
202   *
203   * </pre>
204   *
205   * @see ExecutionGroup.execute Execute a complete ExecutionGroup. Halts until finished or breaked by user
206   * @see ExecutionGroup.scheduleChunkWhenPossible Tries to schedule a single chunk,
207   * checks if all input data is available. Can trigger dependant chunks to be calculated
208   * @see ExecutionGroup.scheduleAreaWhenPossible Tries to schedule an area. This can be multiple chunks
209   * (is called from [@ref ExecutionGroup.scheduleChunkWhenPossible])
210   * @see ExecutionGroup.scheduleChunk Schedule a chunk on the WorkScheduler
211   * @see NodeOperation.determineDependingAreaOfInterest Influence the area of interest of a chunk.
212   * @see WriteBufferOperation NodeOperation to write to a MemoryProxy/MemoryBuffer
213   * @see ReadBufferOperation NodeOperation to read from a MemoryProxy/MemoryBuffer
214   * @see MemoryProxy proxy for information about memory image (a image consist out of multiple chunks)
215   * @see MemoryBuffer Allocated memory for a single chunk
216   *
217   * @section workscheduler WorkScheduler
218   * the WorkScheduler is implemented as a static class. the responsibility of the WorkScheduler is to balance
219   * WorkPackages to the available and free devices.
220   * the workscheduler can work in 2 states. For witching these between the state you need to recompile blender
221   *
222   * @subsection multithread Multi threaded
223   * Default the workscheduler will place all work as WorkPackage in a queue.
224   * For every CPUcore a working thread is created. These working threads will ask the WorkScheduler if there is work
225   * for a specific Device.
226   * the workscheduler will find work for the device and the device will be asked to execute the WorkPackage
227
228   * @subsection singlethread Single threaded
229   * For debugging reasons the multi-threading can be disabled. This is done by changing the COM_CURRENT_THREADING_MODEL
230   * to COM_TM_NOTHREAD. When compiling the workscheduler
231   * will be changes to support no threading and run everything on the CPU.
232   *
233   * @section devices Devices
234   * A Device within the compositor context is a Hardware component that can used to calculate chunks.
235   * This chunk is encapseled in a WorkPackage.
236   * the WorkScheduler controls the devices and selects the device where a WorkPackage will be calculated.
237   *
238   * @subsection WS_Devices Workscheduler
239   * The WorkScheduler controls all Devices. When initializing the compositor the WorkScheduler selects
240   * all devices that will be used during compositor.
241   * There are two types of Devices, CPUDevice and OpenCLDevice.
242   * When an ExecutionGroup schedules a Chunk the schedule method of the WorkScheduler
243   * The Workscheduler determines if the chunk can be run on an OpenCLDevice
244   * (and that there are available OpenCLDevice). If this is the case the chunk will be added to the worklist for
245   * OpenCLDevice's
246   * otherwise the chunk will be added to the worklist of CPUDevices.
247   * 
248   * A thread will read the work-list and sends a workpackage to its device.
249   *
250   * @see WorkScheduler.schedule method that is called to schedule a chunk
251   * @see Device.execute method called to execute a chunk
252   *
253   * @subsection CPUDevice CPUDevice
254   * When a CPUDevice gets a WorkPackage the Device will get the inputbuffer that is needed to calculate the chunk.
255   * Allocation is already done by the ExecutionGroup.
256   * The outputbuffer of the chunk is being created.
257   * The OutputOperation of the ExecutionGroup is called to execute the area of the outputbuffer.
258   *
259   * @see ExecutionGroup 
260   * @see NodeOperation.executeRegion executes a single chunk of a NodeOperation
261   * @see CPUDevice.execute 
262   *
263   * @subsection GPUDevice OpenCLDevice
264   * 
265   * To be completed!
266   * @see NodeOperation.executeOpenCLRegion 
267   * @see OpenCLDevice.execute
268   *
269   * @section executePixel executing a pixel
270   * Finally the last step, the node functionality :)
271
272   * @page newnode Creating new nodes
273   */
274
275 /**
276  * @brief The main method that is used to execute the compositor tree.
277  * It can be executed during editing (blenkernel/node.c) or rendering
278  * (renderer/pipeline.c)
279  *
280  * @param editingtree [struct bNodeTree]
281  *   reference to the compositor editing tree
282  *
283  * @param rendering [true false]
284  *    This parameter determines whether the function is called from rendering (true) or editing (false).
285  *    based on this setting the system will work differently:
286  *     - during rendering only Composite & the File output node will be calculated
287  * @see NodeOperation.isOutputProgram(int rendering) of the specific operations
288  *
289  *     - during editing all output nodes will be calculated
290  * @see NodeOperation.isOutputProgram(int rendering) of the specific operations
291  *
292  *     - another quality setting can be used bNodeTree. The quality is determined by the bNodeTree fields.
293  *       quality can be modified by the user from within the node panels.
294  * @see bNodeTree.edit_quality
295  * @see bNodeTree.render_quality
296  *
297  *     - output nodes can have different priorities in the WorkScheduler.
298  * This is implemented in the COM_execute function.
299  */
300 void COM_execute(bNodeTree *editingtree, int rendering);
301
302 #ifdef __cplusplus
303 }
304 #endif