[Bf-blender-cvs] [c9f12b21e25] master: Compositor: Full frame ID Mask node

Manuel Castilla noreply at git.blender.org
Wed Jun 23 17:55:42 CEST 2021


Commit: c9f12b21e252fee3f102b9e04dfde000016dc099
Author: Manuel Castilla
Date:   Wed Jun 23 17:44:18 2021 +0200
Branches: master
https://developer.blender.org/rBc9f12b21e252fee3f102b9e04dfde000016dc099

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

===================================================================

M	source/blender/compositor/operations/COM_AntiAliasOperation.cc
M	source/blender/compositor/operations/COM_AntiAliasOperation.h
M	source/blender/compositor/operations/COM_IDMaskOperation.cc
M	source/blender/compositor/operations/COM_IDMaskOperation.h

===================================================================

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<MemoryBuffer *> 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<MemoryBuffer *> 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<MemoryBuffer *> 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<MemoryBuffer *> inputs) override;
 };
 
 }  // namespace blender::compositor



More information about the Bf-blender-cvs mailing list