Cycles: Solve dependency between camera and object synchronization
[blender.git] / intern / cycles / render / scene.cpp
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdlib.h>
18
19 #include "background.h"
20 #include "bake.h"
21 #include "camera.h"
22 #include "curves.h"
23 #include "device.h"
24 #include "film.h"
25 #include "integrator.h"
26 #include "light.h"
27 #include "mesh.h"
28 #include "object.h"
29 #include "osl.h"
30 #include "particles.h"
31 #include "scene.h"
32 #include "shader.h"
33 #include "svm.h"
34 #include "tables.h"
35
36 #include "util_foreach.h"
37 #include "util_progress.h"
38
39 CCL_NAMESPACE_BEGIN
40
41 Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
42 : params(params_)
43 {
44         device = NULL;
45         memset(&dscene.data, 0, sizeof(dscene.data));
46
47         camera = new Camera();
48         lookup_tables = new LookupTables();
49         film = new Film();
50         background = new Background();
51         light_manager = new LightManager();
52         mesh_manager = new MeshManager();
53         object_manager = new ObjectManager();
54         integrator = new Integrator();
55         image_manager = new ImageManager();
56         particle_system_manager = new ParticleSystemManager();
57         curve_system_manager = new CurveSystemManager();
58         bake_manager = new BakeManager();
59
60         /* OSL only works on the CPU */
61         if(device_info_.type == DEVICE_CPU)
62                 shader_manager = ShaderManager::create(this, params.shadingsystem);
63         else
64                 shader_manager = ShaderManager::create(this, SHADINGSYSTEM_SVM);
65
66         /* Extended image limits for CPU and GPUs */
67         image_manager->set_extended_image_limits(device_info_);
68 }
69
70 Scene::~Scene()
71 {
72         free_memory(true);
73 }
74
75 void Scene::free_memory(bool final)
76 {
77         foreach(Shader *s, shaders)
78                 delete s;
79         foreach(Mesh *m, meshes)
80                 delete m;
81         foreach(Object *o, objects)
82                 delete o;
83         foreach(Light *l, lights)
84                 delete l;
85         foreach(ParticleSystem *p, particle_systems)
86                 delete p;
87
88         shaders.clear();
89         meshes.clear();
90         objects.clear();
91         lights.clear();
92         particle_systems.clear();
93
94         if(device) {
95                 camera->device_free(device, &dscene);
96                 film->device_free(device, &dscene, this);
97                 background->device_free(device, &dscene);
98                 integrator->device_free(device, &dscene);
99
100                 object_manager->device_free(device, &dscene);
101                 mesh_manager->device_free(device, &dscene);
102                 shader_manager->device_free(device, &dscene, this);
103                 light_manager->device_free(device, &dscene);
104
105                 particle_system_manager->device_free(device, &dscene);
106                 curve_system_manager->device_free(device, &dscene);
107
108                 bake_manager->device_free(device, &dscene);
109
110                 if(!params.persistent_data || final)
111                         image_manager->device_free(device, &dscene);
112                 else
113                         image_manager->device_free_builtin(device, &dscene);
114
115                 lookup_tables->device_free(device, &dscene);
116         }
117
118         if(final) {
119                 delete lookup_tables;
120                 delete camera;
121                 delete film;
122                 delete background;
123                 delete integrator;
124                 delete object_manager;
125                 delete mesh_manager;
126                 delete shader_manager;
127                 delete light_manager;
128                 delete particle_system_manager;
129                 delete curve_system_manager;
130                 delete image_manager;
131                 delete bake_manager;
132         }
133 }
134
135 void Scene::device_update(Device *device_, Progress& progress)
136 {
137         if(!device)
138                 device = device_;
139         
140         /* The order of updates is important, because there's dependencies between
141          * the different managers, using data computed by previous managers.
142          *
143          * - Image manager uploads images used by shaders.
144          * - Camera may be used for adaptive subdivision.
145          * - Displacement shader must have all shader data available.
146          * - Light manager needs lookup tables and final mesh data to compute emission CDF.
147          * - Film needs light manager to run for use_light_visibility
148          * - Lookup tables are done a second time to handle film tables
149          */
150         
151         image_manager->set_pack_images(device->info.pack_images);
152
153         progress.set_status("Updating Shaders");
154         shader_manager->device_update(device, &dscene, this, progress);
155
156         if(progress.get_cancel() || device->have_error()) return;
157
158         progress.set_status("Updating Images");
159         image_manager->device_update(device, &dscene, progress);
160
161         if(progress.get_cancel() || device->have_error()) return;
162
163         progress.set_status("Updating Background");
164         background->device_update(device, &dscene, this);
165
166         if(progress.get_cancel() || device->have_error()) return;
167
168         progress.set_status("Updating Camera");
169         camera->device_update(device, &dscene, this);
170
171         if(progress.get_cancel() || device->have_error()) return;
172
173         progress.set_status("Updating Objects");
174         object_manager->device_update(device, &dscene, this, progress);
175
176         if(progress.get_cancel() || device->have_error()) return;
177
178         progress.set_status("Updating Meshes Flags");
179         mesh_manager->device_update_flags(device, &dscene, this, progress);
180
181         if(progress.get_cancel() || device->have_error()) return;
182
183         progress.set_status("Updating Objects Flags");
184         object_manager->device_update_flags(device, &dscene, this, progress);
185
186         if(progress.get_cancel() || device->have_error()) return;
187
188         progress.set_status("Updating Meshes");
189         mesh_manager->device_update(device, &dscene, this, progress);
190
191         if(progress.get_cancel() || device->have_error()) return;
192
193         progress.set_status("Updating Camera Volume");
194         camera->device_update_volume(device, &dscene, this);
195
196         if(progress.get_cancel() || device->have_error()) return;
197
198         progress.set_status("Updating Hair Systems");
199         curve_system_manager->device_update(device, &dscene, this, progress);
200
201         if(progress.get_cancel() || device->have_error()) return;
202
203         progress.set_status("Updating Lookup Tables");
204         lookup_tables->device_update(device, &dscene);
205
206         if(progress.get_cancel() || device->have_error()) return;
207
208         progress.set_status("Updating Lights");
209         light_manager->device_update(device, &dscene, this, progress);
210
211         if(progress.get_cancel() || device->have_error()) return;
212
213         progress.set_status("Updating Particle Systems");
214         particle_system_manager->device_update(device, &dscene, this, progress);
215
216         if(progress.get_cancel() || device->have_error()) return;
217
218         progress.set_status("Updating Film");
219         film->device_update(device, &dscene, this);
220
221         if(progress.get_cancel() || device->have_error()) return;
222
223         progress.set_status("Updating Integrator");
224         integrator->device_update(device, &dscene, this);
225
226         if(progress.get_cancel() || device->have_error()) return;
227
228         progress.set_status("Updating Lookup Tables");
229         lookup_tables->device_update(device, &dscene);
230
231         if(progress.get_cancel() || device->have_error()) return;
232
233         progress.set_status("Updating Baking");
234         bake_manager->device_update(device, &dscene, this, progress);
235
236         if(progress.get_cancel() || device->have_error()) return;
237
238         if(device->have_error() == false) {
239                 progress.set_status("Updating Device", "Writing constant memory");
240                 device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
241         }
242 }
243
244 Scene::MotionType Scene::need_motion(bool advanced_shading)
245 {
246         if(integrator->motion_blur)
247                 return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
248         else if(Pass::contains(film->passes, PASS_MOTION))
249                 return MOTION_PASS;
250         else
251                 return MOTION_NONE;
252 }
253
254 bool Scene::need_global_attribute(AttributeStandard std)
255 {
256         if(std == ATTR_STD_UV)
257                 return Pass::contains(film->passes, PASS_UV);
258         else if(std == ATTR_STD_MOTION_VERTEX_POSITION)
259                 return need_motion() != MOTION_NONE;
260         else if(std == ATTR_STD_MOTION_VERTEX_NORMAL)
261                 return need_motion() == MOTION_BLUR;
262         
263         return false;
264 }
265
266 void Scene::need_global_attributes(AttributeRequestSet& attributes)
267 {
268         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
269                 if(need_global_attribute((AttributeStandard)std))
270                         attributes.add((AttributeStandard)std);
271 }
272
273 bool Scene::need_update()
274 {
275         return (need_reset() || film->need_update);
276 }
277
278 bool Scene::need_reset()
279 {
280         return (background->need_update
281                 || image_manager->need_update
282                 || camera->need_update
283                 || object_manager->need_update
284                 || mesh_manager->need_update
285                 || light_manager->need_update
286                 || lookup_tables->need_update
287                 || integrator->need_update
288                 || shader_manager->need_update
289                 || particle_system_manager->need_update
290                 || curve_system_manager->need_update
291                 || bake_manager->need_update
292                 || film->need_update);
293 }
294
295 void Scene::reset()
296 {
297         shader_manager->reset(this);
298         shader_manager->add_default(this);
299
300         /* ensure all objects are updated */
301         camera->tag_update();
302         film->tag_update(this);
303         background->tag_update(this);
304         integrator->tag_update(this);
305         object_manager->tag_update(this);
306         mesh_manager->tag_update(this);
307         light_manager->tag_update(this);
308         particle_system_manager->tag_update(this);
309         curve_system_manager->tag_update(this);
310 }
311
312 void Scene::device_free()
313 {
314         free_memory(false);
315 }
316
317 CCL_NAMESPACE_END
318