Fullframe compositor: unify scaling behavior with realtime compositor

This patch unifies the behavior of the scale node by removing the arbitrary limit of scaling images. The change applies to scale and transform nodes.

Note: with this change, Blender can crash for large resizing factors (around 10 000 x 10 000 relative factors). We think it's very unlikely users will run into this issue, so we agreed errors coming from failed memory allocation won't be handled, as is the case for GPU compositor.

Pull Request: https://projects.blender.org/blender/blender/pulls/114764
This commit is contained in:
Habib Gahbiche 2023-12-26 12:58:46 +01:00 committed by Habib Gahbiche
parent 92a0dfed94
commit 57df35c8f9
7 changed files with 0 additions and 45 deletions

View File

@ -63,7 +63,6 @@ void MaskNode::convert_to_operations(NodeConverter &converter,
scale_operation->set_is_aspect(false);
scale_operation->set_is_crop(false);
scale_operation->set_offset(0.0f, 0.0f);
scale_operation->set_scale_canvas_max_size({float(data->size_x), float(data->size_y)});
converter.add_operation(scale_operation);
converter.add_link(operation->get_output_socket(0), scale_operation->get_input_socket(0));

View File

@ -36,8 +36,6 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
operation->set_scale_canvas_max_size(context.get_render_size() * 1.5f);
break;
}
case CMP_NODE_SCALE_RENDER_PERCENT: {
@ -56,7 +54,6 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
operation->set_scale_canvas_max_size(context.get_render_size() * 1.5f);
break;
}
@ -77,7 +74,6 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
operation->set_scale_canvas_max_size(context.get_render_size() * 3.0f);
break;
}
@ -92,7 +88,6 @@ void ScaleNode::convert_to_operations(NodeConverter &converter,
converter.map_output_socket(output_socket, operation->get_output_socket(0));
operation->set_variable_size(input_xsocket->is_linked() || input_ysocket->is_linked());
operation->set_scale_canvas_max_size(context.get_render_size() * 1.5f);
break;
}

View File

