Cleanup: remove non-existing function declarations
[blender.git] / source / blender / compositor / intern / COM_ExecutionSystem.cpp
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 #include "COM_ExecutionSystem.h"
24
25 #include "PIL_time.h"
26 #include "BLI_utildefines.h"
27 extern "C" {
28 #include "BKE_node.h"
29 }
30
31 #include "BLT_translation.h"
32
33 #include "COM_Converter.h"
34 #include "COM_NodeOperationBuilder.h"
35 #include "COM_NodeOperation.h"
36 #include "COM_ExecutionGroup.h"
37 #include "COM_WorkScheduler.h"
38 #include "COM_ReadBufferOperation.h"
39 #include "COM_Debug.h"
40
41 #ifdef WITH_CXX_GUARDEDALLOC
42 #include "MEM_guardedalloc.h"
43 #endif
44
45 ExecutionSystem::ExecutionSystem(RenderData *rd, Scene *scene, bNodeTree *editingtree, bool rendering, bool fastcalculation,
46                                  const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings,
47                                  const char *viewName)
48 {
49         this->m_context.setViewName(viewName);
50         this->m_context.setScene(scene);
51         this->m_context.setbNodeTree(editingtree);
52         this->m_context.setPreviewHash(editingtree->previews);
53         this->m_context.setFastCalculation(fastcalculation);
54         /* initialize the CompositorContext */
55         if (rendering) {
56                 this->m_context.setQuality((CompositorQuality)editingtree->render_quality);
57         }
58         else {
59                 this->m_context.setQuality((CompositorQuality)editingtree->edit_quality);
60         }
61         this->m_context.setRendering(rendering);
62         this->m_context.setHasActiveOpenCLDevices(WorkScheduler::hasGPUDevices() && (editingtree->flag & NTREE_COM_OPENCL));
63
64         this->m_context.setRenderData(rd);
65         this->m_context.setViewSettings(viewSettings);
66         this->m_context.setDisplaySettings(displaySettings);
67
68         {
69                 NodeOperationBuilder builder(&m_context, editingtree);
70                 builder.convertToOperations(this);
71         }
72
73         unsigned int index;
74         unsigned int resolution[2];
75
76         rctf *viewer_border = &editingtree->viewer_border;
77         bool use_viewer_border = (editingtree->flag & NTREE_VIEWER_BORDER) &&
78                                  viewer_border->xmin < viewer_border->xmax &&
79                                  viewer_border->ymin < viewer_border->ymax;
80
81         editingtree->stats_draw(editingtree->sdh, IFACE_("Compositing | Determining resolution"));
82
83         for (index = 0; index < this->m_groups.size(); index++) {
84                 resolution[0] = 0;
85                 resolution[1] = 0;
86                 ExecutionGroup *executionGroup = this->m_groups[index];
87                 executionGroup->determineResolution(resolution);
88
89                 if (rendering) {
90                         /* case when cropping to render border happens is handled in
91                          * compositor output and render layer nodes
92                          */
93                         if ((rd->mode & R_BORDER) && !(rd->mode & R_CROP)) {
94                                 executionGroup->setRenderBorder(rd->border.xmin, rd->border.xmax,
95                                                                 rd->border.ymin, rd->border.ymax);
96                         }
97                 }
98
99                 if (use_viewer_border) {
100                         executionGroup->setViewerBorder(viewer_border->xmin, viewer_border->xmax,
101                                                         viewer_border->ymin, viewer_border->ymax);
102                 }
103         }
104
105 //      DebugInfo::graphviz(this);
106 }
107
108 ExecutionSystem::~ExecutionSystem()
109 {
110         unsigned int index;
111         for (index = 0; index < this->m_operations.size(); index++) {
112                 NodeOperation *operation = this->m_operations[index];
113                 delete operation;
114         }
115         this->m_operations.clear();
116         for (index = 0; index < this->m_groups.size(); index++) {
117                 ExecutionGroup *group = this->m_groups[index];
118                 delete group;
119         }
120         this->m_groups.clear();
121 }
122
123 void ExecutionSystem::set_operations(const Operations &operations, const Groups &groups)
124 {
125         m_operations = operations;
126         m_groups = groups;
127 }
128
129 void ExecutionSystem::execute()
130 {
131         const bNodeTree *editingtree = this->m_context.getbNodeTree();
132         editingtree->stats_draw(editingtree->sdh, IFACE_("Compositing | Initializing execution"));
133
134         DebugInfo::execute_started(this);
135
136         unsigned int order = 0;
137         for (vector<NodeOperation *>::iterator iter = this->m_operations.begin(); iter != this->m_operations.end(); ++iter) {
138                 NodeOperation *operation = *iter;
139                 if (operation->isReadBufferOperation()) {
140                         ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
141                         readOperation->setOffset(order);
142                         order++;
143                 }
144         }
145         unsigned int index;
146
147         // First allocale all write buffer
148         for (index = 0; index < this->m_operations.size(); index++) {
149                 NodeOperation *operation = this->m_operations[index];
150                 if (operation->isWriteBufferOperation()) {
151                         operation->setbNodeTree(this->m_context.getbNodeTree());
152                         operation->initExecution();
153                 }
154         }
155         // Connect read buffers to their write buffers
156         for (index = 0; index < this->m_operations.size(); index++) {
157                 NodeOperation *operation = this->m_operations[index];
158                 if (operation->isReadBufferOperation()) {
159                         ReadBufferOperation *readOperation = (ReadBufferOperation *)operation;
160                         readOperation->updateMemoryBuffer();
161                 }
162         }
163         // initialize other operations
164         for (index = 0; index < this->m_operations.size(); index++) {
165                 NodeOperation *operation = this->m_operations[index];
166                 if (!operation->isWriteBufferOperation()) {
167                         operation->setbNodeTree(this->m_context.getbNodeTree());
168                         operation->initExecution();
169                 }
170         }
171         for (index = 0; index < this->m_groups.size(); index++) {
172                 ExecutionGroup *executionGroup = this->m_groups[index];
173                 executionGroup->setChunksize(this->m_context.getChunksize());
174                 executionGroup->initExecution();
175         }
176
177         WorkScheduler::start(this->m_context);
178
179         executeGroups(COM_PRIORITY_HIGH);
180         if (!this->getContext().isFastCalculation()) {
181                 executeGroups(COM_PRIORITY_MEDIUM);
182                 executeGroups(COM_PRIORITY_LOW);
183         }
184
185         WorkScheduler::finish();
186         WorkScheduler::stop();
187
188         editingtree->stats_draw(editingtree->sdh, IFACE_("Compositing | De-initializing execution"));
189         for (index = 0; index < this->m_operations.size(); index++) {
190                 NodeOperation *operation = this->m_operations[index];
191                 operation->deinitExecution();
192         }
193         for (index = 0; index < this->m_groups.size(); index++) {
194                 ExecutionGroup *executionGroup = this->m_groups[index];
195                 executionGroup->deinitExecution();
196         }
197 }
198
199 void ExecutionSystem::executeGroups(CompositorPriority priority)
200 {
201         unsigned int index;
202         vector<ExecutionGroup *> executionGroups;
203         this->findOutputExecutionGroup(&executionGroups, priority);
204
205         for (index = 0; index < executionGroups.size(); index++) {
206                 ExecutionGroup *group = executionGroups[index];
207                 group->execute(this);
208         }
209 }
210
211 void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result, CompositorPriority priority) const
212 {
213         unsigned int index;
214         for (index = 0; index < this->m_groups.size(); index++) {
215                 ExecutionGroup *group = this->m_groups[index];
216                 if (group->isOutputExecutionGroup() && group->getRenderPriotrity() == priority) {
217                         result->push_back(group);
218                 }
219         }
220 }
221
222 void ExecutionSystem::findOutputExecutionGroup(vector<ExecutionGroup *> *result) const
223 {
224         unsigned int index;
225         for (index = 0; index < this->m_groups.size(); index++) {
226                 ExecutionGroup *group = this->m_groups[index];
227                 if (group->isOutputExecutionGroup()) {
228                         result->push_back(group);
229                 }
230         }
231 }