Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/integrator/render_scheduler.cpp
| Show All 10 Lines | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | * distributed under the License is distributed on an "AS IS" BASIS, | ||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| * See the License for the specific language governing permissions and | * See the License for the specific language governing permissions and | ||||
| * limitations under the License. | * limitations under the License. | ||||
| */ | */ | ||||
| #include "integrator/render_scheduler.h" | #include "integrator/render_scheduler.h" | ||||
| #include "render/session.h" | |||||
| #include "render/tile.h" | |||||
| #include "util/util_logging.h" | #include "util/util_logging.h" | ||||
| #include "util/util_math.h" | #include "util/util_math.h" | ||||
| #include "util/util_time.h" | #include "util/util_time.h" | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| /* -------------------------------------------------------------------- | /* -------------------------------------------------------------------- | ||||
| * Render scheduler. | * Render scheduler. | ||||
| */ | */ | ||||
| RenderScheduler::RenderScheduler(bool headless, bool background, int pixel_size) | RenderScheduler::RenderScheduler(TileManager &tile_manager, const SessionParams ¶ms) | ||||
| : headless_(headless), | : headless_(params.headless), | ||||
| background_(background), | background_(params.background), | ||||
| pixel_size_(pixel_size), | pixel_size_(params.pixel_size), | ||||
| default_start_resolution_divider_(pixel_size * 8) | tile_manager_(tile_manager), | ||||
| default_start_resolution_divider_(pixel_size_ * 8) | |||||
| { | { | ||||
| use_progressive_noise_floor_ = !background_; | use_progressive_noise_floor_ = !background_; | ||||
| } | } | ||||
| void RenderScheduler::set_need_schedule_cryptomatte(bool need_schedule_cryptomatte) | void RenderScheduler::set_need_schedule_cryptomatte(bool need_schedule_cryptomatte) | ||||
| { | { | ||||
| need_schedule_cryptomatte_ = need_schedule_cryptomatte; | need_schedule_cryptomatte_ = need_schedule_cryptomatte; | ||||
| } | } | ||||
| Show All 13 Lines | void RenderScheduler::set_denoiser_params(const DenoiseParams ¶ms) | ||||
| denoiser_params_ = params; | denoiser_params_ = params; | ||||
| } | } | ||||
| void RenderScheduler::set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling) | void RenderScheduler::set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling) | ||||
| { | { | ||||
| adaptive_sampling_ = adaptive_sampling; | adaptive_sampling_ = adaptive_sampling; | ||||
| } | } | ||||
| bool RenderScheduler::is_adaptive_sampling_used() const | |||||
| { | |||||
| return adaptive_sampling_.use; | |||||
| } | |||||
| void RenderScheduler::set_start_sample(int start_sample) | void RenderScheduler::set_start_sample(int start_sample) | ||||
| { | { | ||||
| start_sample_ = start_sample; | start_sample_ = start_sample; | ||||
| } | } | ||||
| int RenderScheduler::get_start_sample() const | int RenderScheduler::get_start_sample() const | ||||
| { | { | ||||
| return start_sample_; | return start_sample_; | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | void RenderScheduler::reset(const BufferParams &buffer_params, int num_samples) | ||||
| state_.num_rebalance_changes = 0; | state_.num_rebalance_changes = 0; | ||||
| state_.last_rebalance_changed = false; | state_.last_rebalance_changed = false; | ||||
| state_.need_rebalance_at_next_work = false; | state_.need_rebalance_at_next_work = false; | ||||
| /* TODO(sergey): Choose better initial value. */ | /* TODO(sergey): Choose better initial value. */ | ||||
| /* NOTE: The adaptive sampling settings might not be available here yet. */ | /* NOTE: The adaptive sampling settings might not be available here yet. */ | ||||
| state_.adaptive_sampling_threshold = 0.4f; | state_.adaptive_sampling_threshold = 0.4f; | ||||
| state_.last_work_was_denoised = false; | state_.last_work_tile_was_denoised = false; | ||||
| state_.final_result_was_written = false; | state_.tile_result_was_written = false; | ||||
| state_.postprocess_work_scheduled = false; | state_.postprocess_work_scheduled = false; | ||||
| state_.full_frame_work_scheduled = false; | |||||
| state_.path_trace_finished = false; | state_.path_trace_finished = false; | ||||
| state_.start_render_time = 0.0; | state_.start_render_time = 0.0; | ||||
| state_.end_render_time = 0.0; | state_.end_render_time = 0.0; | ||||
| state_.time_limit_reached = false; | state_.time_limit_reached = false; | ||||
| first_render_time_.path_trace_per_sample = 0.0; | first_render_time_.path_trace_per_sample = 0.0; | ||||
| Show All 22 Lines | bool RenderScheduler::render_work_reschedule_on_converge(RenderWork &render_work) | ||||
| if (render_work_reschedule_on_idle(render_work)) { | if (render_work_reschedule_on_idle(render_work)) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| state_.path_trace_finished = true; | state_.path_trace_finished = true; | ||||
| bool denoiser_delayed; | bool denoiser_delayed; | ||||
| render_work.denoise = work_need_denoise(denoiser_delayed); | render_work.tile.denoise = work_need_denoise(denoiser_delayed); | ||||
| render_work.update_display = work_need_update_display(denoiser_delayed); | render_work.update_display = work_need_update_display(denoiser_delayed); | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool RenderScheduler::render_work_reschedule_on_idle(RenderWork &render_work) | bool RenderScheduler::render_work_reschedule_on_idle(RenderWork &render_work) | ||||
| { | { | ||||
| Show All 19 Lines | if (adaptive_sampling_.use) { | ||||
| } | } | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| void RenderScheduler::render_work_reschedule_on_cancel(RenderWork &render_work) | void RenderScheduler::render_work_reschedule_on_cancel(RenderWork &render_work) | ||||
| { | { | ||||
| VLOG(3) << "Schedule work for cancel."; | |||||
| /* Un-schedule samples: they will not be rendered and should not be counted. */ | /* Un-schedule samples: they will not be rendered and should not be counted. */ | ||||
| state_.num_rendered_samples -= render_work.path_trace.num_samples; | state_.num_rendered_samples -= render_work.path_trace.num_samples; | ||||
| render_work = RenderWork(); | render_work = RenderWork(); | ||||
| if (!state_.final_result_was_written) { | /* Do not write tile if it has zero samples it it, treat it similarly to all other tiles which | ||||
| render_work.write_final_result = true; | * got cancelled. */ | ||||
| if (!state_.tile_result_was_written && get_num_rendered_samples() != 0) { | |||||
| render_work.tile.write = true; | |||||
| render_work.update_display = true; | render_work.update_display = true; | ||||
| } | } | ||||
| render_work.full.write = true; | |||||
| } | } | ||||
| bool RenderScheduler::done() const | bool RenderScheduler::done() const | ||||
| { | { | ||||
| if (state_.resolution_divider != pixel_size_) { | if (state_.resolution_divider != pixel_size_) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (state_.path_trace_finished || state_.time_limit_reached) { | if (state_.path_trace_finished || state_.time_limit_reached) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| return get_num_rendered_samples() >= num_samples_; | return get_num_rendered_samples() >= num_samples_; | ||||
| } | } | ||||
| RenderWork RenderScheduler::get_render_work() | RenderWork RenderScheduler::get_render_work() | ||||
| { | { | ||||
| check_time_limit_reached(); | check_time_limit_reached(); | ||||
| const double time_now = time_dt(); | const double time_now = time_dt(); | ||||
| if (done()) { | if (done()) { | ||||
| RenderWork render_work; | RenderWork render_work; | ||||
| if (!set_postprocess_render_work(&render_work)) { | if (!set_postprocess_render_work(&render_work)) { | ||||
| if (state_.end_render_time == 0.0) { | set_full_frame_render_work(&render_work); | ||||
| state_.end_render_time = time_now; | |||||
| } | } | ||||
| if (!render_work) { | |||||
| state_.end_render_time = time_now; | |||||
| } | } | ||||
| return render_work; | return render_work; | ||||
| } | } | ||||
| RenderWork render_work; | RenderWork render_work; | ||||
| if (state_.resolution_divider != pixel_size_) { | if (state_.resolution_divider != pixel_size_) { | ||||
| state_.resolution_divider = max(state_.resolution_divider / 2, pixel_size_); | state_.resolution_divider = max(state_.resolution_divider / 2, pixel_size_); | ||||
| state_.num_rendered_samples = 0; | state_.num_rendered_samples = 0; | ||||
| Show All 18 Lines | RenderWork RenderScheduler::get_render_work() | ||||
| * samples are rendered. */ | * samples are rendered. */ | ||||
| state_.num_rendered_samples += render_work.path_trace.num_samples; | state_.num_rendered_samples += render_work.path_trace.num_samples; | ||||
| render_work.adaptive_sampling.filter = work_need_adaptive_filter(); | render_work.adaptive_sampling.filter = work_need_adaptive_filter(); | ||||
| render_work.adaptive_sampling.threshold = work_adaptive_threshold(); | render_work.adaptive_sampling.threshold = work_adaptive_threshold(); | ||||
| render_work.adaptive_sampling.reset = false; | render_work.adaptive_sampling.reset = false; | ||||
| bool denoiser_delayed; | bool denoiser_delayed; | ||||
| render_work.denoise = work_need_denoise(denoiser_delayed); | render_work.tile.denoise = work_need_denoise(denoiser_delayed); | ||||
| state_.last_work_was_denoised = render_work.denoise; | state_.last_work_tile_was_denoised = render_work.tile.denoise; | ||||
| render_work.write_final_result = done(); | render_work.tile.write = done(); | ||||
| state_.final_result_was_written = render_work.write_final_result; | state_.tile_result_was_written = render_work.tile.write; | ||||
| render_work.update_display = work_need_update_display(denoiser_delayed); | render_work.update_display = work_need_update_display(denoiser_delayed); | ||||
| /* A fallback display update time, for the case there is an error of display update, or when | /* A fallback display update time, for the case there is an error of display update, or when | ||||
| * there is no display at all. */ | * there is no display at all. */ | ||||
| if (render_work.update_display) { | if (render_work.update_display) { | ||||
| state_.last_display_update_time = time_now; | state_.last_display_update_time = time_now; | ||||
| state_.last_display_update_sample = state_.num_rendered_samples; | state_.last_display_update_sample = state_.num_rendered_samples; | ||||
| Show All 15 Lines | bool RenderScheduler::set_postprocess_render_work(RenderWork *render_work) | ||||
| bool any_scheduled = false; | bool any_scheduled = false; | ||||
| if (need_schedule_cryptomatte_) { | if (need_schedule_cryptomatte_) { | ||||
| render_work->cryptomatte.postprocess = true; | render_work->cryptomatte.postprocess = true; | ||||
| any_scheduled = true; | any_scheduled = true; | ||||
| } | } | ||||
| if (denoiser_params_.use && !state_.last_work_was_denoised) { | if (denoiser_params_.use && !state_.last_work_tile_was_denoised) { | ||||
| render_work->denoise = true; | render_work->tile.denoise = true; | ||||
| any_scheduled = true; | any_scheduled = true; | ||||
| } | } | ||||
| if (!state_.final_result_was_written) { | if (!state_.tile_result_was_written) { | ||||
| render_work->write_final_result = true; | render_work->tile.write = true; | ||||
| any_scheduled = true; | any_scheduled = true; | ||||
| } | } | ||||
| if (any_scheduled) { | if (any_scheduled) { | ||||
| render_work->update_display = true; | render_work->update_display = true; | ||||
| } | } | ||||
| return any_scheduled; | return any_scheduled; | ||||
| } | } | ||||
| void RenderScheduler::set_full_frame_render_work(RenderWork *render_work) | |||||
| { | |||||
| if (state_.full_frame_work_scheduled) { | |||||
| return; | |||||
| } | |||||
| if (!tile_manager_.has_multiple_tiles()) { | |||||
| /* There is only single tile, so all work has been performed already. */ | |||||
| return; | |||||
| } | |||||
| if (!tile_manager_.done()) { | |||||
| /* There are still tiles to be rendered. */ | |||||
| return; | |||||
| } | |||||
| state_.full_frame_work_scheduled = true; | |||||
| render_work->full.write = true; | |||||
| if (denoiser_params_.use) { | |||||
| render_work->full.denoise = true; | |||||
| } | |||||
| } | |||||
| /* Knowing time which it took to complete a task at the current resolution divider approximate how | /* Knowing time which it took to complete a task at the current resolution divider approximate how | ||||
| * long it would have taken to complete it at a final resolution. */ | * long it would have taken to complete it at a final resolution. */ | ||||
| static double approximate_final_time(const RenderWork &render_work, double time) | static double approximate_final_time(const RenderWork &render_work, double time) | ||||
| { | { | ||||
| if (render_work.resolution_divider == 1) { | if (render_work.resolution_divider == 1) { | ||||
| return time; | return time; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 720 Lines • Show Last 20 Lines | |||||