/* SPDX-License-Identifier: Apache-2.0 * Copyright 2021-2022 Blender Foundation */ #include "blender/output_driver.h" CCL_NAMESPACE_BEGIN BlenderOutputDriver::BlenderOutputDriver(BL::RenderEngine &b_engine) : b_engine_(b_engine) { } BlenderOutputDriver::~BlenderOutputDriver() { } bool BlenderOutputDriver::read_render_tile(const Tile &tile) { /* Get render result. */ BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x, tile.offset.y, tile.size.x, tile.size.y, tile.layer.c_str(), tile.view.c_str()); /* Can happen if the intersected rectangle gives 0 width or height. */ if (b_rr.ptr.data == NULL) { return false; } BL::RenderResult::layers_iterator b_single_rlay; b_rr.layers.begin(b_single_rlay); /* layer will be missing if it was disabled in the UI */ if (b_single_rlay == b_rr.layers.end()) { return false; } BL::RenderLayer b_rlay = *b_single_rlay; /* Copy each pass. * TODO:copy only the required ones for better performance? */ for (BL::RenderPass &b_pass : b_rlay.passes) { tile.set_pass_pixels(b_pass.name(), b_pass.channels(), (float *)b_pass.rect()); } b_engine_.end_result(b_rr, false, false, false); return true; } bool BlenderOutputDriver::update_render_tile(const Tile &tile) { /* Use final write for preview renders, otherwise render result wouldn't be updated * quickly on Blender side. For all other cases we use the display driver. */ if (b_engine_.is_preview()) { write_render_tile(tile); return true; } /* Don't highlight full-frame tile. */ if (!(tile.size == tile.full_size)) { b_engine_.tile_highlight_clear_all(); b_engine_.tile_highlight_set(tile.offset.x, tile.offset.y, tile.size.x, tile.size.y, true); } return false; } void BlenderOutputDriver::write_render_tile(const Tile &tile) { b_engine_.tile_highlight_clear_all(); /* Get render result. */ BL::RenderResult b_rr = b_engine_.begin_result(tile.offset.x, tile.offset.y, tile.size.x, tile.size.y, tile.layer.c_str(), tile.view.c_str()); /* Can happen if the intersected rectangle gives 0 width or height. */ if (b_rr.ptr.data == NULL) { return; } BL::RenderResult::layers_iterator b_single_rlay; b_rr.layers.begin(b_single_rlay); /* Layer will be missing if it was disabled in the UI. */ if (b_single_rlay == b_rr.layers.end()) { return; } BL::RenderLayer b_rlay = *b_single_rlay; vector pixels(static_cast(tile.size.x) * tile.size.y * 4); /* Copy each pass. */ for (BL::RenderPass &b_pass : b_rlay.passes) { if (!tile.get_pass_pixels(b_pass.name(), b_pass.channels(), &pixels[0])) { memset(&pixels[0], 0, pixels.size() * sizeof(float)); } b_pass.rect(&pixels[0]); } b_engine_.end_result(b_rr, false, false, true); } CCL_NAMESPACE_END