Add unit tests for back-and-forth conversions through sRGB and Rec. 709 gamma.
[movit] / effect_chain_test.cpp
1 // Unit tests for EffectChain.
2 //
3 // Note that this also contains the tests for some of the simpler effects.
4
5 #include "effect_chain.h"
6 #include "flat_input.h"
7 #include "gtest/gtest.h"
8 #include "mirror_effect.h"
9 #include "opengl.h"
10 #include "test_util.h"
11
12 TEST(EffectChainTest, EmptyChain) {
13         float data[] = {
14                 0.0f, 0.25f, 0.3f,
15                 0.75f, 1.0f, 1.0f,
16         };
17         float out_data[6];
18         EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
19         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
20
21         expect_equal(data, out_data, 3, 2);
22 }
23
24 // An effect that does nothing.
25 class IdentityEffect : public Effect {
26 public:
27         IdentityEffect() {}
28         virtual std::string effect_type_id() const { return "IdentityEffect"; }
29         std::string output_fragment_shader() { return read_file("identity.frag"); }
30 };
31
32 TEST(EffectChainTest, Identity) {
33         float data[] = {
34                 0.0f, 0.25f, 0.3f,
35                 0.75f, 1.0f, 1.0f,
36         };
37         float out_data[6];
38         EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
39         tester.get_chain()->add_effect(new IdentityEffect());
40         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
41
42         expect_equal(data, out_data, 3, 2);
43 }
44
45 // An effect that does nothing, but requests texture bounce.
46 class BouncingIdentityEffect : public Effect {
47 public:
48         BouncingIdentityEffect() {}
49         virtual std::string effect_type_id() const { return "IdentityEffect"; }
50         std::string output_fragment_shader() { return read_file("identity.frag"); }
51         bool needs_texture_bounce() const { return true; }
52 };
53
54 TEST(EffectChainTest, TextureBouncePreservesIdentity) {
55         float data[] = {
56                 0.0f, 0.25f, 0.3f,
57                 0.75f, 1.0f, 1.0f,
58         };
59         float out_data[6];
60         EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
61         tester.get_chain()->add_effect(new BouncingIdentityEffect());
62         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
63
64         expect_equal(data, out_data, 3, 2);
65 }
66
67 TEST(MirrorTest, BasicTest) {
68         float data[] = {
69                 0.0f, 0.25f, 0.3f,
70                 0.75f, 1.0f, 1.0f,
71         };
72         float expected_data[6] = {
73                 0.3f, 0.25f, 0.0f,
74                 1.0f, 1.0f, 0.75f,
75         };
76         float out_data[6];
77         EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
78         tester.get_chain()->add_effect(new MirrorEffect());
79         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
80
81         expect_equal(expected_data, out_data, 3, 2);
82 }
83
84 // The identity effect needs linear light, and thus will get conversions on both sides.
85 // Verify that sRGB data is properly converted to and from linear light for the entire ramp.
86 TEST(EffectChainTest, IdentityThroughsRGBConversions) {
87         float data[256];
88         for (unsigned i = 0; i < 256; ++i) {
89                 data[i] = i / 255.0;
90         };
91         float out_data[256];
92         EffectChainTester tester(data, 256, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB);
93         tester.get_chain()->add_effect(new IdentityEffect());
94         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB);
95
96         expect_equal(data, out_data, 256, 1);
97 }
98
99 // Same, for the Rec. 601/709 gamma curve.
100 TEST(EffectChainTest, IdentityThroughRec709) {
101         float data[256];
102         for (unsigned i = 0; i < 256; ++i) {
103                 data[i] = i / 255.0;
104         };
105         float out_data[256];
106         EffectChainTester tester(data, 256, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_REC_709);
107         tester.get_chain()->add_effect(new IdentityEffect());
108         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_REC_709);
109
110         expect_equal(data, out_data, 256, 1);
111 }