Fix an issue where the last pass would have been rendered with the sRGB flag set...
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 26 Feb 2017 15:10:47 +0000 (16:10 +0100)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 26 Feb 2017 15:10:47 +0000 (16:10 +0100)
effect_chain.cpp
effect_chain_test.cpp

index 10573ef..7b0861f 100644 (file)
@@ -1733,8 +1733,10 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
        check_error();
        glDisable(GL_DITHER);
        check_error();
-       glEnable(GL_FRAMEBUFFER_SRGB);
+
+       const bool final_srgb = glIsEnabled(GL_FRAMEBUFFER_SRGB);
        check_error();
+       bool current_srgb = final_srgb;
 
        // Save original viewport.
        GLuint x = 0, y = 0;
@@ -1800,7 +1802,22 @@ void EffectChain::render_to_fbo(GLuint dest_fbo, unsigned width, unsigned height
                                CHECK(dither_effect->set_int("output_height", height));
                        }
                }
-               execute_phase(phase, phase_num == phases.size() - 1, &bound_attribute_indices, &output_textures, &generated_mipmaps);
+               bool last_phase = (phase_num == phases.size() - 1);
+
+               // Enable sRGB rendering for intermediates in case we are
+               // rendering to an sRGB format.
+               bool needs_srgb = last_phase ? final_srgb : true;
+               if (needs_srgb && !current_srgb) {
+                       glEnable(GL_FRAMEBUFFER_SRGB);
+                       check_error();
+                       current_srgb = true;
+               } else if (!needs_srgb && current_srgb) {
+                       glDisable(GL_FRAMEBUFFER_SRGB);
+                       check_error();
+                       current_srgb = true;
+               }
+
+               execute_phase(phase, last_phase, &bound_attribute_indices, &output_textures, &generated_mipmaps);
                if (do_phase_timing) {
                        glEndQuery(GL_TIME_ELAPSED);
                }
index cb30d4d..bbb58a0 100644 (file)
@@ -1319,6 +1319,9 @@ TEST(EffectChainTest, sRGBIntermediate) {
            << "Expected sRGB not to be able to represent 0.5 exactly (got " << out_data[1] << ")";
        EXPECT_LT(fabs(out_data[1] - data[1]), 0.1f)
            << "Expected sRGB to be able to represent 0.5 approximately (got " << out_data[1] << ")";
+
+       // This state should have been preserved.
+       EXPECT_FALSE(glIsEnabled(GL_FRAMEBUFFER_SRGB));
 }
 
 // An effect that is like IdentityEffect, but also does not require linear light.