Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/render/session.cpp
| Show First 20 Lines • Show All 221 Lines • ▼ Show 20 Lines | void Session::run_gpu() | ||||
| reset_time = time_dt(); | reset_time = time_dt(); | ||||
| last_update_time = time_dt(); | last_update_time = time_dt(); | ||||
| last_display_time = last_update_time; | last_display_time = last_update_time; | ||||
| progress.set_render_start_time(); | progress.set_render_start_time(); | ||||
| while (!progress.get_cancel()) { | while (!progress.get_cancel()) { | ||||
| /* advance to next tile */ | const bool no_tiles = !run_update_for_next_iteration(); | ||||
| bool no_tiles = !tile_manager.next(); | |||||
| DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN; | |||||
| if (no_tiles) { | if (no_tiles) { | ||||
| kernel_state = device->get_active_kernel_switch_state(); | |||||
| } | |||||
| if (params.background) { | if (params.background) { | ||||
| /* if no work left and in background mode, we can stop immediately */ | /* if no work left and in background mode, we can stop immediately */ | ||||
| if (no_tiles) { | |||||
| progress.set_status("Finished"); | progress.set_status("Finished"); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) { | if (run_wait_for_work(no_tiles)) { | ||||
| reset_gpu(tile_manager.params, params.samples); | continue; | ||||
| } | |||||
| else { | |||||
| /* if in interactive mode, and we are either paused or done for now, | |||||
| * wait for pause condition notify to wake up again */ | |||||
| thread_scoped_lock pause_lock(pause_mutex); | |||||
| 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) { | |||||
| scoped_timer pause_timer; | |||||
| pause_cond.wait(pause_lock); | |||||
| if (pause) { | |||||
| progress.add_skip_time(pause_timer, params.background); | |||||
| } | |||||
| update_status_time(pause, no_tiles); | |||||
| progress.set_update(); | |||||
| if (!pause) | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (!no_tiles) { | if (!no_tiles) { | ||||
| /* update scene */ | |||||
| scoped_timer update_timer; | |||||
| if (update_scene()) { | |||||
| profiler.reset(scene->shaders.size(), scene->objects.size()); | |||||
| } | |||||
| progress.add_skip_time(update_timer, params.background); | |||||
| if (!device->error_message().empty()) | if (!device->error_message().empty()) | ||||
| progress.set_error(device->error_message()); | progress.set_error(device->error_message()); | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| break; | break; | ||||
| /* buffers mutex is locked entirely while rendering each | /* buffers mutex is locked entirely while rendering each | ||||
| * sample, and released/reacquired on each iteration to allow | * sample, and released/reacquired on each iteration to allow | ||||
| ▲ Show 20 Lines • Show All 426 Lines • ▼ Show 20 Lines | |||||
| void Session::run_cpu() | void Session::run_cpu() | ||||
| { | { | ||||
| bool tiles_written = false; | bool tiles_written = false; | ||||
| last_update_time = time_dt(); | last_update_time = time_dt(); | ||||
| last_display_time = last_update_time; | last_display_time = last_update_time; | ||||
| { | |||||
| /* 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; | |||||
| } | |||||
| while (!progress.get_cancel()) { | while (!progress.get_cancel()) { | ||||
| /* advance to next tile */ | const bool no_tiles = !run_update_for_next_iteration(); | ||||
| bool no_tiles = !tile_manager.next(); | |||||
| bool need_copy_to_display_buffer = false; | bool need_copy_to_display_buffer = false; | ||||
| DeviceKernelStatus kernel_state = DEVICE_KERNEL_UNKNOWN; | |||||
| if (no_tiles) { | if (no_tiles) { | ||||
| kernel_state = device->get_active_kernel_switch_state(); | |||||
| } | |||||
| if (params.background) { | if (params.background) { | ||||
| /* if no work left and in background mode, we can stop immediately */ | /* if no work left and in background mode, we can stop immediately */ | ||||
| if (no_tiles) { | |||||
| progress.set_status("Finished"); | progress.set_status("Finished"); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else if (no_tiles && kernel_state == DEVICE_KERNEL_FEATURE_KERNEL_AVAILABLE) { | if (run_wait_for_work(no_tiles)) { | ||||
| reset_cpu(tile_manager.params, params.samples); | continue; | ||||
| } | |||||
| else { | |||||
| /* if in interactive mode, and we are either paused or done for now, | |||||
| * wait for pause condition notify to wake up again */ | |||||
| thread_scoped_lock pause_lock(pause_mutex); | |||||
| 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) { | |||||
| scoped_timer pause_timer; | |||||
| pause_cond.wait(pause_lock); | |||||
| if (pause) { | |||||
| progress.add_skip_time(pause_timer, params.background); | |||||
| } | |||||
| update_status_time(pause, no_tiles); | |||||
| progress.set_update(); | |||||
| if (!pause) | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) { | ||||
| break; | break; | ||||
| } | } | ||||
| if (!no_tiles) { | if (!no_tiles) { | ||||
| /* update scene */ | |||||
| scoped_timer update_timer; | |||||
| if (update_scene()) { | |||||
| profiler.reset(scene->shaders.size(), scene->objects.size()); | |||||
| } | |||||
| progress.add_skip_time(update_timer, params.background); | |||||
| if (!device->error_message().empty()) | if (!device->error_message().empty()) | ||||
| progress.set_error(device->error_message()); | progress.set_error(device->error_message()); | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| break; | break; | ||||
| /* buffers mutex is locked entirely while rendering each | /* buffers mutex is locked entirely while rendering each | ||||
| * sample, and released/reacquired on each iteration to allow | * sample, and released/reacquired on each iteration to allow | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | void Session::run() | ||||
| /* progress update */ | /* progress update */ | ||||
| if (progress.get_cancel()) | if (progress.get_cancel()) | ||||
| progress.set_status(progress.get_cancel_message()); | progress.set_status(progress.get_cancel_message()); | ||||
| else | else | ||||
| progress.set_update(); | progress.set_update(); | ||||
| } | } | ||||
| bool Session::run_update_for_next_iteration() | |||||
| { | |||||
| thread_scoped_lock scene_lock(scene->mutex); | |||||
| thread_scoped_lock reset_lock(delayed_reset.mutex); | |||||
| if (delayed_reset.do_reset) { | |||||
| thread_scoped_lock buffers_lock(buffers_mutex); | |||||
| reset_(delayed_reset.params, delayed_reset.samples); | |||||
| delayed_reset.do_reset = false; | |||||
| } | |||||
| const bool have_tiles = tile_manager.next(); | |||||
| if (have_tiles) { | |||||
| scoped_timer update_timer; | |||||
| if (update_scene()) { | |||||
| profiler.reset(scene->shaders.size(), scene->objects.size()); | |||||
| } | |||||
| progress.add_skip_time(update_timer, params.background); | |||||
| } | |||||
| return have_tiles; | |||||
| } | |||||
| bool Session::run_wait_for_work(bool no_tiles) | |||||
| { | |||||
| /* In an offline rendering there is no pause, and no tiles will mean the job is fully done. */ | |||||
| if (params.background) { | |||||
| return false; | |||||
| } | |||||
| thread_scoped_lock pause_lock(pause_mutex); | |||||
| if (!pause && !no_tiles) { | |||||
| return false; | |||||
| } | |||||
| update_status_time(pause, no_tiles); | |||||
| while (true) { | |||||
| scoped_timer pause_timer; | |||||
| pause_cond.wait(pause_lock); | |||||
| if (pause) { | |||||
| progress.add_skip_time(pause_timer, params.background); | |||||
| } | |||||
| update_status_time(pause, no_tiles); | |||||
| progress.set_update(); | |||||
| if (!pause) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| return no_tiles; | |||||
| } | |||||
| bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params) | bool Session::draw(BufferParams &buffer_params, DeviceDrawParams &draw_params) | ||||
| { | { | ||||
| if (device_use_gl) | if (device_use_gl) | ||||
| return draw_gpu(buffer_params, draw_params); | return draw_gpu(buffer_params, draw_params); | ||||
| else | else | ||||
| return draw_cpu(buffer_params, draw_params); | return draw_cpu(buffer_params, draw_params); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | if (session_thread) { | ||||
| delete session_thread; | delete session_thread; | ||||
| } | } | ||||
| session_thread = NULL; | session_thread = NULL; | ||||
| } | } | ||||
| bool Session::update_scene() | bool Session::update_scene() | ||||
| { | { | ||||
| thread_scoped_lock scene_lock(scene->mutex); | |||||
| /* update camera if dimensions changed for progressive render. the camera | /* update camera if dimensions changed for progressive render. the camera | ||||
| * knows nothing about progressive or cropped rendering, it just gets the | * knows nothing about progressive or cropped rendering, it just gets the | ||||
| * image dimensions passed in */ | * image dimensions passed in */ | ||||
| Camera *cam = scene->camera; | Camera *cam = scene->camera; | ||||
| int width = tile_manager.state.buffer.full_width; | int width = tile_manager.state.buffer.full_width; | ||||
| int height = tile_manager.state.buffer.full_height; | int height = tile_manager.state.buffer.full_height; | ||||
| int resolution = tile_manager.state.resolution_divider; | int resolution = tile_manager.state.resolution_divider; | ||||
| ▲ Show 20 Lines • Show All 285 Lines • Show Last 20 Lines | |||||