diff options
author | Manuel Castilla <manzanillawork@gmail.com> | 2021-07-19 19:17:41 +0300 |
---|---|---|
committer | Manuel Castilla <manzanillawork@gmail.com> | 2021-07-19 22:26:58 +0300 |
commit | 0a0c2c0217d492308f7b0ba4659ef3961fa792bb (patch) | |
tree | d7e1eca970ee99e2d401c399753b957d9cf5b5ea /source/blender/compositor | |
parent | 45b46e5de9fbfb4985d81ac43cf61a6dcb339ff7 (diff) |
Compositor: Full frame Ellipse Mask node
Adds full frame implementation to this node operation.
No functional changes.
3x times faster than tiled fallback.
Reviewed By: jbakker
Differential Revision: https://developer.blender.org/D11635
Diffstat (limited to 'source/blender/compositor')
-rw-r--r-- | source/blender/compositor/operations/COM_EllipseMaskOperation.cc | 73 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_EllipseMaskOperation.h | 16 |
2 files changed, 87 insertions, 2 deletions
diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc index 5a4503fecec..eb1fd98a590 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cc +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cc @@ -20,6 +20,8 @@ #include "BLI_math.h" #include "DNA_node_types.h" +#include <functional> + namespace blender::compositor { EllipseMaskOperation::EllipseMaskOperation() @@ -114,6 +116,77 @@ void EllipseMaskOperation::executePixelSampled(float output[4], } } +void EllipseMaskOperation::update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) +{ + MaskFunc mask_func; + switch (m_maskType) { + case CMP_NODE_MASKTYPE_ADD: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? MAX2(mask[0], value[0]) : mask[0]; + }; + break; + case CMP_NODE_MASKTYPE_SUBTRACT: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? CLAMPIS(mask[0] - value[0], 0, 1) : mask[0]; + }; + break; + case CMP_NODE_MASKTYPE_MULTIPLY: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + return is_inside ? mask[0] * value[0] : 0; + }; + break; + case CMP_NODE_MASKTYPE_NOT: + mask_func = [](const bool is_inside, const float *mask, const float *value) { + if (is_inside) { + return mask[0] > 0.0f ? 0.0f : value[0]; + } + return mask[0]; + }; + break; + } + apply_mask(output, area, inputs, mask_func); +} + +void EllipseMaskOperation::apply_mask(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs, + MaskFunc mask_func) +{ + const MemoryBuffer *input_mask = inputs[0]; + const MemoryBuffer *input_value = inputs[1]; + const float op_w = this->getWidth(); + const float op_h = this->getHeight(); + const float half_w = this->m_data->width / 2.0f; + const float half_h = this->m_data->height / 2.0f; + const float tx = half_w * half_w; + const float ty = half_h * half_h; + for (const int y : YRange(area)) { + const float op_ry = y / op_h; + const float dy = (op_ry - this->m_data->y) / m_aspectRatio; + float *out = output->get_elem(area.xmin, y); + const float *mask = input_mask->get_elem(area.xmin, y); + const float *value = input_value->get_elem(area.xmin, y); + for (const int x : XRange(area)) { + const float op_rx = x / op_w; + const float dx = op_rx - this->m_data->x; + const float rx = this->m_data->x + (m_cosine * dx + m_sine * dy); + const float ry = this->m_data->y + (-m_sine * dx + m_cosine * dy); + float sx = rx - this->m_data->x; + sx *= sx; + float sy = ry - this->m_data->y; + sy *= sy; + const bool inside = ((sx / tx) + (sy / ty)) < 1.0f; + out[0] = mask_func(inside, mask, value); + + mask += input_mask->elem_stride; + value += input_value->elem_stride; + out += output->elem_stride; + } + } +} + void EllipseMaskOperation::deinitExecution() { this->m_inputMask = nullptr; diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.h b/source/blender/compositor/operations/COM_EllipseMaskOperation.h index 64afe0145cf..fba3f979d26 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.h +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.h @@ -18,12 +18,14 @@ #pragma once -#include "COM_NodeOperation.h" +#include "COM_MultiThreadedOperation.h" namespace blender::compositor { -class EllipseMaskOperation : public NodeOperation { +class EllipseMaskOperation : public MultiThreadedOperation { private: + using MaskFunc = std::function<float(bool is_inside, const float *mask, const float *value)>; + /** * Cached reference to the inputProgram */ @@ -64,6 +66,16 @@ class EllipseMaskOperation : public NodeOperation { { this->m_maskType = maskType; } + + void update_memory_buffer_partial(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs) override; + + private: + void apply_mask(MemoryBuffer *output, + const rcti &area, + Span<MemoryBuffer *> inputs, + MaskFunc mask_func); }; } // namespace blender::compositor |