Cycles: preview passes setting to set the max number of passes to render in

the viewport working now, set to 0 for unlimited (well, actually 2147483647).
This commit is contained in:
Brecht Van Lommel 2011-08-29 10:21:10 +00:00
parent bae896691a
commit 47fb31404f
4 changed files with 145 additions and 51 deletions

@ -43,16 +43,15 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, bpy.types.Panel):
split = layout.split()
col = split.column()
col.prop(cscene, "passes", text="Render Passes")
#sub = col.row()
#sub.active = cscene.preview_passes >= 1
#sub.prop(cscene, "preview_passes")
sub = col.column(align=True)
sub.prop(cscene, "passes", text="Render Passes")
sub.prop(cscene, "preview_passes")
col.prop(cscene, "no_caustics")
col = split.column()
col = col.column(align=True)
col.prop(cscene, "max_bounces")
col.prop(cscene, "min_bounces")
sub = col.column(align=True)
sub.prop(cscene, "max_bounces")
sub.prop(cscene, "min_bounces")
#row = col.row()
#row.prop(cscene, "blur_caustics")
@ -74,9 +73,10 @@ class CyclesRender_PT_film(CyclesButtonsPanel, bpy.types.Panel):
col.prop(cscene, "transparent")
col = split.column()
col.prop(cscene, "filter_type", text="")
sub = col.column(align=True)
sub.prop(cscene, "filter_type", text="")
if cscene.filter_type != 'BOX':
col.prop(cscene, "filter_width", text="Width")
sub.prop(cscene, "filter_width", text="Width")
class CyclesRender_PT_performance(CyclesButtonsPanel, bpy.types.Panel):
bl_label = "Performance"

@ -0,0 +1,28 @@
/*
* Copyright 2011, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "stdosl.h"
shader node_background(
color Color = color(0.8, 0.8, 0.8),
float Strength = 1.0,
output closure color Background = background())
{
Background = Color*Strength*background();
}

@ -57,6 +57,7 @@ Session::Session(const SessionParams& params_)
display_outdated = false;
gpu_draw_ready = false;
gpu_need_tonemap = false;
pause = false;
}
Session::~Session()
@ -65,6 +66,7 @@ Session::~Session()
progress.set_cancel("Exiting");
gpu_need_tonemap = false;
gpu_need_tonemap_cond.notify_all();
set_pause(false);
wait();
}
@ -111,6 +113,8 @@ void Session::reset_gpu(int w, int h, int passes)
gpu_need_tonemap = false;
gpu_need_tonemap_cond.notify_all();
pause_cond.notify_all();
}
bool Session::draw_gpu(int w, int h)
@ -150,52 +154,72 @@ void Session::run_gpu()
reset_time = time_dt();
while(!progress.get_cancel()) {
/* advance to next tile */
bool done = !tile_manager.next();
if(done && params.background)
break;
/* any work left? */
if(done) {
/* if in background mode, we can stop immediately */
if(params.background) {
break;
}
else {
/* in interactive mode, we wait until woken up */
thread_scoped_lock pause_lock(pause_mutex);
pause_cond.wait(pause_lock);
}
}
else {
/* test for pause and wait until woken up */
thread_scoped_lock pause_lock(pause_mutex);
while(pause)
pause_cond.wait(pause_lock);
}
/* todo: wait when done in interactive mode */
{
/* buffers mutex is locked entirely while rendering each
pass, and released/reacquired on each iteration to allow
reset and draw in between */
thread_scoped_lock buffers_lock(buffers->mutex);
/* buffers mutex is locked entirely while rendering each
pass, and released/reacquired on each iteration to allow
reset and draw in between */
thread_scoped_lock buffers_lock(buffers->mutex);
/* update scene */
update_scene();
if(progress.get_cancel())
break;
/* update scene */
update_scene();
if(progress.get_cancel())
break;
/* update status and timing */
update_status_time();
/* update status and timing */
update_status_time();
/* path trace */
foreach(Tile& tile, tile_manager.state.tiles) {
path_trace(tile);
/* path trace */
foreach(Tile& tile, tile_manager.state.tiles) {
path_trace(tile);
device->task_wait();
device->task_wait();
if(progress.get_cancel())
break;
}
/* update status and timing */
update_status_time();
gpu_need_tonemap = true;
gpu_draw_ready = true;
progress.set_update();
/* wait for tonemap */
if(!params.background) {
while(gpu_need_tonemap) {
if(progress.get_cancel())
break;
gpu_need_tonemap_cond.wait(buffers_lock);
}
}
if(progress.get_cancel())
break;
}
gpu_need_tonemap = true;
gpu_draw_ready = true;
progress.set_update();
/* wait for tonemap */
if(!params.background) {
while(gpu_need_tonemap) {
if(progress.get_cancel())
break;
gpu_need_tonemap_cond.wait(buffers_lock);
}
}
if(progress.get_cancel())
break;
}
}
@ -213,6 +237,8 @@ void Session::reset_cpu(int w, int h, int passes)
delayed_reset.passes = passes;
delayed_reset.do_reset = true;
device->task_cancel();
pause_cond.notify_all();
}
bool Session::draw_cpu(int w, int h)
@ -249,14 +275,33 @@ void Session::run_cpu()
}
while(!progress.get_cancel()) {
/* advance to next tile */
bool done = !tile_manager.next();
bool need_tonemap = false;
if(done && params.background)
break;
/* any work left? */
if(done) {
/* if in background mode, we can stop immediately */
if(params.background) {
break;
}
else {
/* in interactive mode, we wait until woken up */
thread_scoped_lock pause_lock(pause_mutex);
pause_cond.wait(pause_lock);
}
}
else {
/* test for pause and wait until woken up */
thread_scoped_lock pause_lock(pause_mutex);
while(pause)
pause_cond.wait(pause_lock);
}
/* todo: wait when done in interactive mode */
{
if(!done) {
/* buffers mutex is locked entirely while rendering each
pass, and released/reacquired on each iteration to allow
reset and draw in between */
thread_scoped_lock buffers_lock(buffers->mutex);
/* update scene */
@ -267,9 +312,14 @@ void Session::run_cpu()
/* update status and timing */
update_status_time();
/* path trace all tiles */
/* path trace */
foreach(Tile& tile, tile_manager.state.tiles)
path_trace(tile);
/* update status and timing */
update_status_time();
need_tonemap = true;
}
device->task_wait();
@ -284,7 +334,7 @@ void Session::run_cpu()
delayed_reset.do_reset = false;
reset_(delayed_reset.w, delayed_reset.h, delayed_reset.passes);
}
else {
else if(need_tonemap) {
/* tonemap only if we do not reset, we don't we don't
want to show the result of an incomplete pass*/
tonemap();
@ -357,10 +407,21 @@ void Session::set_passes(int passes)
if(passes != params.passes) {
params.passes = passes;
tile_manager.set_passes(passes);
/* todo: awake in paused loop */
pause_cond.notify_all();
}
}
void Session::set_pause(bool pause_)
{
{
thread_scoped_lock pause_lock(pause_mutex);
pause = pause_;
}
pause_cond.notify_all();
}
void Session::wait()
{
session_thread->join();

@ -109,6 +109,7 @@ public:
bool ready_to_reset();
void reset(int w, int h, int passes);
void set_passes(int passes);
void set_pause(bool pause);
protected:
struct DelayedReset {
@ -146,6 +147,10 @@ protected:
volatile bool gpu_need_tonemap;
thread_condition_variable gpu_need_tonemap_cond;
bool pause;
thread_condition_variable pause_cond;
thread_mutex pause_mutex;
double start_time;
double reset_time;
double preview_time;