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-08-26 19:49:40 +0300
committerManuel Castilla <manzanillawork@gmail.com>2021-08-26 19:49:40 +0300
commite8f41f1b9399471d83f99914c9a2c5074dc0beb3 (patch)
tree1e1f69845904d4a8a8258a025d1c7d99872bac09 /source/blender/compositor/intern
parentc8897efa53fd33262433ac0c62b0d39df86bf44f (diff)
Compositor: Replace resolution concept by canvas
This is a code refactor in preparation of supporting canvas compositing and fix all cropping issues on full frame implementation. No functional changes, all canvases are at (0, 0) position matching tiled implementation.
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.cc77
-rw-r--r--source/blender/compositor/intern/COM_NodeOperation.h93
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.cc25
-rw-r--r--source/blender/compositor/intern/COM_NodeOperationBuilder.h4
9 files changed, 111 insertions, 137 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 1983eb190e2..2958e494b55 100644
--- a/source/blender/compositor/intern/COM_Converter.cc
+++ b/source/blender/compositor/intern/COM_Converter.cc
@@ -456,9 +456,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. */
@@ -531,10 +531,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);
}
@@ -553,10 +553,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 a0333cf96cf..be606f0bd1f 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 71295f38c5b..66d34e58a3d 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);
if (!BLI_rcti_is_empty(&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 1b87cdf72fb..550801a8cdd 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;
}
@@ -61,48 +60,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()
@@ -213,7 +210,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();
}
}
@@ -373,12 +370,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;
}
/******************
@@ -390,18 +391,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);
}
}
}
@@ -423,8 +422,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 b402dc7f174..368ab6c4602 100644
--- a/source/blender/compositor/intern/COM_NodeOperation.h
+++ b/source/blender/compositor/intern/COM_NodeOperation.h
@@ -128,7 +128,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")
@@ -156,12 +156,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")
@@ -209,9 +204,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).
@@ -255,7 +250,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;
@@ -283,11 +278,11 @@ class NodeOperation {
Vector<NodeOperationOutput> m_outputs;
/**
- * \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
@@ -311,15 +306,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.
@@ -333,10 +320,8 @@ class NodeOperation {
{
}
- void set_execution_model(const eExecutionModel model)
- {
- execution_model_ = model;
- }
+ /* Renturns false when input is not constant */
+ bool get_input_constant(const int input_idx, float *r_constant);
void set_name(const std::string name)
{
@@ -381,14 +366,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
@@ -410,6 +388,11 @@ class NodeOperation {
return false;
}
+ void set_execution_model(const eExecutionModel model)
+ {
+ execution_model_ = model;
+ }
+
void setbNodeTree(const bNodeTree *tree)
{
this->m_btree = tree;
@@ -484,19 +467,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
@@ -514,18 +497,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;
}
/**
@@ -552,12 +535,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)
@@ -629,13 +612,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 10a91bbcd3e..895aaa8102b 100644
--- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
+++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc
@@ -109,7 +109,7 @@ void NodeOperationBuilder::convertToOperations(ExecutionSystem *system)
folder.fold_operations();
}
- determineResolutions();
+ determine_canvases();
if (m_context->get_execution_model() == eExecutionModel::Tiled) {
/* surround complex ops with read/write buffer */
@@ -417,28 +417,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) {
@@ -451,7 +450,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 1f76765c846..58bdde04b6b 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;