]> git.sesse.net Git - movit/blobdiff - effect_chain_test.cpp
Add an effect for 4:2:2 interleaved YCbCr input (UYVY).
[movit] / effect_chain_test.cpp
index 5fe1862584bb83ca89accd6f1e7beff084dec0c8..516dd54ea00e84eaeaac7e2afd2e58b1f545343e 100644 (file)
@@ -2,6 +2,10 @@
 //
 // Note that this also contains the tests for some of the simpler effects.
 
+#include <locale>
+#include <sstream>
+#include <string>
+
 #include <epoxy/gl.h>
 #include <assert.h>
 
@@ -152,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<InvertEffect> *effect = new RewritingEffect<InvertEffect>();
        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());
@@ -172,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) {
@@ -223,7 +231,7 @@ private:
        GammaCurve overridden_gamma_curve;
 };
 
-TEST(EffectChainTester, HandlesInputChangingColorspace) {
+TEST(EffectChainTest, HandlesInputChangingColorspace) {
        const int size = 4;
 
        float data[size] = {
@@ -596,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,
@@ -1037,4 +1120,45 @@ TEST(EffectChainTest, IdentityWithOwnPool) {
        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