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
This commit is contained in:
Sergey Sharybin 2021-08-06 16:25:18 +02:00
parent 69c9363e39
commit 4f64fa4f86
Notes: blender-bot 2023-02-14 05:25:44 +01:00
Referenced by commit 52c349cfcd, Fix T90511: Cycles preview does not update once preview is done
Referenced by issue #90511, Preview does not update once preview is done
2 changed files with 32 additions and 10 deletions

View File

@ -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);
pause_cond_.notify_all();
if (samples == params.samples) {
return;
}
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)

View File

@ -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_;