From 3a918307fb46478ea8080222a58406cfe04a7cbe Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 26 Feb 2017 16:10:47 +0100 Subject: [PATCH] Fix an issue where the last pass would have been rendered with the sRGB flag set, which confused Qt applications running in certain NVIDIA configurations. --- effect_chain.cpp | 21 +++++++++++++++++++-- effect_chain_test.cpp | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/effect_chain.cpp b/effect_chain.cpp index 10573ef..7b0861f 100644 --- a/effect_chain.cpp +++ b/effect_chain.cpp @@ -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); } diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index cb30d4d..bbb58a0 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -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. -- 2.39.2