Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Castilla <manzanillawork@gmail.com>2021-07-26 20:07:08 +0300
committerManuel Castilla <manzanillawork@gmail.com>2021-07-26 21:13:03 +0300
commita117794f8c05ad2e2b7db0b0f43c3059f20e62a1 (patch)
tree8f29140bdbfc0f669f7301f5f3ccc8115bb374f9 /source/blender
parentcf74cd93674c11e8e5ef599100d0c7bf3cc8a79c (diff)
Compositor: Full frame Scale node
Adds full frame implementation to this node operations. No functional changes. Includes a new operation method `init_data` used to initialize any data needed after operations are linked and resolutions determined. Once tiled implementation is removed `initExecution` may be renamed to `init_rendering` and `init_data` to `init_execution`. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D11944
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/compositor/intern/COM_ConstantFolder.cc1
-rw-r--r--source/blender/compositor/intern/COM_Converter.cc2
-rw-r--r--source/blender/compositor/intern/COM_Enums.cc19
-rw-r--r--source/blender/compositor/intern/COM_Enums.h9
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.cc3
-rw-r--r--source/blender/compositor/intern/COM_MemoryBuffer.h23
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cc5
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h12
-rw-r--r--source/blender/compositor/nodes/COM_ScaleNode.cc4
-rw-r--r--source/blender/compositor/nodes/COM_Stabilize2dNode.cc2
-rw-r--r--source/blender/compositor/nodes/COM_TransformNode.cc2
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.cc188
-rw-r--r--source/blender/compositor/operations/COM_ScaleOperation.h67
13 files changed, 265 insertions, 72 deletions
diff --git a/source/blender/compositor/intern/COM_ConstantFolder.cc b/source/blender/compositor/intern/COM_ConstantFolder.cc
index 15450572958..5b48ff8fc08 100644
--- a/source/blender/compositor/intern/COM_ConstantFolder.cc
+++ b/source/blender/compositor/intern/COM_ConstantFolder.cc
@@ -94,6 +94,7 @@ ConstantOperation *ConstantFolder::fold_operation(NodeOperation *operation)
const DataType data_type = operation->getOutputSocket()->getDataType();
MemoryBuffer fold_buf(data_type, first_elem_area_);
Vector<MemoryBuffer *> input_bufs = get_constant_input_buffers(operation);
+ operation->init_data();
operation->render(&fold_buf, {first_elem_area_}, input_bufs);
MemoryBuffer *constant_buf = create_constant_buffer(data_type);
diff --git a/source/blender/compositor/intern/COM_Converter.cc b/source/blender/compositor/intern/COM_Converter.cc
index 18973bb5a00..1983eb190e2 100644
--- a/source/blender/compositor/intern/COM_Converter.cc
+++ b/source/blender/compositor/intern/COM_Converter.cc
@@ -518,7 +518,7 @@ void COM_convert_resolution(NodeOperationBuilder &builder,
NodeOperation *first = nullptr;
ScaleOperation *scaleOperation = nullptr;
if (doScale) {
- scaleOperation = new ScaleOperation(fromSocket->getDataType());
+ scaleOperation = new ScaleRelativeOperation(fromSocket->getDataType());
scaleOperation->getInputSocket(1)->setResizeMode(ResizeMode::None);
scaleOperation->getInputSocket(2)->setResizeMode(ResizeMode::None);
first = scaleOperation;
diff --git a/source/blender/compositor/intern/COM_Enums.cc b/source/blender/compositor/intern/COM_Enums.cc
index d218de92544..2f20d2652ba 100644
--- a/source/blender/compositor/intern/COM_Enums.cc
+++ b/source/blender/compositor/intern/COM_Enums.cc
@@ -17,9 +17,28 @@
*/
#include "COM_Enums.h"
+#include "BLI_rect.h"
namespace blender::compositor {
+void expand_area_for_sampler(rcti &area, PixelSampler sampler)
+{
+ switch (sampler) {
+ case PixelSampler::Nearest:
+ break;
+ case PixelSampler::Bilinear:
+ area.xmax += 1;
+ area.ymax += 1;
+ break;
+ case PixelSampler::Bicubic:
+ area.xmin -= 1;
+ area.xmax += 2;
+ area.ymin -= 1;
+ area.ymax += 2;
+ break;
+ }
+}
+
std::ostream &operator<<(std::ostream &os, const eCompositorPriority &priority)
{
switch (priority) {
diff --git a/source/blender/compositor/intern/COM_Enums.h b/source/blender/compositor/intern/COM_Enums.h
index 519e7df940e..7e5a1b73132 100644
--- a/source/blender/compositor/intern/COM_Enums.h
+++ b/source/blender/compositor/intern/COM_Enums.h
@@ -22,6 +22,8 @@
#include <ostream>
+struct rcti;
+
namespace blender::compositor {
/**
@@ -85,6 +87,13 @@ enum class eWorkPackageType {
CustomFunction = 1
};
+enum class PixelSampler {
+ Nearest = 0,
+ Bilinear = 1,
+ Bicubic = 2,
+};
+void expand_area_for_sampler(rcti &area, PixelSampler sampler);
+
std::ostream &operator<<(std::ostream &os, const eCompositorPriority &priority);
std::ostream &operator<<(std::ostream &os, const eWorkPackageState &execution_state);
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cc b/source/blender/compositor/intern/COM_ExecutionSystem.cc
index 60caf22be1b..cd2738fc2c7 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.cc
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.cc
@@ -112,6 +112,9 @@ void ExecutionSystem::set_operations(const Vector<NodeOperation *> &operations,
void ExecutionSystem::execute()
{
DebugInfo::execute_started(this);
+ for (NodeOperation *op : m_operations) {
+ op->init_data();
+ }
execution_model_->execute(*this);
}
diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.h b/source/blender/compositor/intern/COM_MemoryBuffer.h
index 048ed4c5d6e..ae12c444dc1 100644
--- a/source/blender/compositor/intern/COM_MemoryBuffer.h
+++ b/source/blender/compositor/intern/COM_MemoryBuffer.h
@@ -189,6 +189,25 @@ class MemoryBuffer {
return m_buffer + get_coords_offset(x, y);
}
+ void read_elem(int x, int y, float *out) const
+ {
+ memcpy(out, get_elem(x, y), m_num_channels * sizeof(float));
+ }
+
+ void read_elem_sampled(float x, float y, PixelSampler sampler, float *out) const
+ {
+ switch (sampler) {
+ case PixelSampler::Nearest:
+ this->read_elem(x, y, out);
+ break;
+ case PixelSampler::Bilinear:
+ case PixelSampler::Bicubic:
+ /* No bicubic. Current implementation produces fuzzy results. */
+ this->readBilinear(out, x, y);
+ break;
+ }
+ }
+
/**
* Get channel value at given coordinates.
*/
@@ -330,7 +349,7 @@ class MemoryBuffer {
inline void wrap_pixel(float &x,
float &y,
MemoryBufferExtend extend_x,
- MemoryBufferExtend extend_y)
+ MemoryBufferExtend extend_y) const
{
const float w = (float)getWidth();
const float h = (float)getHeight();
@@ -427,7 +446,7 @@ class MemoryBuffer {
float x,
float y,
MemoryBufferExtend extend_x = MemoryBufferExtend::Clip,
- MemoryBufferExtend extend_y = MemoryBufferExtend::Clip)
+ MemoryBufferExtend extend_y = MemoryBufferExtend::Clip) const
{
float u = x;
float v = y;
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index 4e115cb3f2f..575e8446abe 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -100,6 +100,11 @@ void NodeOperation::setResolutionInputSocketIndex(unsigned int index)
{
this->m_resolutionInputSocketIndex = index;
}
+
+void NodeOperation::init_data()
+{
+ /* Pass. */
+}
void NodeOperation::initExecution()
{
/* pass */
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index fb9ec1e7a83..934007d25ce 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -75,12 +75,6 @@ enum class ResizeMode {
Stretch = NS_CR_STRETCH,
};
-enum class PixelSampler {
- Nearest = 0,
- Bilinear = 1,
- Bicubic = 2,
-};
-
class NodeOperationInput {
private:
NodeOperation *m_operation;
@@ -424,6 +418,12 @@ class NodeOperation {
exec_system_ = system;
}
+ /**
+ * Initializes operation data needed after operations are linked and resolutions determined. For
+ * rendering heap memory data use initExecution().
+ */
+ virtual void init_data();
+
virtual void initExecution();
/**
diff --git a/source/blender/compositor/nodes/COM_ScaleNode.cc b/source/blender/compositor/nodes/COM_ScaleNode.cc
index 50d2902f375..819d2e72f30 100644
--- a/source/blender/compositor/nodes/COM_ScaleNode.cc
+++ b/source/blender/compositor/nodes/COM_ScaleNode.cc
@@ -43,7 +43,7 @@ void ScaleNode::convertToOperations(NodeConverter &converter,
switch (bnode->custom1) {
case CMP_SCALE_RELATIVE: {
- ScaleOperation *operation = new ScaleOperation();
+ ScaleRelativeOperation *operation = new ScaleRelativeOperation();
converter.addOperation(operation);
converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
@@ -59,7 +59,7 @@ void ScaleNode::convertToOperations(NodeConverter &converter,
scaleFactorOperation->setValue(context.getRenderPercentageAsFactor());
converter.addOperation(scaleFactorOperation);
- ScaleOperation *operation = new ScaleOperation();
+ ScaleRelativeOperation *operation = new ScaleRelativeOperation();
converter.addOperation(operation);
converter.mapInputSocket(inputSocket, operation->getInputSocket(0));
diff --git a/source/blender/compositor/nodes/COM_Stabilize2dNode.cc b/source/blender/compositor/nodes/COM_Stabilize2dNode.cc
index fc72b48eca2..0262f653d1a 100644
--- a/source/blender/compositor/nodes/COM_Stabilize2dNode.cc
+++ b/source/blender/compositor/nodes/COM_Stabilize2dNode.cc
@@ -43,7 +43,7 @@ void Stabilize2dNode::convertToOperations(NodeConverter &converter,
MovieClip *clip = (MovieClip *)editorNode->id;
bool invert = (editorNode->custom2 & CMP_NODEFLAG_STABILIZE_INVERSE) != 0;
- ScaleOperation *scaleOperation = new ScaleOperation();
+ ScaleRelativeOperation *scaleOperation = new ScaleRelativeOperation();
scaleOperation->setSampler((PixelSampler)editorNode->custom1);
RotateOperation *rotateOperation = new RotateOperation();
rotateOperation->setDoDegree2RadConversion(false);
diff --git a/source/blender/compositor/nodes/COM_TransformNode.cc b/source/blender/compositor/nodes/COM_TransformNode.cc
index cd12939ab43..e1deaf616a4 100644
--- a/source/blender/compositor/nodes/COM_TransformNode.cc
+++ b/source/blender/compositor/nodes/COM_TransformNode.cc
@@ -40,7 +40,7 @@ void TransformNode::convertToOperations(NodeConverter &converter,
NodeInput *angleInput = this->getInputSocket(3);
NodeInput *scaleInput = this->getInputSocket(4);
- ScaleOperation *scaleOperation = new ScaleOperation();
+ ScaleRelativeOperation *scaleOperation = new ScaleRelativeOperation();
converter.addOperation(scaleOperation);
RotateOperation *rotateOperation = new RotateOperation();
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.cc b/source/blender/compositor/operations/COM_ScaleOperation.cc
index f03b9fcf34d..2cb61ae746b 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.cc
+++ b/source/blender/compositor/operations/COM_ScaleOperation.cc
@@ -17,6 +17,7 @@
*/
#include "COM_ScaleOperation.h"
+#include "COM_ConstantOperation.h"
namespace blender::compositor {
@@ -52,13 +53,60 @@ ScaleOperation::ScaleOperation(DataType data_type) : BaseScaleOperation()
this->m_inputXOperation = nullptr;
this->m_inputYOperation = nullptr;
}
+
+static std::optional<float> get_constant_scale(NodeOperation *op)
+{
+ if (op->get_flags().is_constant_operation) {
+ return ((ConstantOperation *)op)->get_constant_elem()[0];
+ }
+
+ return std::optional<float>();
+}
+
+float ScaleOperation::get_constant_scale_x()
+{
+ std::optional<float> scale_x = get_constant_scale(getInputOperation(1));
+ if (scale_x.has_value()) {
+ return scale_x.value() * get_relative_scale_x_factor();
+ }
+
+ return 1.0f;
+}
+
+float ScaleOperation::get_constant_scale_y()
+{
+ std::optional<float> scale_y = get_constant_scale(getInputOperation(2));
+ if (scale_y.has_value()) {
+ return scale_y.value() * get_relative_scale_y_factor();
+ }
+
+ return 1.0f;
+}
+
+BLI_INLINE float scale_coord(const int coord, const float center, const float relative_scale)
+{
+ return center + (coord - center) / relative_scale;
+}
+
+void ScaleOperation::scale_area(rcti &rect, float scale_x, float scale_y)
+{
+ rect.xmin = scale_coord(rect.xmin, m_centerX, scale_x);
+ rect.xmax = scale_coord(rect.xmax, m_centerX, scale_x);
+ rect.ymin = scale_coord(rect.ymin, m_centerY, scale_y);
+ rect.ymax = scale_coord(rect.ymax, m_centerY, scale_y);
+}
+
+void ScaleOperation::init_data()
+{
+ m_centerX = getWidth() / 2.0f;
+ m_centerY = getHeight() / 2.0f;
+}
+
void ScaleOperation::initExecution()
{
this->m_inputOperation = this->getInputSocketReader(0);
this->m_inputXOperation = this->getInputSocketReader(1);
this->m_inputYOperation = this->getInputSocketReader(2);
- this->m_centerX = this->getWidth() / 2.0;
- this->m_centerY = this->getHeight() / 2.0;
}
void ScaleOperation::deinitExecution()
@@ -68,7 +116,52 @@ void ScaleOperation::deinitExecution()
this->m_inputYOperation = nullptr;
}
-void ScaleOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+void ScaleOperation::get_area_of_interest(const int input_idx,
+ const rcti &output_area,
+ rcti &r_input_area)
+{
+ r_input_area = output_area;
+ if (input_idx != 0 || m_variable_size) {
+ return;
+ }
+
+ float scale_x = get_constant_scale_x();
+ float scale_y = get_constant_scale_y();
+ scale_area(r_input_area, scale_x, scale_y);
+ expand_area_for_sampler(r_input_area, (PixelSampler)m_sampler);
+}
+
+void ScaleOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ const MemoryBuffer *input_img = inputs[0];
+ MemoryBuffer *input_x = inputs[1];
+ MemoryBuffer *input_y = inputs[2];
+ const float scale_x_factor = get_relative_scale_x_factor();
+ const float scale_y_factor = get_relative_scale_y_factor();
+ BuffersIterator<float> it = output->iterate_with({input_x, input_y}, area);
+ for (; !it.is_end(); ++it) {
+ const float rel_scale_x = *it.in(0) * scale_x_factor;
+ const float rel_scale_y = *it.in(1) * scale_y_factor;
+ const float scaled_x = scale_coord(it.x, m_centerX, rel_scale_x);
+ const float scaled_y = scale_coord(it.y, m_centerY, rel_scale_y);
+ input_img->read_elem_sampled(scaled_x, scaled_y, (PixelSampler)m_sampler, it.out);
+ }
+}
+
+ScaleRelativeOperation::ScaleRelativeOperation() : ScaleOperation()
+{
+}
+
+ScaleRelativeOperation::ScaleRelativeOperation(DataType data_type) : ScaleOperation(data_type)
+{
+}
+
+void ScaleRelativeOperation::executePixelSampled(float output[4],
+ float x,
+ float y,
+ PixelSampler sampler)
{
PixelSampler effective_sampler = getEffectiveSampler(sampler);
@@ -86,9 +179,9 @@ void ScaleOperation::executePixelSampled(float output[4], float x, float y, Pixe
this->m_inputOperation->readSampled(output, nx, ny, effective_sampler);
}
-bool ScaleOperation::determineDependingAreaOfInterest(rcti *input,
- ReadBufferOperation *readOperation,
- rcti *output)
+bool ScaleRelativeOperation::determineDependingAreaOfInterest(rcti *input,
+ ReadBufferOperation *readOperation,
+ rcti *output)
{
rcti newInput;
if (!m_variable_size) {
@@ -115,34 +208,6 @@ bool ScaleOperation::determineDependingAreaOfInterest(rcti *input,
return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
-// SCALE ABSOLUTE
-ScaleAbsoluteOperation::ScaleAbsoluteOperation() : BaseScaleOperation()
-{
- this->addInputSocket(DataType::Color);
- this->addInputSocket(DataType::Value);
- this->addInputSocket(DataType::Value);
- this->addOutputSocket(DataType::Color);
- this->setResolutionInputSocketIndex(0);
- this->m_inputOperation = nullptr;
- this->m_inputXOperation = nullptr;
- this->m_inputYOperation = nullptr;
-}
-void ScaleAbsoluteOperation::initExecution()
-{
- this->m_inputOperation = this->getInputSocketReader(0);
- this->m_inputXOperation = this->getInputSocketReader(1);
- this->m_inputYOperation = this->getInputSocketReader(2);
- this->m_centerX = this->getWidth() / 2.0;
- this->m_centerY = this->getHeight() / 2.0;
-}
-
-void ScaleAbsoluteOperation::deinitExecution()
-{
- this->m_inputOperation = nullptr;
- this->m_inputXOperation = nullptr;
- this->m_inputYOperation = nullptr;
-}
-
void ScaleAbsoluteOperation::executePixelSampled(float output[4],
float x,
float y,
@@ -202,8 +267,7 @@ bool ScaleAbsoluteOperation::determineDependingAreaOfInterest(rcti *input,
newInput.ymax = this->getHeight();
newInput.ymin = 0;
}
-
- return BaseScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
+ return ScaleOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
}
// Absolute fixed size
@@ -215,11 +279,12 @@ ScaleFixedSizeOperation::ScaleFixedSizeOperation() : BaseScaleOperation()
this->m_inputOperation = nullptr;
this->m_is_offset = false;
}
-void ScaleFixedSizeOperation::initExecution()
+
+void ScaleFixedSizeOperation::init_data()
{
- this->m_inputOperation = this->getInputSocketReader(0);
- this->m_relX = this->m_inputOperation->getWidth() / (float)this->m_newWidth;
- this->m_relY = this->m_inputOperation->getHeight() / (float)this->m_newHeight;
+ const NodeOperation *input_op = getInputOperation(0);
+ this->m_relX = input_op->getWidth() / (float)this->m_newWidth;
+ this->m_relY = input_op->getHeight() / (float)this->m_newHeight;
/* *** all the options below are for a fairly special case - camera framing *** */
if (this->m_offsetX != 0.0f || this->m_offsetY != 0.0f) {
@@ -237,8 +302,8 @@ void ScaleFixedSizeOperation::initExecution()
if (this->m_is_aspect) {
/* apply aspect from clip */
- const float w_src = this->m_inputOperation->getWidth();
- const float h_src = this->m_inputOperation->getHeight();
+ const float w_src = input_op->getWidth();
+ const float h_src = input_op->getHeight();
/* destination aspect is already applied from the camera frame */
const float w_dst = this->m_newWidth;
@@ -267,6 +332,11 @@ void ScaleFixedSizeOperation::initExecution()
/* *** end framing options *** */
}
+void ScaleFixedSizeOperation::initExecution()
+{
+ this->m_inputOperation = this->getInputSocketReader(0);
+}
+
void ScaleFixedSizeOperation::deinitExecution()
{
this->m_inputOperation = nullptr;
@@ -315,4 +385,38 @@ void ScaleFixedSizeOperation::determineResolution(unsigned int resolution[2],
resolution[1] = this->m_newHeight;
}
+void ScaleFixedSizeOperation::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 - m_offsetX) * this->m_relX;
+ r_input_area.xmin = (output_area.xmin - m_offsetX) * this->m_relX;
+ r_input_area.ymax = (output_area.ymax - m_offsetY) * this->m_relY;
+ r_input_area.ymin = (output_area.ymin - m_offsetY) * this->m_relY;
+ expand_area_for_sampler(r_input_area, (PixelSampler)m_sampler);
+}
+
+void ScaleFixedSizeOperation::update_memory_buffer_partial(MemoryBuffer *output,
+ const rcti &area,
+ Span<MemoryBuffer *> inputs)
+{
+ const MemoryBuffer *input_img = inputs[0];
+ PixelSampler sampler = (PixelSampler)m_sampler;
+ BuffersIterator<float> it = output->iterate_with({}, area);
+ if (this->m_is_offset) {
+ for (; !it.is_end(); ++it) {
+ const float nx = (it.x - this->m_offsetX) * this->m_relX;
+ const float ny = (it.y - this->m_offsetY) * this->m_relY;
+ input_img->read_elem_sampled(nx, ny, sampler, it.out);
+ }
+ }
+ else {
+ for (; !it.is_end(); ++it) {
+ input_img->read_elem_sampled(it.x * this->m_relX, it.y * this->m_relY, sampler, it.out);
+ }
+ }
+}
+
} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ScaleOperation.h b/source/blender/compositor/operations/COM_ScaleOperation.h
index 2f9a7be92e6..b2f41a1e98a 100644
--- a/source/blender/compositor/operations/COM_ScaleOperation.h
+++ b/source/blender/compositor/operations/COM_ScaleOperation.h
@@ -18,11 +18,11 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_MultiThreadedOperation.h"
namespace blender::compositor {
-class BaseScaleOperation : public NodeOperation {
+class BaseScaleOperation : public MultiThreadedOperation {
public:
void setSampler(PixelSampler sampler)
{
@@ -46,7 +46,7 @@ class BaseScaleOperation : public NodeOperation {
};
class ScaleOperation : public BaseScaleOperation {
- private:
+ protected:
SocketReader *m_inputOperation;
SocketReader *m_inputXOperation;
SocketReader *m_inputYOperation;
@@ -56,31 +56,58 @@ class ScaleOperation : public BaseScaleOperation {
public:
ScaleOperation();
ScaleOperation(DataType data_type);
- bool determineDependingAreaOfInterest(rcti *input,
- ReadBufferOperation *readOperation,
- rcti *output) override;
- void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+ void init_data() override;
void initExecution() override;
void deinitExecution() override;
-};
-class ScaleAbsoluteOperation : public BaseScaleOperation {
- SocketReader *m_inputOperation;
- SocketReader *m_inputXOperation;
- SocketReader *m_inputYOperation;
- float m_centerX;
- float m_centerY;
+ 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;
+
+ protected:
+ virtual float get_relative_scale_x_factor() = 0;
+ virtual float get_relative_scale_y_factor() = 0;
+
+ private:
+ float get_constant_scale_x();
+ float get_constant_scale_y();
+ void scale_area(rcti &rect, float scale_x, float scale_y);
+};
+class ScaleRelativeOperation : public ScaleOperation {
public:
- ScaleAbsoluteOperation();
+ ScaleRelativeOperation();
+ ScaleRelativeOperation(DataType data_type);
bool determineDependingAreaOfInterest(rcti *input,
ReadBufferOperation *readOperation,
rcti *output) override;
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+ float get_relative_scale_x_factor() override
+ {
+ return 1.0f;
+ }
+ float get_relative_scale_y_factor() override
+ {
+ return 1.0f;
+ }
+};
- void initExecution() override;
- void deinitExecution() override;
+class ScaleAbsoluteOperation : public ScaleOperation {
+ public:
+ bool determineDependingAreaOfInterest(rcti *input,
+ ReadBufferOperation *readOperation,
+ rcti *output) override;
+ void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+ float get_relative_scale_x_factor() override
+ {
+ return 1.0f / getWidth();
+ }
+ float get_relative_scale_y_factor() override
+ {
+ return 1.0f / getHeight();
+ }
};
class ScaleFixedSizeOperation : public BaseScaleOperation {
@@ -108,6 +135,7 @@ class ScaleFixedSizeOperation : public BaseScaleOperation {
unsigned int preferredResolution[2]) override;
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
+ void init_data() override;
void initExecution() override;
void deinitExecution() override;
void setNewWidth(int width)
@@ -131,6 +159,11 @@ class ScaleFixedSizeOperation : public BaseScaleOperation {
this->m_offsetX = x;
this->m_offsetY = y;
}
+
+ 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