]> git.sesse.net Git - nageru/commitdiff
Make sure our uploaded RGBA textures can deal with being asked for linear gamma.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Tue, 11 Apr 2017 19:53:00 +0000 (21:53 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 12 Apr 2017 16:58:36 +0000 (18:58 +0200)
They still are not used for anything, though.

flags.h
mixer.cpp
pbo_frame_allocator.cpp
theme.cpp
tweaked_inputs.h

diff --git a/flags.h b/flags.h
index caeaf2bc0cf43a2c769d23c8d2121a456a32bef2..7f39fdde11be10b18980c82ac5e3dfc4461f169c 100644 (file)
--- a/flags.h
+++ b/flags.h
@@ -58,6 +58,7 @@ struct Flags {
        bool ten_bit_output = false;  // Implies x264_video_to_disk == true and x264_bit_depth == 10.
        int x264_bit_depth = 8;  // Not user-settable.
        bool use_zerocopy = false;  // Not user-settable.
+       bool can_disable_srgb_decoder = false;  // Not user-settable.
 };
 extern Flags global_flags;
 
index 317c762a70575e9307b4c6a52c1e55aa59cb4304..385ca237d94364e48d834271fe2eabf82072c2c1 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -124,7 +124,11 @@ void ensure_texture_resolution(PBOFrameAllocator::Userdata *userdata, unsigned f
                case bmusb::PixelFormat_8BitRGBA:
                        glBindTexture(GL_TEXTURE_2D, userdata->tex_rgba[field]);
                        check_error();
-                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+                       if (global_flags.can_disable_srgb_decoder) {  // See the comments in tweaked_inputs.h.
+                               glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+                       } else {
+                               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+                       }
                        check_error();
                        break;
                }
@@ -206,6 +210,9 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards)
        CHECK(init_movit(MOVIT_SHADER_DIR, MOVIT_DEBUG_OFF));
        check_error();
 
+       // This nearly always should be true.
+       global_flags.can_disable_srgb_decoder = epoxy_has_gl_extension("GL_EXT_texture_sRGB_decode");
+
        // Since we allow non-bouncing 4:2:2 YCbCrInputs, effective subpixel precision
        // will be halved when sampling them, and we need to compensate here.
        movit_texel_subpixel_precision /= 2.0;
index e27aa6949cb65ee1d1a74575de0f5048bd8d8dfd..ed1ddb5f9a1c0eb94588daa508c4ebf2fdaad858 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <cstddef>
 
+#include "flags.h"
 #include "v210_converter.h"
 
 using namespace std;
@@ -143,7 +144,11 @@ PBOFrameAllocator::PBOFrameAllocator(bmusb::PixelFormat pixel_format, size_t fra
                                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                                check_error();
                                if (field == 0) {
-                                       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+                                       if (global_flags.can_disable_srgb_decoder) {  // See the comments in tweaked_inputs.h.
+                                               glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+                                       } else {
+                                               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+                                       }
                                        check_error();
                                }
                                break;
index b6a19acd2ea5b5eb28e36772fc560400d36d5d9c..f92143e954573b5c121c05c26585b5c484f113cd 100644 (file)
--- a/theme.cpp
+++ b/theme.cpp
@@ -630,7 +630,11 @@ LiveInputWrapper::LiveInputWrapper(Theme *theme, EffectChain *chain, bmusb::Pixe
 
        if (pixel_format == bmusb::PixelFormat_8BitRGBA) {
                for (unsigned i = 0; i < num_inputs; ++i) {
-                       rgba_inputs.push_back(new FlatInput(inout_format, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, GL_UNSIGNED_BYTE, global_flags.width, global_flags.height));
+                       if (global_flags.can_disable_srgb_decoder) {
+                               rgba_inputs.push_back(new sRGBSwitchingFlatInput(inout_format, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, GL_UNSIGNED_BYTE, global_flags.width, global_flags.height));
+                       } else {
+                               rgba_inputs.push_back(new NonsRGBCapableFlatInput(inout_format, FORMAT_RGBA_POSTMULTIPLIED_ALPHA, GL_UNSIGNED_BYTE, global_flags.width, global_flags.height));
+                       }
                        chain->add_input(rgba_inputs.back());
                }
 
index 5478ddee21594d8e708e7b0a00a8b7a667f8ebfb..37c67827fe922f0cc247035729b50bec49e69deb 100644 (file)
@@ -21,4 +21,57 @@ public:
         bool override_disable_bounce() const override { return true; }
 };
 
+// We use FlatInput with RGBA inputs a few places where we can't tell when
+// uploading the texture whether it needs to be converted from sRGB to linear
+// or not. (FlatInput deals with this if you give it pixels, but we give it
+// already uploaded textures.)
+//
+// If we have GL_EXT_texture_sRGB_decode (very common, as far as I can tell),
+// we can just always upload with the sRGB flag turned on, and then turn it off
+// if not requested; that's sRGBSwitchingFlatInput. If not, we just need to
+// turn off the functionality altogether, which is NonsRGBCapableFlatInput.
+//
+// If you're using NonsRGBCapableFlatInput, upload with GL_RGBA8.
+// If using sRGBSwitchingFlatInput, upload with GL_SRGB8_ALPHA8.
+
+class NonsRGBCapableFlatInput : public movit::FlatInput {
+public:
+       NonsRGBCapableFlatInput(movit::ImageFormat format, movit::MovitPixelFormat pixel_format, GLenum type, unsigned width, unsigned height)
+           : movit::FlatInput(format, pixel_format, type, width, height) {}
+
+       bool can_output_linear_gamma() const override { return false; }
+};
+
+class sRGBSwitchingFlatInput : public movit::FlatInput {
+public:
+       sRGBSwitchingFlatInput(movit::ImageFormat format, movit::MovitPixelFormat pixel_format, GLenum type, unsigned width, unsigned height)
+           : movit::FlatInput(format, pixel_format, type, width, height) {}
+
+       void set_gl_state(GLuint glsl_program_num, const std::string &prefix, unsigned *sampler_num) override
+       {
+               movit::FlatInput::set_gl_state(glsl_program_num, prefix, sampler_num);
+
+               // This flag is ignored for non-sRGB-uploaded textures, so we can set it
+               // without checking can_output_linear_gamma().
+               glActiveTexture(GL_TEXTURE0 + *sampler_num - 1);
+               if (output_linear_gamma) {
+                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
+               } else {
+                       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+               }
+       }
+
+       bool set_int(const std::string &key, int value) override
+       {
+               if (key == "output_linear_gamma") {
+                       output_linear_gamma = value;
+               }
+               return movit::FlatInput::set_int(key, value);
+       }
+
+private:
+       int output_linear_gamma = false;
+};
+
+
 #endif  // !defined(_TWEAKED_INPUTS_H)