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:
-rw-r--r--source/blender/compositor/CMakeLists.txt4
-rw-r--r--source/blender/compositor/intern/COM_BufferOperation.cc7
-rw-r--r--source/blender/compositor/intern/COM_BufferOperation.h5
-rw-r--r--source/blender/compositor/intern/COM_ConstantFolder.cc186
-rw-r--r--source/blender/compositor/intern/COM_ConstantFolder.h64
-rw-r--r--source/blender/compositor/intern/COM_Debug.cc9
-rw-r--r--source/blender/compositor/intern/COM_Debug.h2
-rw-r--r--source/blender/compositor/intern/COM_FullFrameExecutionModel.cc6
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cc6
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h14
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cc32
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.h3
-rw-r--r--source/blender/compositor/operations/COM_ConstantOperation.cc28
-rw-r--r--source/blender/compositor/operations/COM_ConstantOperation.h36
-rw-r--r--source/blender/compositor/operations/COM_SetColorOperation.h9
-rw-r--r--source/blender/compositor/operations/COM_SetValueOperation.h9
-rw-r--r--source/blender/compositor/operations/COM_SetVectorOperation.cc6
-rw-r--r--source/blender/compositor/operations/COM_SetVectorOperation.h35
18 files changed, 431 insertions, 30 deletions
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index c6d52a19e43..08d9be8b90e 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -59,6 +59,8 @@ set(SRC
intern/COM_ChunkOrderHotspot.h
intern/COM_CompositorContext.cc
intern/COM_CompositorContext.h
+ intern/COM_ConstantFolder.cc
+ intern/COM_ConstantFolder.h
intern/COM_Converter.cc
intern/COM_Converter.h
intern/COM_Debug.cc
@@ -450,6 +452,8 @@ set(SRC
operations/COM_MixOperation.h
operations/COM_ReadBufferOperation.cc
operations/COM_ReadBufferOperation.h
+ operations/COM_ConstantOperation.cc
+ operations/COM_ConstantOperation.h
operations/COM_SetColorOperation.cc
operations/COM_SetColorOperation.h
operations/COM_SetValueOperation.cc
diff --git a/source/blender/compositor/intern/COM_BufferOperation.cc b/source/blender/compositor/intern/COM_BufferOperation.cc
index c07a6f01451..90c97f2a9c7 100644
--- a/source/blender/compositor/intern/COM_BufferOperation.cc
+++ b/source/blender/compositor/intern/COM_BufferOperation.cc
@@ -31,6 +31,13 @@ BufferOperation::BufferOperation(MemoryBuffer *buffer, DataType data_type)
resolution[1] = buffer->getHeight();
setResolution(resolution);
addOutputSocket(data_type);
+ flags.is_constant_operation = buffer_->is_a_single_elem();
+}
+
+const float *BufferOperation::get_constant_elem()
+{
+ BLI_assert(buffer_->is_a_single_elem());
+ return buffer_->getBuffer();
}
void *BufferOperation::initializeTileData(rcti * /*rect*/)
diff --git a/source/blender/compositor/intern/COM_BufferOperation.h b/source/blender/compositor/intern/COM_BufferOperation.h
index e07f5bde6bf..705264c37b7 100644
--- a/source/blender/compositor/intern/COM_BufferOperation.h
+++ b/source/blender/compositor/intern/COM_BufferOperation.h
@@ -18,11 +18,11 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_ConstantOperation.h"
namespace blender::compositor {
-class BufferOperation : public NodeOperation {
+class BufferOperation : public ConstantOperation {
private:
MemoryBuffer *buffer_;
MemoryBuffer *inflated_buffer_;
@@ -30,6 +30,7 @@ class BufferOperation : public NodeOperation {
public:
BufferOperation(MemoryBuffer *buffer, DataType data_type);
+ const float *get_constant_elem() override;
void *initializeTileData(rcti *rect) override;
void deinitExecution() override;
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler) override;
diff --git a/source/blender/compositor/intern/COM_ConstantFolder.cc b/source/blender/compositor/intern/COM_ConstantFolder.cc
new file mode 100644
index 00000000000..0612c25cf94
--- /dev/null
+++ b/source/blender/compositor/intern/COM_ConstantFolder.cc
@@ -0,0 +1,186 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#include "BLI_rect.h"
+
+#include "COM_ConstantFolder.h"
+#include "COM_ConstantOperation.h"
+#include "COM_SetColorOperation.h"
+#include "COM_SetValueOperation.h"
+#include "COM_SetVectorOperation.h"
+
+namespace blender::compositor {
+
+using Link = NodeOperationBuilder::Link;
+
+/**
+ * \param operations_builder: Contains all operations to fold.
+ * \param exec_system: Execution system.
+ */
+ConstantFolder::ConstantFolder(NodeOperationBuilder &operations_builder)
+ : operations_builder_(operations_builder)
+{
+ BLI_rcti_init(&max_area_, INT_MIN, INT_MAX, INT_MIN, INT_MAX);
+ BLI_rcti_init(&first_elem_area_, 0, 1, 0, 1);
+}
+
+static bool is_constant_foldable(NodeOperation *operation)
+{
+ if (operation->get_flags().can_be_constant && !operation->get_flags().is_constant_operation) {
+ for (int i = 0; i < operation->getNumberOfInputSockets(); i++) {
+ if (!operation->get_input_operation(i)->get_flags().is_constant_operation) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+static Vector<NodeOperation *> find_constant_foldable_operations(Span<NodeOperation *> operations)
+{
+ Vector<NodeOperation *> foldable_ops;
+ for (NodeOperation *op : operations) {
+ if (is_constant_foldable(op)) {
+ foldable_ops.append(op);
+ }
+ }
+ return foldable_ops;
+}
+
+static ConstantOperation *create_constant_operation(DataType data_type, const float *constant_elem)
+{
+ switch (data_type) {
+ case DataType::Color: {
+ SetColorOperation *color_op = new SetColorOperation();
+ color_op->setChannels(constant_elem);
+ return color_op;
+ }
+ case DataType::Vector: {
+ SetVectorOperation *vector_op = new SetVectorOperation();
+ vector_op->setVector(constant_elem);
+ return vector_op;
+ }
+ case DataType::Value: {
+ SetValueOperation *value_op = new SetValueOperation();
+ value_op->setValue(*constant_elem);
+ return value_op;
+ }
+ default: {
+ BLI_assert(!"Non implemented data type");
+ return nullptr;
+ }
+ }
+}
+
+ConstantOperation *ConstantFolder::fold_operation(NodeOperation *operation)
+{
+ const DataType data_type = operation->getOutputSocket()->getDataType();
+ MemoryBuffer *fold_buf = create_constant_buffer(data_type);
+ Vector<MemoryBuffer *> input_bufs = get_constant_input_buffers(operation);
+ operation->render(fold_buf, {first_elem_area_}, input_bufs);
+
+ ConstantOperation *constant_op = create_constant_operation(data_type, fold_buf->getBuffer());
+ operations_builder_.replace_operation_with_constant(operation, constant_op);
+ constant_buffers_.add_new(constant_op, fold_buf);
+ return constant_op;
+}
+
+MemoryBuffer *ConstantFolder::create_constant_buffer(const DataType data_type)
+{
+ /* Create a single elem buffer with maximum area possible so readers can read any coordinate
+ * returning always same element. */
+ return new MemoryBuffer(data_type, max_area_, true);
+}
+
+Vector<MemoryBuffer *> ConstantFolder::get_constant_input_buffers(NodeOperation *operation)
+{
+ const int num_inputs = operation->getNumberOfInputSockets();
+ Vector<MemoryBuffer *> inputs_bufs(num_inputs);
+ for (int i = 0; i < num_inputs; i++) {
+ BLI_assert(operation->get_input_operation(i)->get_flags().is_constant_operation);
+ ConstantOperation *constant_op = static_cast<ConstantOperation *>(
+ operation->get_input_operation(i));
+ MemoryBuffer *constant_buf = constant_buffers_.lookup_or_add_cb(constant_op, [=] {
+ MemoryBuffer *buf = create_constant_buffer(constant_op->getOutputSocket()->getDataType());
+ constant_op->render(buf, {first_elem_area_}, {});
+ return buf;
+ });
+ inputs_bufs[i] = constant_buf;
+ }
+ return inputs_bufs;
+}
+
+/** Returns constant operations resulted from folded operations. */
+Vector<ConstantOperation *> ConstantFolder::try_fold_operations(Span<NodeOperation *> operations)
+{
+ Vector<NodeOperation *> foldable_ops = find_constant_foldable_operations(operations);
+ if (foldable_ops.size() == 0) {
+ return Vector<ConstantOperation *>();
+ }
+
+ Vector<ConstantOperation *> new_folds;
+ for (NodeOperation *op : foldable_ops) {
+ ConstantOperation *constant_op = fold_operation(op);
+ new_folds.append(constant_op);
+ }
+ return new_folds;
+}
+
+/**
+ * Evaluate operations with constant elements into primitive constant operations.
+ */
+int ConstantFolder::fold_operations()
+{
+ Vector<ConstantOperation *> last_folds = try_fold_operations(
+ operations_builder_.get_operations());
+ int folds_count = last_folds.size();
+ while (last_folds.size() > 0) {
+ Vector<NodeOperation *> ops_to_fold;
+ for (ConstantOperation *fold : last_folds) {
+ get_operation_output_operations(fold, ops_to_fold);
+ }
+ last_folds = try_fold_operations(ops_to_fold);
+ folds_count += last_folds.size();
+ }
+
+ delete_constant_buffers();
+
+ return folds_count;
+}
+
+void ConstantFolder::delete_constant_buffers()
+{
+ for (MemoryBuffer *buf : constant_buffers_.values()) {
+ delete buf;
+ }
+ constant_buffers_.clear();
+}
+
+void ConstantFolder::get_operation_output_operations(NodeOperation *operation,
+ Vector<NodeOperation *> &r_outputs)
+{
+ const Vector<Link> &links = operations_builder_.get_links();
+ for (const Link &link : links) {
+ if (&link.from()->getOperation() == operation) {
+ r_outputs.append(&link.to()->getOperation());
+ }
+ }
+}
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/intern/COM_ConstantFolder.h b/source/blender/compositor/intern/COM_ConstantFolder.h
new file mode 100644
index 00000000000..2432e859a5a
--- /dev/null
+++ b/source/blender/compositor/intern/COM_ConstantFolder.h
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#pragma once
+
+#include "BLI_map.hh"
+#include "BLI_set.hh"
+#include "BLI_vector.hh"
+
+#include "COM_NodeOperationBuilder.h"
+#include "COM_defines.h"
+
+namespace blender::compositor {
+
+class NodeOperation;
+class ConstantOperation;
+class MemoryBuffer;
+
+/**
+ * Evaluates all operations with constant elements into primitive constant operations
+ * (Value/Vector/Color).
+ */
+class ConstantFolder {
+ private:
+ NodeOperationBuilder &operations_builder_;
+
+ /** Constant operations buffers. */
+ Map<ConstantOperation *, MemoryBuffer *> constant_buffers_;
+
+ rcti max_area_;
+ rcti first_elem_area_;
+
+ public:
+ ConstantFolder(NodeOperationBuilder &operations_builder);
+ int fold_operations();
+
+ private:
+ Vector<ConstantOperation *> try_fold_operations(Span<NodeOperation *> operations);
+ ConstantOperation *fold_operation(NodeOperation *operation);
+
+ MemoryBuffer *create_constant_buffer(DataType data_type);
+ Vector<MemoryBuffer *> get_constant_input_buffers(NodeOperation *operation);
+ void delete_constant_buffers();
+
+ void get_operation_output_operations(NodeOperation *operation,
+ Vector<NodeOperation *> &r_outputs);
+};
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc
index 4cf7e09a7d8..f5af7cf9147 100644
--- a/source/blender/compositor/intern/COM_Debug.cc
+++ b/source/blender/compositor/intern/COM_Debug.cc
@@ -401,7 +401,7 @@ bool DebugInfo::graphviz_system(const ExecutionSystem *system, char *str, int ma
return (len < maxlen);
}
-void DebugInfo::graphviz(const ExecutionSystem *system)
+void DebugInfo::graphviz(const ExecutionSystem *system, StringRefNull name)
{
if (!COM_EXPORT_GRAPHVIZ) {
return;
@@ -411,7 +411,12 @@ void DebugInfo::graphviz(const ExecutionSystem *system)
char basename[FILE_MAX];
char filename[FILE_MAX];
- BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index);
+ if (name.is_empty()) {
+ BLI_snprintf(basename, sizeof(basename), "compositor_%d.dot", m_file_index);
+ }
+ else {
+ BLI_strncpy(basename, (name + ".dot").c_str(), sizeof(basename));
+ }
BLI_join_dirfile(filename, sizeof(filename), BKE_tempdir_session(), basename);
m_file_index++;
diff --git a/source/blender/compositor/intern/COM_Debug.h b/source/blender/compositor/intern/COM_Debug.h
index 0de3a5e39dc..a2fbab45a2c 100644
--- a/source/blender/compositor/intern/COM_Debug.h
+++ b/source/blender/compositor/intern/COM_Debug.h
@@ -116,7 +116,7 @@ class DebugInfo {
}
};
- static void graphviz(const ExecutionSystem *system);
+ static void graphviz(const ExecutionSystem *system, StringRefNull name = "");
protected:
static int graphviz_operation(const ExecutionSystem *system,
diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
index c9fc11868e8..c61512ef49e 100644
--- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
@@ -60,7 +60,7 @@ void FullFrameExecutionModel::execute(ExecutionSystem &exec_system)
const bNodeTree *node_tree = this->context_.getbNodeTree();
node_tree->stats_draw(node_tree->sdh, TIP_("Compositing | Initializing execution"));
- DebugInfo::graphviz(&exec_system);
+ DebugInfo::graphviz(&exec_system, "compositor_prior_rendering");
determine_areas_to_render_and_reads();
render_operations();
@@ -101,9 +101,7 @@ MemoryBuffer *FullFrameExecutionModel::create_operation_buffer(NodeOperation *op
BLI_rcti_init(&op_rect, 0, op->getWidth(), 0, op->getHeight());
const DataType data_type = op->getOutputSocket(0)->getDataType();
- /* TODO: We should check if the operation is constant instead of is_set_operation. Finding a way
- * to know if an operation is constant has to be implemented yet. */
- const bool is_a_single_elem = op->get_flags().is_set_operation;
+ const bool is_a_single_elem = op->get_flags().is_constant_operation;
return new MemoryBuffer(data_type, op_rect, is_a_single_elem);
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index 04c5019af62..6484c75f364 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -441,6 +441,12 @@ std::ostream &operator<<(std::ostream &os, const NodeOperationFlags &node_operat
if (node_operation_flags.is_fullframe_operation) {
os << "full_frame,";
}
+ if (node_operation_flags.is_constant_operation) {
+ os << "contant_operation,";
+ }
+ if (node_operation_flags.can_be_constant) {
+ os << "can_be_constant,";
+ }
return os;
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index 168cdbda573..fb9ec1e7a83 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -221,6 +221,7 @@ struct NodeOperationFlags {
/**
* Is this a set operation (value, color, vector).
+ * TODO: To be replaced by is_constant_operation flag once tiled implementation is removed.
*/
bool is_set_operation : 1;
bool is_write_buffer_operation : 1;
@@ -242,6 +243,17 @@ struct NodeOperationFlags {
*/
bool is_fullframe_operation : 1;
+ /**
+ * Whether operation is a primitive constant operation (Color/Vector/Value).
+ */
+ bool is_constant_operation : 1;
+
+ /**
+ * Whether operation have constant elements/pixels values when all its inputs are constant
+ * operations.
+ */
+ bool can_be_constant : 1;
+
NodeOperationFlags()
{
complex = false;
@@ -258,6 +270,8 @@ struct NodeOperationFlags {
is_preview_operation = false;
use_datatype_conversion = true;
is_fullframe_operation = false;
+ is_constant_operation = false;
+ can_be_constant = false;
}
};
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
index 3036e3f55dd..a679f347ab6 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
@@ -36,6 +36,7 @@
#include "COM_ViewerOperation.h"
#include "COM_WriteBufferOperation.h"
+#include "COM_ConstantFolder.h"
#include "COM_NodeOperationBuilder.h" /* own include */
namespace blender::compositor {
@@ -97,6 +98,15 @@ void NodeOperationBuilder::convertToOperations(ExecutionSystem *system)
add_datatype_conversions();
+ if (m_context->get_execution_model() == eExecutionModel::FullFrame) {
+ /* Copy operations to system. Needed for graphviz. */
+ system->set_operations(m_operations, {});
+
+ DebugInfo::graphviz(system, "compositor_prior_folding");
+ ConstantFolder folder(*this);
+ folder.fold_operations();
+ }
+
determineResolutions();
if (m_context->get_execution_model() == eExecutionModel::Tiled) {
@@ -132,6 +142,28 @@ void NodeOperationBuilder::addOperation(NodeOperation *operation)
operation->set_execution_model(m_context->get_execution_model());
}
+void NodeOperationBuilder::replace_operation_with_constant(NodeOperation *operation,
+ ConstantOperation *constant_operation)
+{
+ BLI_assert(constant_operation->getNumberOfInputSockets() == 0);
+ int i = 0;
+ while (i < m_links.size()) {
+ Link &link = m_links[i];
+ if (&link.to()->getOperation() == operation) {
+ link.to()->setLink(nullptr);
+ m_links.remove(i);
+ continue;
+ }
+
+ if (&link.from()->getOperation() == operation) {
+ link.to()->setLink(constant_operation->getOutputSocket());
+ m_links[i] = Link(constant_operation->getOutputSocket(), link.to());
+ }
+ i++;
+ }
+ addOperation(constant_operation);
+}
+
void NodeOperationBuilder::mapInputSocket(NodeInput *node_socket,
NodeOperationInput *operation_socket)
{
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
index b2fb822af25..6c4bf397d92 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.h
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
@@ -41,6 +41,7 @@ class NodeOperationOutput;
class PreviewOperation;
class WriteBufferOperation;
class ViewerOperation;
+class ConstantOperation;
class NodeOperationBuilder {
public:
@@ -96,6 +97,8 @@ class NodeOperationBuilder {
void convertToOperations(ExecutionSystem *system);
void addOperation(NodeOperation *operation);
+ void replace_operation_with_constant(NodeOperation *operation,
+ ConstantOperation *constant_operation);
/** Map input socket of the current node to an operation socket */
void mapInputSocket(NodeInput *node_socket, NodeOperationInput *operation_socket);
diff --git a/source/blender/compositor/operations/COM_ConstantOperation.cc b/source/blender/compositor/operations/COM_ConstantOperation.cc
new file mode 100644
index 00000000000..f905edbde76
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConstantOperation.cc
@@ -0,0 +1,28 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#include "COM_ConstantOperation.h"
+
+namespace blender::compositor {
+
+ConstantOperation::ConstantOperation()
+{
+ flags.is_constant_operation = true;
+}
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_ConstantOperation.h b/source/blender/compositor/operations/COM_ConstantOperation.h
new file mode 100644
index 00000000000..2709efeebd8
--- /dev/null
+++ b/source/blender/compositor/operations/COM_ConstantOperation.h
@@ -0,0 +1,36 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2021, Blender Foundation.
+ */
+
+#pragma once
+
+#include "COM_NodeOperation.h"
+
+namespace blender::compositor {
+
+/**
+ * Base class for primitive constant operations (Color/Vector/Value). The rest of operations that
+ * can be constant are evaluated into primitives during constant folding.
+ */
+class ConstantOperation : public NodeOperation {
+ public:
+ ConstantOperation();
+
+ virtual const float *get_constant_elem() = 0;
+};
+
+} // namespace blender::compositor
diff --git a/source/blender/compositor/operations/COM_SetColorOperation.h b/source/blender/compositor/operations/COM_SetColorOperation.h
index 6785a2c5ca3..f4c0948ee1b 100644
--- a/source/blender/compositor/operations/COM_SetColorOperation.h
+++ b/source/blender/compositor/operations/COM_SetColorOperation.h
@@ -18,7 +18,7 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_ConstantOperation.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 SetColorOperation : public NodeOperation {
+class SetColorOperation : public ConstantOperation {
private:
float m_color[4];
@@ -36,6 +36,11 @@ class SetColorOperation : public NodeOperation {
*/
SetColorOperation();
+ const float *get_constant_elem() override
+ {
+ return m_color;
+ }
+
float getChannel1()
{
return this->m_color[0];
diff --git a/source/blender/compositor/operations/COM_SetValueOperation.h b/source/blender/compositor/operations/COM_SetValueOperation.h
index e346bc12ffb..f18d44d9554 100644
--- a/source/blender/compositor/operations/COM_SetValueOperation.h
+++ b/source/blender/compositor/operations/COM_SetValueOperation.h
@@ -18,7 +18,7 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_ConstantOperation.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 SetValueOperation : public NodeOperation {
+class SetValueOperation : public ConstantOperation {
private:
float m_value;
@@ -36,6 +36,11 @@ class SetValueOperation : public NodeOperation {
*/
SetValueOperation();
+ const float *get_constant_elem() override
+ {
+ return &m_value;
+ }
+
float getValue()
{
return this->m_value;
diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cc b/source/blender/compositor/operations/COM_SetVectorOperation.cc
index 7152d5e61d4..7b8cf44048c 100644
--- a/source/blender/compositor/operations/COM_SetVectorOperation.cc
+++ b/source/blender/compositor/operations/COM_SetVectorOperation.cc
@@ -32,9 +32,9 @@ void SetVectorOperation::executePixelSampled(float output[4],
float /*y*/,
PixelSampler /*sampler*/)
{
- output[0] = this->m_x;
- output[1] = this->m_y;
- output[2] = this->m_z;
+ output[0] = vector_.x;
+ output[1] = vector_.y;
+ output[2] = vector_.z;
}
void SetVectorOperation::determineResolution(unsigned int resolution[2],
diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.h b/source/blender/compositor/operations/COM_SetVectorOperation.h
index b444339fcb2..41fd06659d6 100644
--- a/source/blender/compositor/operations/COM_SetVectorOperation.h
+++ b/source/blender/compositor/operations/COM_SetVectorOperation.h
@@ -18,7 +18,7 @@
#pragma once
-#include "COM_NodeOperation.h"
+#include "COM_ConstantOperation.h"
namespace blender::compositor {
@@ -26,12 +26,14 @@ namespace blender::compositor {
* this program converts an input color to an output value.
* it assumes we are in sRGB color space.
*/
-class SetVectorOperation : public NodeOperation {
+class SetVectorOperation : public ConstantOperation {
private:
- float m_x;
- float m_y;
- float m_z;
- float m_w;
+ struct {
+ float x;
+ float y;
+ float z;
+ float w;
+ } vector_;
public:
/**
@@ -39,37 +41,42 @@ class SetVectorOperation : public NodeOperation {
*/
SetVectorOperation();
+ const float *get_constant_elem() override
+ {
+ return reinterpret_cast<float *>(&vector_);
+ }
+
float getX()
{
- return this->m_x;
+ return vector_.x;
}
void setX(float value)
{
- this->m_x = value;
+ vector_.x = value;
}
float getY()
{
- return this->m_y;
+ return vector_.y;
}
void setY(float value)
{
- this->m_y = value;
+ vector_.y = value;
}
float getZ()
{
- return this->m_z;
+ return vector_.z;
}
void setZ(float value)
{
- this->m_z = value;
+ vector_.z = value;
}
float getW()
{
- return this->m_w;
+ return vector_.w;
}
void setW(float value)
{
- this->m_w = value;
+ vector_.w = value;
}
/**