Compositor: Full frame convert nodes

Adds full frame implementation to all nodes in "Converter" sub-menu
except "ID Mask" which is implemented separately.
No functional changes.

Part of T88150.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12095
This commit is contained in:
Manuel Castilla
2021-08-23 15:28:08 +02:00
parent 21d4a888b8
commit 8f4730e66f
10 changed files with 750 additions and 17 deletions

View File

@@ -29,6 +29,7 @@ ColorRampOperation::ColorRampOperation()
this->m_inputProgram = nullptr;
this->m_colorBand = nullptr;
this->flags.can_be_constant = true;
}
void ColorRampOperation::initExecution()
{
@@ -51,4 +52,13 @@ void ColorRampOperation::deinitExecution()
this->m_inputProgram = nullptr;
}
void ColorRampOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
BKE_colorband_evaluate(m_colorBand, *it.in(0), it.out);
}
}
} // namespace blender::compositor

View File

@@ -18,12 +18,12 @@
#pragma once
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
#include "DNA_texture_types.h"
namespace blender::compositor {
class ColorRampOperation : public NodeOperation {
class ColorRampOperation : public MultiThreadedOperation {
private:
/**
* Cached reference to the inputProgram
@@ -53,6 +53,10 @@ class ColorRampOperation : public NodeOperation {
{
this->m_colorBand = colorBand;
}
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor

View File

@@ -27,6 +27,7 @@ namespace blender::compositor {
ConvertBaseOperation::ConvertBaseOperation()
{
this->m_inputOperation = nullptr;
this->flags.can_be_constant = true;
}
void ConvertBaseOperation::initExecution()
@@ -39,6 +40,14 @@ void ConvertBaseOperation::deinitExecution()
this->m_inputOperation = nullptr;
}
void ConvertBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
BuffersIterator<float> it = output->iterate_with(inputs, area);
update_memory_buffer_partial(it);
}
/* ******** Value to Color ******** */
ConvertValueToColorOperation::ConvertValueToColorOperation() : ConvertBaseOperation()
@@ -58,6 +67,14 @@ void ConvertValueToColorOperation::executePixelSampled(float output[4],
output[3] = 1.0f;
}
void ConvertValueToColorOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
it.out[0] = it.out[1] = it.out[2] = *it.in(0);
it.out[3] = 1.0f;
}
}
/* ******** Color to Value ******** */
ConvertColorToValueOperation::ConvertColorToValueOperation() : ConvertBaseOperation()
@@ -76,6 +93,14 @@ void ConvertColorToValueOperation::executePixelSampled(float output[4],
output[0] = (inputColor[0] + inputColor[1] + inputColor[2]) / 3.0f;
}
void ConvertColorToValueOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
it.out[0] = (in[0] + in[1] + in[2]) / 3.0f;
}
}
/* ******** Color to BW ******** */
ConvertColorToBWOperation::ConvertColorToBWOperation() : ConvertBaseOperation()
@@ -94,6 +119,13 @@ void ConvertColorToBWOperation::executePixelSampled(float output[4],
output[0] = IMB_colormanagement_get_luminance(inputColor);
}
void ConvertColorToBWOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
it.out[0] = IMB_colormanagement_get_luminance(it.in(0));
}
}
/* ******** Color to Vector ******** */
ConvertColorToVectorOperation::ConvertColorToVectorOperation() : ConvertBaseOperation()
@@ -112,6 +144,13 @@ void ConvertColorToVectorOperation::executePixelSampled(float output[4],
copy_v3_v3(output, color);
}
void ConvertColorToVectorOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
copy_v3_v3(it.out, it.in(0));
}
}
/* ******** Value to Vector ******** */
ConvertValueToVectorOperation::ConvertValueToVectorOperation() : ConvertBaseOperation()
@@ -130,6 +169,13 @@ void ConvertValueToVectorOperation::executePixelSampled(float output[4],
output[0] = output[1] = output[2] = value;
}
void ConvertValueToVectorOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
it.out[0] = it.out[1] = it.out[2] = *it.in(0);
}
}
/* ******** Vector to Color ******** */
ConvertVectorToColorOperation::ConvertVectorToColorOperation() : ConvertBaseOperation()
@@ -147,6 +193,14 @@ void ConvertVectorToColorOperation::executePixelSampled(float output[4],
output[3] = 1.0f;
}
void ConvertVectorToColorOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
copy_v3_v3(it.out, it.in(0));
it.out[3] = 1.0f;
}
}
/* ******** Vector to Value ******** */
ConvertVectorToValueOperation::ConvertVectorToValueOperation() : ConvertBaseOperation()
@@ -165,6 +219,14 @@ void ConvertVectorToValueOperation::executePixelSampled(float output[4],
output[0] = (input[0] + input[1] + input[2]) / 3.0f;
}
void ConvertVectorToValueOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
it.out[0] = (in[0] + in[1] + in[2]) / 3.0f;
}
}
/* ******** RGB to YCC ******** */
ConvertRGBToYCCOperation::ConvertRGBToYCCOperation() : ConvertBaseOperation()
@@ -207,6 +269,18 @@ void ConvertRGBToYCCOperation::executePixelSampled(float output[4],
output[3] = inputColor[3];
}
void ConvertRGBToYCCOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
rgb_to_ycc(in[0], in[1], in[2], &it.out[0], &it.out[1], &it.out[2], this->m_mode);
/* Normalize for viewing (#rgb_to_ycc returns 0-255 values). */
mul_v3_fl(it.out, 1.0f / 255.0f);
it.out[3] = in[3];
}
}
/* ******** YCC to RGB ******** */
ConvertYCCToRGBOperation::ConvertYCCToRGBOperation() : ConvertBaseOperation()
@@ -253,6 +327,22 @@ void ConvertYCCToRGBOperation::executePixelSampled(float output[4],
output[3] = inputColor[3];
}
void ConvertYCCToRGBOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
/* Multiply by 255 to un-normalize (#ycc_to_rgb needs input values in 0-255 range). */
ycc_to_rgb(in[0] * 255.0f,
in[1] * 255.0f,
in[2] * 255.0f,
&it.out[0],
&it.out[1],
&it.out[2],
this->m_mode);
it.out[3] = in[3];
}
}
/* ******** RGB to YUV ******** */
ConvertRGBToYUVOperation::ConvertRGBToYUVOperation() : ConvertBaseOperation()
@@ -278,6 +368,15 @@ void ConvertRGBToYUVOperation::executePixelSampled(float output[4],
output[3] = inputColor[3];
}
void ConvertRGBToYUVOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
rgb_to_yuv(in[0], in[1], in[2], &it.out[0], &it.out[1], &it.out[2], BLI_YUV_ITU_BT709);
it.out[3] = in[3];
}
}
/* ******** YUV to RGB ******** */
ConvertYUVToRGBOperation::ConvertYUVToRGBOperation() : ConvertBaseOperation()
@@ -303,6 +402,15 @@ void ConvertYUVToRGBOperation::executePixelSampled(float output[4],
output[3] = inputColor[3];
}
void ConvertYUVToRGBOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
yuv_to_rgb(in[0], in[1], in[2], &it.out[0], &it.out[1], &it.out[2], BLI_YUV_ITU_BT709);
it.out[3] = in[3];
}
}
/* ******** RGB to HSV ******** */
ConvertRGBToHSVOperation::ConvertRGBToHSVOperation() : ConvertBaseOperation()
@@ -322,6 +430,15 @@ void ConvertRGBToHSVOperation::executePixelSampled(float output[4],
output[3] = inputColor[3];
}
void ConvertRGBToHSVOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
rgb_to_hsv_v(in, it.out);
it.out[3] = in[3];
}
}
/* ******** HSV to RGB ******** */
ConvertHSVToRGBOperation::ConvertHSVToRGBOperation() : ConvertBaseOperation()
@@ -344,6 +461,18 @@ void ConvertHSVToRGBOperation::executePixelSampled(float output[4],
output[3] = inputColor[3];
}
void ConvertHSVToRGBOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
hsv_to_rgb_v(in, it.out);
it.out[0] = max_ff(it.out[0], 0.0f);
it.out[1] = max_ff(it.out[1], 0.0f);
it.out[2] = max_ff(it.out[2], 0.0f);
it.out[3] = in[3];
}
}
/* ******** Premul to Straight ******** */
ConvertPremulToStraightOperation::ConvertPremulToStraightOperation() : ConvertBaseOperation()
@@ -363,6 +492,13 @@ void ConvertPremulToStraightOperation::executePixelSampled(float output[4],
copy_v4_v4(output, converted);
}
void ConvertPremulToStraightOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
copy_v4_v4(it.out, ColorSceneLinear4f<eAlpha::Premultiplied>(it.in(0)).unpremultiply_alpha());
}
}
/* ******** Straight to Premul ******** */
ConvertStraightToPremulOperation::ConvertStraightToPremulOperation() : ConvertBaseOperation()
@@ -382,6 +518,13 @@ void ConvertStraightToPremulOperation::executePixelSampled(float output[4],
copy_v4_v4(output, converted);
}
void ConvertStraightToPremulOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
copy_v4_v4(it.out, ColorSceneLinear4f<eAlpha::Straight>(it.in(0)).premultiply_alpha());
}
}
/* ******** Separate Channels ******** */
SeparateChannelOperation::SeparateChannelOperation()
@@ -410,6 +553,15 @@ void SeparateChannelOperation::executePixelSampled(float output[4],
output[0] = input[this->m_channel];
}
void SeparateChannelOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
it.out[0] = it.in(0)[this->m_channel];
}
}
/* ******** Combine Channels ******** */
CombineChannelsOperation::CombineChannelsOperation()
@@ -466,4 +618,16 @@ void CombineChannelsOperation::executePixelSampled(float output[4],
}
}
void CombineChannelsOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
it.out[0] = *it.in(0);
it.out[1] = *it.in(1);
it.out[2] = *it.in(2);
it.out[3] = *it.in(3);
}
}
} // namespace blender::compositor

