Merged revision(s) 57587-57670 from trunk/blender into soc-2013-dingto
[blender.git] / intern / cycles / render / scene.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
19 #include <stdlib.h>
20
21 #include "background.h"
22 #include "camera.h"
23 #include "curves.h"
24 #include "device.h"
25 #include "film.h"
26 #include "integrator.h"
27 #include "light.h"
28 #include "mesh.h"
29 #include "object.h"
30 #include "osl.h"
31 #include "particles.h"
32 #include "scene.h"
33 #include "shader.h"
34 #include "svm.h"
35 #include "tables.h"
36
37 #include "util_foreach.h"
38 #include "util_progress.h"
39
40 CCL_NAMESPACE_BEGIN
41
42 Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
43 : params(params_)
44 {
45         device = NULL;
46         memset(&dscene.data, 0, sizeof(dscene.data));
47
48         camera = new Camera();
49         lookup_tables = new LookupTables();
50         film = new Film();
51         background = new Background();
52         light_manager = new LightManager();
53         mesh_manager = new MeshManager();
54         object_manager = new ObjectManager();
55         integrator = new Integrator();
56         image_manager = new ImageManager();
57         particle_system_manager = new ParticleSystemManager();
58         curve_system_manager = new CurveSystemManager();
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, SceneParams::SVM);
65
66         /* Extended Image limits for CPU and Kepler 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                 if(!params.persistent_data || final)
109                         image_manager->device_free(device, &dscene);
110
111                 lookup_tables->device_free(device, &dscene);
112         }
113
114         if(final) {
115                 delete lookup_tables;
116                 delete camera;
117                 delete film;
118                 delete background;
119                 delete integrator;
120                 delete object_manager;
121                 delete mesh_manager;
122                 delete shader_manager;
123                 delete light_manager;
124                 delete particle_system_manager;
125                 delete curve_system_manager;
126                 delete image_manager;
127         }
128 }
129
130 void Scene::device_update(Device *device_, Progress& progress)
131 {
132         if(!device)
133                 device = device_;
134         
135         /* The order of updates is important, because there's dependencies between
136          * the different managers, using data computed by previous managers.
137          *
138          * - Background generates shader graph compiled by shader manager.
139          * - Image manager uploads images used by shaders.
140          * - Camera may be used for adapative subdivison.
141          * - Displacement shader must have all shader data available.
142          * - Light manager needs final mesh data to compute emission CDF.
143          */
144         
145         image_manager->set_pack_images(device->info.pack_images);
146
147         progress.set_status("Updating Background");
148         background->device_update(device, &dscene, this);
149
150         if(progress.get_cancel()) return;
151
152         progress.set_status("Updating Shaders");
153         shader_manager->device_update(device, &dscene, this, progress);
154
155         if(progress.get_cancel()) return;
156
157         progress.set_status("Updating Images");
158         image_manager->device_update(device, &dscene, progress);
159
160         if(progress.get_cancel()) return;
161
162         progress.set_status("Updating Camera");
163         camera->device_update(device, &dscene, this);
164
165         if(progress.get_cancel()) return;
166
167         progress.set_status("Updating Objects");
168         object_manager->device_update(device, &dscene, this, progress);
169
170         if(progress.get_cancel()) return;
171
172         progress.set_status("Updating Hair Systems");
173         curve_system_manager->device_update(device, &dscene, this, progress);
174
175         if(progress.get_cancel()) return;
176
177         progress.set_status("Updating Meshes");
178         mesh_manager->device_update(device, &dscene, this, progress);
179
180         if(progress.get_cancel()) return;
181
182         progress.set_status("Updating Lights");
183         light_manager->device_update(device, &dscene, this, progress);
184
185         if(progress.get_cancel()) return;
186
187         progress.set_status("Updating Particle Systems");
188         particle_system_manager->device_update(device, &dscene, this, progress);
189
190         if(progress.get_cancel()) return;
191
192         progress.set_status("Updating Film");
193         film->device_update(device, &dscene, this);
194
195         if(progress.get_cancel()) return;
196
197         progress.set_status("Updating Integrator");
198         integrator->device_update(device, &dscene, this);
199
200         if(progress.get_cancel()) return;
201
202         progress.set_status("Updating Lookup Tables");
203         lookup_tables->device_update(device, &dscene);
204
205         if(progress.get_cancel()) return;
206
207         progress.set_status("Updating Device", "Writing constant memory");
208         device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
209 }
210
211 Scene::MotionType Scene::need_motion(bool advanced_shading)
212 {
213         if(integrator->motion_blur)
214                 return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
215         else if(Pass::contains(film->passes, PASS_MOTION))
216                 return MOTION_PASS;
217         else
218                 return MOTION_NONE;
219 }
220
221 bool Scene::need_global_attribute(AttributeStandard std)
222 {
223         if(std == ATTR_STD_UV)
224                 return Pass::contains(film->passes, PASS_UV);
225         if(std == ATTR_STD_MOTION_PRE || ATTR_STD_MOTION_POST)
226                 return need_motion() == MOTION_PASS;
227         
228         return false;
229 }
230
231 void Scene::need_global_attributes(AttributeRequestSet& attributes)
232 {
233         for(int std = ATTR_STD_NONE; std < ATTR_STD_NUM; std++)
234                 if(need_global_attribute((AttributeStandard)std))
235                         attributes.add((AttributeStandard)std);
236 }
237
238 bool Scene::need_update()
239 {
240         return (need_reset() || film->need_update);
241 }
242
243 bool Scene::need_reset()
244 {
245         return (background->need_update
246                 || image_manager->need_update
247                 || camera->need_update
248                 || object_manager->need_update
249                 || mesh_manager->need_update
250                 || light_manager->need_update
251                 || lookup_tables->need_update
252                 || integrator->need_update
253                 || shader_manager->need_update
254                 || particle_system_manager->need_update
255                 || curve_system_manager->need_update);
256 }
257
258 void Scene::reset()
259 {
260         shader_manager->reset(this);
261         shader_manager->add_default(this);
262
263         /* ensure all objects are updated */
264         camera->tag_update();
265         film->tag_update(this);
266         background->tag_update(this);
267         integrator->tag_update(this);
268 }
269
270 void Scene::device_free()
271 {
272         free_memory(false);
273 }
274
275 CCL_NAMESPACE_END
276