From 96a4b54cfb5c183d9e05c6fe8d96e290f1a98bf6 Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Tue, 13 Jul 2021 21:48:42 +0200 Subject: Compositor: Full frame Render Layers node Adds full frame implementation to this node operations. No functional changes. 2.5x faster than tiled fallback on average. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D11690 --- source/blender/compositor/COM_defines.h | 3 + .../compositor/operations/COM_RenderLayersProg.cc | 66 ++++++++++++++++++++++ .../compositor/operations/COM_RenderLayersProg.h | 25 +++++++- 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index 857cbf0beee..9f8e6f10215 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -60,9 +60,12 @@ constexpr int COM_data_type_num_channels(const DataType datatype) } constexpr int COM_DATA_TYPE_VALUE_CHANNELS = COM_data_type_num_channels(DataType::Value); +constexpr int COM_DATA_TYPE_VECTOR_CHANNELS = COM_data_type_num_channels(DataType::Vector); constexpr int COM_DATA_TYPE_COLOR_CHANNELS = COM_data_type_num_channels(DataType::Color); +constexpr float COM_VECTOR_ZERO[3] = {0.0f, 0.0f, 0.0f}; constexpr float COM_VALUE_ZERO[1] = {0.0f}; +constexpr float COM_VALUE_ONE[1] = {1.0f}; /** * Utility to get data type for given number of channels. diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cc b/source/blender/compositor/operations/COM_RenderLayersProg.cc index 1ac451b95c2..34fea705c75 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cc +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cc @@ -43,6 +43,7 @@ RenderLayersProg::RenderLayersProg(const char *passName, DataType type, int elem this->m_inputBuffer = nullptr; this->m_elementsize = elementsize; this->m_rd = nullptr; + layer_buffer_ = nullptr; this->addOutputSocket(type); } @@ -65,6 +66,9 @@ void RenderLayersProg::initExecution() if (rl) { this->m_inputBuffer = RE_RenderLayerGetPass( rl, this->m_passName.c_str(), this->m_viewName); + if (m_inputBuffer) { + layer_buffer_ = new MemoryBuffer(m_inputBuffer, m_elementsize, getWidth(), getHeight()); + } } } } @@ -186,6 +190,10 @@ void RenderLayersProg::executePixelSampled(float output[4], float x, float y, Pi void RenderLayersProg::deinitExecution() { this->m_inputBuffer = nullptr; + if (layer_buffer_) { + delete layer_buffer_; + layer_buffer_ = nullptr; + } } void RenderLayersProg::determineResolution(unsigned int resolution[2], @@ -255,6 +263,20 @@ std::unique_ptr RenderLayersProg::getMetaData() return std::move(callback_data.meta_data); } +void RenderLayersProg::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span UNUSED(inputs)) +{ + BLI_assert(output->get_num_channels() >= m_elementsize); + if (layer_buffer_) { + output->copy_from(layer_buffer_, area, 0, m_elementsize, 0); + } + else { + std::unique_ptr zero_elem = std::make_unique(m_elementsize); + output->fill(area, 0, zero_elem.get(), m_elementsize); + } +} + /* ******** Render Layers AO Operation ******** */ void RenderLayersAOOperation::executePixelSampled(float output[4], float x, @@ -271,6 +293,21 @@ void RenderLayersAOOperation::executePixelSampled(float output[4], output[3] = 1.0f; } +void RenderLayersAOOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span UNUSED(inputs)) +{ + BLI_assert(output->get_num_channels() == COM_DATA_TYPE_COLOR_CHANNELS); + BLI_assert(m_elementsize == COM_DATA_TYPE_COLOR_CHANNELS); + if (layer_buffer_) { + output->copy_from(layer_buffer_, area, 0, COM_DATA_TYPE_VECTOR_CHANNELS, 0); + } + else { + output->fill(area, 0, COM_VECTOR_ZERO, COM_DATA_TYPE_VECTOR_CHANNELS); + } + output->fill(area, 3, COM_VALUE_ONE, COM_DATA_TYPE_VALUE_CHANNELS); +} + /* ******** Render Layers Alpha Operation ******** */ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, @@ -289,6 +326,20 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], } } +void RenderLayersAlphaProg::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span UNUSED(inputs)) +{ + BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS); + BLI_assert(m_elementsize == COM_DATA_TYPE_COLOR_CHANNELS); + if (layer_buffer_) { + output->copy_from(layer_buffer_, area, 3, COM_DATA_TYPE_VALUE_CHANNELS, 0); + } + else { + output->fill(area, COM_VALUE_ZERO); + } +} + /* ******** Render Layers Depth Operation ******** */ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, @@ -309,4 +360,19 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], } } +void RenderLayersDepthProg::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span UNUSED(inputs)) +{ + BLI_assert(output->get_num_channels() == COM_DATA_TYPE_VALUE_CHANNELS); + BLI_assert(m_elementsize == COM_DATA_TYPE_VALUE_CHANNELS); + if (layer_buffer_) { + output->copy_from(layer_buffer_, area); + } + else { + const float default_depth = 10e10f; + output->fill(area, &default_depth); + } +} + } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h index 56f83f691e8..dd76a56d645 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.h +++ b/source/blender/compositor/operations/COM_RenderLayersProg.h @@ -20,7 +20,7 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedOperation.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -33,7 +33,7 @@ namespace blender::compositor { * * \todo Rename to operation. */ -class RenderLayersProg : public NodeOperation { +class RenderLayersProg : public MultiThreadedOperation { protected: /** * Reference to the scene object. @@ -50,8 +50,11 @@ class RenderLayersProg : public NodeOperation { */ const char *m_viewName; + const MemoryBuffer *layer_buffer_; + /** - * cached instance to the float buffer inside the layer + * Cached instance to the float buffer inside the layer. + * TODO: To be removed with tiled implementation. */ float *m_inputBuffer; @@ -126,6 +129,10 @@ class RenderLayersProg : public NodeOperation { void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; std::unique_ptr getMetaData() override; + + virtual void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; }; class RenderLayersAOOperation : public RenderLayersProg { @@ -135,6 +142,10 @@ class RenderLayersAOOperation : public RenderLayersProg { { } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; }; class RenderLayersAlphaProg : public RenderLayersProg { @@ -144,6 +155,10 @@ class RenderLayersAlphaProg : public RenderLayersProg { { } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; }; class RenderLayersDepthProg : public RenderLayersProg { @@ -153,6 +168,10 @@ class RenderLayersDepthProg : public RenderLayersProg { { } void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override; + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; }; } // namespace blender::compositor -- cgit v1.2.3