Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_session.cpp
| Show First 20 Lines • Show All 154 Lines • ▼ Show 20 Lines | void BlenderSession::create_session() | ||||
| } | } | ||||
| /* set buffer parameters */ | /* set buffer parameters */ | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params( | ||||
| b_v3d, b_rv3d, scene->camera, width, height); | b_v3d, b_rv3d, scene->camera, width, height); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, session_params.samples); | ||||
| /* Create GPU display. */ | /* Create GPU display. */ | ||||
| if (!background) { | if (!b_engine.is_preview()) { | ||||
| session->set_gpu_display(make_unique<BlenderGPUDisplay>(b_engine, b_scene)); | session->set_gpu_display( | ||||
| make_unique<BlenderGPUDisplay>(b_engine, b_scene, b_v3d ? false : true)); | |||||
| } | } | ||||
| /* TODO(sergey): Decide on what is to be communicated to the engine here. There is no tiled | /* TODO(sergey): Decide on what is to be communicated to the engine here. There is no tiled | ||||
| * rendering for from visual point of view when render buffer fits big tile. But for huge | * rendering for from visual point of view when render buffer fits big tile. But for huge | ||||
| * render resolutions it might still be helpful to see which big tile is being sampled. */ | * render resolutions it might still be helpful to see which big tile is being sampled. */ | ||||
| /* b_engine.use_highlight_tiles(session_params.progressive_refine == false); */ | /* b_engine.use_highlight_tiles(session_params.progressive_refine == false); */ | ||||
| update_resumable_tile_manager(session_params.samples); | update_resumable_tile_manager(session_params.samples); | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
| void BlenderSession::free_session() | void BlenderSession::free_session() | ||||
| { | { | ||||
| session->cancel(true); | session->cancel(true); | ||||
| delete sync; | delete sync; | ||||
| delete session; | delete session; | ||||
| } | } | ||||
| void BlenderSession::do_write_update_render_tile(bool do_update_only) | void BlenderSession::read_render_tile() | ||||
| { | { | ||||
| const int2 tile_offset = session->get_render_tile_offset(); | const int2 tile_offset = session->get_render_tile_offset(); | ||||
| const int2 tile_size = session->get_render_tile_size(); | const int2 tile_size = session->get_render_tile_size(); | ||||
| /* get render result */ | /* get render result */ | ||||
| BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x, | BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x, | ||||
| tile_offset.y, | tile_offset.y, | ||||
| tile_size.x, | tile_size.x, | ||||
| Show All 10 Lines | void BlenderSession::read_render_tile() | ||||
| b_rr.layers.begin(b_single_rlay); | b_rr.layers.begin(b_single_rlay); | ||||
| /* layer will be missing if it was disabled in the UI */ | /* layer will be missing if it was disabled in the UI */ | ||||
| if (b_single_rlay == b_rr.layers.end()) | if (b_single_rlay == b_rr.layers.end()) | ||||
| return; | return; | ||||
| BL::RenderLayer b_rlay = *b_single_rlay; | BL::RenderLayer b_rlay = *b_single_rlay; | ||||
| if (do_update_only) { | vector<float> pixels(tile_size.x * tile_size.y * 4); | ||||
| update_render_result(b_rlay); | |||||
| } | /* Copy each pass. | ||||
| else { | * TODO:copy only the required ones for better performance? */ | ||||
| write_render_result(b_rlay); | for (BL::RenderPass &b_pass : b_rlay.passes) { | ||||
| session->set_render_tile_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect()); | |||||
| } | } | ||||
| b_engine.end_result(b_rr, true, false, true); | b_engine.end_result(b_rr, false, false, false); | ||||
| } | } | ||||
| void BlenderSession::read_render_tile() | void BlenderSession::write_render_tile() | ||||
| { | { | ||||
| const int2 tile_offset = session->get_render_tile_offset(); | const int2 tile_offset = session->get_render_tile_offset(); | ||||
| const int2 tile_size = session->get_render_tile_size(); | const int2 tile_size = session->get_render_tile_size(); | ||||
| /* get render result */ | /* get render result */ | ||||
| BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x, | BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x, | ||||
| tile_offset.y, | tile_offset.y, | ||||
| tile_size.x, | tile_size.x, | ||||
| Show All 10 Lines | void BlenderSession::write_render_tile() | ||||
| b_rr.layers.begin(b_single_rlay); | b_rr.layers.begin(b_single_rlay); | ||||
| /* layer will be missing if it was disabled in the UI */ | /* layer will be missing if it was disabled in the UI */ | ||||
| if (b_single_rlay == b_rr.layers.end()) | if (b_single_rlay == b_rr.layers.end()) | ||||
| return; | return; | ||||
| BL::RenderLayer b_rlay = *b_single_rlay; | BL::RenderLayer b_rlay = *b_single_rlay; | ||||
| vector<float> pixels(tile_size.x * tile_size.y * 4); | write_render_result(b_rlay); | ||||
| /* Copy each pass. | |||||
| * TODO:copy only the required ones for better performance? */ | |||||
| for (BL::RenderPass &b_pass : b_rlay.passes) { | |||||
| session->set_render_tile_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect()); | |||||
| } | |||||
| b_engine.end_result(b_rr, false, false, false); | |||||
| } | |||||
| void BlenderSession::write_render_tile() | |||||
| { | |||||
| do_write_update_render_tile(false); | |||||
| } | |||||
| void BlenderSession::update_render_tile() | b_engine.end_result(b_rr, true, false, true); | ||||
| { | |||||
| /* use final write for preview renders, otherwise render result wouldn't be | |||||
| * be updated in blender side | |||||
| * would need to be investigated a bit further, but for now shall be fine | |||||
| */ | |||||
| if (!b_engine.is_preview()) | |||||
| do_write_update_render_tile(true); | |||||
| else | |||||
| do_write_update_render_tile(false); | |||||
| } | } | ||||
| static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest) | static void add_cryptomatte_layer(BL::RenderResult &b_rr, string name, string manifest) | ||||
| { | { | ||||
| string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0)); | string identifier = string_printf("%08x", util_murmur_hash3(name.c_str(), name.length(), 0)); | ||||
| string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/"; | string prefix = "cryptomatte/" + identifier.substr(0, 7) + "/"; | ||||
| render_add_metadata(b_rr, prefix + "name", name); | render_add_metadata(b_rr, prefix + "name", name); | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | void BlenderSession::render(BL::Depsgraph &b_depsgraph_) | ||||
| if (session->progress.get_cancel()) { | if (session->progress.get_cancel()) { | ||||
| update_status_progress(); | update_status_progress(); | ||||
| return; | return; | ||||
| } | } | ||||
| /* set callback to write out render results */ | /* set callback to write out render results */ | ||||
| session->write_render_tile_cb = [&]() { write_render_tile(); }; | session->write_render_tile_cb = [&]() { write_render_tile(); }; | ||||
| session->update_render_tile_cb = [&]() { update_render_tile(); }; | |||||
| /* Use final write for preview renders, otherwise render result wouldn't be be updated on Blender | |||||
| * side. */ | |||||
| /* TODO(sergey): Investigate whether GPUDisplay can be used for the preview as well. */ | |||||
| if (b_engine.is_preview()) { | |||||
| session->update_render_tile_cb = [&]() { write_render_tile(); }; | |||||
| } | |||||
| BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); | BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); | ||||
| /* get buffer parameters */ | /* get buffer parameters */ | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background); | b_engine, b_userpref, b_scene, background); | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params( | ||||
| b_v3d, b_rv3d, scene->camera, width, height); | b_v3d, b_rv3d, scene->camera, width, height); | ||||
| ▲ Show 20 Lines • Show All 351 Lines • ▼ Show 20 Lines | void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) | ||||
| /* unlock */ | /* unlock */ | ||||
| session->scene->mutex.unlock(); | session->scene->mutex.unlock(); | ||||
| /* Start rendering thread, if it's not running already. Do this | /* Start rendering thread, if it's not running already. Do this | ||||
| * after all scene data has been synced at least once. */ | * after all scene data has been synced at least once. */ | ||||
| session->start(); | session->start(); | ||||
| } | } | ||||
| void BlenderSession::draw(int /*w*/, int /*h*/) | |||||
| { | |||||
| if (!session) { | |||||
| /* Offline render drawing does not force the render engine update, which means it's possible | |||||
| * that the Session is not created yet. */ | |||||
| /* TODO(sergey): Ensure the checkeboard is drawn in this case. */ | |||||
| return; | |||||
| } | |||||
| session->draw(); | |||||
| } | |||||
| void BlenderSession::view_draw(int w, int h) | void BlenderSession::view_draw(int w, int h) | ||||
| { | { | ||||
| /* pause in redraw in case update is not being called due to final render */ | /* pause in redraw in case update is not being called due to final render */ | ||||
| session->set_pause(BlenderSync::get_session_pause(b_scene, background)); | session->set_pause(BlenderSync::get_session_pause(b_scene, background)); | ||||
| /* before drawing, we verify camera and viewport size changes, because | /* before drawing, we verify camera and viewport size changes, because | ||||
| * we do not get update callbacks for those, we must detect them here */ | * we do not get update callbacks for those, we must detect them here */ | ||||
| if (session->ready_to_reset()) { | if (session->ready_to_reset()) { | ||||
| ▲ Show 20 Lines • Show All 248 Lines • Show Last 20 Lines | |||||