#include "mirror_effect.h"
#include "multiply_effect.h"
#include "resize_effect.h"
+#include "resource_pool.h"
#include "test_util.h"
#include "util.h"
<< "Expected sRGB not to be able to represent 0.5 exactly (got " << out_data[1] << ")";
EXPECT_LT(fabs(out_data[1] - data[1]), 0.1f)
<< "Expected sRGB to be able to represent 0.5 approximately (got " << out_data[1] << ")";
+
+ // This state should have been preserved.
+ EXPECT_FALSE(glIsEnabled(GL_FRAMEBUFFER_SRGB));
}
// An effect that is like IdentityEffect, but also does not require linear light.
}
// This maximum error is pretty bad; about 6.5 levels of a 10-bit sRGB
- // framebuffer.
- expect_equal(linear_data, out_data, size, 1, 7e-3, 2e-5);
+ // framebuffer. (Slightly more on NVIDIA cards.)
+ expect_equal(linear_data, out_data, size, 1, 7.5e-3, 2e-5);
}
TEST(EffectChainTest, SquareRoot10bitIntermediateAccuracy) {
// This maximum error is much better; about 0.7 levels of a 10-bit sRGB
// framebuffer (ideal would be 0.5). That is an order of magnitude better
// than in the linear test above. The RMS error is much better, too.
- expect_equal(linear_data, out_data, size, 1, 7e-4, 5e-6);
+ expect_equal(linear_data, out_data, size, 1, 7.5e-4, 5e-6);
}
TEST(EffectChainTest, SquareRootIntermediateIsTurnedOffForNonLinearData) {
expect_equal(data, out_data, size, 1, 1e-6, 1e-6);
}
+// An effect that stores which program number was last run under.
+class RecordingIdentityEffect : public Effect {
+public:
+ RecordingIdentityEffect() {}
+ virtual string effect_type_id() const { return "RecordingIdentityEffect"; }
+ string output_fragment_shader() { return read_file("identity.frag"); }
+
+ GLuint last_glsl_program_num;
+ void set_gl_state(GLuint glsl_program_num, const std::string& prefix, unsigned *sampler_num)
+ {
+ last_glsl_program_num = glsl_program_num;
+ }
+};
+
+TEST(EffectChainTest, ProgramsAreClonedForMultipleThreads) {
+ float data[] = {
+ 0.0f, 0.25f, 0.3f,
+ 0.75f, 1.0f, 1.0f,
+ };
+ float out_data[6];
+ EffectChainTester tester(data, 3, 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
+ RecordingIdentityEffect *effect = new RecordingIdentityEffect();
+ tester.get_chain()->add_effect(effect);
+ tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
+
+ expect_equal(data, out_data, 3, 2);
+
+ ASSERT_NE(0, effect->last_glsl_program_num);
+
+ // Now pretend some other effect is using this program number;
+ // ResourcePool will then need to clone it.
+ ResourcePool *resource_pool = tester.get_chain()->get_resource_pool();
+ GLuint master_program_num = resource_pool->use_glsl_program(effect->last_glsl_program_num);
+ EXPECT_EQ(effect->last_glsl_program_num, master_program_num);
+
+ // Re-run should still give the correct data, but it should have run
+ // with a different program.
+ tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
+ expect_equal(data, out_data, 3, 2);
+ EXPECT_NE(effect->last_glsl_program_num, master_program_num);
+
+ // Release the program, and check one final time.
+ resource_pool->unuse_glsl_program(master_program_num);
+ tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
+ expect_equal(data, out_data, 3, 2);
+}
+
} // namespace movit