Merging r50522 through r50572 from trunk into soc-2011-tomato
[blender.git] / intern / cycles / render / session.cpp
index 9926e906ddfb91bac870124ec2a548e5a2bfbb5a..05c57ba48ecad8063303a405f91984ecd255170a 100644 (file)
@@ -36,7 +36,7 @@ CCL_NAMESPACE_BEGIN
 
 Session::Session(const SessionParams& params_)
 : params(params_),
-  tile_manager(params.progressive, params.samples, params.tile_size, params.min_size,
+  tile_manager(params.progressive, params.samples, params.tile_size, params.resolution,
        (params.background)? 1: max(params.device.multi_devices.size(), 1))
 {
        device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
@@ -61,7 +61,6 @@ Session::Session(const SessionParams& params_)
        reset_time = 0.0;
        preview_time = 0.0;
        paused_time = 0.0;
-       sample = 0;
 
        delayed_reset.do_reset = false;
        delayed_reset.samples = 0;
@@ -141,6 +140,12 @@ void Session::reset_gpu(BufferParams& buffer_params, int samples)
        pause_cond.notify_all();
 }
 
+bool Session::resetting_gpu() const
+{
+       /* no need to wait for gpu device */
+       return false;
+}
+
 bool Session::draw_gpu(BufferParams& buffer_params)
 {
        /* block for buffer access */
@@ -291,6 +296,11 @@ void Session::reset_cpu(BufferParams& buffer_params, int samples)
        pause_cond.notify_all();
 }
 
+bool Session::resetting_cpu() const
+{
+       return device->task_cancelled();
+}
+
 bool Session::draw_cpu(BufferParams& buffer_params)
 {
        thread_scoped_lock display_lock(display_mutex);
@@ -321,7 +331,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 
        /* get next tile from manager */
        Tile tile;
-       int device_num = device->device_number(tile_device);
+       int device_num = (params.background)? 0: device->device_number(tile_device);
 
        if(!tile_manager.next_tile(tile, device_num))
                return false;
@@ -339,7 +349,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 
        /* in case of a permant buffer, return it, otherwise we will allocate
         * a new temporary buffer */
-       if(!write_render_buffers_cb) {
+       if(!write_render_tile_cb) {
                tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
 
                rtile.buffer = buffers->buffer.device_pointer;
@@ -377,11 +387,10 @@ void Session::update_tile_sample(RenderTile& rtile)
 {
        thread_scoped_lock tile_lock(tile_mutex);
 
-       if(update_render_buffers_cb) {
+       if(update_render_tile_cb) {
                /* todo: optimize this by making it thread safe and removing lock */
 
-               if(!progress.get_cancel())
-                       update_render_buffers_cb(rtile.buffers);
+               update_render_tile_cb(rtile);
        }
 
        update_status_time();
@@ -391,10 +400,10 @@ void Session::release_tile(RenderTile& rtile)
 {
        thread_scoped_lock tile_lock(tile_mutex);
 
-       if(write_render_buffers_cb) {
+       if(write_render_tile_cb) {
                /* todo: optimize this by making it thread safe and removing lock */
-               if(!progress.get_cancel())
-                       write_render_buffers_cb(rtile.buffers);
+               write_render_tile_cb(rtile);
+
                delete rtile.buffers;
        }
 
@@ -534,6 +543,9 @@ void Session::run()
 
        /* run */
        if(!progress.get_cancel()) {
+               /* reset number of rendered samples */
+               progress.reset_sample();
+
                if(device_use_gl)
                        run_gpu();
                else
@@ -570,7 +582,6 @@ void Session::reset_(BufferParams& buffer_params, int samples)
        start_time = time_dt();
        preview_time = 0.0;
        paused_time = 0.0;
-       sample = 0;
 
        if(!params.background)
                progress.set_start_time(start_time + paused_time);
@@ -584,6 +595,14 @@ void Session::reset(BufferParams& buffer_params, int samples)
                reset_cpu(buffer_params, samples);
 }
 
+bool Session::resetting() const
+{
+       if(device_use_gl)
+               return resetting_gpu();
+       else
+               return resetting_cpu();
+}
+
 void Session::set_samples(int samples)
 {
        if(samples != params.samples) {
@@ -649,16 +668,38 @@ void Session::update_scene()
 void Session::update_status_time(bool show_pause, bool show_done)
 {
        int sample = tile_manager.state.sample;
-       int num_samples = tile_manager.state.num_samples;
        int resolution = tile_manager.state.resolution;
        int num_tiles = tile_manager.state.num_tiles;
-       int tile = num_tiles - tile_manager.state.tiles.size();
+       int tile = tile_manager.state.num_rendered_tiles;
 
        /* update status */
        string status, substatus;
 
-       if(!params.progressive)
+       if(!params.progressive) {
                substatus = string_printf("Path Tracing Tile %d/%d", tile, num_tiles);
+
+               if(params.device.type == DEVICE_CUDA || params.device.type == DEVICE_OPENCL ||
+                       (params.device.type == DEVICE_CPU && num_tiles == 1)) {
+                       /* when rendering on GPU multithreading happens within single tile, as in
+                        * tiles are handling sequentially and in this case we could display
+                        * currently rendering sample number
+                        * this helps a lot from feedback point of view.
+                        * also display the info on CPU, when using 1 tile only
+                        */
+
+                       int sample = progress.get_sample(), num_samples = tile_manager.state.num_samples;
+
+                       if(tile > 1) {
+                               /* sample counter is global for all tiles, subtract samples
+                                * from already finished tiles to get sample counter for
+                                * current tile only
+                                */
+                               sample -= (tile - 1) * num_samples;
+                       }
+
+                       substatus += string_printf(", Sample %d/%d", sample, num_samples);
+               }
+       }
        else if(params.samples == INT_MAX)
                substatus = string_printf("Path Tracing Sample %d", sample+1);
        else
@@ -677,12 +718,17 @@ void Session::update_status_time(bool show_pause, bool show_done)
        if(preview_time == 0.0 && resolution == 1)
                preview_time = time_dt();
        
-       double sample_time = (sample == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
+       double tile_time = (tile == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
 
        /* negative can happen when we pause a bit before rendering, can discard that */
        if(preview_time < 0.0) preview_time = 0.0;
 
-       progress.set_sample(sample + num_samples, sample_time);
+       progress.set_tile(tile, tile_time);
+}
+
+void Session::update_progress_sample()
+{
+       progress.increment_sample();
 }
 
 void Session::path_trace()
@@ -694,6 +740,7 @@ void Session::path_trace()
        task.release_tile = function_bind(&Session::release_tile, this, _1);
        task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
        task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1);
+       task.update_progress_sample = function_bind(&Session::update_progress_sample, this);
 
        device->task_add(task);
 }