@ -72,7 +72,6 @@ void TransformNode::convert_to_operations(NodeConverter &converter,
PixelSampler sampler = (PixelSampler)this->get_bnode()->custom1;
scale_operation->set_sampler(sampler);
rotate_operation->set_sampler(sampler);
scale_operation->set_scale_canvas_max_size(context.get_render_size());
converter.map_input_socket(image_input, scale_operation->get_input_socket(0));
converter.map_input_socket(scale_input, scale_operation->get_input_socket(1));

View File

@ -24,11 +24,6 @@ BaseScaleOperation::BaseScaleOperation()
variable_size_ = false;
}
void BaseScaleOperation::set_scale_canvas_max_size(Size2f size)
{
max_scale_canvas_size_ = size;
}
ScaleOperation::ScaleOperation() : ScaleOperation(DataType::Color) {}
ScaleOperation::ScaleOperation(DataType data_type) : BaseScaleOperation()
@ -224,9 +219,6 @@ void ScaleOperation::determine_canvas(const rcti &preferred_area, rcti &r_area)
const float scale_x = get_constant_scale_x(input_width);
const float scale_y = get_constant_scale_y(input_height);
scale_area(r_area, scale_x, scale_y);
const Size2f max_scale_size = {std::max(input_width, max_scale_canvas_size_.x),
std::max(input_height, max_scale_canvas_size_.y)};
clamp_area_size_max(r_area, max_scale_size);
/* Re-determine canvases of x and y constant inputs with scaled canvas as preferred. */
get_input_operation(X_INPUT_INDEX)->unset_canvas();
@ -405,9 +397,6 @@ void ScaleFixedSizeOperation::init_data(const rcti &input_canvas)
offset_x_ += ((w_src - (w_src * div)) / (w_src / w_dst)) / 2.0f;
if (is_crop_ && execution_model_ == eExecutionModel::FullFrame) {
int fit_width = new_width_ * div;
if (fit_width > max_scale_canvas_size_.x) {
fit_width = max_scale_canvas_size_.x;
}
const int added_width = fit_width - new_width_;
new_width_ += added_width;
@ -421,9 +410,6 @@ void ScaleFixedSizeOperation::init_data(const rcti &input_canvas)
offset_y_ += ((h_src - (h_src * div)) / (h_src / h_dst)) / 2.0f;
if (is_crop_ && execution_model_ == eExecutionModel::FullFrame) {
int fit_height = new_height_ * div;
if (fit_height > max_scale_canvas_size_.y) {
fit_height = max_scale_canvas_size_.y;
}
const int added_height = fit_height - new_height_;
new_height_ += added_height;

View File

@ -9,8 +9,6 @@
namespace blender::compositor {
class BaseScaleOperation : public MultiThreadedOperation {
public:
static constexpr float DEFAULT_MAX_SCALE_CANVAS_SIZE = 12000;
public:
void set_sampler(PixelSampler sampler)
@ -22,8 +20,6 @@ class BaseScaleOperation : public MultiThreadedOperation {
variable_size_ = variable_size;
};
void set_scale_canvas_max_size(Size2f size);
protected:
BaseScaleOperation();
@ -32,7 +28,6 @@ class BaseScaleOperation : public MultiThreadedOperation {
return (sampler_ == -1) ? sampler : (PixelSampler)sampler_;
}
Size2f max_scale_canvas_size_ = {DEFAULT_MAX_SCALE_CANVAS_SIZE, DEFAULT_MAX_SCALE_CANVAS_SIZE};
int sampler_;
/* TODO(manzanilla): to be removed with tiled implementation. */
bool variable_size_;

View File

@ -22,17 +22,10 @@ TransformOperation::TransformOperation()
convert_degree_to_rad_ = false;
sampler_ = PixelSampler::Bilinear;
invert_ = false;
max_scale_canvas_size_ = {ScaleOperation::DEFAULT_MAX_SCALE_CANVAS_SIZE,
ScaleOperation::DEFAULT_MAX_SCALE_CANVAS_SIZE};
flags_.can_be_constant = true;
}
void TransformOperation::set_scale_canvas_max_size(Size2f size)
{
max_scale_canvas_size_ = size;
}
void TransformOperation::init_data()
{
@ -126,10 +119,6 @@ void TransformOperation::determine_canvas(const rcti &preferred_area, rcti &r_ar
/* Scale -> Rotate -> Translate. */
scale_canvas_ = image_canvas;
ScaleOperation::scale_area(scale_canvas_, scale_, scale_);
const Size2f max_scale_size = {
MAX2(BLI_rcti_size_x(&image_canvas), max_scale_canvas_size_.x),
MAX2(BLI_rcti_size_y(&image_canvas), max_scale_canvas_size_.y)};
ScaleOperation::clamp_area_size_max(scale_canvas_, max_scale_size);
RotateOperation::get_rotation_canvas(
scale_canvas_, rotate_sine_, rotate_cosine_, rotate_canvas_);
@ -150,11 +139,6 @@ void TransformOperation::determine_canvas(const rcti &preferred_area, rcti &r_ar
scale_canvas_ = rotate_canvas_;
ScaleOperation::scale_area(scale_canvas_, scale_, scale_);
const Size2f max_scale_size = {
MAX2(BLI_rcti_size_x(&rotate_canvas_), max_scale_canvas_size_.x),
MAX2(BLI_rcti_size_y(&rotate_canvas_), max_scale_canvas_size_.y)};
ScaleOperation::clamp_area_size_max(scale_canvas_, max_scale_size);
r_area = scale_canvas_;
}
}

View File

@ -31,7 +31,6 @@ class TransformOperation : public MultiThreadedOperation {
float translate_factor_x_;
float translate_factor_y_;
bool invert_;
Size2f max_scale_canvas_size_;
public:
TransformOperation();
@ -57,8 +56,6 @@ class TransformOperation : public MultiThreadedOperation {
invert_ = value;
}
void set_scale_canvas_max_size(Size2f size);
void init_data() override;
void get_area_of_interest(int input_idx, const rcti &output_area, rcti &r_input_area) override;
void update_memory_buffer_partial(MemoryBuffer *output,