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:
authorSergey Sharybin <sergey@blender.org>2021-08-06 17:25:18 +0300
committerSergey Sharybin <sergey@blender.org>2021-08-06 17:26:51 +0300
commit4f64fa4f8628aa514ec1f14d798b2f406a3bf6ef (patch)
treeae017fd594feb33454ff7b2e53dbe8b26b30a31c
parent69c9363e39957a47f7d18e8a24d048cbb99df3b5 (diff)
Cycles: Fix for possible viewport dead-lock
This is a backport of recent development in the Cycles X branch. Fixes possible dead-lock in viewport rendering when exiting at an exact bad moment (couldn't reproduce in master branch, but in the cycles-x branch it was happening every now and then). Differential Revision: https://developer.blender.org/D12154
-rw-r--r--intern/cycles/render/session.cpp37
-rw-r--r--intern/cycles/render/session.h3
2 files changed, 31 insertions, 9 deletions
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 6b50522b660..1a08d8f52d6 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -73,7 +73,10 @@ Session::Session(const SessionParams &params_)
display_outdated_ = false;
gpu_draw_ready_ = false;
gpu_need_display_buffer_update_ = false;
+
pause_ = false;
+ cancel_ = false;
+ new_work_added_ = false;
buffers = NULL;
display = NULL;
@@ -144,6 +147,7 @@ void Session::cancel()
{
thread_scoped_lock pause_lock(pause_mutex_);
pause_ = false;
+ cancel_ = true;
}
pause_cond_.notify_all();
@@ -832,26 +836,34 @@ bool Session::run_wait_for_work(bool no_tiles)
thread_scoped_lock pause_lock(pause_mutex_);
if (!pause_ && !no_tiles) {
+ /* Rendering is not paused and there is work to be done. No need to wait for anything. */
return false;
}
update_status_time(pause_, no_tiles);
- while (true) {
+ /* 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_ && (!no_tiles || 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);
}
update_status_time(pause_, no_tiles);
progress.set_update();
-
- if (!pause_) {
- break;
- }
}
+ new_work_added_ = false;
+
return no_tiles;
}
@@ -896,12 +908,19 @@ void Session::reset(BufferParams &buffer_params, int samples)
void Session::set_samples(int samples)
{
- if (samples != params.samples) {
- params.samples = samples;
- tile_manager.set_samples(samples);
+ if (samples == params.samples) {
+ return;
+ }
- pause_cond_.notify_all();
+ params.samples = samples;
+ tile_manager.set_samples(samples);
+
+ {
+ 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 fe043994197..05025c10f9c 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -218,6 +218,9 @@ class Session {
thread_condition_variable gpu_need_display_buffer_update_cond_;
bool pause_;
+ bool cancel_;
+ bool new_work_added_;
+
thread_condition_variable pause_cond_;
thread_mutex pause_mutex_;
thread_mutex tile_mutex_;