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
This commit is contained in:
parent
35db01325f
commit
c9f12b21e2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue