From d4109eee4f38a13a7f8432755bc8b6bf02ceda46 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 20 Mar 2014 23:35:59 +0100 Subject: [PATCH] Make handling of non-RGBA sRGB textures more consistent. Previously, we'd ask the driver to convert these to RGBA, which maybe isn't ideal, and certainly doesn't work with GLES. Now we send in the right format for RGB and RGBA, and refuse hardware conversions with single-channel (which GLES doesn't accept). I don't think this is optimal, but finding a use-case for sRGB single-channel is a bit tricky anyway, and the fallback is fast, too. --- effect_chain_test.cpp | 24 ++++++++++++++---------- flat_input.cpp | 8 +++++++- flat_input.h | 6 ++++++ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/effect_chain_test.cpp b/effect_chain_test.cpp index 5fe1862..2552b6f 100644 --- a/effect_chain_test.cpp +++ b/effect_chain_test.cpp @@ -152,19 +152,23 @@ TEST(EffectChainTest, RewritingWorksAndGammaConversionsAreInserted) { TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) { unsigned char data[] = { - 0, 64, - 128, 255, + 0, 0, 0, 255, + 64, 64, 64, 255, + 128, 128, 128, 255, + 255, 255, 255, 255, }; - float expected_data[4] = { - 1.0f, 0.9771f, - 0.8983f, 0.0f, + float expected_data[] = { + 1.0000f, 1.0000f, 1.0000f, 1.0000f, + 0.9771f, 0.9771f, 0.9771f, 1.0000f, + 0.8983f, 0.8983f, 0.8983f, 1.0000f, + 0.0000f, 0.0000f, 0.0000f, 1.0000f }; - float out_data[4]; - EffectChainTester tester(NULL, 2, 2); - tester.add_input(data, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_sRGB); + float out_data[4 * 4]; + EffectChainTester tester(NULL, 1, 4); + tester.add_input(data, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, GAMMA_sRGB); RewritingEffect *effect = new RewritingEffect(); tester.get_chain()->add_effect(effect); - tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_sRGB); + tester.run(out_data, GL_RGBA, COLORSPACE_sRGB, GAMMA_sRGB); Node *node = effect->replaced_node; ASSERT_EQ(1, node->incoming_links.size()); @@ -172,7 +176,7 @@ TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) { EXPECT_EQ("FlatInput", node->incoming_links[0]->effect->effect_type_id()); EXPECT_EQ("GammaCompressionEffect", node->outgoing_links[0]->effect->effect_type_id()); - expect_equal(expected_data, out_data, 2, 2); + expect_equal(expected_data, out_data, 4, 4); } TEST(EffectChainTest, RewritingWorksAndColorspaceConversionsAreInserted) { diff --git a/flat_input.cpp b/flat_input.cpp index e99eba3..f6ae827 100644 --- a/flat_input.cpp +++ b/flat_input.cpp @@ -102,7 +102,13 @@ void FlatInput::set_gl_state(GLuint glsl_program_num, const string& prefix, unsi } } else if (output_linear_gamma) { assert(type == GL_UNSIGNED_BYTE); - internal_format = GL_SRGB8_ALPHA8; + if (pixel_format == FORMAT_RGB) { + internal_format = GL_SRGB8; + } else if (pixel_format == FORMAT_RGBA_POSTMULTIPLIED_ALPHA) { + internal_format = GL_SRGB8_ALPHA8; + } else { + assert(false); + } } else { assert(type == GL_UNSIGNED_BYTE); if (pixel_format == FORMAT_R) { diff --git a/flat_input.h b/flat_input.h index 8c88989..25b9091 100644 --- a/flat_input.h +++ b/flat_input.h @@ -26,8 +26,14 @@ public: virtual std::string effect_type_id() const { return "FlatInput"; } virtual bool can_output_linear_gamma() const { + // On desktop OpenGL, there's also GL_SLUMINANCE8 which could give us + // support for single-channel sRGB decoding, but it's not supported + // on GLES, and we're already actively rewriting single-channel inputs + // to GL_RED (even on desktop), so we stick to 3- and 4-channel inputs. return (movit_srgb_textures_supported && type == GL_UNSIGNED_BYTE && + (pixel_format == FORMAT_RGB || + pixel_format == FORMAT_RGBA_POSTMULTIPLIED_ALPHA) && (image_format.gamma_curve == GAMMA_LINEAR || image_format.gamma_curve == GAMMA_sRGB)); } -- 2.39.2