Cycles: Adjust resolution divider to achieve a more usable viewport #105581

Merged
Brecht Van Lommel merged 1 commits from Alaska/blender:cycles-adjust-minimum-viewport-resolution into main 2023-03-17 11:16:09 +01:00
2 changed files with 29 additions and 9 deletions

View File

@ -128,9 +128,8 @@ void RenderScheduler::reset(const BufferParams &buffer_params, int num_samples,
state_.resolution_divider = 1;
}
else {
/* NOTE: Divide by 2 because of the way how scheduling works: it advances resolution divider
* first and then initialized render work. */
state_.resolution_divider = start_resolution_divider_ * 2;
state_.user_is_navigating = true;
state_.resolution_divider = start_resolution_divider_;
}
state_.num_rendered_samples = 0;
@ -312,7 +311,21 @@ RenderWork RenderScheduler::get_render_work()
RenderWork render_work;
if (state_.resolution_divider != pixel_size_) {
state_.resolution_divider = max(state_.resolution_divider / 2, pixel_size_);
if (state_.user_is_navigating) {
/* Don't progress the resolution divider as the user is currently navigating in the scene. */
state_.user_is_navigating = false;
}
else {
/* If the resolution divider is greater than or equal to default_start_resolution_divider_,
* drop the resolution divider down to 4. This is so users with slow hardware and thus high
* resolution dividers (E.G. 16), get an update to let them know something is happening
* rather than having to wait for the full 1:1 render to show up. */
state_.resolution_divider = state_.resolution_divider > default_start_resolution_divider_ ?
(4 * pixel_size_) :
1;
}
state_.resolution_divider = max(state_.resolution_divider, pixel_size_);
state_.num_rendered_samples = 0;
state_.last_display_update_sample = -1;
}
@ -1058,10 +1071,16 @@ void RenderScheduler::update_start_resolution_divider()
return;
}
/* Calculate the maximum resolution divider possible while keeping the long axis of the viewport
* above our prefered minimum axis size (128) */
const int long_viewport_axis = max(buffer_params_.width, buffer_params_.height);
const int max_res_divider_for_desired_size = long_viewport_axis / 128;
if (start_resolution_divider_ == 0) {
/* Resolution divider has never been calculated before: use default resolution, so that we have
* somewhat good initial behavior, giving a chance to collect real numbers. */
start_resolution_divider_ = default_start_resolution_divider_;
/* Resolution divider has never been calculated before: start with a high resolution divider so
* that we have a somewhat good initial behavior, giving a chance to collect real numbers. */
start_resolution_divider_ = min(default_start_resolution_divider_,
max_res_divider_for_desired_size);
VLOG_WORK << "Initial resolution divider is " << start_resolution_divider_;
return;
}
@ -1089,8 +1108,7 @@ void RenderScheduler::update_start_resolution_divider()
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
* unreadable viewport render. */
start_resolution_divider_ = min(resolution_divider_for_update,
default_start_resolution_divider_);
start_resolution_divider_ = min(resolution_divider_for_update, max_res_divider_for_desired_size);
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
}

View File

@ -332,6 +332,8 @@ class RenderScheduler {
};
struct {
bool user_is_navigating = false;
int resolution_divider = 1;
/* Number of rendered samples on top of the start sample. */