View File

@@ -18,11 +18,11 @@
#pragma once
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
class ConvertBaseOperation : public NodeOperation {
class ConvertBaseOperation : public MultiThreadedOperation {
protected:
SocketReader *m_inputOperation;
@@ -31,6 +31,13 @@ class ConvertBaseOperation : public NodeOperation {
void initExecution() override;
void deinitExecution() override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) final;
protected:
virtual void update_memory_buffer_partial(BuffersIterator<float> &it) = 0;
};
class ConvertValueToColorOperation : public ConvertBaseOperation {
@@ -38,6 +45,9 @@ class ConvertValueToColorOperation : public ConvertBaseOperation {
ConvertValueToColorOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertColorToValueOperation : public ConvertBaseOperation {
@@ -45,6 +55,9 @@ class ConvertColorToValueOperation : public ConvertBaseOperation {
ConvertColorToValueOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertColorToBWOperation : public ConvertBaseOperation {
@@ -52,6 +65,9 @@ class ConvertColorToBWOperation : public ConvertBaseOperation {
ConvertColorToBWOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertColorToVectorOperation : public ConvertBaseOperation {
@@ -59,6 +75,9 @@ class ConvertColorToVectorOperation : public ConvertBaseOperation {
ConvertColorToVectorOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertValueToVectorOperation : public ConvertBaseOperation {
@@ -66,6 +85,9 @@ class ConvertValueToVectorOperation : public ConvertBaseOperation {
ConvertValueToVectorOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertVectorToColorOperation : public ConvertBaseOperation {
@@ -73,6 +95,9 @@ class ConvertVectorToColorOperation : public ConvertBaseOperation {
ConvertVectorToColorOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertVectorToValueOperation : public ConvertBaseOperation {
@@ -80,6 +105,9 @@ class ConvertVectorToValueOperation : public ConvertBaseOperation {
ConvertVectorToValueOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertRGBToYCCOperation : public ConvertBaseOperation {
@@ -94,6 +122,9 @@ class ConvertRGBToYCCOperation : public ConvertBaseOperation {
/** Set the YCC mode */
void setMode(int mode);
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertYCCToRGBOperation : public ConvertBaseOperation {
@@ -108,6 +139,9 @@ class ConvertYCCToRGBOperation : public ConvertBaseOperation {
/** Set the YCC mode */
void setMode(int mode);
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertRGBToYUVOperation : public ConvertBaseOperation {
@@ -115,6 +149,9 @@ class ConvertRGBToYUVOperation : public ConvertBaseOperation {
ConvertRGBToYUVOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertYUVToRGBOperation : public ConvertBaseOperation {
@@ -122,6 +159,9 @@ class ConvertYUVToRGBOperation : public ConvertBaseOperation {
ConvertYUVToRGBOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertRGBToHSVOperation : public ConvertBaseOperation {
@@ -129,6 +169,9 @@ class ConvertRGBToHSVOperation : public ConvertBaseOperation {
ConvertRGBToHSVOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertHSVToRGBOperation : public ConvertBaseOperation {
@@ -136,6 +179,9 @@ class ConvertHSVToRGBOperation : public ConvertBaseOperation {
ConvertHSVToRGBOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertPremulToStraightOperation : public ConvertBaseOperation {
@@ -143,6 +189,9 @@ class ConvertPremulToStraightOperation : public ConvertBaseOperation {
ConvertPremulToStraightOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertStraightToPremulOperation : public ConvertBaseOperation {
@@ -150,9 +199,12 @@ class ConvertStraightToPremulOperation : public ConvertBaseOperation {
ConvertStraightToPremulOperation();
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class SeparateChannelOperation : public NodeOperation {
class SeparateChannelOperation : public MultiThreadedOperation {
private:
SocketReader *m_inputOperation;
int m_channel;
@@ -168,9 +220,13 @@ class SeparateChannelOperation : public NodeOperation {
{
this->m_channel = channel;
}
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
class CombineChannelsOperation : public NodeOperation {
class CombineChannelsOperation : public MultiThreadedOperation {
private:
SocketReader *m_inputChannel1Operation;
SocketReader *m_inputChannel2Operation;
@@ -183,6 +239,10 @@ class CombineChannelsOperation : public NodeOperation {
void initExecution() override;
void deinitExecution() override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor

View File

@@ -24,6 +24,8 @@ namespace blender::compositor {
MathBaseOperation::MathBaseOperation()
{
/* TODO(manzanilla): after removing tiled implementation, template this class to only add needed
* number of inputs. */
this->addInputSocket(DataType::Value);
this->addInputSocket(DataType::Value);
this->addInputSocket(DataType::Value);
@@ -32,6 +34,7 @@ MathBaseOperation::MathBaseOperation()
this->m_inputValue2Operation = nullptr;
this->m_inputValue3Operation = nullptr;
this->m_useClamp = false;
this->flags.can_be_constant = true;
}
void MathBaseOperation::initExecution()
@@ -73,6 +76,14 @@ void MathBaseOperation::clampIfNeeded(float *color)
}
}
void MathBaseOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
BuffersIterator<float> it = output->iterate_with(inputs, area);
update_memory_buffer_partial(it);
}
void MathAddOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float inputValue1[4];
@@ -139,6 +150,14 @@ void MathDivideOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathDivideOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float divisor = *it.in(1);
*it.out = clamp_when_enabled((divisor == 0) ? 0 : *it.in(0) / divisor);
}
}
void MathSineOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -155,6 +174,14 @@ void MathSineOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathSineOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = sin(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathCosineOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -171,6 +198,14 @@ void MathCosineOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathCosineOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = cos(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathTangentOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -187,6 +222,14 @@ void MathTangentOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathTangentOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = tan(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathHyperbolicSineOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -203,6 +246,14 @@ void MathHyperbolicSineOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathHyperbolicSineOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = sinh(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathHyperbolicCosineOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -219,6 +270,14 @@ void MathHyperbolicCosineOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathHyperbolicCosineOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = cosh(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathHyperbolicTangentOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -235,6 +294,14 @@ void MathHyperbolicTangentOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathHyperbolicTangentOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = tanh(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathArcSineOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -256,6 +323,14 @@ void MathArcSineOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathArcSineOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
float value1 = *it.in(0);
*it.out = clamp_when_enabled((value1 <= 1 && value1 >= -1) ? asin(value1) : 0.0f);
}
}
void MathArcCosineOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -277,6 +352,14 @@ void MathArcCosineOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathArcCosineOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
float value1 = *it.in(0);
*it.out = clamp_when_enabled((value1 <= 1 && value1 >= -1) ? acos(value1) : 0.0f);
}
}
void MathArcTangentOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -293,6 +376,14 @@ void MathArcTangentOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathArcTangentOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = atan(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathPowerOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -321,6 +412,29 @@ void MathPowerOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathPowerOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value1 = *it.in(0);
const float value2 = *it.in(1);
if (value1 >= 0) {
*it.out = pow(value1, value2);
}
else {
const float y_mod_1 = fmod(value2, 1);
/* If input value is not nearly an integer, fall back to zero, nicer than straight rounding.
*/
if (y_mod_1 > 0.999f || y_mod_1 < 0.001f) {
*it.out = pow(value1, floorf(value2 + 0.5f));
}
else {
*it.out = 0.0f;
}
}
clamp_when_enabled(it.out);
}
}
void MathLogarithmOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -342,6 +456,21 @@ void MathLogarithmOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathLogarithmOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value1 = *it.in(0);
const float value2 = *it.in(1);
if (value1 > 0 && value2 > 0) {
*it.out = log(value1) / log(value2);
}
else {
*it.out = 0.0;
}
clamp_when_enabled(it.out);
}
}
void MathMinimumOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -358,6 +487,14 @@ void MathMinimumOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathMinimumOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = MIN2(*it.in(0), *it.in(1));
clamp_when_enabled(it.out);
}
}
void MathMaximumOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -374,6 +511,14 @@ void MathMaximumOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathMaximumOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = MAX2(*it.in(0), *it.in(1));
clamp_when_enabled(it.out);
}
}
void MathRoundOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -390,6 +535,14 @@ void MathRoundOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathRoundOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = round(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathLessThanOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -443,6 +596,15 @@ void MathModuloOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathModuloOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value2 = *it.in(1);
*it.out = (value2 == 0) ? 0 : fmod(*it.in(0), value2);
clamp_when_enabled(it.out);
}
}
void MathAbsoluteOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -457,6 +619,14 @@ void MathAbsoluteOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathAbsoluteOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = fabs(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathRadiansOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -471,6 +641,14 @@ void MathRadiansOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathRadiansOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = DEG2RADF(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathDegreesOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -485,6 +663,14 @@ void MathDegreesOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathDegreesOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = RAD2DEGF(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathArcTan2Operation::executePixelSampled(float output[4],
float x,
float y,
@@ -501,6 +687,14 @@ void MathArcTan2Operation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathArcTan2Operation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = atan2(*it.in(0), *it.in(1));
clamp_when_enabled(it.out);
}
}
void MathFloorOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -515,6 +709,14 @@ void MathFloorOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathFloorOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = floor(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathCeilOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -529,6 +731,14 @@ void MathCeilOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathCeilOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = ceil(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathFractOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -543,6 +753,14 @@ void MathFractOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathFractOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value = *it.in(0);
*it.out = clamp_when_enabled(value - floor(value));
}
}
void MathSqrtOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -562,6 +780,14 @@ void MathSqrtOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathSqrtOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value = *it.in(0);
*it.out = clamp_when_enabled(value > 0 ? sqrt(value) : 0.0f);
}
}
void MathInverseSqrtOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -581,6 +807,14 @@ void MathInverseSqrtOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathInverseSqrtOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value = *it.in(0);
*it.out = clamp_when_enabled(value > 0 ? 1.0f / sqrt(value) : 0.0f);
}
}
void MathSignOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -595,6 +829,14 @@ void MathSignOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathSignOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = compatible_signf(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathExponentOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -609,6 +851,14 @@ void MathExponentOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathExponentOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = expf(*it.in(0));
clamp_when_enabled(it.out);
}
}
void MathTruncOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -623,6 +873,15 @@ void MathTruncOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathTruncOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value = *it.in(0);
*it.out = (value >= 0.0f) ? floor(value) : ceil(value);
clamp_when_enabled(it.out);
}
}
void MathSnapOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -644,6 +903,21 @@ void MathSnapOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathSnapOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value1 = *it.in(0);
const float value2 = *it.in(1);
if (value1 == 0 || value2 == 0) { /* Avoid dividing by zero. */
*it.out = 0.0f;
}
else {
*it.out = floorf(value1 / value2) * value2;
}
clamp_when_enabled(it.out);
}
}
void MathWrapOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -662,6 +936,14 @@ void MathWrapOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathWrapOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = wrapf(*it.in(0), *it.in(1), *it.in(2));
clamp_when_enabled(it.out);
}
}
void MathPingpongOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -678,6 +960,14 @@ void MathPingpongOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathPingpongOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = pingpongf(*it.in(0), *it.in(1));
clamp_when_enabled(it.out);
}
}
void MathCompareOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -697,6 +987,14 @@ void MathCompareOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathCompareOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = (fabsf(*it.in(0) - *it.in(1)) <= MAX2(*it.in(2), 1e-5f)) ? 1.0f : 0.0f;
clamp_when_enabled(it.out);
}
}
void MathMultiplyAddOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -715,6 +1013,14 @@ void MathMultiplyAddOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathMultiplyAddOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = it.in(0)[0] * it.in(1)[0] + it.in(2)[0];
clamp_when_enabled(it.out);
}
}
void MathSmoothMinOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -733,6 +1039,14 @@ void MathSmoothMinOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathSmoothMinOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = smoothminf(*it.in(0), *it.in(1), *it.in(2));
clamp_when_enabled(it.out);
}
}
void MathSmoothMaxOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -751,4 +1065,12 @@ void MathSmoothMaxOperation::executePixelSampled(float output[4],
clampIfNeeded(output);
}
void MathSmoothMaxOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
*it.out = -smoothminf(-it.in(0)[0], -it.in(1)[0], it.in(2)[0]);
clamp_when_enabled(it.out);
}
}
} // namespace blender::compositor

View File

@@ -18,7 +18,7 @@
#pragma once
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
@@ -26,7 +26,7 @@ namespace blender::compositor {
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
class MathBaseOperation : public NodeOperation {
class MathBaseOperation : public MultiThreadedOperation {
protected:
/**
* Prefetched reference to the inputProgram
@@ -43,8 +43,24 @@ class MathBaseOperation : public NodeOperation {
*/
MathBaseOperation();
/* TODO(manzanilla): to be removed with tiled implementation. */
void clampIfNeeded(float color[4]);
float clamp_when_enabled(float value)
{
if (this->m_useClamp) {
return CLAMPIS(value, 0.0f, 1.0f);
}
return value;
}
void clamp_when_enabled(float *out)
{
if (this->m_useClamp) {
CLAMP(*out, 0.0f, 1.0f);
}
}
public:
/**
* Initialize the execution
@@ -66,87 +82,151 @@ class MathBaseOperation : public NodeOperation {
{
this->m_useClamp = value;
}
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) final;
protected:
virtual void update_memory_buffer_partial(BuffersIterator<float> &it) = 0;
};
class MathAddOperation : public MathBaseOperation {
template<template<typename> typename TFunctor>
class MathFunctor2Operation : public MathBaseOperation {
void update_memory_buffer_partial(BuffersIterator<float> &it) final
{
TFunctor functor;
for (; !it.is_end(); ++it) {
*it.out = functor(*it.in(0), *it.in(1));
clamp_when_enabled(it.out);
}
}
};
class MathAddOperation : public MathFunctor2Operation<std::plus> {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
};
class MathSubtractOperation : public MathBaseOperation {
class MathSubtractOperation : public MathFunctor2Operation<std::minus> {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
};
class MathMultiplyOperation : public MathBaseOperation {
class MathMultiplyOperation : public MathFunctor2Operation<std::multiplies> {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
};
class MathDivideOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathSineOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathCosineOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathTangentOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathHyperbolicSineOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathHyperbolicCosineOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathHyperbolicTangentOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathArcSineOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathArcCosineOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathArcTangentOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathPowerOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathLogarithmOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathMinimumOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathMaximumOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathRoundOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathLessThanOperation : public MathBaseOperation {
class MathLessThanOperation : public MathFunctor2Operation<std::less> {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
};
class MathGreaterThanOperation : public MathBaseOperation {
class MathGreaterThanOperation : public MathFunctor2Operation<std::greater> {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
};
@@ -154,101 +234,161 @@ class MathGreaterThanOperation : public MathBaseOperation {
class MathModuloOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathAbsoluteOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathRadiansOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathDegreesOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathArcTan2Operation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathFloorOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathCeilOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathFractOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathSqrtOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathInverseSqrtOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathSignOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathExponentOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathTruncOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathSnapOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathWrapOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathPingpongOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathCompareOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathMultiplyAddOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathSmoothMinOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathSmoothMaxOperation : public MathBaseOperation {
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
} // namespace blender::compositor

View File

@@ -28,6 +28,7 @@ SetAlphaMultiplyOperation::SetAlphaMultiplyOperation()
this->m_inputColor = nullptr;
this->m_inputAlpha = nullptr;
this->flags.can_be_constant = true;
}
void SetAlphaMultiplyOperation::initExecution()
@@ -56,4 +57,15 @@ void SetAlphaMultiplyOperation::deinitExecution()
this->m_inputAlpha = nullptr;
}
void SetAlphaMultiplyOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
const float *color = it.in(0);
const float alpha = *it.in(1);
mul_v4_v4fl(it.out, color, alpha);
}
}
} // namespace blender::compositor

View File

@@ -18,7 +18,7 @@
#pragma once
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
@@ -27,7 +27,7 @@ namespace blender::compositor {
*
* `output color.rgba = input color.rgba * input alpha`
*/
class SetAlphaMultiplyOperation : public NodeOperation {
class SetAlphaMultiplyOperation : public MultiThreadedOperation {
private:
SocketReader *m_inputColor;
SocketReader *m_inputAlpha;
@@ -39,6 +39,10 @@ class SetAlphaMultiplyOperation : public NodeOperation {
void initExecution() override;
void deinitExecution() override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor

View File

@@ -28,6 +28,7 @@ SetAlphaReplaceOperation::SetAlphaReplaceOperation()
this->m_inputColor = nullptr;
this->m_inputAlpha = nullptr;
this->flags.can_be_constant = true;
}
void SetAlphaReplaceOperation::initExecution()
@@ -54,4 +55,16 @@ void SetAlphaReplaceOperation::deinitExecution()
this->m_inputAlpha = nullptr;
}
void SetAlphaReplaceOperation::update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs)
{
for (BuffersIterator<float> it = output->iterate_with(inputs, area); !it.is_end(); ++it) {
const float *color = it.in(0);
const float alpha = *it.in(1);
copy_v3_v3(it.out, color);
it.out[3] = alpha;
}
}
} // namespace blender::compositor

View File

@@ -18,7 +18,7 @@
#pragma once
#include "COM_NodeOperation.h"
#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
@@ -26,7 +26,7 @@ namespace blender::compositor {
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
class SetAlphaReplaceOperation : public NodeOperation {
class SetAlphaReplaceOperation : public MultiThreadedOperation {
private:
SocketReader *m_inputColor;
SocketReader *m_inputAlpha;
@@ -44,6 +44,10 @@ class SetAlphaReplaceOperation : public NodeOperation {
void initExecution() override;
void deinitExecution() override;
void update_memory_buffer_partial(MemoryBuffer *output,
const rcti &area,
Span<MemoryBuffer *> inputs) override;
};
} // namespace blender::compositor