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-09-28 20:32:49 +0300
committerManuel Castilla <manzanillawork@gmail.com>2021-09-28 23:00:16 +0300
commit76377f0176b9561a7fc8f46b4ed704c631ddd90d (patch)
tree96775442f403dfdb0dc4d91f835495c72c1ca9c1 /source/blender/compositor/intern
parent2ecd963d87e4f5215d1d86e7f1c22ab7833697f3 (diff)
Compositor: Replace resolution concept by canvas
This is a code refactor in preparation of supporting canvas compositing. See {D12466}. No functional changes, all canvases are at (0,0) position matching tiled implementation. Differential Revision: https://developer.blender.org/D12465
Diffstat (limited to 'source/blender/compositor/intern')
-rw-r--r--source/blender/compositor/intern/COM_BufferOperation.cc7
-rw-r--r--source/blender/compositor/intern/COM_Converter.cc22
-rw-r--r--source/blender/compositor/intern/COM_Converter.h6
-rw-r--r--source/blender/compositor/intern/COM_Debug.cc4
-rw-r--r--source/blender/compositor/intern/COM_FullFrameExecutionModel.cc10
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.cc85
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h92
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cc25
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.h4
9 files changed, 115 insertions, 140 deletions
diff --git a/source/blender/compositor/intern/COM_BufferOperation.cc b/source/blender/compositor/intern/COM_BufferOperation.cc
index cafdff89c8e..c6530cf6bd1 100644
--- a/source/blender/compositor/intern/COM_BufferOperation.cc
+++ b/source/blender/compositor/intern/COM_BufferOperation.cc
@@ -24,12 +24,7 @@ BufferOperation::BufferOperation(MemoryBuffer *buffer, DataType data_type)
{
buffer_ = buffer;
inflated_buffer_ = nullptr;
- /* TODO: Implement a MemoryBuffer get_size() method returning a Size2d type. Shorten following
- * code to: set_resolution(buffer.get_size()) */
- unsigned int resolution[2];
- resolution[0] = buffer->getWidth();
- resolution[1] = buffer->getHeight();
- setResolution(resolution);
+ set_canvas(buffer->get_rect());
addOutputSocket(data_type);
flags.is_constant_operation = buffer_->is_a_single_elem();
flags.is_fullframe_operation = false;
diff --git a/source/blender/compositor/intern/COM_Converter.cc b/source/blender/compositor/intern/COM_Converter.cc
index 4b103c21c75..bd05a8e4ef0 100644
--- a/source/blender/compositor/intern/COM_Converter.cc
+++ b/source/blender/compositor/intern/COM_Converter.cc
@@ -460,9 +460,9 @@ NodeOperation *COM_convert_data_type(const NodeOperationOutput &from, const Node
return nullptr;
}
-void COM_convert_resolution(NodeOperationBuilder &builder,
- NodeOperationOutput *fromSocket,
- NodeOperationInput *toSocket)
+void COM_convert_canvas(NodeOperationBuilder &builder,
+ NodeOperationOutput *fromSocket,
+ NodeOperationInput *toSocket)
{
/* Data type conversions are executed before resolutions to ensure convert operations have
* resolution. This method have to ensure same datatypes are linked for new operations. */
@@ -535,10 +535,10 @@ void COM_convert_resolution(NodeOperationBuilder &builder,
builder.addOperation(sxop);
builder.addOperation(syop);
- unsigned int resolution[2] = {fromOperation->getWidth(), fromOperation->getHeight()};
- scaleOperation->setResolution(resolution);
- sxop->setResolution(resolution);
- syop->setResolution(resolution);
+ const rcti &scale_canvas = fromOperation->get_canvas();
+ scaleOperation->set_canvas(scale_canvas);
+ sxop->set_canvas(scale_canvas);
+ syop->set_canvas(scale_canvas);
builder.addOperation(scaleOperation);
}
@@ -557,10 +557,10 @@ void COM_convert_resolution(NodeOperationBuilder &builder,
builder.addOperation(xop);
builder.addOperation(yop);
- unsigned int resolution[2] = {toOperation->getWidth(), toOperation->getHeight()};
- translateOperation->setResolution(resolution);
- xop->setResolution(resolution);
- yop->setResolution(resolution);
+ const rcti &translate_canvas = toOperation->get_canvas();
+ translateOperation->set_canvas(translate_canvas);
+ xop->set_canvas(translate_canvas);
+ yop->set_canvas(translate_canvas);
builder.addOperation(translateOperation);
if (doScale) {
diff --git a/source/blender/compositor/intern/COM_Converter.h b/source/blender/compositor/intern/COM_Converter.h
index 28136437103..7f0402d4e70 100644
--- a/source/blender/compositor/intern/COM_Converter.h
+++ b/source/blender/compositor/intern/COM_Converter.h
@@ -65,8 +65,8 @@ NodeOperation *COM_convert_data_type(const NodeOperationOutput &from,
* \note Conversion logic is implemented in this function.
* \see InputSocketResizeMode for the possible conversions.
*/
-void COM_convert_resolution(NodeOperationBuilder &builder,
- NodeOperationOutput *fromSocket,
- NodeOperationInput *toSocket);
+void COM_convert_canvas(NodeOperationBuilder &builder,
+ NodeOperationOutput *fromSocket,
+ NodeOperationInput *toSocket);
} // namespace blender::compositor
diff --git a/source/blender/compositor/intern/COM_Debug.cc b/source/blender/compositor/intern/COM_Debug.cc
index f2dcba65b7c..9e47aa9fcb5 100644
--- a/source/blender/compositor/intern/COM_Debug.cc
+++ b/source/blender/compositor/intern/COM_Debug.cc
@@ -162,8 +162,10 @@ int DebugInfo::graphviz_operation(const ExecutionSystem *system,
len += snprintf(str + len,
maxlen > len ? maxlen - len : 0,
- "#%d (%u,%u)",
+ "#%d (%i,%i) (%u,%u)",
operation->get_id(),
+ operation->get_canvas().xmin,
+ operation->get_canvas().ymin,
operation->getWidth(),
operation->getHeight());
diff --git a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
index bd3a481d691..957bbe24e5f 100644
--- a/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
+++ b/source/blender/compositor/intern/COM_FullFrameExecutionModel.cc
@@ -87,12 +87,9 @@ Vector<MemoryBuffer *> FullFrameExecutionModel::get_input_buffers(NodeOperation
MemoryBuffer *FullFrameExecutionModel::create_operation_buffer(NodeOperation *op)
{
- rcti op_rect;
- BLI_rcti_init(&op_rect, 0, op->getWidth(), 0, op->getHeight());
-
const DataType data_type = op->getOutputSocket(0)->getDataType();
const bool is_a_single_elem = op->get_flags().is_constant_operation;
- return new MemoryBuffer(data_type, op_rect, is_a_single_elem);
+ return new MemoryBuffer(data_type, op->get_canvas(), is_a_single_elem);
}
void FullFrameExecutionModel::render_operation(NodeOperation *op)
@@ -199,12 +196,11 @@ void FullFrameExecutionModel::determine_areas_to_render(NodeOperation *output_op
const int num_inputs = operation->getNumberOfInputSockets();
for (int i = 0; i < num_inputs; i++) {
NodeOperation *input_op = operation->get_input_operation(i);
- rcti input_op_rect, input_area;
- BLI_rcti_init(&input_op_rect, 0, input_op->getWidth(), 0, input_op->getHeight());
+ rcti input_area;
operation->get_area_of_interest(input_op, render_area, input_area);
/* Ensure area of interest is within operation bounds, cropping areas outside. */
- BLI_rcti_isect(&input_area, &input_op_rect, &input_area);
+ BLI_rcti_isect(&input_area, &input_op->get_canvas(), &input_area);
stack.append({input_op, input_area});
}
diff --git a/source/blender/compositor/intern/COM_NodeOperation.cc b/source/blender/compositor/intern/COM_NodeOperation.cc
index 3bbd1b22d60..ff232efdb08 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.cc
+++ b/source/blender/compositor/intern/COM_NodeOperation.cc
@@ -35,9 +35,8 @@ namespace blender::compositor {
NodeOperation::NodeOperation()
{
- this->m_resolutionInputSocketIndex = 0;
- this->m_width = 0;
- this->m_height = 0;
+ canvas_input_index_ = 0;
+ canvas_ = COM_AREA_NONE;
this->m_btree = nullptr;
}
@@ -48,7 +47,7 @@ NodeOperation::NodeOperation()
*/
std::optional<NodeOperationHash> NodeOperation::generate_hash()
{
- params_hash_ = get_default_hash_2(m_width, m_height);
+ params_hash_ = get_default_hash_2(canvas_.xmin, canvas_.xmax);
/* Hash subclasses params. */
is_hash_output_params_implemented_ = true;
@@ -57,7 +56,11 @@ std::optional<NodeOperationHash> NodeOperation::generate_hash()
return std::nullopt;
}
- hash_param(getOutputSocket()->getDataType());
+ hash_params(canvas_.ymin, canvas_.ymax);
+ if (m_outputs.size() > 0) {
+ BLI_assert(m_outputs.size() == 1);
+ hash_param(this->getOutputSocket()->getDataType());
+ }
NodeOperationHash hash;
hash.params_hash_ = params_hash_;
@@ -108,48 +111,46 @@ void NodeOperation::addOutputSocket(DataType datatype)
m_outputs.append(NodeOperationOutput(this, datatype));
}
-void NodeOperation::determineResolution(unsigned int resolution[2],
- unsigned int preferredResolution[2])
+void NodeOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
{
- unsigned int used_resolution_index = 0;
- if (m_resolutionInputSocketIndex == RESOLUTION_INPUT_ANY) {
+ unsigned int used_canvas_index = 0;
+ if (canvas_input_index_ == RESOLUTION_INPUT_ANY) {
for (NodeOperationInput &input : m_inputs) {
- unsigned int any_resolution[2] = {0, 0};
- input.determineResolution(any_resolution, preferredResolution);
- if (any_resolution[0] * any_resolution[1] > 0) {
- resolution[0] = any_resolution[0];
- resolution[1] = any_resolution[1];
+ rcti any_area = COM_AREA_NONE;
+ const bool determined = input.determine_canvas(preferred_area, any_area);
+ if (determined) {
+ r_area = any_area;
break;
}
- used_resolution_index += 1;
+ used_canvas_index += 1;
}
}
- else if (m_resolutionInputSocketIndex < m_inputs.size()) {
- NodeOperationInput &input = m_inputs[m_resolutionInputSocketIndex];
- input.determineResolution(resolution, preferredResolution);
- used_resolution_index = m_resolutionInputSocketIndex;
+ else if (canvas_input_index_ < m_inputs.size()) {
+ NodeOperationInput &input = m_inputs[canvas_input_index_];
+ input.determine_canvas(preferred_area, r_area);
+ used_canvas_index = canvas_input_index_;
}
- if (modify_determined_resolution_fn_) {
- modify_determined_resolution_fn_(resolution);
+ if (modify_determined_canvas_fn_) {
+ modify_determined_canvas_fn_(r_area);
}
- unsigned int temp2[2] = {resolution[0], resolution[1]};
- unsigned int temp[2];
+ rcti unused_area;
+ const rcti &local_preferred_area = r_area;
for (unsigned int index = 0; index < m_inputs.size(); index++) {
- if (index == used_resolution_index) {
+ if (index == used_canvas_index) {
continue;
}
NodeOperationInput &input = m_inputs[index];
if (input.isConnected()) {
- input.determineResolution(temp, temp2);
+ input.determine_canvas(local_preferred_area, unused_area);
}
}
}
-void NodeOperation::setResolutionInputSocketIndex(unsigned int index)
+void NodeOperation::set_canvas_input_index(unsigned int index)
{
- this->m_resolutionInputSocketIndex = index;
+ this->canvas_input_index_ = index;
}
void NodeOperation::init_data()
@@ -260,7 +261,7 @@ void NodeOperation::get_area_of_interest(const int input_idx,
/* Non full-frame operations never implement this method. To ensure correctness assume
* whole area is used. */
NodeOperation *input_op = getInputOperation(input_idx);
- BLI_rcti_init(&r_input_area, 0, input_op->getWidth(), 0, input_op->getHeight());
+ r_input_area = input_op->get_canvas();
}
}
@@ -420,12 +421,16 @@ SocketReader *NodeOperationInput::getReader()
return nullptr;
}
-void NodeOperationInput::determineResolution(unsigned int resolution[2],
- unsigned int preferredResolution[2])
+/**
+ * \return Whether canvas area could be determined.
+ */
+bool NodeOperationInput::determine_canvas(const rcti &preferred_area, rcti &r_area)
{
if (m_link) {
- m_link->determineResolution(resolution, preferredResolution);
+ m_link->determine_canvas(preferred_area, r_area);
+ return !BLI_rcti_is_empty(&r_area);
}
+ return false;
}
/******************
@@ -437,18 +442,16 @@ NodeOperationOutput::NodeOperationOutput(NodeOperation *op, DataType datatype)
{
}
-void NodeOperationOutput::determineResolution(unsigned int resolution[2],
- unsigned int preferredResolution[2])
+void NodeOperationOutput::determine_canvas(const rcti &preferred_area, rcti &r_area)
{
NodeOperation &operation = getOperation();
- if (operation.get_flags().is_resolution_set) {
- resolution[0] = operation.getWidth();
- resolution[1] = operation.getHeight();
+ if (operation.get_flags().is_canvas_set) {
+ r_area = operation.get_canvas();
}
else {
- operation.determineResolution(resolution, preferredResolution);
- if (resolution[0] > 0 && resolution[1] > 0) {
- operation.setResolution(resolution);
+ operation.determine_canvas(preferred_area, r_area);
+ if (!BLI_rcti_is_empty(&r_area)) {
+ operation.set_canvas(r_area);
}
}
}
@@ -470,8 +473,8 @@ std::ostream &operator<<(std::ostream &os, const NodeOperationFlags &node_operat
if (node_operation_flags.use_viewer_border) {
os << "view_border,";
}
- if (node_operation_flags.is_resolution_set) {
- os << "resolution_set,";
+ if (node_operation_flags.is_canvas_set) {
+ os << "canvas_set,";
}
if (node_operation_flags.is_set_operation) {
os << "set_operation,";
diff --git a/source/blender/compositor/intern/COM_NodeOperation.h b/source/blender/compositor/intern/COM_NodeOperation.h
index ef7cf319222..9f113b60345 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -130,7 +130,7 @@ class NodeOperationInput {
SocketReader *getReader();
- void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
+ bool determine_canvas(const rcti &preferred_area, rcti &r_area);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
@@ -158,12 +158,7 @@ class NodeOperationOutput {
return m_datatype;
}
- /**
- * \brief determine the resolution of this data going through this socket
- * \param resolution: the result of this operation
- * \param preferredResolution: the preferable resolution as no resolution could be determined
- */
- void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
+ void determine_canvas(const rcti &preferred_area, rcti &r_area);
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:NodeOperation")
@@ -211,9 +206,9 @@ struct NodeOperationFlags {
bool use_viewer_border : 1;
/**
- * Is the resolution of the operation set.
+ * Is the canvas of the operation set.
*/
- bool is_resolution_set : 1;
+ bool is_canvas_set : 1;
/**
* Is this a set operation (value, color, vector).
@@ -257,7 +252,7 @@ struct NodeOperationFlags {
open_cl = false;
use_render_border = false;
use_viewer_border = false;
- is_resolution_set = false;
+ is_canvas_set = false;
is_set_operation = false;
is_read_buffer_operation = false;
is_write_buffer_operation = false;
@@ -324,11 +319,11 @@ class NodeOperation {
bool is_hash_output_params_implemented_;
/**
- * \brief the index of the input socket that will be used to determine the resolution
+ * \brief the index of the input socket that will be used to determine the canvas
*/
- unsigned int m_resolutionInputSocketIndex;
+ unsigned int canvas_input_index_;
- std::function<void(unsigned int resolution[2])> modify_determined_resolution_fn_;
+ std::function<void(rcti &canvas)> modify_determined_canvas_fn_;
/**
* \brief mutex reference for very special node initializations
@@ -352,15 +347,7 @@ class NodeOperation {
*/
eExecutionModel execution_model_;
- /**
- * Width of the output of this operation.
- */
- unsigned int m_width;
-
- /**
- * Height of the output of this operation.
- */
- unsigned int m_height;
+ rcti canvas_;
/**
* Flags how to evaluate this operation.
@@ -374,11 +361,6 @@ class NodeOperation {
{
}
- void set_execution_model(const eExecutionModel model)
- {
- execution_model_ = model;
- }
-
void set_name(const std::string name)
{
m_name = name;
@@ -424,14 +406,7 @@ class NodeOperation {
return getInputOperation(index);
}
- /**
- * \brief determine the resolution of this node
- * \note this method will not set the resolution, this is the responsibility of the caller
- * \param resolution: the result of this operation
- * \param preferredResolution: the preferable resolution as no resolution could be determined
- */
- virtual void determineResolution(unsigned int resolution[2],
- unsigned int preferredResolution[2]);
+ virtual void determine_canvas(const rcti &preferred_area, rcti &r_area);
/**
* \brief isOutputOperation determines whether this operation is an output of the
@@ -453,6 +428,11 @@ class NodeOperation {
return false;
}
+ void set_execution_model(const eExecutionModel model)
+ {
+ execution_model_ = model;
+ }
+
void setbNodeTree(const bNodeTree *tree)
{
this->m_btree = tree;
@@ -527,19 +507,19 @@ class NodeOperation {
}
virtual void deinitExecution();
- /**
- * \brief set the resolution
- * \param resolution: the resolution to set
- */
- void setResolution(unsigned int resolution[2])
+ void set_canvas(const rcti &canvas_area)
{
- if (!this->flags.is_resolution_set) {
- this->m_width = resolution[0];
- this->m_height = resolution[1];
- this->flags.is_resolution_set = true;
+ if (!this->flags.is_canvas_set) {
+ canvas_ = canvas_area;
+ flags.is_canvas_set = true;
}
}
+ const rcti &get_canvas() const
+ {
+ return canvas_;
+ }
+
/**
* \brief is this operation the active viewer output
* user can select an ViewerNode to be active
@@ -557,18 +537,18 @@ class NodeOperation {
rcti *output);
/**
- * \brief set the index of the input socket that will determine the resolution of this
+ * \brief set the index of the input socket that will determine the canvas of this
* operation \param index: the index to set
*/
- void setResolutionInputSocketIndex(unsigned int index);
+ void set_canvas_input_index(unsigned int index);
/**
- * Set a custom function to modify determined resolution from main input just before setting it
- * as preferred resolution for the other inputs.
+ * Set a custom function to modify determined canvas from main input just before setting it
+ * as preferred for the other inputs.
*/
- void set_determined_resolution_modifier(std::function<void(unsigned int resolution[2])> fn)
+ void set_determined_canvas_modifier(std::function<void(rcti &canvas)> fn)
{
- modify_determined_resolution_fn_ = fn;
+ modify_determined_canvas_fn_ = fn;
}
/**
@@ -595,12 +575,12 @@ class NodeOperation {
unsigned int getWidth() const
{
- return m_width;
+ return BLI_rcti_size_x(&canvas_);
}
unsigned int getHeight() const
{
- return m_height;
+ return BLI_rcti_size_y(&canvas_);
}
inline void readSampled(float result[4], float x, float y, PixelSampler sampler)
@@ -699,13 +679,13 @@ class NodeOperation {
void setWidth(unsigned int width)
{
- this->m_width = width;
- this->flags.is_resolution_set = true;
+ canvas_.xmax = canvas_.xmin + width;
+ this->flags.is_canvas_set = true;
}
void setHeight(unsigned int height)
{
- this->m_height = height;
- this->flags.is_resolution_set = true;
+ canvas_.ymax = canvas_.ymin + height;
+ this->flags.is_canvas_set = true;
}
SocketReader *getInputSocketReader(unsigned int inputSocketindex);
NodeOperation *getInputOperation(unsigned int inputSocketindex);
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
index b2cd76be2c3..3791d05602d 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
@@ -106,7 +106,7 @@ void NodeOperationBuilder::convertToOperations(ExecutionSystem *system)
folder.fold_operations();
}
- determineResolutions();
+ determine_canvases();
save_graphviz("compositor_prior_merging");
merge_equal_operations();
@@ -423,28 +423,27 @@ void NodeOperationBuilder::resolve_proxies()
}
}
-void NodeOperationBuilder::determineResolutions()
+void NodeOperationBuilder::determine_canvases()
{
- /* determine all resolutions of the operations (Width/Height) */
+ /* Determine all canvas areas of the operations. */
+ const rcti &preferred_area = COM_AREA_NONE;
for (NodeOperation *op : m_operations) {
if (op->isOutputOperation(m_context->isRendering()) && !op->get_flags().is_preview_operation) {
- unsigned int resolution[2] = {0, 0};
- unsigned int preferredResolution[2] = {0, 0};
- op->determineResolution(resolution, preferredResolution);
- op->setResolution(resolution);
+ rcti canvas = COM_AREA_NONE;
+ op->determine_canvas(preferred_area, canvas);
+ op->set_canvas(canvas);
}
}
for (NodeOperation *op : m_operations) {
if (op->isOutputOperation(m_context->isRendering()) && op->get_flags().is_preview_operation) {
- unsigned int resolution[2] = {0, 0};
- unsigned int preferredResolution[2] = {0, 0};
- op->determineResolution(resolution, preferredResolution);
- op->setResolution(resolution);
+ rcti canvas = COM_AREA_NONE;
+ op->determine_canvas(preferred_area, canvas);
+ op->set_canvas(canvas);
}
}
- /* add convert resolution operations when needed */
+ /* Convert operation canvases when needed. */
{
Vector<Link> convert_links;
for (const Link &link : m_links) {
@@ -457,7 +456,7 @@ void NodeOperationBuilder::determineResolutions()
}
}
for (const Link &link : convert_links) {
- COM_convert_resolution(*this, link.from(), link.to());
+ COM_convert_canvas(*this, link.from(), link.to());
}
}
}
diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.h b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
index aca4d043d41..1f9c86b51cd 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.h
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.h
@@ -145,8 +145,8 @@ class NodeOperationBuilder {
/** Replace proxy operations with direct links */
void resolve_proxies();
- /** Calculate resolution for each operation */
- void determineResolutions();
+ /** Calculate canvas area for each operation. */
+ void determine_canvases();
/** Helper function to store connected inputs for replacement */
Vector<NodeOperationInput *> cache_output_links(NodeOperationOutput *output) const;