Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/object.cpp')
-rw-r--r--intern/cycles/render/object.cpp82
1 files changed, 14 insertions, 68 deletions
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 61deef4cd76..c45ae5553a8 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -31,6 +31,7 @@
#include "util/util_murmurhash.h"
#include "util/util_progress.h"
#include "util/util_set.h"
+#include "util/util_task.h"
#include "util/util_vector.h"
#include "subd/subd_patch_table.h"
@@ -77,7 +78,6 @@ struct UpdateObjectTransformState {
Scene *scene;
/* Some locks to keep everything thread-safe. */
- thread_spin_lock queue_lock;
thread_spin_lock surface_area_lock;
/* First unused object index in the queue. */
@@ -219,7 +219,6 @@ void Object::tag_update(Scene *scene)
}
scene->camera->need_flags_update = true;
- scene->curve_system_manager->need_update = true;
scene->geometry_manager->need_update = true;
scene->object_manager->need_update = true;
}
@@ -550,41 +549,6 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
}
}
-bool ObjectManager::device_update_object_transform_pop_work(UpdateObjectTransformState *state,
- int *start_index,
- int *num_objects)
-{
- /* Tweakable parameter, number of objects per chunk.
- * Too small value will cause some extra overhead due to spin lock,
- * too big value might not use all threads nicely.
- */
- static const int OBJECTS_PER_TASK = 32;
- bool have_work = false;
- state->queue_lock.lock();
- int num_scene_objects = state->scene->objects.size();
- if (state->queue_start_object < num_scene_objects) {
- int count = min(OBJECTS_PER_TASK, num_scene_objects - state->queue_start_object);
- *start_index = state->queue_start_object;
- *num_objects = count;
- state->queue_start_object += count;
- have_work = true;
- }
- state->queue_lock.unlock();
- return have_work;
-}
-
-void ObjectManager::device_update_object_transform_task(UpdateObjectTransformState *state)
-{
- int start_index, num_objects;
- while (device_update_object_transform_pop_work(state, &start_index, &num_objects)) {
- for (int i = 0; i < num_objects; ++i) {
- const int object_index = start_index + i;
- Object *ob = state->scene->objects[object_index];
- device_update_object_transform(state, ob);
- }
- }
-}
-
void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
{
UpdateObjectTransformState state;
@@ -630,28 +594,19 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
numparticles += psys->particles.size();
}
- /* NOTE: If it's just a handful of objects we deal with them in a single
- * thread to avoid threading overhead. However, this threshold is might
- * need some tweaks to make mid-complex scenes optimal.
- */
- if (scene->objects.size() < 64) {
- foreach (Object *ob, scene->objects) {
- device_update_object_transform(&state, ob);
- if (progress.get_cancel()) {
- return;
- }
- }
- }
- else {
- const int num_threads = TaskScheduler::num_threads();
- TaskPool pool;
- for (int i = 0; i < num_threads; ++i) {
- pool.push(function_bind(&ObjectManager::device_update_object_transform_task, this, &state));
- }
- pool.wait_work();
- if (progress.get_cancel()) {
- return;
- }
+ /* Parallel object update, with grain size to avoid too much threading overhead
+ * for individual objects. */
+ static const int OBJECTS_PER_TASK = 32;
+ parallel_for(blocked_range<size_t>(0, scene->objects.size(), OBJECTS_PER_TASK),
+ [&](const blocked_range<size_t> &r) {
+ for (size_t i = r.begin(); i != r.end(); i++) {
+ Object *ob = state.scene->objects[i];
+ device_update_object_transform(&state, ob);
+ }
+ });
+
+ if (progress.get_cancel()) {
+ return;
}
dscene->objects.copy_to_device();
@@ -664,7 +619,6 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
dscene->data.bvh.have_motion = state.have_motion;
dscene->data.bvh.have_curves = state.have_curves;
- dscene->data.bvh.have_instancing = true;
}
void ObjectManager::device_update(Device *device,
@@ -839,7 +793,6 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
bool motion_blur = need_motion == Scene::MOTION_BLUR;
bool apply_to_motion = need_motion != Scene::MOTION_PASS;
int i = 0;
- bool have_instancing = false;
foreach (Object *object, scene->objects) {
map<Geometry *, int>::iterator it = geometry_users.find(object->geometry);
@@ -885,22 +838,15 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
if (geom->transform_negative_scaled)
object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED;
}
- else
- have_instancing = true;
}
- else
- have_instancing = true;
i++;
}
-
- dscene->data.bvh.have_instancing = have_instancing;
}
void ObjectManager::tag_update(Scene *scene)
{
need_update = true;
- scene->curve_system_manager->need_update = true;
scene->geometry_manager->need_update = true;
scene->light_manager->need_update = true;
}