]> git.sesse.net Git - movit/blobdiff - effect_chain.cpp
Release Movit 1.2.0.
[movit] / effect_chain.cpp
index bf017166a770f5a2d4d52adf0d68cf303aab30bd..8d030c287a483e72fc7fd7d4898dd1b0cfabd056 100644 (file)
@@ -39,6 +39,7 @@ EffectChain::EffectChain(float aspect_nom, float aspect_denom, ResourcePool *res
          aspect_denom(aspect_denom),
          dither_effect(NULL),
          num_dither_bits(0),
+         output_origin(OUTPUT_ORIGIN_BOTTOM_LEFT),
          finalized(false),
          resource_pool(resource_pool),
          do_phase_timing(false) {
@@ -82,13 +83,14 @@ void EffectChain::add_output(const ImageFormat &format, OutputAlphaFormat alpha_
 }
 
 void EffectChain::add_ycbcr_output(const ImageFormat &format, OutputAlphaFormat alpha_format,
-                                   const YCbCrFormat &ycbcr_format)
+                                   const YCbCrFormat &ycbcr_format, YCbCrOutputSplitting output_splitting)
 {
        assert(!finalized);
        output_format = format;
        output_alpha_format = alpha_format;
        output_color_type = OUTPUT_COLOR_YCBCR;
        output_ycbcr_format = ycbcr_format;
+       output_ycbcr_splitting = output_splitting;
 
        assert(ycbcr_format.chroma_subsampling_x == 1);
        assert(ycbcr_format.chroma_subsampling_y == 1);
@@ -361,6 +363,23 @@ void EffectChain::compile_glsl_program(Phase *phase)
                frag_shader += "\n";
        }
        frag_shader += string("#define INPUT ") + phase->effect_ids[phase->effects.back()] + "\n";
+
+       // If we're the last phase, add the right #defines for Y'CbCr multi-output as needed.
+       if (phase->output_node->outgoing_links.empty() && output_color_type == OUTPUT_COLOR_YCBCR) {
+               switch (output_ycbcr_splitting) {
+               case YCBCR_OUTPUT_INTERLEAVED:
+                       // No #defines set.
+                       break;
+               case YCBCR_OUTPUT_SPLIT_Y_AND_CBCR:
+                       frag_shader += "#define YCBCR_OUTPUT_SPLIT_Y_AND_CBCR 1\n";
+                       break;
+               case YCBCR_OUTPUT_PLANAR:
+                       frag_shader += "#define YCBCR_OUTPUT_PLANAR 1\n";
+                       break;
+               default:
+                       assert(false);
+               }
+       }
        frag_shader.append(read_version_dependent_file("footer", "frag"));
 
        // Collect uniforms from all effects and output them. Note that this needs
@@ -389,6 +408,17 @@ void EffectChain::compile_glsl_program(Phase *phase)
        frag_shader = frag_shader_header + frag_shader_uniforms + frag_shader;
 
        string vert_shader = read_version_dependent_file("vs", "vert");
+
+       // If we're the last phase and need to flip the picture to compensate for
+       // the origin, tell the vertex shader so.
+       if (phase->output_node->outgoing_links.empty() && output_origin == OUTPUT_ORIGIN_TOP_LEFT) {
+               const string needle = "#define FLIP_ORIGIN 0";
+               size_t pos = vert_shader.find(needle);
+               assert(pos != string::npos);
+
+               vert_shader[pos + needle.size() - 1] = '1';
+       }
+
        phase->glsl_program_num = resource_pool->compile_glsl_program(vert_shader, frag_shader);
 
        // Collect the resulting location numbers for each uniform.