fd24593c6b61fb0e64479cc4974c5ba14c5f956a
[blender.git] / intern / cycles / blender / blender_sync.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 "background.h"
18 #include "camera.h"
19 #include "film.h"
20 #include "graph.h"
21 #include "integrator.h"
22 #include "light.h"
23 #include "mesh.h"
24 #include "nodes.h"
25 #include "object.h"
26 #include "scene.h"
27 #include "shader.h"
28 #include "curves.h"
29
30 #include "device.h"
31
32 #include "blender_sync.h"
33 #include "blender_session.h"
34 #include "blender_util.h"
35
36 #include "util_debug.h"
37 #include "util_foreach.h"
38 #include "util_opengl.h"
39 #include "util_hash.h"
40
41 CCL_NAMESPACE_BEGIN
42
43 /* Constructor */
44
45 BlenderSync::BlenderSync(BL::RenderEngine& b_engine,
46                          BL::BlendData& b_data,
47                          BL::Scene& b_scene,
48                          Scene *scene,
49                          bool preview,
50                          Progress &progress,
51                          bool is_cpu)
52 : b_engine(b_engine),
53   b_data(b_data),
54   b_scene(b_scene),
55   shader_map(&scene->shaders),
56   object_map(&scene->objects),
57   mesh_map(&scene->meshes),
58   light_map(&scene->lights),
59   particle_system_map(&scene->particle_systems),
60   world_map(NULL),
61   world_recalc(false),
62   scene(scene),
63   preview(preview),
64   experimental(false),
65   is_cpu(is_cpu),
66   dicing_rate(1.0f),
67   max_subdivisions(12),
68   progress(progress)
69 {
70         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
71         dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate") : RNA_float_get(&cscene, "dicing_rate");
72         max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
73 }
74
75 BlenderSync::~BlenderSync()
76 {
77 }
78
79 /* Sync */
80
81 bool BlenderSync::sync_recalc()
82 {
83         /* sync recalc flags from blender to cycles. actual update is done separate,
84          * so we can do it later on if doing it immediate is not suitable */
85
86         BL::BlendData::materials_iterator b_mat;
87         bool has_updated_objects = b_data.objects.is_updated();
88         for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
89                 if(b_mat->is_updated() || (b_mat->node_tree() && b_mat->node_tree().is_updated())) {
90                         shader_map.set_recalc(*b_mat);
91                 }
92                 else {
93                         Shader *shader = shader_map.find(*b_mat);
94                         if(has_updated_objects && shader != NULL && shader->has_object_dependency) {
95                                 shader_map.set_recalc(*b_mat);
96                         }
97                 }
98         }
99
100         BL::BlendData::lamps_iterator b_lamp;
101
102         for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp)
103                 if(b_lamp->is_updated() || (b_lamp->node_tree() && b_lamp->node_tree().is_updated()))
104                         shader_map.set_recalc(*b_lamp);
105
106         BL::BlendData::objects_iterator b_ob;
107
108         for(b_data.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) {
109                 if(b_ob->is_updated()) {
110                         object_map.set_recalc(*b_ob);
111                         light_map.set_recalc(*b_ob);
112                 }
113
114                 if(object_is_mesh(*b_ob)) {
115                         if(b_ob->is_updated_data() || b_ob->data().is_updated()) {
116                                 BL::ID key = BKE_object_is_modified(*b_ob)? *b_ob: b_ob->data();
117                                 mesh_map.set_recalc(key);
118                         }
119                 }
120                 else if(object_is_light(*b_ob)) {
121                         if(b_ob->is_updated_data() || b_ob->data().is_updated())
122                                 light_map.set_recalc(*b_ob);
123                 }
124                 
125                 if(b_ob->is_updated_data()) {
126                         BL::Object::particle_systems_iterator b_psys;
127                         for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
128                                 particle_system_map.set_recalc(*b_ob);
129                 }
130         }
131
132         bool dicing_prop_changed = false;
133
134         if(experimental) {
135                 PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
136
137                 float updated_dicing_rate = preview ? RNA_float_get(&cscene, "preview_dicing_rate")
138                                                     : RNA_float_get(&cscene, "dicing_rate");
139
140                 if(dicing_rate != updated_dicing_rate) {
141                         dicing_rate = updated_dicing_rate;
142                         dicing_prop_changed = true;
143                 }
144
145                 int updated_max_subdivisions = RNA_int_get(&cscene, "max_subdivisions");
146
147                 if(max_subdivisions != updated_max_subdivisions) {
148                         max_subdivisions = updated_max_subdivisions;
149                         dicing_prop_changed = true;
150                 }
151         }
152
153         BL::BlendData::meshes_iterator b_mesh;
154
155         for(b_data.meshes.begin(b_mesh); b_mesh != b_data.meshes.end(); ++b_mesh) {
156                 if(b_mesh->is_updated()) {
157                         mesh_map.set_recalc(*b_mesh);
158                 }
159                 else if(dicing_prop_changed) {
160                         PointerRNA cmesh = RNA_pointer_get(&b_mesh->ptr, "cycles");
161
162                         if(RNA_enum_get(&cmesh, "subdivision_type"))
163                                 mesh_map.set_recalc(*b_mesh);
164                 }
165         }
166
167
168         BL::BlendData::worlds_iterator b_world;
169
170         for(b_data.worlds.begin(b_world); b_world != b_data.worlds.end(); ++b_world) {
171                 if(world_map == b_world->ptr.data) {
172                         if(b_world->is_updated() ||
173                            (b_world->node_tree() && b_world->node_tree().is_updated()))
174                         {
175                                 world_recalc = true;
176                         }
177                         else if(b_world->node_tree() && b_world->use_nodes()) {
178                                 Shader *shader = scene->default_background;
179                                 if(has_updated_objects && shader->has_object_dependency) {
180                                         world_recalc = true;
181                                 }
182                         }
183                 }
184         }
185
186         bool recalc =
187                 shader_map.has_recalc() ||
188                 object_map.has_recalc() ||
189                 light_map.has_recalc() ||
190                 mesh_map.has_recalc() ||
191                 particle_system_map.has_recalc() ||
192                 BlendDataObjects_is_updated_get(&b_data.ptr) ||
193                 world_recalc;
194
195         return recalc;
196 }
197
198 void BlenderSync::sync_data(BL::RenderSettings& b_render,
199                             BL::SpaceView3D& b_v3d,
200                             BL::Object& b_override,
201                             int width, int height,
202                             void **python_thread_state,
203                             const char *layer)
204 {
205         sync_render_layers(b_v3d, layer);
206         sync_integrator();
207         sync_film();
208         sync_shaders();
209         sync_images();
210         sync_curve_settings();
211
212         mesh_synced.clear(); /* use for objects and motion sync */
213
214         if(scene->need_motion() == Scene::MOTION_PASS ||
215            scene->need_motion() == Scene::MOTION_NONE ||
216            scene->camera->motion_position == Camera::MOTION_POSITION_CENTER)
217         {
218                 sync_objects(b_v3d);
219         }
220         sync_motion(b_render,
221                     b_v3d,
222                     b_override,
223                     width, height,
224                     python_thread_state);
225
226         mesh_synced.clear();
227 }
228
229 /* Integrator */
230
231 void BlenderSync::sync_integrator()
232 {
233 #ifdef __CAMERA_MOTION__
234         BL::RenderSettings r = b_scene.render();
235 #endif
236         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
237
238         experimental = (get_enum(cscene, "feature_set") != 0);
239
240         Integrator *integrator = scene->integrator;
241         Integrator previntegrator = *integrator;
242
243         integrator->min_bounce = get_int(cscene, "min_bounces");
244         integrator->max_bounce = get_int(cscene, "max_bounces");
245
246         integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces");
247         integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces");
248         integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces");
249         integrator->max_volume_bounce = get_int(cscene, "volume_bounces");
250
251         integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
252         integrator->transparent_min_bounce = get_int(cscene, "transparent_min_bounces");
253         integrator->transparent_shadows = get_boolean(cscene, "use_transparent_shadows");
254
255         integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
256         integrator->volume_step_size = get_float(cscene, "volume_step_size");
257
258         integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective");
259         integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive");
260         integrator->filter_glossy = get_float(cscene, "blur_glossy");
261
262         integrator->seed = get_int(cscene, "seed");
263         if(get_boolean(cscene, "use_animated_seed"))
264                 integrator->seed = hash_int_2d(b_scene.frame_current(), get_int(cscene, "seed"));
265
266         integrator->sampling_pattern = (SamplingPattern)get_enum(
267                 cscene,
268                 "sampling_pattern",
269                 SAMPLING_NUM_PATTERNS,
270                 SAMPLING_PATTERN_SOBOL);
271
272         integrator->layer_flag = render_layer.layer;
273
274         integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct");
275         integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect");
276 #ifdef __CAMERA_MOTION__
277         if(!preview) {
278                 if(integrator->motion_blur != r.use_motion_blur()) {
279                         scene->object_manager->tag_update(scene);
280                         scene->camera->tag_update();
281                 }
282
283                 integrator->motion_blur = r.use_motion_blur();
284         }
285 #endif
286
287         integrator->method = (Integrator::Method)get_enum(cscene,
288                                                           "progressive",
289                                                           Integrator::NUM_METHODS,
290                                                           Integrator::PATH);
291
292         integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct");
293         integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
294
295         int diffuse_samples = get_int(cscene, "diffuse_samples");
296         int glossy_samples = get_int(cscene, "glossy_samples");
297         int transmission_samples = get_int(cscene, "transmission_samples");
298         int ao_samples = get_int(cscene, "ao_samples");
299         int mesh_light_samples = get_int(cscene, "mesh_light_samples");
300         int subsurface_samples = get_int(cscene, "subsurface_samples");
301         int volume_samples = get_int(cscene, "volume_samples");
302
303         if(get_boolean(cscene, "use_square_samples")) {
304                 integrator->diffuse_samples = diffuse_samples * diffuse_samples;
305                 integrator->glossy_samples = glossy_samples * glossy_samples;
306                 integrator->transmission_samples = transmission_samples * transmission_samples;
307                 integrator->ao_samples = ao_samples * ao_samples;
308                 integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples;
309                 integrator->subsurface_samples = subsurface_samples * subsurface_samples;
310                 integrator->volume_samples = volume_samples * volume_samples;
311         } 
312         else {
313                 integrator->diffuse_samples = diffuse_samples;
314                 integrator->glossy_samples = glossy_samples;
315                 integrator->transmission_samples = transmission_samples;
316                 integrator->ao_samples = ao_samples;
317                 integrator->mesh_light_samples = mesh_light_samples;
318                 integrator->subsurface_samples = subsurface_samples;
319                 integrator->volume_samples = volume_samples;
320         }
321
322         if(integrator->modified(previntegrator))
323                 integrator->tag_update(scene);
324 }
325
326 /* Film */
327
328 void BlenderSync::sync_film()
329 {
330         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
331
332         Film *film = scene->film;
333         Film prevfilm = *film;
334         
335         film->exposure = get_float(cscene, "film_exposure");
336         film->filter_type = (FilterType)get_enum(cscene,
337                                                  "pixel_filter_type",
338                                                  FILTER_NUM_TYPES,
339                                                  FILTER_BLACKMAN_HARRIS);
340         film->filter_width = (film->filter_type == FILTER_BOX)? 1.0f: get_float(cscene, "filter_width");
341
342         if(b_scene.world()) {
343                 BL::WorldMistSettings b_mist = b_scene.world().mist_settings();
344
345                 film->mist_start = b_mist.start();
346                 film->mist_depth = b_mist.depth();
347
348                 switch(b_mist.falloff()) {
349                         case BL::WorldMistSettings::falloff_QUADRATIC:
350                                 film->mist_falloff = 2.0f;
351                                 break;
352                         case BL::WorldMistSettings::falloff_LINEAR:
353                                 film->mist_falloff = 1.0f;
354                                 break;
355                         case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC:
356                                 film->mist_falloff = 0.5f;
357                                 break;
358                 }
359         }
360
361         if(film->modified(prevfilm))
362                 film->tag_update(scene);
363 }
364
365 /* Render Layer */
366
367 void BlenderSync::sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer)
368 {
369         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
370         string layername;
371
372         /* 3d view */
373         if(b_v3d) {
374                 if(RNA_boolean_get(&cscene, "preview_active_layer")) {
375                         BL::RenderLayers layers(b_scene.render().ptr);
376                         layername = layers.active().name();
377                         layer = layername.c_str();
378                 }
379                 else {
380                         render_layer.use_localview = (b_v3d.local_view() ? true : false);
381                         render_layer.scene_layer = get_layer(b_v3d.layers(), b_v3d.layers_local_view(), render_layer.use_localview);
382                         render_layer.layer = render_layer.scene_layer;
383                         render_layer.exclude_layer = 0;
384                         render_layer.holdout_layer = 0;
385                         render_layer.material_override = PointerRNA_NULL;
386                         render_layer.use_background_shader = true;
387                         render_layer.use_background_ao = true;
388                         render_layer.use_hair = true;
389                         render_layer.use_surfaces = true;
390                         render_layer.use_viewport_visibility = true;
391                         render_layer.samples = 0;
392                         render_layer.bound_samples = false;
393                         return;
394                 }
395         }
396
397         /* render layer */
398         BL::RenderSettings r = b_scene.render();
399         BL::RenderSettings::layers_iterator b_rlay;
400         int use_layer_samples = get_enum(cscene, "use_layer_samples");
401         bool first_layer = true;
402         uint layer_override = get_layer(b_engine.layer_override());
403         uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers());
404
405         for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) {
406                 if((!layer && first_layer) || (layer && b_rlay->name() == layer)) {
407                         render_layer.name = b_rlay->name();
408
409                         render_layer.holdout_layer = get_layer(b_rlay->layers_zmask());
410                         render_layer.exclude_layer = get_layer(b_rlay->layers_exclude());
411
412                         render_layer.scene_layer = scene_layers & ~render_layer.exclude_layer;
413                         render_layer.scene_layer |= render_layer.exclude_layer & render_layer.holdout_layer;
414
415                         render_layer.layer = get_layer(b_rlay->layers());
416                         render_layer.layer |= render_layer.holdout_layer;
417
418                         render_layer.material_override = b_rlay->material_override();
419                         render_layer.use_background_shader = b_rlay->use_sky();
420                         render_layer.use_background_ao = b_rlay->use_ao();
421                         render_layer.use_surfaces = b_rlay->use_solid();
422                         render_layer.use_hair = b_rlay->use_strand();
423                         render_layer.use_viewport_visibility = false;
424                         render_layer.use_localview = false;
425
426                         render_layer.bound_samples = (use_layer_samples == 1);
427                         if(use_layer_samples != 2) {
428                                 int samples = b_rlay->samples();
429                                 if(get_boolean(cscene, "use_square_samples"))
430                                         render_layer.samples = samples * samples;
431                                 else
432                                         render_layer.samples = samples;
433                         }
434                 }
435
436                 first_layer = false;
437         }
438 }
439
440 /* Images */
441 void BlenderSync::sync_images()
442 {
443         /* Sync is a convention for this API, but currently it frees unused buffers. */
444
445         const bool is_interface_locked = b_engine.render() &&
446                                          b_engine.render().use_lock_interface();
447         if(is_interface_locked == false && BlenderSession::headless == false) {
448                 /* If interface is not locked, it's possible image is needed for
449                  * the display.
450                  */
451                 return;
452         }
453         /* Free buffers used by images which are not needed for render. */
454         BL::BlendData::images_iterator b_image;
455         for(b_data.images.begin(b_image);
456             b_image != b_data.images.end();
457             ++b_image)
458         {
459                 /* TODO(sergey): Consider making it an utility function to check
460                  * whether image is considered builtin.
461                  */
462                 const bool is_builtin = b_image->packed_file() ||
463                                         b_image->source() == BL::Image::source_GENERATED ||
464                                         b_image->source() == BL::Image::source_MOVIE ||
465                                         b_engine.is_preview();
466                 if(is_builtin == false) {
467                         b_image->buffers_free();
468                 }
469                 /* TODO(sergey): Free builtin images not used by any shader. */
470         }
471 }
472
473 /* Scene Parameters */
474
475 SceneParams BlenderSync::get_scene_params(BL::Scene& b_scene,
476                                           bool background,
477                                           bool is_cpu)
478 {
479         BL::RenderSettings r = b_scene.render();
480         SceneParams params;
481         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
482         const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
483
484         if(shadingsystem == 0)
485                 params.shadingsystem = SHADINGSYSTEM_SVM;
486         else if(shadingsystem == 1)
487                 params.shadingsystem = SHADINGSYSTEM_OSL;
488         
489         if(background)
490                 params.bvh_type = SceneParams::BVH_STATIC;
491         else
492                 params.bvh_type = (SceneParams::BVHType)get_enum(
493                         cscene,
494                         "debug_bvh_type",
495                         SceneParams::BVH_NUM_TYPES,
496                         SceneParams::BVH_STATIC);
497
498         params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
499
500         if(background && params.shadingsystem != SHADINGSYSTEM_OSL)
501                 params.persistent_data = r.use_persistent_data();
502         else
503                 params.persistent_data = false;
504
505 #if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
506         if(is_cpu) {
507                 params.use_qbvh = DebugFlags().cpu.qbvh && system_cpu_support_sse2();
508         }
509         else
510 #endif
511         {
512                 params.use_qbvh = false;
513         }
514
515         return params;
516 }
517
518 /* Session Parameters */
519
520 bool BlenderSync::get_session_pause(BL::Scene& b_scene, bool background)
521 {
522         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
523         return (background)? false: get_boolean(cscene, "preview_pause");
524 }
525
526 SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
527                                               BL::UserPreferences& b_userpref,
528                                               BL::Scene& b_scene,
529                                               bool background)
530 {
531         SessionParams params;
532         PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
533
534         /* feature set */
535         params.experimental = (get_enum(cscene, "feature_set") != 0);
536
537         /* device type */
538         vector<DeviceInfo>& devices = Device::available_devices();
539         
540         /* device default CPU */
541         params.device = devices[0];
542
543         if(get_enum(cscene, "device") == 2) {
544                 /* find network device */
545                 foreach(DeviceInfo& info, devices)
546                         if(info.type == DEVICE_NETWORK)
547                                 params.device = info;
548         }
549         else if(get_enum(cscene, "device") == 1) {
550                 /* find GPU device with given id */
551                 PointerRNA systemptr = b_userpref.system().ptr;
552                 PropertyRNA *deviceprop = RNA_struct_find_property(&systemptr, "compute_device");
553                 int device_id = b_userpref.system().compute_device();
554
555                 const char *id;
556
557                 if(RNA_property_enum_identifier(NULL, &systemptr, deviceprop, device_id, &id)) {
558                         foreach(DeviceInfo& info, devices)
559                                 if(info.id == id)
560                                         params.device = info;
561                 }
562         }
563
564         /* Background */
565         params.background = background;
566
567         /* samples */
568         int samples = get_int(cscene, "samples");
569         int aa_samples = get_int(cscene, "aa_samples");
570         int preview_samples = get_int(cscene, "preview_samples");
571         int preview_aa_samples = get_int(cscene, "preview_aa_samples");
572         
573         if(get_boolean(cscene, "use_square_samples")) {
574                 aa_samples = aa_samples * aa_samples;
575                 preview_aa_samples = preview_aa_samples * preview_aa_samples;
576
577                 samples = samples * samples;
578                 preview_samples = preview_samples * preview_samples;
579         }
580
581         if(get_enum(cscene, "progressive") == 0) {
582                 if(background) {
583                         params.samples = aa_samples;
584                 }
585                 else {
586                         params.samples = preview_aa_samples;
587                         if(params.samples == 0)
588                                 params.samples = INT_MAX;
589                 }
590         }
591         else {
592                 if(background) {
593                         params.samples = samples;
594                 }
595                 else {
596                         params.samples = preview_samples;
597                         if(params.samples == 0)
598                                 params.samples = INT_MAX;
599                 }
600         }
601
602         /* tiles */
603         if(params.device.type != DEVICE_CPU && !background) {
604                 /* currently GPU could be much slower than CPU when using tiles,
605                  * still need to be investigated, but meanwhile make it possible
606                  * to work in viewport smoothly
607                  */
608                 int debug_tile_size = get_int(cscene, "debug_tile_size");
609
610                 params.tile_size = make_int2(debug_tile_size, debug_tile_size);
611         }
612         else {
613                 int tile_x = b_engine.tile_x();
614                 int tile_y = b_engine.tile_y();
615
616                 params.tile_size = make_int2(tile_x, tile_y);
617         }
618
619         if((BlenderSession::headless == false) && background) {
620                 params.tile_order = (TileOrder)get_enum(cscene, "tile_order");
621         }
622         else {
623                 params.tile_order = TILE_BOTTOM_TO_TOP;
624         }
625
626         params.start_resolution = get_int(cscene, "preview_start_resolution");
627
628         /* other parameters */
629         if(b_scene.render().threads_mode() == BL::RenderSettings::threads_mode_FIXED)
630                 params.threads = b_scene.render().threads();
631         else
632                 params.threads = 0;
633
634         params.cancel_timeout = get_float(cscene, "debug_cancel_timeout");
635         params.reset_timeout = get_float(cscene, "debug_reset_timeout");
636         params.text_timeout = get_float(cscene, "debug_text_timeout");
637
638         params.progressive_refine = get_boolean(cscene, "use_progressive_refine");
639
640         if(background) {
641                 if(params.progressive_refine)
642                         params.progressive = true;
643                 else
644                         params.progressive = false;
645
646                 params.start_resolution = INT_MAX;
647         }
648         else
649                 params.progressive = true;
650
651         /* shading system - scene level needs full refresh */
652         const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
653
654         if(shadingsystem == 0)
655                 params.shadingsystem = SHADINGSYSTEM_SVM;
656         else if(shadingsystem == 1)
657                 params.shadingsystem = SHADINGSYSTEM_OSL;
658         
659         /* color managagement */
660 #ifdef GLEW_MX
661         /* When using GLEW MX we need to check whether we've got an OpenGL
662          * context for current window. This is because command line rendering
663          * doesn't have OpenGL context actually.
664          */
665         if(glewGetContext() != NULL)
666 #endif
667         {
668                 params.display_buffer_linear = GLEW_ARB_half_float_pixel &&
669                                                b_engine.support_display_space_shader(b_scene);
670         }
671
672         if(b_engine.is_preview()) {
673                 /* For preview rendering we're using same timeout as
674                  * blender's job update.
675                  */
676                 params.progressive_update_timeout = 0.1;
677         }
678
679         return params;
680 }
681
682 CCL_NAMESPACE_END
683