]> git.sesse.net Git - movit/blobdiff - effect_chain.cpp
Bump version after new format support.
[movit] / effect_chain.cpp
index b0d4aafbac71dc9a2864c0941ddf01cfc10c8bd0..fa7340d7a456839f7ef2563d76c5a872182491ff 100644 (file)
@@ -1,5 +1,3 @@
-#define GL_GLEXT_PROTOTYPES 1
-
 #include <epoxy/gl.h>
 #include <assert.h>
 #include <math.h>
@@ -34,12 +32,13 @@ using namespace std;
 
 namespace movit {
 
-EffectChain::EffectChain(float aspect_nom, float aspect_denom, ResourcePool *resource_pool)
+EffectChain::EffectChain(float aspect_nom, float aspect_denom, ResourcePool *resource_pool, GLenum intermediate_format)
        : aspect_nom(aspect_nom),
          aspect_denom(aspect_denom),
          output_color_rgba(false),
          output_color_ycbcr(false),
          dither_effect(NULL),
+         intermediate_format(intermediate_format),
          num_dither_bits(0),
          output_origin(OUTPUT_ORIGIN_BOTTOM_LEFT),
          finalized(false),
@@ -652,9 +651,8 @@ Phase *EffectChain::construct_phase(Node *output, map<Node *, Phase *> *complete
        // Actually make the shader for this phase.
        compile_glsl_program(phase);
 
-       // Initialize timer objects.
+       // Initialize timers.
        if (movit_timer_queries_supported) {
-               glGenQueries(1, &phase->timer_query_object);
                phase->time_elapsed_ns = 0;
                phase->num_measured_iterations = 0;
        }
@@ -1695,6 +1693,8 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
        check_error();
        glDisable(GL_DITHER);
        check_error();
+       glEnable(GL_FRAMEBUFFER_SRGB);
+       check_error();
 
        // Save original viewport.
        GLuint x = 0, y = 0;
@@ -1738,7 +1738,15 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
                Phase *phase = phases[phase_num];
 
                if (do_phase_timing) {
-                       glBeginQuery(GL_TIME_ELAPSED, phase->timer_query_object);
+                       GLuint timer_query_object;
+                       if (phase->timer_query_objects_free.empty()) {
+                               glGenQueries(1, &timer_query_object);
+                       } else {
+                               timer_query_object = phase->timer_query_objects_free.front();
+                               phase->timer_query_objects_free.pop_front();
+                       }
+                       glBeginQuery(GL_TIME_ELAPSED, timer_query_object);
+                       phase->timer_query_objects_running.push_back(timer_query_object);
                }
                if (phase_num == phases.size() - 1) {
                        // Last phase goes to the output the user specified.
@@ -1758,13 +1766,6 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
                }
        }
 
-       for (set<GLint>::iterator attr_it = bound_attribute_indices.begin();
-            attr_it != bound_attribute_indices.end();
-            ++attr_it) {
-               glDisableVertexAttribArray(*attr_it);
-               check_error();
-       }
-
        for (map<Phase *, GLuint>::const_iterator texture_it = output_textures.begin();
             texture_it != output_textures.end();
             ++texture_it) {
@@ -1787,14 +1788,22 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
                // Get back the timer queries.
                for (unsigned phase_num = 0; phase_num < phases.size(); ++phase_num) {
                        Phase *phase = phases[phase_num];
-                       GLint available = 0;
-                       while (!available) {
-                               glGetQueryObjectiv(phase->timer_query_object, GL_QUERY_RESULT_AVAILABLE, &available);
+                       for (std::list<GLuint>::iterator timer_it = phase->timer_query_objects_running.begin();
+                            timer_it != phase->timer_query_objects_running.end(); ) {
+                               GLint timer_query_object = *timer_it;
+                               GLint available;
+                               glGetQueryObjectiv(timer_query_object, GL_QUERY_RESULT_AVAILABLE, &available);
+                               if (available) {
+                                       GLuint64 time_elapsed;
+                                       glGetQueryObjectui64v(timer_query_object, GL_QUERY_RESULT, &time_elapsed);
+                                       phase->time_elapsed_ns += time_elapsed;
+                                       ++phase->num_measured_iterations;
+                                       phase->timer_query_objects_free.push_back(timer_query_object);
+                                       phase->timer_query_objects_running.erase(timer_it++);
+                               } else {
+                                       ++timer_it;
+                               }
                        }
-                       GLuint64 time_elapsed;
-                       glGetQueryObjectui64v(phase->timer_query_object, GL_QUERY_RESULT, &time_elapsed);
-                       phase->time_elapsed_ns += time_elapsed;
-                       ++phase->num_measured_iterations;
                }
        }
 }
@@ -1847,13 +1856,11 @@ void EffectChain::execute_phase(Phase *phase, bool last_phase,
        if (!last_phase) {
                find_output_size(phase);
 
-               GLuint tex_num = resource_pool->create_2d_texture(GL_RGBA16F, phase->output_width, phase->output_height);
+               GLuint tex_num = resource_pool->create_2d_texture(intermediate_format, phase->output_width, phase->output_height);
                output_textures->insert(make_pair(phase, tex_num));
        }
 
-       const GLuint glsl_program_num = phase->glsl_program_num;
-       check_error();
-       glUseProgram(glsl_program_num);
+       glUseProgram(phase->glsl_program_num);
        check_error();
 
        // Set up RTT inputs for this phase.
@@ -1884,7 +1891,7 @@ void EffectChain::execute_phase(Phase *phase, bool last_phase,
        for (unsigned i = 0; i < phase->effects.size(); ++i) {
                Node *node = phase->effects[i];
                unsigned old_sampler_num = sampler_num;
-               node->effect->set_gl_state(glsl_program_num, phase->effect_ids[node], &sampler_num);
+               node->effect->set_gl_state(phase->glsl_program_num, phase->effect_ids[node], &sampler_num);
                check_error();
 
                if (node->effect->is_single_texture()) {
@@ -1927,9 +1934,6 @@ void EffectChain::execute_phase(Phase *phase, bool last_phase,
        glDrawArrays(GL_TRIANGLES, 0, 3);
        check_error();
        
-       glUseProgram(0);
-       check_error();
-
        for (unsigned i = 0; i < phase->effects.size(); ++i) {
                Node *node = phase->effects[i];
                node->effect->clear_gl_state();