From 807c97809f0e7a11d1af600d562d8841370e7250 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sat, 13 Oct 2012 00:59:23 +0200 Subject: [PATCH] Add tests to check that rewriting works, and that gamma conversions are or are not inserted as needed. --- effect_chain_test.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++ invert_effect.frag | 7 ++++ 2 files changed, 102 insertions(+) create mode 100644 invert_effect.frag diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 20fd9bc..585df22 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -81,6 +81,101 @@ TEST(MirrorTest, BasicTest) { expect_equal(expected_data, out_data, 3, 2); } +// A dummy effect that inverts its input. +class InvertEffect : public Effect { +public: + InvertEffect() {} + virtual std::string effect_type_id() const { return "InvertEffect"; } + std::string output_fragment_shader() { return read_file("invert_effect.frag"); } +}; + +// Like IdentityEffect, but rewrites itself out of the loop, +// splicing in a InvertEffect instead. Also stores the new node, +// so we later can check that there are gamma conversion effects +// on both sides. +class RewritingToInvertEffect : public Effect { +public: + RewritingToInvertEffect() {} + virtual std::string effect_type_id() const { return "RewritingToInvertEffect"; } + std::string output_fragment_shader() { EXPECT_TRUE(false); return read_file("identity.frag"); } + virtual void rewrite_graph(EffectChain *graph, Node *self) { + Node *invert_node = graph->add_node(new InvertEffect()); + graph->replace_receiver(self, invert_node); + graph->replace_sender(self, invert_node); + + self->disabled = true; + this->invert_node = invert_node; + } + + Node *invert_node; +}; + +TEST(EffectChainTest, RewritingWorksAndGammaConversionsAreInserted) { + float data[] = { + 0.0f, 0.25f, 0.3f, + 0.75f, 1.0f, 1.0f, + }; + float expected_data[6] = { + 1.0f, 0.9771f, 0.9673f, + 0.7192f, 0.0f, 0.0f, + }; + float out_data[6]; + EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB); + RewritingToInvertEffect *effect = new RewritingToInvertEffect(); + tester.get_chain()->add_effect(effect); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB); + + Node *node = effect->invert_node; + ASSERT_EQ(1, node->incoming_links.size()); + ASSERT_EQ(1, node->outgoing_links.size()); + EXPECT_EQ("GammaExpansionEffect", node->incoming_links[0]->effect->effect_type_id()); + EXPECT_EQ("GammaCompressionEffect", node->outgoing_links[0]->effect->effect_type_id()); + + expect_equal(expected_data, out_data, 3, 2); +} + +// Like RewritingToInvertEffect, but splicing in a MirrorEffect instead, +// which does not need linear light. +class RewritingToMirrorEffect : public Effect { +public: + RewritingToMirrorEffect() {} + virtual std::string effect_type_id() const { return "RewritingToMirrorEffect"; } + std::string output_fragment_shader() { EXPECT_TRUE(false); return read_file("identity.frag"); } + virtual void rewrite_graph(EffectChain *graph, Node *self) { + Node *mirror_node = graph->add_node(new MirrorEffect()); + graph->replace_receiver(self, mirror_node); + graph->replace_sender(self, mirror_node); + + self->disabled = true; + this->mirror_node = mirror_node; + } + + Node *mirror_node; +}; + +TEST(EffectChainTest, NoGammaConversionsWhenLinearLightNotNeeded) { + float data[] = { + 0.0f, 0.25f, 0.3f, + 0.75f, 1.0f, 1.0f, + }; + float expected_data[6] = { + 0.3f, 0.25f, 0.0f, + 1.0f, 1.0f, 0.75f, + }; + float out_data[6]; + EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB); + RewritingToMirrorEffect *effect = new RewritingToMirrorEffect(); + tester.get_chain()->add_effect(effect); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB); + + Node *node = effect->mirror_node; + ASSERT_EQ(1, node->incoming_links.size()); + EXPECT_EQ(0, node->outgoing_links.size()); + EXPECT_EQ("FlatInput", node->incoming_links[0]->effect->effect_type_id()); + + expect_equal(expected_data, out_data, 3, 2); +} + // The identity effect needs linear light, and thus will get conversions on both sides. // Verify that sRGB data is properly converted to and from linear light for the entire ramp. TEST(EffectChainTest, IdentityThroughsRGBConversions) { diff --git a/invert_effect.frag b/invert_effect.frag new file mode 100644 index 0000000..78a5e7a --- /dev/null +++ b/invert_effect.frag @@ -0,0 +1,7 @@ +// Used only during testing. Inverts its input. +vec4 FUNCNAME(vec2 tc) +{ + vec4 rgba = INPUT(tc); + rgba.rgb = vec3(1.0) - rgba.rgb; + return rgba; +} -- 2.39.2