Compositor: Buffer iterators tests
See D11882 for a description of the iterators. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D12001
This commit is contained in:
parent
d2675c3c5d
commit
549e2b7539
|
@ -635,3 +635,19 @@ if(CXX_WARN_NO_SUGGEST_OVERRIDE)
|
|||
endif()
|
||||
|
||||
add_dependencies(bf_compositor smaa_areatex_header)
|
||||
|
||||
if(WITH_GTESTS)
|
||||
set(TEST_SRC
|
||||
tests/COM_BufferArea_test.cc
|
||||
tests/COM_BufferRange_test.cc
|
||||
tests/COM_BuffersIterator_test.cc
|
||||
)
|
||||
set(TEST_INC
|
||||
)
|
||||
set(TEST_LIB
|
||||
bf_compositor
|
||||
)
|
||||
include(GTestTesting)
|
||||
blender_add_test_lib(bf_compositor_tests "${TEST_SRC}" "${INC};${TEST_INC}" "${INC_SYS}" "${LIB};${TEST_LIB}")
|
||||
endif()
|
||||
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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 "testing/testing.h"
|
||||
|
||||
#include "COM_BufferArea.h"
|
||||
|
||||
namespace blender::compositor::tests {
|
||||
|
||||
static rcti create_rect(int width, int height)
|
||||
{
|
||||
rcti rect;
|
||||
BLI_rcti_init(&rect, 0, width, 0, height);
|
||||
return rect;
|
||||
}
|
||||
|
||||
static rcti create_rect(int width, int height, int offset)
|
||||
{
|
||||
rcti rect;
|
||||
BLI_rcti_init(&rect, offset, offset + width, offset, offset + height);
|
||||
return rect;
|
||||
}
|
||||
|
||||
TEST(BufferArea, BufferConstructor)
|
||||
{
|
||||
const int width = 2;
|
||||
const int height = 3;
|
||||
BufferArea<float> area(nullptr, width, height, 4);
|
||||
EXPECT_EQ(area.width(), width);
|
||||
EXPECT_EQ(area.height(), height);
|
||||
rcti rect = create_rect(width, height);
|
||||
EXPECT_TRUE(BLI_rcti_compare(&area.get_rect(), &rect));
|
||||
}
|
||||
|
||||
TEST(BufferArea, AreaConstructor)
|
||||
{
|
||||
const int buf_width = 5;
|
||||
const int area_width = 1;
|
||||
const int area_height = 3;
|
||||
rcti area_rect = create_rect(area_width, area_height, 1);
|
||||
BufferArea<float> area(nullptr, buf_width, area_rect, 4);
|
||||
EXPECT_EQ(area.width(), area_width);
|
||||
EXPECT_EQ(area.height(), area_height);
|
||||
EXPECT_TRUE(BLI_rcti_compare(&area.get_rect(), &area_rect));
|
||||
}
|
||||
|
||||
static void fill_buffer_with_indexes(float *buf, int buf_len)
|
||||
{
|
||||
for (int i = 0; i < buf_len; i++) {
|
||||
buf[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_single_elem_iteration(float *buffer, BufferArea<float> area)
|
||||
{
|
||||
int elems_count = 0;
|
||||
for (float *elem : area) {
|
||||
EXPECT_EQ(elem, buffer);
|
||||
elems_count++;
|
||||
}
|
||||
EXPECT_EQ(elems_count, 1);
|
||||
}
|
||||
|
||||
static void test_full_buffer_iteration(
|
||||
float *buf, int buf_width, int buf_len, int num_channels, BufferArea<float> area)
|
||||
{
|
||||
fill_buffer_with_indexes(buf, buf_len);
|
||||
rcti rect = area.get_rect();
|
||||
int x = rect.xmin;
|
||||
int y = rect.ymin;
|
||||
for (float *elem : area) {
|
||||
for (int ch = 0; ch < num_channels; ch++) {
|
||||
const int buf_index = y * buf_width * num_channels + x * num_channels + ch;
|
||||
EXPECT_NEAR(elem[ch], buf_index, FLT_EPSILON);
|
||||
}
|
||||
x++;
|
||||
if (x == rect.xmax) {
|
||||
y++;
|
||||
x = rect.xmin;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(x, rect.xmin);
|
||||
EXPECT_EQ(y, rect.ymax);
|
||||
}
|
||||
|
||||
TEST(BufferArea, SingleElemBufferIteration)
|
||||
{
|
||||
const int buf_width = 4;
|
||||
const int buf_height = 5;
|
||||
const int area_width = 2;
|
||||
const int area_height = 3;
|
||||
const int num_channels = 4;
|
||||
const int stride = 0;
|
||||
float buf[num_channels];
|
||||
{
|
||||
BufferArea area(buf, buf_width, buf_height, stride);
|
||||
test_single_elem_iteration(buf, area);
|
||||
}
|
||||
{
|
||||
rcti area_rect = create_rect(area_width, area_height, 1);
|
||||
BufferArea area(buf, buf_width, area_rect, stride);
|
||||
test_single_elem_iteration(buf, area);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BufferArea, FullBufferIteration)
|
||||
{
|
||||
const int buf_width = 4;
|
||||
const int area_width = 2;
|
||||
const int area_height = 3;
|
||||
const int buf_height = (area_height + 1);
|
||||
const int num_channels = 4;
|
||||
const int buf_len = buf_height * buf_width * num_channels;
|
||||
float buf[buf_len];
|
||||
{
|
||||
BufferArea area(buf, buf_width, buf_height, num_channels);
|
||||
test_full_buffer_iteration(buf, buf_width, buf_len, num_channels, area);
|
||||
}
|
||||
{
|
||||
rcti area_rect = create_rect(area_width, area_height, 1);
|
||||
BufferArea area(buf, buf_width, area_rect, num_channels);
|
||||
test_full_buffer_iteration(buf, buf_width, buf_len, num_channels, area);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::compositor::tests
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* 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 "testing/testing.h"
|
||||
|
||||
#include "COM_BufferRange.h"
|
||||
|
||||
namespace blender::compositor::tests {
|
||||
|
||||
TEST(BufferRange, Constructor)
|
||||
{
|
||||
const int size = 5;
|
||||
BufferRange<float> range(nullptr, 1, size, 4);
|
||||
EXPECT_EQ(range.size(), size);
|
||||
}
|
||||
|
||||
static void fill_buffer_with_indexes(float *buf, int buf_len)
|
||||
{
|
||||
for (int i = 0; i < buf_len; i++) {
|
||||
buf[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(BufferRange, Subscript)
|
||||
{
|
||||
const int start = 2;
|
||||
const int size = 4;
|
||||
const int num_channels = 3;
|
||||
const int buf_len = (start + size) * num_channels;
|
||||
float buf[buf_len];
|
||||
|
||||
BufferRange<float> range(buf, start, size, num_channels);
|
||||
|
||||
fill_buffer_with_indexes(buf, buf_len);
|
||||
int buf_index = start * num_channels;
|
||||
for (int i = 0; i < size; i++) {
|
||||
const float *elem = range[i];
|
||||
for (int ch = 0; ch < num_channels; ch++) {
|
||||
EXPECT_NEAR(elem[ch], buf_index, FLT_EPSILON);
|
||||
buf_index++;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(buf_index, buf_len);
|
||||
}
|
||||
|
||||
TEST(BufferRange, SingleElemBufferIteration)
|
||||
{
|
||||
const int start = 1;
|
||||
const int size = 3;
|
||||
const int num_channels = 4;
|
||||
float buf[num_channels];
|
||||
const int stride = 0;
|
||||
BufferRange<float> range(buf, start, size, stride);
|
||||
|
||||
int elems_count = 0;
|
||||
for (float *elem : range) {
|
||||
EXPECT_EQ(elem, buf);
|
||||
elems_count++;
|
||||
}
|
||||
EXPECT_EQ(elems_count, 1);
|
||||
}
|
||||
|
||||
TEST(BufferRange, FullBufferIteration)
|
||||
{
|
||||
const int start = 2;
|
||||
const int size = 5;
|
||||
const int num_channels = 4;
|
||||
const int buf_len = (start + size) * num_channels;
|
||||
float buf[buf_len];
|
||||
BufferRange<float> range(buf, start, size, num_channels);
|
||||
|
||||
fill_buffer_with_indexes(buf, buf_len);
|
||||
int buf_index = start * num_channels;
|
||||
for (float *elem : range) {
|
||||
for (int ch = 0; ch < num_channels; ch++) {
|
||||
EXPECT_NEAR(elem[ch], buf_index, FLT_EPSILON);
|
||||
buf_index++;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(buf_index, buf_len);
|
||||
}
|
||||
|
||||
} // namespace blender::compositor::tests
|
|
@ -0,0 +1,299 @@
|
|||
/*
|
||||
* 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 "testing/testing.h"
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "COM_BuffersIterator.h"
|
||||
|
||||
namespace blender::compositor::tests {
|
||||
|
||||
constexpr int BUFFER_WIDTH = 5;
|
||||
constexpr int BUFFER_HEIGHT = 4;
|
||||
constexpr int BUFFER_OFFSET_X = 5;
|
||||
constexpr int BUFFER_OFFSET_Y = 6;
|
||||
constexpr int NUM_CHANNELS = 4;
|
||||
constexpr int FULL_BUFFER_LEN = BUFFER_WIDTH * BUFFER_HEIGHT * NUM_CHANNELS;
|
||||
constexpr int SINGLE_ELEM_BUFFER_LEN = NUM_CHANNELS;
|
||||
constexpr int NUM_INPUTS = 2;
|
||||
|
||||
static float *create_buffer(int len)
|
||||
{
|
||||
return (float *)MEM_callocN(len * sizeof(float), "COM_BuffersIteratorTest");
|
||||
}
|
||||
|
||||
static const float *create_input_buffer(int input_idx, bool is_a_single_elem)
|
||||
{
|
||||
const int len = is_a_single_elem ? SINGLE_ELEM_BUFFER_LEN : FULL_BUFFER_LEN;
|
||||
float *buf = create_buffer(len);
|
||||
/* Fill buffer with variable data. */
|
||||
for (int i = 0; i < len; i++) {
|
||||
buf[i] = input_idx * 1.5f * (i + 1) + i * 0.9f;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
using IterFunc = std::function<void(BuffersIterator<float> &it, const rcti &area)>;
|
||||
using ValidateElemFunc = std::function<void(float *out, Span<const float *> ins, int x, int y)>;
|
||||
|
||||
class BuffersIteratorTest : public testing::Test {
|
||||
private:
|
||||
float *output_;
|
||||
bool use_offsets_;
|
||||
bool use_single_elem_inputs_;
|
||||
bool use_inputs_;
|
||||
|
||||
static rcti buffer_area;
|
||||
static rcti buffer_offset_area;
|
||||
static Array<const float *, NUM_INPUTS> single_elem_inputs;
|
||||
static Array<const float *, NUM_INPUTS> full_buffer_inputs;
|
||||
|
||||
public:
|
||||
void set_inputs_enabled(bool value)
|
||||
{
|
||||
use_inputs_ = value;
|
||||
}
|
||||
|
||||
void test_iteration(IterFunc iter_func, ValidateElemFunc validate_elem_func = {})
|
||||
{
|
||||
use_single_elem_inputs_ = false;
|
||||
validate_iteration(iter_func, validate_elem_func);
|
||||
if (use_inputs_) {
|
||||
use_single_elem_inputs_ = true;
|
||||
validate_iteration(iter_func, validate_elem_func);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
static void SetUpTestCase()
|
||||
{
|
||||
BLI_rcti_init(&buffer_area, 0, BUFFER_WIDTH, 0, BUFFER_HEIGHT);
|
||||
BLI_rcti_init(&buffer_offset_area,
|
||||
BUFFER_OFFSET_X,
|
||||
BUFFER_OFFSET_X + BUFFER_WIDTH,
|
||||
BUFFER_OFFSET_Y,
|
||||
BUFFER_OFFSET_Y + BUFFER_HEIGHT);
|
||||
for (int i = 0; i < NUM_INPUTS; i++) {
|
||||
single_elem_inputs[i] = create_input_buffer(i, true);
|
||||
full_buffer_inputs[i] = create_input_buffer(i, false);
|
||||
}
|
||||
}
|
||||
|
||||
static void TearDownTestCase()
|
||||
{
|
||||
for (int i = 0; i < NUM_INPUTS; i++) {
|
||||
MEM_freeN((void *)single_elem_inputs[i]);
|
||||
single_elem_inputs[i] = nullptr;
|
||||
MEM_freeN((void *)full_buffer_inputs[i]);
|
||||
full_buffer_inputs[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void SetUp() override
|
||||
{
|
||||
use_offsets_ = false;
|
||||
use_single_elem_inputs_ = false;
|
||||
use_inputs_ = false;
|
||||
output_ = create_buffer(FULL_BUFFER_LEN);
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
MEM_freeN(output_);
|
||||
}
|
||||
|
||||
private:
|
||||
void validate_iteration(IterFunc iter_func, ValidateElemFunc validate_elem_func)
|
||||
{
|
||||
{
|
||||
use_offsets_ = false;
|
||||
BuffersIterator<float> it = iterate();
|
||||
iter_func(it, buffer_area);
|
||||
validate_result(buffer_area, validate_elem_func);
|
||||
}
|
||||
{
|
||||
use_offsets_ = true;
|
||||
BuffersIterator<float> it = offset_iterate(buffer_offset_area);
|
||||
iter_func(it, buffer_offset_area);
|
||||
validate_result(buffer_offset_area, validate_elem_func);
|
||||
}
|
||||
{
|
||||
use_offsets_ = true;
|
||||
rcti area = buffer_offset_area;
|
||||
area.xmin += 1;
|
||||
area.ymin += 1;
|
||||
area.xmax -= 1;
|
||||
area.ymax -= 1;
|
||||
BuffersIterator<float> it = offset_iterate(area);
|
||||
iter_func(it, area);
|
||||
validate_result(area, validate_elem_func);
|
||||
}
|
||||
}
|
||||
|
||||
void validate_result(rcti &area, ValidateElemFunc validate_elem_func)
|
||||
{
|
||||
Span<const float *> inputs = get_inputs();
|
||||
Array<const float *> ins(inputs.size());
|
||||
for (int y = area.ymin; y < area.ymax; y++) {
|
||||
for (int x = area.xmin; x < area.xmax; x++) {
|
||||
const int out_offset = get_buffer_relative_y(y) * BUFFER_WIDTH * NUM_CHANNELS +
|
||||
get_buffer_relative_x(x) * NUM_CHANNELS;
|
||||
float *out = &output_[out_offset];
|
||||
|
||||
const int in_offset = use_single_elem_inputs_ ? 0 : out_offset;
|
||||
for (int i = 0; i < inputs.size(); i++) {
|
||||
ins[i] = &inputs[i][in_offset];
|
||||
}
|
||||
|
||||
if (validate_elem_func) {
|
||||
validate_elem_func(out, ins, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Span<const float *> get_inputs()
|
||||
{
|
||||
if (use_inputs_) {
|
||||
return use_single_elem_inputs_ ? single_elem_inputs : full_buffer_inputs;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int get_buffer_relative_x(int x)
|
||||
{
|
||||
return use_offsets_ ? x - BUFFER_OFFSET_X : x;
|
||||
}
|
||||
int get_buffer_relative_y(int y)
|
||||
{
|
||||
return use_offsets_ ? y - BUFFER_OFFSET_Y : y;
|
||||
}
|
||||
|
||||
/** Iterates whole buffers with no offsets. */
|
||||
BuffersIterator<float> iterate()
|
||||
{
|
||||
BLI_assert(!use_offsets_);
|
||||
BuffersIteratorBuilder<float> builder(output_, BUFFER_WIDTH, BUFFER_HEIGHT, NUM_CHANNELS);
|
||||
if (use_inputs_) {
|
||||
const int input_stride = use_single_elem_inputs_ ? 0 : NUM_CHANNELS;
|
||||
for (const float *input : get_inputs()) {
|
||||
builder.add_input(input, BUFFER_WIDTH, input_stride);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/** Iterates a given buffers area with default offsets. */
|
||||
BuffersIterator<float> offset_iterate(const rcti &area)
|
||||
{
|
||||
BLI_assert(use_offsets_);
|
||||
const rcti &buf_area = buffer_offset_area;
|
||||
BuffersIteratorBuilder<float> builder(output_, buf_area, area, NUM_CHANNELS);
|
||||
if (use_inputs_) {
|
||||
const int input_stride = use_single_elem_inputs_ ? 0 : NUM_CHANNELS;
|
||||
for (const float *input : get_inputs()) {
|
||||
builder.add_input(input, buf_area, input_stride);
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
};
|
||||
|
||||
rcti BuffersIteratorTest::buffer_area;
|
||||
rcti BuffersIteratorTest::buffer_offset_area;
|
||||
Array<const float *, NUM_INPUTS> BuffersIteratorTest::single_elem_inputs(NUM_INPUTS);
|
||||
Array<const float *, NUM_INPUTS> BuffersIteratorTest::full_buffer_inputs(NUM_INPUTS);
|
||||
|
||||
static void iterate_coordinates(BuffersIterator<float> &it, const rcti &area)
|
||||
{
|
||||
int x = area.xmin;
|
||||
int y = area.ymin;
|
||||
for (; !it.is_end(); ++it) {
|
||||
EXPECT_EQ(x, it.x);
|
||||
EXPECT_EQ(y, it.y);
|
||||
x++;
|
||||
if (x == area.xmax) {
|
||||
x = area.xmin;
|
||||
y++;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(x, area.xmin);
|
||||
EXPECT_EQ(y, area.ymax);
|
||||
}
|
||||
|
||||
TEST_F(BuffersIteratorTest, CoordinatesIterationWithNoInputs)
|
||||
{
|
||||
set_inputs_enabled(false);
|
||||
test_iteration(iterate_coordinates);
|
||||
}
|
||||
|
||||
TEST_F(BuffersIteratorTest, CoordinatesIterationWithInputs)
|
||||
{
|
||||
set_inputs_enabled(true);
|
||||
test_iteration(iterate_coordinates);
|
||||
}
|
||||
|
||||
TEST_F(BuffersIteratorTest, OutputIteration)
|
||||
{
|
||||
set_inputs_enabled(false);
|
||||
test_iteration(
|
||||
[](BuffersIterator<float> &it, const rcti &UNUSED(area)) {
|
||||
EXPECT_EQ(it.get_num_inputs(), 0);
|
||||
for (; !it.is_end(); ++it) {
|
||||
const int dummy = it.y * BUFFER_WIDTH + it.x;
|
||||
it.out[0] = dummy + 1.0f;
|
||||
it.out[1] = dummy + 2.0f;
|
||||
it.out[2] = dummy + 3.0f;
|
||||
it.out[3] = dummy + 4.0f;
|
||||
}
|
||||
},
|
||||
[](float *out, Span<const float *> UNUSED(ins), const int x, const int y) {
|
||||
const int dummy = y * BUFFER_WIDTH + x;
|
||||
EXPECT_NEAR(out[0], dummy + 1.0f, FLT_EPSILON);
|
||||
EXPECT_NEAR(out[1], dummy + 2.0f, FLT_EPSILON);
|
||||
EXPECT_NEAR(out[2], dummy + 3.0f, FLT_EPSILON);
|
||||
EXPECT_NEAR(out[3], dummy + 4.0f, FLT_EPSILON);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(BuffersIteratorTest, OutputAndInputsIteration)
|
||||
{
|
||||
set_inputs_enabled(true);
|
||||
test_iteration(
|
||||
[](BuffersIterator<float> &it, const rcti &UNUSED(area)) {
|
||||
EXPECT_EQ(it.get_num_inputs(), NUM_INPUTS);
|
||||
for (; !it.is_end(); ++it) {
|
||||
const float *in1 = it.in(0);
|
||||
const float *in2 = it.in(1);
|
||||
it.out[0] = in1[0] + in2[0];
|
||||
it.out[1] = in1[1] + in2[3];
|
||||
it.out[2] = in1[2] - in2[2];
|
||||
it.out[3] = in1[3] - in2[1];
|
||||
}
|
||||
},
|
||||
[](float *out, Span<const float *> ins, const int UNUSED(x), const int UNUSED(y)) {
|
||||
const float *in1 = ins[0];
|
||||
const float *in2 = ins[1];
|
||||
EXPECT_NEAR(out[0], in1[0] + in2[0], FLT_EPSILON);
|
||||
EXPECT_NEAR(out[1], in1[1] + in2[3], FLT_EPSILON);
|
||||
EXPECT_NEAR(out[2], in1[2] - in2[2], FLT_EPSILON);
|
||||
EXPECT_NEAR(out[3], in1[3] - in2[1], FLT_EPSILON);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace blender::compositor::tests
|
Loading…
Reference in New Issue