// without any explicit recursion.
void EffectChain::construct_glsl_programs(Node *output)
{
- // Which effects have already been completed in this phase?
+ // Which effects have already been completed?
// We need to keep track of it, as an effect with multiple outputs
// could otherwise be calculated multiple times.
std::set<Node *> completed_effects;
// This should currently only happen for effects that are inputs
// (either true inputs or phase outputs). We special-case inputs,
// and then deduplicate phase outputs in compile_glsl_program().
- if (node->effect->num_inputs() == 0 && completed_effects.count(node)) {
- continue;
+ if (node->effect->num_inputs() == 0) {
+ if (find(this_phase_effects.begin(), this_phase_effects.end(), node) != this_phase_effects.end()) {
+ continue;
+ }
+ } else {
+ assert(completed_effects.count(node) == 0);
}
- assert(completed_effects.count(node) == 0);
this_phase_effects.push_back(node);
completed_effects.insert(node);
virtual std::string effect_type_id() const { return "IdentityEffect"; }
std::string output_fragment_shader() { return read_file("identity.frag"); }
bool needs_texture_bounce() const { return true; }
+ AlphaHandling alpha_handling() const { return DONT_CARE_ALPHA_TYPE; }
};
TEST(EffectChainTest, TextureBouncePreservesIdentity) {
expect_equal(expected_data, out_data, 2, 2);
}
+
+// Constructs the graph
+//
+// FlatInput |
+// / \ |
+// MultiplyEffect MultiplyEffect |
+// \ | |
+// \ BouncingIdentityEffect |
+// \ / |
+// AddEffect |
+//
+// and verifies that it gives the correct output.
+TEST(EffectChainTest, DiamondGraphWithOneInputUsedInTwoPhases) {
+ float data[] = {
+ 1.0f, 1.0f,
+ 1.0f, 0.0f,
+ };
+ float expected_data[] = {
+ 2.5f, 2.5f,
+ 2.5f, 0.0f,
+ };
+ float out_data[2 * 2];
+
+ MultiplyEffect *mul_half = new MultiplyEffect();
+ ASSERT_TRUE(mul_half->set_float("factor", 0.5f));
+
+ MultiplyEffect *mul_two = new MultiplyEffect();
+ ASSERT_TRUE(mul_two->set_float("factor", 2.0f));
+
+ BouncingIdentityEffect *bounce = new BouncingIdentityEffect();
+
+ EffectChainTester tester(NULL, 2, 2);
+
+ ImageFormat format;
+ format.color_space = COLORSPACE_sRGB;
+ format.gamma_curve = GAMMA_LINEAR;
+
+ FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 2, 2);
+ input->set_pixel_data(data);
+
+ tester.get_chain()->add_input(input);
+ tester.get_chain()->add_effect(mul_half, input);
+ tester.get_chain()->add_effect(mul_two, input);
+ tester.get_chain()->add_effect(bounce, mul_two);
+ tester.get_chain()->add_effect(new AddEffect(), mul_half, bounce);
+ tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+ expect_equal(expected_data, out_data, 2, 2);
+}