Cycles Hair: Strand Minimum Pixel Size
[blender.git] / intern / cycles / render / session.cpp
index 7f6b43c1e002f80d6bd02518ccd3b4c2c48e04fa..569c29e0b094e7ef08eba7f005acb4829f6d3668 100644 (file)
@@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN
 Session::Session(const SessionParams& params_)
 : params(params_),
   tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
-       params.background == false || params.progressive_refine, params.background,
+       params.background == false || params.progressive_refine, params.background, params.tile_order,
        max(params.device.multi_devices.size(), 1)),
   stats()
 {
@@ -132,6 +132,8 @@ bool Session::ready_to_reset()
 
 void Session::reset_gpu(BufferParams& buffer_params, int samples)
 {
+       thread_scoped_lock pause_lock(pause_mutex);
+
        /* block for buffer acces and reset immediately. we can't do this
         * in the thread, because we need to allocate an OpenGL buffer, and
         * that only works in the main thread */
@@ -208,7 +210,12 @@ void Session::run_gpu()
                         * wait for pause condition notify to wake up again */
                        thread_scoped_lock pause_lock(pause_mutex);
 
-                       if(pause || no_tiles) {
+                       if(!pause && !tile_manager.done()) {
+                               /* reset could have happened after no_tiles was set, before this lock.
+                                * in this case we shall not wait for pause condition
+                                */
+                       }
+                       else if(pause || no_tiles) {
                                update_status_time(pause, no_tiles);
 
                                while(1) {
@@ -295,6 +302,7 @@ void Session::run_gpu()
 void Session::reset_cpu(BufferParams& buffer_params, int samples)
 {
        thread_scoped_lock reset_lock(delayed_reset.mutex);
+       thread_scoped_lock pause_lock(pause_mutex);
 
        display_outdated = true;
        reset_time = time_dt();
@@ -357,7 +365,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 
        tile_lock.unlock();
 
-       /* in case of a permant buffer, return it, otherwise we will allocate
+       /* in case of a permanent buffer, return it, otherwise we will allocate
         * a new temporary buffer */
        if(!params.background) {
                tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
@@ -381,7 +389,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 
        buffer_params.get_offset_stride(rtile.offset, rtile.stride);
 
-       RenderBuffers *tilebuffers = new RenderBuffers(tile_device);
+       RenderBuffers *tilebuffers;
 
        /* allocate buffers */
        if(params.progressive_refine) {
@@ -411,6 +419,12 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
        rtile.rgba = 0;
        rtile.buffers = tilebuffers;
 
+       /* this will tag tile as IN PROGRESS in blender-side render pipeline,
+        * which is needed to highlight currently rendering tile before first
+        * sample was processed for it
+        */
+       update_tile_sample(rtile);
+
        return true;
 }
 
@@ -478,7 +492,16 @@ void Session::run_cpu()
                         * wait for pause condition notify to wake up again */
                        thread_scoped_lock pause_lock(pause_mutex);
 
-                       if(pause || no_tiles) {
+                       if(!pause && delayed_reset.do_reset) {
+                               /* reset once to start */
+                               thread_scoped_lock reset_lock(delayed_reset.mutex);
+                               thread_scoped_lock buffers_lock(buffers_mutex);
+                               thread_scoped_lock display_lock(display_mutex);
+
+                               reset_(delayed_reset.params, delayed_reset.samples);
+                               delayed_reset.do_reset = false;
+                       }
+                       else if(pause || no_tiles) {
                                update_status_time(pause, no_tiles);
 
                                while(1) {
@@ -546,7 +569,7 @@ void Session::run_cpu()
                        }
                        else if(need_tonemap) {
                                /* tonemap only if we do not reset, we don't we don't
-                                * wan't to show the result of an incomplete sample*/
+                                * want to show the result of an incomplete sample*/
                                tonemap();
                        }
 
@@ -637,6 +660,15 @@ void Session::reset(BufferParams& buffer_params, int samples)
                reset_gpu(buffer_params, samples);
        else
                reset_cpu(buffer_params, samples);
+
+       if(params.progressive_refine) {
+               thread_scoped_lock buffers_lock(buffers_mutex);
+
+               foreach(RenderBuffers *buffers, tile_buffers)
+                       delete buffers;
+
+               tile_buffers.clear();
+       }
 }
 
 void Session::set_samples(int samples)
@@ -687,10 +719,12 @@ void Session::update_scene()
        Camera *cam = scene->camera;
        int width = tile_manager.state.buffer.full_width;
        int height = tile_manager.state.buffer.full_height;
+       int resolution = tile_manager.state.resolution_divider;
 
        if(width != cam->width || height != cam->height) {
                cam->width = width;
                cam->height = height;
+               cam->resolution = resolution;
                cam->tag_update();
        }
 
@@ -726,7 +760,7 @@ void Session::update_status_time(bool show_pause, bool show_done)
                         * also display the info on CPU, when using 1 tile only
                         */
 
-                       int sample = progress.get_sample(), num_samples = tile_manager.state.num_samples;
+                       int sample = progress.get_sample(), num_samples = tile_manager.num_samples;
 
                        if(tile > 1) {
                                /* sample counter is global for all tiles, subtract samples
@@ -739,10 +773,10 @@ void Session::update_status_time(bool show_pause, bool show_done)
                        substatus += string_printf(", Sample %d/%d", sample, num_samples);
                }
        }
-       else if(params.samples == INT_MAX)
+       else if(tile_manager.num_samples == INT_MAX)
                substatus = string_printf("Path Tracing Sample %d", sample+1);
        else
-               substatus = string_printf("Path Tracing Sample %d/%d", sample+1, params.samples);
+               substatus = string_printf("Path Tracing Sample %d/%d", sample+1, tile_manager.num_samples);
        
        if(show_pause)
                status = "Paused";
@@ -757,7 +791,7 @@ void Session::update_status_time(bool show_pause, bool show_done)
        if(preview_time == 0.0 && resolution == 1)
                preview_time = time_dt();
        
-       double tile_time = (tile == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
+       double tile_time = (tile == 0 || sample == 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;
@@ -814,7 +848,7 @@ void Session::tonemap()
 bool Session::update_progressive_refine(bool cancel)
 {
        int sample = tile_manager.state.sample + 1;
-       bool write = sample == params.samples || cancel;
+       bool write = sample == tile_manager.num_samples || cancel;
 
        double current_time = time_dt();
 
@@ -842,4 +876,18 @@ bool Session::update_progressive_refine(bool cancel)
        return write;
 }
 
+void Session::device_free()
+{
+       scene->device_free();
+
+       foreach(RenderBuffers *buffers, tile_buffers)
+               delete buffers;
+
+       tile_buffers.clear();
+
+       /* used from background render only, so no need to
+        * re-create render/display buffers here
+        */
+}
+
 CCL_NAMESPACE_END