From 4f64fa4f8628aa514ec1f14d798b2f406a3bf6ef Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 6 Aug 2021 16:25:18 +0200 Subject: 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 --- intern/cycles/render/session.cpp | 37 ++++++++++++++++++++++++++++--------- intern/cycles/render/session.h | 3 +++ 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 ¶ms_) 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_; -- cgit v1.2.3