Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brecht>2021-09-30 17:51:03 +0300
committerBrecht Van Lommel <brecht@blender.org>2021-09-30 21:53:27 +0300
commit1a134c4c30a643ada1b9a7a037040b5f5c173a28 (patch)
treeb4216998527ff24fb3fc9e9351ced05cd7b7eb08 /intern/cycles/blender
parenta754e35198d852ea34e2b82cd2b126538e6f5a3b (diff)
Cycles: refactor API for render output
* Add OutputDriver, replacing function callbacks in Session. * Add PathTraceTile, replacing tile access methods in Session. * Add more detailed comments about how this driver should be implemented. * Add OIIOOutputDriver for Cycles standalone to output an image. Differential Revision: https://developer.blender.org/D12627
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r--intern/cycles/blender/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/blender_output_driver.cpp127
-rw-r--r--intern/cycles/blender/blender_output_driver.h40
-rw-r--r--intern/cycles/blender/blender_session.cpp154
-rw-r--r--intern/cycles/blender/blender_session.h13
5 files changed, 178 insertions, 158 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index 2660eee017b..a0442b3394b 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -38,6 +38,7 @@ set(SRC
blender_mesh.cpp
blender_object.cpp
blender_object_cull.cpp
+ blender_output_driver.cpp
blender_particles.cpp
blender_curves.cpp
blender_logging.cpp
@@ -55,6 +56,7 @@ set(SRC
blender_id_map.h
blender_image.h
blender_object_cull.h
+ blender_output_driver.h
blender_sync.h
blender_session.h
blender_texture.h
diff --git a/intern/cycles/blender/blender_output_driver.cpp b/intern/cycles/blender/blender_output_driver.cpp
new file mode 100644
index 00000000000..f380b7b3bb1
--- /dev/null
+++ b/intern/cycles/blender/blender_output_driver.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2021 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "blender/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;
+
+ vector<float> pixels(tile.size.x * tile.size.y * 4);
+
+ /* 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 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;
+ }
+ else {
+ /* 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<float> pixels(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, true, false, true);
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_output_driver.h b/intern/cycles/blender/blender_output_driver.h
new file mode 100644
index 00000000000..8a1cf92d7c7
--- /dev/null
+++ b/intern/cycles/blender/blender_output_driver.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2021 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_blender_cpp.h"
+
+#include "render/output_driver.h"
+
+CCL_NAMESPACE_BEGIN
+
+class BlenderOutputDriver : public OutputDriver {
+ public:
+ BlenderOutputDriver(BL::RenderEngine &b_engine);
+ ~BlenderOutputDriver();
+
+ virtual void write_render_tile(const Tile &tile) override;
+ virtual bool update_render_tile(const Tile &tile) override;
+ virtual bool read_render_tile(const Tile &tile) override;
+
+ protected:
+ BL::RenderEngine b_engine_;
+};
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 1a42456eda0..3be7ff32bd8 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -43,6 +43,7 @@
#include "util/util_time.h"
#include "blender/blender_display_driver.h"
+#include "blender/blender_output_driver.h"
#include "blender/blender_session.h"
#include "blender/blender_sync.h"
#include "blender/blender_util.h"
@@ -157,7 +158,8 @@ void BlenderSession::create_session()
b_v3d, b_rv3d, scene->camera, width, height);
session->reset(session_params, buffer_params);
- /* Create GPU display. */
+ /* Create GPU display.
+ * TODO(sergey): Investigate whether DisplayDriver can be used for the preview as well. */
if (!b_engine.is_preview() && !headless) {
unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(b_engine,
b_scene);
@@ -279,96 +281,6 @@ void BlenderSession::free_session()
session = nullptr;
}
-void BlenderSession::read_render_tile()
-{
- const int2 tile_offset = session->get_render_tile_offset();
- const int2 tile_size = session->get_render_tile_size();
-
- /* get render result */
- BL::RenderResult b_rr = b_engine.begin_result(tile_offset.x,
- tile_offset.y,
- tile_size.x,
- tile_size.y,
- b_rlay_name.c_str(),
- b_rview_name.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<float> pixels(tile_size.x * tile_size.y * 4);
-
- /* 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()
-{
- const int2 tile_offset = session->get_render_tile_offset();
- const int2 tile_size = session->get_render_tile_size();
-
- const string_view render_layer_name = session->get_render_tile_layer();
- const string_view render_view_name = session->get_render_tile_view();
-
- 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,
- render_layer_name.c_str(),
- render_view_name.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;
-
- write_render_result(b_rlay);
-
- b_engine.end_result(b_rr, true, false, true);
-}
-
-void BlenderSession::update_render_tile()
-{
- if (!session->has_multiple_render_tiles()) {
- /* Don't highlight full-frame tile. */
- return;
- }
-
- const int2 tile_offset = session->get_render_tile_offset();
- const int2 tile_size = session->get_render_tile_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);
-}
-
void BlenderSession::full_buffer_written(string_view filename)
{
full_buffer_files_.emplace_back(filename);
@@ -442,18 +354,8 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
return;
}
- /* set callback to write out render results */
- session->write_render_tile_cb = [&]() { write_render_tile(); };
-
- /* Use final write for preview renders, otherwise render result wouldn't be be updated on Blender
- * side. */
- /* TODO(sergey): Investigate whether DisplayDriver can be used for the preview as well. */
- if (b_engine.is_preview()) {
- session->update_render_tile_cb = [&]() { write_render_tile(); };
- }
- else {
- session->update_render_tile_cb = [&]() { update_render_tile(); };
- }
+ /* Create driver to write out render results. */
+ session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
session->full_buffer_written_cb = [&](string_view filename) { full_buffer_written(filename); };
@@ -599,9 +501,8 @@ void BlenderSession::render_frame_finish()
path_remove(filename);
}
- /* clear callback */
- session->write_render_tile_cb = function_null;
- session->update_render_tile_cb = function_null;
+ /* Clear driver. */
+ session->set_output_driver(nullptr);
session->full_buffer_written_cb = function_null;
}
@@ -707,9 +608,8 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
pass->set_type(bake_type_to_pass(bake_type, bake_filter));
pass->set_include_albedo((bake_filter & BL::BakeSettings::pass_filter_COLOR));
- session->read_render_tile_cb = [&]() { read_render_tile(); };
- session->write_render_tile_cb = [&]() { write_render_tile(); };
session->set_display_driver(nullptr);
+ session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
if (!session->progress.get_cancel()) {
/* Sync scene. */
@@ -752,43 +652,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
session->wait();
}
- session->read_render_tile_cb = function_null;
- session->write_render_tile_cb = function_null;
-}
-
-void BlenderSession::write_render_result(BL::RenderLayer &b_rlay)
-{
- if (!session->copy_render_tile_from_device()) {
- return;
- }
-
- const int2 tile_size = session->get_render_tile_size();
- vector<float> pixels(tile_size.x * tile_size.y * 4);
-
- /* Copy each pass. */
- for (BL::RenderPass &b_pass : b_rlay.passes) {
- if (!session->get_render_tile_pixels(b_pass.name(), b_pass.channels(), &pixels[0])) {
- memset(&pixels[0], 0, pixels.size() * sizeof(float));
- }
-
- b_pass.rect(&pixels[0]);
- }
-}
-
-void BlenderSession::update_render_result(BL::RenderLayer &b_rlay)
-{
- if (!session->copy_render_tile_from_device()) {
- return;
- }
-
- const int2 tile_size = session->get_render_tile_size();
- vector<float> pixels(tile_size.x * tile_size.y * 4);
-
- /* Copy combined pass. */
- BL::RenderPass b_combined_pass(b_rlay.passes.find_by_name("Combined", b_rview_name.c_str()));
- if (session->get_render_tile_pixels("Combined", b_combined_pass.channels(), &pixels[0])) {
- b_combined_pass.rect(&pixels[0]);
- }
+ session->set_output_driver(nullptr);
}
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 1ca8fdf87d0..fef6ad1adfc 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -70,20 +70,7 @@ class BlenderSession {
const int bake_width,
const int bake_height);
- void write_render_result(BL::RenderLayer &b_rlay);
- void write_render_tile();
-
- void update_render_tile();
-
void full_buffer_written(string_view filename);
-
- /* update functions are used to update display buffer only after sample was rendered
- * only needed for better visual feedback */
- void update_render_result(BL::RenderLayer &b_rlay);
-
- /* read functions for baking input */
- void read_render_tile();
-
/* interactive updates */
void synchronize(BL::Depsgraph &b_depsgraph);