From c9f12b21e252fee3f102b9e04dfde000016dc099 Mon Sep 17 00:00:00 2001 From: Manuel Castilla Date: Wed, 23 Jun 2021 17:44:18 +0200 Subject: Compositor: Full frame ID Mask node Adds full frame implementation to this node operations. No functional changes. 1.2x faster than tiled fallback. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D11638 --- .../operations/COM_AntiAliasOperation.cc | 68 ++++++++++++++++++++++ .../compositor/operations/COM_AntiAliasOperation.h | 10 +++- .../compositor/operations/COM_IDMaskOperation.cc | 18 ++++++ .../compositor/operations/COM_IDMaskOperation.h | 8 ++- 4 files changed, 100 insertions(+), 4 deletions(-) (limited to 'source') diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cc b/source/blender/compositor/operations/COM_AntiAliasOperation.cc index 23d6f4b80c7..deccbb28f49 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cc +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cc @@ -202,4 +202,72 @@ void *AntiAliasOperation::initializeTileData(rcti *rect) return getInputOperation(0)->initializeTileData(rect); } +void AntiAliasOperation::get_area_of_interest(const int input_idx, + const rcti &output_area, + rcti &r_input_area) +{ + BLI_assert(input_idx == 0); + UNUSED_VARS_NDEBUG(input_idx); + r_input_area.xmax = output_area.xmax + 1; + r_input_area.xmin = output_area.xmin - 1; + r_input_area.ymax = output_area.ymax + 1; + r_input_area.ymin = output_area.ymin - 1; +} + +void AntiAliasOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) +{ + const MemoryBuffer *input = inputs[0]; + const rcti &input_area = input->get_rect(); + float ninepix[9]; + for (int y = area.ymin; y < area.ymax; y++) { + float *out = output->get_elem(area.xmin, y); + const float *row_curr = input->get_elem(area.xmin, y); + const float *row_prev = row_curr - input->row_stride; + const float *row_next = row_curr + input->row_stride; + int x_offset = 0; + for (int x = area.xmin; x < area.xmax; + x++, out += output->elem_stride, x_offset += input->elem_stride) { + if (x == input_area.xmin || x == input_area.xmax - 1 || y == input_area.xmin || + y == input_area.ymax - 1) { + out[0] = row_curr[x_offset]; + continue; + } + + if (extrapolate9(&ninepix[0], + &ninepix[1], + &ninepix[2], + &ninepix[3], + &ninepix[4], + &ninepix[5], + &ninepix[6], + &ninepix[7], + &ninepix[8], + &row_prev[x_offset - input->elem_stride], + &row_prev[x_offset], + &row_prev[x_offset + input->elem_stride], + &row_curr[x_offset - input->elem_stride], + &row_curr[x_offset], + &row_curr[x_offset + input->elem_stride], + &row_next[x_offset - input->elem_stride], + &row_next[x_offset], + &row_next[x_offset + input->elem_stride])) { + /* Some rounding magic to make weighting correct with the + * original coefficients. */ + unsigned char result = ((3 * ninepix[0] + 5 * ninepix[1] + 3 * ninepix[2] + + 5 * ninepix[3] + 6 * ninepix[4] + 5 * ninepix[5] + + 3 * ninepix[6] + 5 * ninepix[7] + 3 * ninepix[8]) * + 255.0f + + 19.0f) / + 38.0f; + out[0] = result / 255.0f; + } + else { + out[0] = row_curr[x_offset]; + } + } + } +} + } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.h b/source/blender/compositor/operations/COM_AntiAliasOperation.h index fc9102b5b4c..b5048248425 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.h +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.h @@ -18,7 +18,7 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedOperation.h" #include "DNA_node_types.h" namespace blender::compositor { @@ -28,7 +28,7 @@ namespace blender::compositor { * it only supports anti aliasing on BW buffers. * \ingroup operation */ -class AntiAliasOperation : public NodeOperation { +class AntiAliasOperation : public MultiThreadedOperation { protected: /** * \brief Cached reference to the reader @@ -57,6 +57,12 @@ class AntiAliasOperation : public NodeOperation { bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) override; + + void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override; + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; }; } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cc b/source/blender/compositor/operations/COM_IDMaskOperation.cc index 1bb247e9bc5..38f8b7e075f 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.cc +++ b/source/blender/compositor/operations/COM_IDMaskOperation.cc @@ -42,4 +42,22 @@ void IDMaskOperation::executePixel(float output[4], int x, int y, void *data) output[0] = (roundf(buffer[buffer_index]) == this->m_objectIndex) ? 1.0f : 0.0f; } +void IDMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) +{ + const MemoryBuffer *input = inputs[0]; + const int width = BLI_rcti_size_x(&area); + for (int y = area.ymin; y < area.ymax; y++) { + float *out = output->get_elem(area.xmin, y); + const float *in = input->get_elem(area.xmin, y); + const float *row_end = out + width * output->elem_stride; + while (out < row_end) { + out[0] = (roundf(in[0]) == m_objectIndex) ? 1.0f : 0.0f; + in += input->elem_stride; + out += output->elem_stride; + } + } +} + } // namespace blender::compositor diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.h b/source/blender/compositor/operations/COM_IDMaskOperation.h index 79b7e53b67c..c2e13641b46 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.h +++ b/source/blender/compositor/operations/COM_IDMaskOperation.h @@ -18,11 +18,11 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedOperation.h" namespace blender::compositor { -class IDMaskOperation : public NodeOperation { +class IDMaskOperation : public MultiThreadedOperation { private: float m_objectIndex; @@ -36,6 +36,10 @@ class IDMaskOperation : public NodeOperation { { this->m_objectIndex = objectIndex; } + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span inputs) override; }; } // namespace blender::compositor -- cgit v1.2.3