They still are not used for anything, though.
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;
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;
}
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;
#include <stdio.h>
#include <cstddef>
+#include "flags.h"
#include "v210_converter.h"
using namespace std;
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;
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());
}
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)