[Bf-blender-cvs] [105f245d3cc] cycles-x: Fix 100% core usage in viewport in Cycles X

Sergey Sharybin noreply at git.blender.org
Fri Aug 6 12:47:42 CEST 2021


Commit: 105f245d3cc40308b39a7d29351d68f4746d2f65
Author: Sergey Sharybin
Date:   Fri Aug 6 11:15:01 2021 +0200
Branches: cycles-x
https://developer.blender.org/rB105f245d3cc40308b39a7d29351d68f4746d2f65

Fix 100% core usage in viewport in Cycles X

Is a regression since the previous fix for the dead-lock on exit
(was done in the revision 24458a1e7a0).

We need to do `pause_cond_.wait()` when we've run out work to be done.

The new code does check for both states: pause and new work added.

Annoyingly, had to introduce an extra flag which we can check prior
to `wait()`. Without this we have nothing to check whether wait is
needed or not.

The change is against Cycles X, but would also need to be ported
to master.

Differential Revision: https://developer.blender.org/D12148

===================================================================

M	intern/cycles/render/session.cpp
M	intern/cycles/render/session.h

===================================================================

diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index f62e22532c3..69ca4df4d54 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -53,6 +53,8 @@ Session::Session(const SessionParams &params_, const SceneParams &scene_params)
   delayed_reset_.samples = 0;
 
   pause_ = false;
+  cancel_ = false;
+  new_work_added_ = false;
 
   device = Device::create(params.device, stats, profiler);
 
@@ -142,6 +144,7 @@ void Session::cancel(bool quick)
     {
       thread_scoped_lock pause_lock(pause_mutex_);
       pause_ = false;
+      cancel_ = true;
     }
     pause_cond_.notify_all();
 
@@ -327,17 +330,26 @@ bool Session::run_wait_for_work(const RenderWork &render_work)
 
   thread_scoped_lock pause_lock(pause_mutex_);
 
-  const bool no_work = !render_work;
-
-  if (!pause_ && !no_work) {
+  if (!pause_ && render_work) {
+    /* Rendering is not paused and there is work to be done. No need to wait for anything. */
     return false;
   }
 
+  const bool no_work = !render_work;
   update_status_time(pause_, no_work);
 
-  while (pause_) {
+  /* Only leave the loop when rendering is not paused. But even if the current render is un-paused
+   * but there is nothing to render keep waiting until new work is added. */
+  while (!cancel_) {
     scoped_timer pause_timer;
+
+    if (!pause_ && (render_work || new_work_added_ || delayed_reset_.do_reset)) {
+      break;
+    }
+
+    /* Wait for either pause state changed, or extra samples added to render. */
     pause_cond_.wait(pause_lock);
+
     if (pause_) {
       progress.add_skip_time(pause_timer, params.background);
     }
@@ -346,6 +358,8 @@ bool Session::run_wait_for_work(const RenderWork &render_work)
     progress.set_update();
   }
 
+  new_work_added_ = false;
+
   return no_work;
 }
 
@@ -387,35 +401,50 @@ void Session::do_delayed_reset()
 
 void Session::reset(BufferParams &buffer_params, int samples)
 {
+  {
+    thread_scoped_lock reset_lock(delayed_reset_.mutex);
+    thread_scoped_lock pause_lock(pause_mutex_);
 
-  thread_scoped_lock reset_lock(delayed_reset_.mutex);
-  thread_scoped_lock pause_lock(pause_mutex_);
-
-  delayed_reset_.params = buffer_params;
-  delayed_reset_.samples = samples;
-  delayed_reset_.do_reset = true;
+    delayed_reset_.params = buffer_params;
+    delayed_reset_.samples = samples;
+    delayed_reset_.do_reset = true;
 
-  path_trace_->cancel();
+    path_trace_->cancel();
+  }
 
   pause_cond_.notify_all();
 }
 
 void Session::set_samples(int samples)
 {
-  if (samples != params.samples) {
-    params.samples = samples;
+  if (samples == params.samples) {
+    return;
+  }
 
-    pause_cond_.notify_all();
+  params.samples = samples;
+
+  {
+    thread_scoped_lock pause_lock(pause_mutex_);
+    new_work_added_ = true;
   }
+
+  pause_cond_.notify_all();
 }
 
 void Session::set_time_limit(double time_limit)
 {
-  if (time_limit != params.time_limit) {
-    params.time_limit = time_limit;
+  if (time_limit == params.time_limit) {
+    return;
+  }
 
-    pause_cond_.notify_all();
+  params.time_limit = time_limit;
+
+  {
+    thread_scoped_lock pause_lock(pause_mutex_);
+    new_work_added_ = true;
   }
+
+  pause_cond_.notify_all();
 }
 
 void Session::set_pause(bool pause)
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 3514f2026fd..bd7e5058fee 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -195,7 +195,10 @@ class Session {
 
   thread *session_thread_;
 
-  bool pause_;
+  bool pause_ = false;
+  bool cancel_ = false;
+  bool new_work_added_ = false;
+
   thread_condition_variable pause_cond_;
   thread_mutex pause_mutex_;
   thread_mutex tile_mutex_;



More information about the Bf-blender-cvs mailing list