Generate the FBO anew every render.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 29 Dec 2013 22:59:05 +0000 (23:59 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 29 Dec 2013 22:59:05 +0000 (23:59 +0100)
This fixes an issue where reusing the same EffectChain from two different GL
contexts would cause errors even if they are shared, because FBOs cannot be
shared between contexts (in the ARB extension, anyway).

There might be some negative performance implications to this, but I was unable
to measure any on Intel/Mesa. If this should prove to be a problem in the future,
we could maybe keep one around per context, or have the caller invalidate the
FBO for us.

effect_chain.cpp
effect_chain.h

index e68895d..f88a4f7 100644 (file)
@@ -29,7 +29,6 @@ EffectChain::EffectChain(float aspect_nom, float aspect_denom)
        : aspect_nom(aspect_nom),
          aspect_denom(aspect_denom),
          dither_effect(NULL),
-         fbo(0),
          num_dither_bits(0),
          finalized(false) {}
 
@@ -48,9 +47,6 @@ EffectChain::~EffectChain()
                glDeleteShader(phases[i]->fragment_shader);
                delete phases[i];
        }
-       if (fbo != 0) {
-               glDeleteFramebuffers(1, &fbo);
-       }
 }
 
 Input *EffectChain::add_input(Input *input)
@@ -1433,8 +1429,6 @@ void EffectChain::finalize()
        // since otherwise this turns into an (albeit simple)
        // register allocation problem.
        if (phases.size() > 1) {
-               glGenFramebuffers(1, &fbo);
-
                for (unsigned i = 0; i < phases.size() - 1; ++i) {
                        inform_input_sizes(phases[i]);
                        find_output_size(phases[i]);
@@ -1473,6 +1467,7 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
 
        // Save original viewport.
        GLuint x = 0, y = 0;
+       GLuint fbo = 0;
 
        if (width == 0 && height == 0) {
                GLint viewport[4];
@@ -1499,6 +1494,8 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
        glLoadIdentity();
 
        if (phases.size() > 1) {
+               glGenFramebuffers(1, &fbo);
+               check_error();
                glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                check_error();
        }
@@ -1614,4 +1611,12 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
                        node->effect->clear_gl_state();
                }
        }
+
+       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+       check_error();
+
+       if (fbo != 0) {
+               glDeleteFramebuffers(1, &fbo);
+               check_error();
+       }
 }
index f41e7e4..6698c6f 100644 (file)
@@ -229,8 +229,6 @@ private:
        Effect *dither_effect;
 
        std::vector<Input *> inputs;  // Also contained in nodes.
-
-       GLuint fbo;
        std::vector<Phase *> phases;
 
        unsigned num_dither_bits;