]> git.sesse.net Git - movit/blobdiff - effect_chain.cpp
Add explicit support for requesting no mipmaps.
[movit] / effect_chain.cpp
index aefae8f0c908a105457d0e2416481eda6c0a4297..95bf1c0b1a0f4e58fc9b717ebeb22d0ecda455b6 100644 (file)
@@ -163,7 +163,7 @@ Node *EffectChain::add_node(Effect *effect)
        node->output_color_space = COLORSPACE_INVALID;
        node->output_gamma_curve = GAMMA_INVALID;
        node->output_alpha_type = ALPHA_INVALID;
-       node->needs_mipmaps = false;
+       node->needs_mipmaps = Effect::DOES_NOT_NEED_MIPMAPS;
        node->one_to_one_sampling = false;
        node->strong_one_to_one_sampling = false;
 
@@ -523,6 +523,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
 
        if (phase->is_compute_shader) {
                frag_shader.append(read_file("footer.comp"));
+               phase->compute_shader_node->effect->register_uniform_ivec2("output_size", phase->uniform_output_size);
                phase->compute_shader_node->effect->register_uniform_vec2("inv_output_size", (float *)&phase->inv_output_size);
                phase->compute_shader_node->effect->register_uniform_vec2("output_texcoord_adjust", (float *)&phase->output_texcoord_adjust);
        } else {
@@ -544,6 +545,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
                extract_uniform_declarations(effect->uniforms_sampler2d, "sampler2D", effect_id, &phase->uniforms_sampler2d, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_bool, "bool", effect_id, &phase->uniforms_bool, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_int, "int", effect_id, &phase->uniforms_int, &frag_shader_uniforms);
+               extract_uniform_declarations(effect->uniforms_ivec2, "ivec2", effect_id, &phase->uniforms_ivec2, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_float, "float", effect_id, &phase->uniforms_float, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_vec2, "vec2", effect_id, &phase->uniforms_vec2, &frag_shader_uniforms);
                extract_uniform_declarations(effect->uniforms_vec3, "vec3", effect_id, &phase->uniforms_vec3, &frag_shader_uniforms);
@@ -607,6 +609,7 @@ void EffectChain::compile_glsl_program(Phase *phase)
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_sampler2d);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_bool);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_int);
+       collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_ivec2);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_float);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_vec2);
        collect_uniform_locations(phase->glsl_program_num, &phase->uniforms_vec3);
@@ -652,8 +655,12 @@ Phase *EffectChain::construct_phase(Node *output, map<Node *, Phase *> *complete
 
                assert(node->effect->one_to_one_sampling() >= node->effect->strong_one_to_one_sampling());
 
-               if (node->effect->needs_mipmaps()) {
-                       node->needs_mipmaps = true;
+               if (node->effect->needs_mipmaps() != Effect::DOES_NOT_NEED_MIPMAPS) {
+                       // Can't have incompatible requirements imposed on us from a dependent effect;
+                       // if so, it should have started a new phase instead.
+                       assert(node->needs_mipmaps == Effect::DOES_NOT_NEED_MIPMAPS ||
+                              node->needs_mipmaps == node->effect->needs_mipmaps());
+                       node->needs_mipmaps = node->effect->needs_mipmaps();
                }
 
                // This should currently only happen for effects that are inputs
@@ -691,12 +698,14 @@ Phase *EffectChain::construct_phase(Node *output, map<Node *, Phase *> *complete
                        // Note that we cannot do this propagation as a normal pass,
                        // because it needs information about where the phases end
                        // (we should not propagate the flag across phases).
-                       if (node->needs_mipmaps) {
-                               if (deps[i]->effect->num_inputs() == 0) {
+                       if (node->needs_mipmaps != Effect::DOES_NOT_NEED_MIPMAPS) {
+                               if (deps[i]->effect->num_inputs() == 0 && node->needs_mipmaps == Effect::NEEDS_MIPMAPS) {
                                        Input *input = static_cast<Input *>(deps[i]->effect);
                                        start_new_phase |= !input->can_supply_mipmaps();
-                               } else {
-                                       deps[i]->needs_mipmaps = true;
+                               } else if (deps[i]->effect->needs_mipmaps() == Effect::DOES_NOT_NEED_MIPMAPS) {
+                                       deps[i]->needs_mipmaps = node->needs_mipmaps;
+                               } else if (deps[i]->effect->needs_mipmaps() != node->needs_mipmaps) {
+                                       start_new_phase = true;
                                }
                        }
 
@@ -785,7 +794,9 @@ Phase *EffectChain::construct_phase(Node *output, map<Node *, Phase *> *complete
        phase->input_needs_mipmaps = false;
        for (unsigned i = 0; i < phase->effects.size(); ++i) {
                Node *node = phase->effects[i];
-               phase->input_needs_mipmaps |= node->effect->needs_mipmaps();
+               if (node->effect->needs_mipmaps() == Effect::NEEDS_MIPMAPS) {
+                       phase->input_needs_mipmaps = true;
+               }
        }
        for (unsigned i = 0; i < phase->effects.size(); ++i) {
                Node *node = phase->effects[i];
@@ -2154,6 +2165,8 @@ void EffectChain::execute_phase(Phase *phase,
                phase->outbuf_image_unit = 0;
                glBindImageTexture(phase->outbuf_image_unit, destinations[0].texnum, 0, GL_FALSE, 0, GL_WRITE_ONLY, destinations[0].format);
                check_error();
+               phase->uniform_output_size[0] = phase->output_width;
+               phase->uniform_output_size[1] = phase->output_height;
                phase->inv_output_size.x = 1.0f / phase->output_width;
                phase->inv_output_size.y = 1.0f / phase->output_height;
                phase->output_texcoord_adjust.x = 0.5f / phase->output_width;
@@ -2247,6 +2260,12 @@ void EffectChain::setup_uniforms(Phase *phase)
                        glUniform1iv(uniform.location, uniform.num_values, uniform.value);
                }
        }
+       for (size_t i = 0; i < phase->uniforms_ivec2.size(); ++i) {
+               const Uniform<int> &uniform = phase->uniforms_ivec2[i];
+               if (uniform.location != -1) {
+                       glUniform2iv(uniform.location, uniform.num_values, uniform.value);
+               }
+       }
        for (size_t i = 0; i < phase->uniforms_float.size(); ++i) {
                const Uniform<float> &uniform = phase->uniforms_float[i];
                if (uniform.location != -1) {