]> git.sesse.net Git - nageru/commitdiff
Fix an issue where RGBA videos would flicker.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 21 Apr 2017 22:55:17 +0000 (00:55 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 21 Apr 2017 22:57:02 +0000 (00:57 +0200)
The issue would be that the preview chains and the live chain would often
have different sRGB texture needs, and they'd run at the same time and thus
have a race condition. Solve this by using a sampler object instead, which
overrides the texture state.

Makefile
mixer.cpp
tweaked_inputs.cpp [new file with mode: 0644]
tweaked_inputs.h

index 9dc55261a97068601a560001d30be91f7a23bc2a..1a041fefab6d297e11f2fcbdd572e807424e01c4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ OBJS += midi_mapper.o midi_mapping.pb.o
 
 # Mixer objects
 AUDIO_MIXER_OBJS = audio_mixer.o alsa_input.o alsa_pool.o ebu_r128_proc.o stereocompressor.o resampling_queue.o flags.o correlation_measurer.o filter.o input_mapping.o state.pb.o
-OBJS += chroma_subsampler.o v210_converter.o mixer.o pbo_frame_allocator.o context.o ref_counted_frame.o theme.o httpd.o flags.o image_input.o alsa_output.o disk_space_estimator.o print_latency.o timecode_renderer.o $(AUDIO_MIXER_OBJS)
+OBJS += chroma_subsampler.o v210_converter.o mixer.o pbo_frame_allocator.o context.o ref_counted_frame.o theme.o httpd.o flags.o image_input.o alsa_output.o disk_space_estimator.o print_latency.o timecode_renderer.o tweaked_inputs.o $(AUDIO_MIXER_OBJS)
 
 # Streaming and encoding objects
 OBJS += quicksync_encoder.o x264_encoder.o x264_dynamic.o x264_speed_control.o video_encoder.o metacube2.o mux.o audio_encoder.o ffmpeg_raii.o ffmpeg_util.o
index 3a14a757431a88b2924a3430dcbf922fe1b3e73c..c21ac95943bcbbaa7a6b97e4def90bf6d70770ea 100644 (file)
--- a/mixer.cpp
+++ b/mixer.cpp
@@ -212,7 +212,9 @@ Mixer::Mixer(const QSurfaceFormat &format, unsigned num_cards)
        check_error();
 
        // This nearly always should be true.
-       global_flags.can_disable_srgb_decoder = epoxy_has_gl_extension("GL_EXT_texture_sRGB_decode");
+       global_flags.can_disable_srgb_decoder =
+               epoxy_has_gl_extension("GL_EXT_texture_sRGB_decode") &&
+               epoxy_has_gl_extension("GL_ARB_sampler_objects");
 
        // Since we allow non-bouncing 4:2:2 YCbCrInputs, effective subpixel precision
        // will be halved when sampling them, and we need to compensate here.
diff --git a/tweaked_inputs.cpp b/tweaked_inputs.cpp
new file mode 100644 (file)
index 0000000..304c3b4
--- /dev/null
@@ -0,0 +1,48 @@
+#include <epoxy/gl.h>
+#include <movit/flat_input.h>
+#include <movit/util.h>
+
+#include "tweaked_inputs.h"
+
+sRGBSwitchingFlatInput::~sRGBSwitchingFlatInput()
+{
+       if (sampler_obj != 0) {
+               glDeleteSamplers(1, &sampler_obj);
+       }
+}
+
+void sRGBSwitchingFlatInput::set_gl_state(GLuint glsl_program_num, const std::string &prefix, unsigned *sampler_num)
+{
+       movit::FlatInput::set_gl_state(glsl_program_num, prefix, sampler_num);
+       texture_unit = *sampler_num - 1;
+
+       if (sampler_obj == 0) {
+               glGenSamplers(1, &sampler_obj);
+               check_error();
+               glSamplerParameteri(sampler_obj, GL_TEXTURE_MIN_FILTER, needs_mipmaps ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR);
+               check_error();
+               glSamplerParameteri(sampler_obj, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+               check_error();
+               glSamplerParameteri(sampler_obj, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+               check_error()
+               // This needs to be done on a sampler and not a texture parameter,
+               // because the texture could be used from multiple different
+               // contexts at the same time. This flag is ignored for non-sRGB-uploaded
+               // textures, so we can set it without checking can_output_linear_gamma().
+               if (output_linear_gamma) {
+                       glSamplerParameteri(sampler_obj, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
+               } else {
+                       glSamplerParameteri(sampler_obj, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+               }
+               check_error();
+       }
+
+       glBindSampler(texture_unit, sampler_obj);
+       check_error();
+}
+
+void sRGBSwitchingFlatInput::clear_gl_state()
+{
+       glBindSampler(texture_unit, 0);
+       check_error();
+}
index 37c67827fe922f0cc247035729b50bec49e69deb..0ca13ced94877a3084fec7609bdc0cdd93a39f8b 100644 (file)
@@ -47,30 +47,26 @@ 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);
-               }
-       }
+       ~sRGBSwitchingFlatInput();
+       void set_gl_state(GLuint glsl_program_num, const std::string &prefix, unsigned *sampler_num) override;
+       void clear_gl_state() override;
 
        bool set_int(const std::string &key, int value) override
        {
                if (key == "output_linear_gamma") {
                        output_linear_gamma = value;
                }
+               if (key == "needs_mipmaps") {
+                       needs_mipmaps = value;
+               }
                return movit::FlatInput::set_int(key, value);
        }
 
 private:
-       int output_linear_gamma = false;
+       bool output_linear_gamma = false;
+       bool needs_mipmaps = false;
+       GLuint sampler_obj = 0;
+       GLuint texture_unit;
 };