diff options
author | Manuel Castilla <manzanillawork@gmail.com> | 2021-09-28 20:32:49 +0300 |
---|---|---|
committer | Manuel Castilla <manzanillawork@gmail.com> | 2021-09-28 23:00:16 +0300 |
commit | 76377f0176b9561a7fc8f46b4ed704c631ddd90d (patch) | |
tree | 96775442f403dfdb0dc4d91f835495c72c1ca9c1 /source/blender/compositor/intern | |
parent | 2ecd963d87e4f5215d1d86e7f1c22ab7833697f3 (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')
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; |