X-Git-Url: https://git.sesse.net/?p=movit;a=blobdiff_plain;f=effect_chain_test.cpp;h=516dd54ea00e84eaeaac7e2afd2e58b1f545343e;hp=25cd50a26839ba5942998d13b872f42ea13225ef;hb=ba60914d4e5eda7b28af700bf43e9699b7aa720d;hpb=03b416172e9db37845b8c897d51064cbc6b3aa3f diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 25cd50a..516dd54 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -2,7 +2,11 @@ // // Note that this also contains the tests for some of the simpler effects. -#include +#include +#include +#include + +#include #include #include "effect.h" @@ -19,6 +23,8 @@ using namespace std; +namespace movit { + TEST(EffectChainTest, EmptyChain) { float data[] = { 0.0f, 0.25f, 0.3f, @@ -150,19 +156,23 @@ TEST(EffectChainTest, RewritingWorksAndGammaConversionsAreInserted) { TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) { unsigned char data[] = { - 0, 64, - 128, 255, + 0, 0, 0, 255, + 64, 64, 64, 255, + 128, 128, 128, 255, + 255, 255, 255, 255, }; - float expected_data[4] = { - 1.0f, 0.9771f, - 0.8983f, 0.0f, + float expected_data[] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 0.9771f, 0.9771f, 0.9771f, 1.0000f, + 0.8983f, 0.8983f, 0.8983f, 1.0000f, + 0.0000f, 0.0000f, 0.0000f, 1.0000f }; - float out_data[4]; - EffectChainTester tester(NULL, 2, 2); - tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB); + float out_data[4 * 4]; + EffectChainTester tester(NULL, 1, 4); + tester.add_input(data, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_sRGB); RewritingEffect *effect = new RewritingEffect(); tester.get_chain()->add_effect(effect); - tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB); + tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); Node *node = effect->replaced_node; ASSERT_EQ(1, node->incoming_links.size()); @@ -170,7 +180,7 @@ TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) { EXPECT_EQ("FlatInput", 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, 2, 2); + expect_equal(expected_data, out_data, 4, 4); } TEST(EffectChainTest, RewritingWorksAndColorspaceConversionsAreInserted) { @@ -221,7 +231,7 @@ private: GammaCurve overridden_gamma_curve; }; -TEST(EffectChainTester, HandlesInputChangingColorspace) { +TEST(EffectChainTest, HandlesInputChangingColorspace) { const int size = 4; float data[size] = { @@ -520,17 +530,27 @@ class MipmapNeedingEffect : public Effect { public: MipmapNeedingEffect() {} virtual bool needs_mipmaps() const { return true; } + + // To be allowed to mess with the sampler state. + virtual bool needs_texture_bounce() const { return true; } + virtual string effect_type_id() const { return "MipmapNeedingEffect"; } string output_fragment_shader() { return read_file("mipmap_needing_effect.frag"); } + virtual void inform_added(EffectChain *chain) { this->chain = chain; } + void set_gl_state(GLuint glsl_program_num, const string& prefix, unsigned *sampler_num) { - glActiveTexture(GL_TEXTURE0); + Node *self = chain->find_node_for_effect(this); + glActiveTexture(chain->get_input_sampler(self, 0)); check_error(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); check_error(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); check_error(); } + +private: + EffectChain *chain; }; TEST(EffectChainTest, MipmapGenerationWorks) { @@ -584,6 +604,81 @@ TEST(EffectChainTest, MipmapGenerationWorks) { expect_equal(expected_data, out_data, 4, 16); } +class NonMipmapCapableInput : public FlatInput { +public: + NonMipmapCapableInput(ImageFormat format, MovitPixelFormat pixel_format, GLenum type, unsigned width, unsigned height) + : FlatInput(format, pixel_format, type, width, height) {} + + virtual bool can_supply_mipmaps() const { return false; } + bool set_int(const std::string& key, int value) { + if (key == "needs_mipmaps") { + assert(value == 0); + } + return FlatInput::set_int(key, value); + } +}; + +// The same test as MipmapGenerationWorks, but with an input that refuses +// to supply mipmaps. +TEST(EffectChainTest, MipmapsWithNonMipmapCapableInput) { + float data[] = { // In 4x4 blocks. + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.5f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + + 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, + }; + float expected_data[] = { // Repeated four times each way. + 0.125f, 0.125f, 0.125f, 0.125f, + 0.09375f, 0.09375f, 0.09375f, 0.09375f, + 1.0f, 1.0f, 1.0f, 1.0f, + 0.25f, 0.25f, 0.25f, 0.25f, + + 0.125f, 0.125f, 0.125f, 0.125f, + 0.09375f, 0.09375f, 0.09375f, 0.09375f, + 1.0f, 1.0f, 1.0f, 1.0f, + 0.25f, 0.25f, 0.25f, 0.25f, + + 0.125f, 0.125f, 0.125f, 0.125f, + 0.09375f, 0.09375f, 0.09375f, 0.09375f, + 1.0f, 1.0f, 1.0f, 1.0f, + 0.25f, 0.25f, 0.25f, 0.25f, + + 0.125f, 0.125f, 0.125f, 0.125f, + 0.09375f, 0.09375f, 0.09375f, 0.09375f, + 1.0f, 1.0f, 1.0f, 1.0f, + 0.25f, 0.25f, 0.25f, 0.25f, + }; + float out_data[4 * 16]; + EffectChainTester tester(NULL, 4, 16, FORMAT_GRAYSCALE); + + ImageFormat format; + format.color_space = COLORSPACE_sRGB; + format.gamma_curve = GAMMA_LINEAR; + + NonMipmapCapableInput *input = new NonMipmapCapableInput(format, FORMAT_GRAYSCALE, GL_FLOAT, 4, 16); + input->set_pixel_data(data); + tester.get_chain()->add_input(input); + tester.get_chain()->add_effect(new MipmapNeedingEffect()); + tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR); + + expect_equal(expected_data, out_data, 4, 16); +} + TEST(EffectChainTest, ResizeDownByFourThenUpByFour) { float data[] = { // In 4x4 blocks. 1.0f, 0.0f, 0.0f, 0.0f, @@ -971,7 +1066,7 @@ TEST(EffectChainTest, IdentityWithOwnPool) { 0.75f, 1.0f, 1.0f, 0.0f, 0.25f, 0.3f, }; - float out_data[6]; + float out_data[6], temp[6 * 4]; EffectChain chain(width, height); movit_debug_level = MOVIT_DEBUG_ON; @@ -990,7 +1085,7 @@ TEST(EffectChainTest, IdentityWithOwnPool) { check_error(); glBindTexture(GL_TEXTURE_2D, texnum); check_error(); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL); check_error(); glGenFramebuffers(1, &fbo); @@ -1012,10 +1107,58 @@ TEST(EffectChainTest, IdentityWithOwnPool) { chain.render_to_fbo(fbo, width, height); glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glReadPixels(0, 0, width, height, GL_RED, GL_FLOAT, out_data); + check_error(); + glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, temp); + check_error(); + for (unsigned i = 0; i < 6; ++i) { + out_data[i] = temp[i * 4]; + } expect_equal(expected_data, out_data, width, height); // Reset the debug status again. movit_debug_level = MOVIT_DEBUG_OFF; } + +// A dummy effect whose only purpose is to test sprintf decimal behavior. +class PrintfingBlueEffect : public Effect { +public: + PrintfingBlueEffect() {} + virtual string effect_type_id() const { return "PrintfingBlueEffect"; } + string output_fragment_shader() { + stringstream ss; + ss.imbue(locale("C")); + ss.precision(8); + ss << "vec4 FUNCNAME(vec2 tc) { return vec4(" + << 0.0f << ", " << 0.0f << ", " + << 0.5f << ", " << 1.0f << "); }\n"; + return ss.str(); + } +}; + +TEST(EffectChainTest, StringStreamLocalesWork) { + // An example of a locale with comma instead of period as decimal separator. + // Obviously, if you run on a machine without this locale available, + // the test will always succeed. Note that the OpenGL driver might call + // setlocale() behind-the-scenes, and that might corrupt the returned + // pointer, so we need to take our own copy of it here. + char *saved_locale = strdup(setlocale(LC_ALL, "nb_NO.UTF_8")); + float data[] = { + 0.0f, 0.0f, 0.0f, 0.0f, + }; + float expected_data[] = { + 0.0f, 0.0f, 0.5f, 1.0f, + }; + float out_data[4]; + EffectChainTester tester(data, 1, 1, FORMAT_RGBA_PREMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_LINEAR); + tester.get_chain()->add_effect(new PrintfingBlueEffect()); + tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_LINEAR); + + expect_equal(expected_data, out_data, 4, 1); + + setlocale(LC_ALL, saved_locale); + free(saved_locale); +} + + +} // namespace movit