This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/compositor/tests/COM_NodeOperation_test.cc
Manuel Castilla b225a7c470 Compositor: Merge equal operations
Some operations can take a lot of time to execute and
any duplication should be avoided.

This patch implements a compile step that detects
operations with the same type, inputs and parameters that
produce the same result and merge them. Now operations
can generate a hash that represents their output result. They only
need to implement `hash_output_params` and hash any parameter
that affects the output result.

Reviewed By: jbakker

Differential Revision: https://developer.blender.org/D12341
2021-09-04 17:09:59 +02:00

170 lines
4.1 KiB
C++

/*
* 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_ConstantOperation.h"
namespace blender::compositor::tests {
class NonHashedOperation : public NodeOperation {
public:
NonHashedOperation(int id)
{
set_id(id);
addOutputSocket(DataType::Value);
setWidth(2);
setHeight(3);
}
};
class NonHashedConstantOperation : public ConstantOperation {
float constant_;
public:
NonHashedConstantOperation(int id)
{
set_id(id);
addOutputSocket(DataType::Value);
setWidth(2);
setHeight(3);
constant_ = 1.0f;
}
const float *get_constant_elem() override
{
return &constant_;
}
void set_constant(float value)
{
constant_ = value;
}
};
class HashedOperation : public NodeOperation {
private:
int param1;
float param2;
public:
HashedOperation(NodeOperation &input, int width, int height)
{
addInputSocket(DataType::Value);
addOutputSocket(DataType::Color);
setWidth(width);
setHeight(height);
param1 = 2;
param2 = 7.0f;
getInputSocket(0)->setLink(input.getOutputSocket());
}
void set_param1(int value)
{
param1 = value;
}
void hash_output_params() override
{
hash_params(param1, param2);
}
};
static void test_non_equal_hashes_compare(NodeOperationHash &h1,
NodeOperationHash &h2,
NodeOperationHash &h3)
{
if (h1 < h2) {
if (h3 < h1) {
EXPECT_TRUE(h3 < h2);
}
else if (h3 < h2) {
EXPECT_TRUE(h1 < h3);
}
else {
EXPECT_TRUE(h1 < h3);
EXPECT_TRUE(h2 < h3);
}
}
else {
EXPECT_TRUE(h2 < h1);
}
}
TEST(NodeOperation, generate_hash)
{
/* Constant input. */
{
NonHashedConstantOperation input_op1(1);
input_op1.set_constant(1.0f);
EXPECT_EQ(input_op1.generate_hash(), std::nullopt);
HashedOperation op1(input_op1, 6, 4);
std::optional<NodeOperationHash> hash1_opt = op1.generate_hash();
EXPECT_NE(hash1_opt, std::nullopt);
NodeOperationHash hash1 = *hash1_opt;
NonHashedConstantOperation input_op2(1);
input_op2.set_constant(1.0f);
HashedOperation op2(input_op2, 6, 4);
NodeOperationHash hash2 = *op2.generate_hash();
EXPECT_EQ(hash1, hash2);
input_op2.set_constant(3.0f);
hash2 = *op2.generate_hash();
EXPECT_NE(hash1, hash2);
}
/* Non constant input. */
{
NonHashedOperation input_op(1);
EXPECT_EQ(input_op.generate_hash(), std::nullopt);
HashedOperation op1(input_op, 6, 4);
HashedOperation op2(input_op, 6, 4);
NodeOperationHash hash1 = *op1.generate_hash();
NodeOperationHash hash2 = *op2.generate_hash();
EXPECT_EQ(hash1, hash2);
op1.set_param1(-1);
hash1 = *op1.generate_hash();
EXPECT_NE(hash1, hash2);
HashedOperation op3(input_op, 11, 14);
NodeOperationHash hash3 = *op3.generate_hash();
EXPECT_NE(hash2, hash3);
EXPECT_NE(hash1, hash3);
test_non_equal_hashes_compare(hash1, hash2, hash3);
test_non_equal_hashes_compare(hash3, hash2, hash1);
test_non_equal_hashes_compare(hash2, hash3, hash1);
test_non_equal_hashes_compare(hash3, hash1, hash2);
NonHashedOperation input_op2(2);
HashedOperation op4(input_op2, 11, 14);
NodeOperationHash hash4 = *op4.generate_hash();
EXPECT_NE(hash3, hash4);
input_op2.set_id(1);
hash4 = *op4.generate_hash();
EXPECT_EQ(hash3, hash4);
}
}
} // namespace blender::compositor::tests