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.
TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) {
unsigned char data[] = {
TEST(EffectChainTest, RewritingWorksAndTexturesAreAskedForsRGB) {
unsigned char data[] = {
+ 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<InvertEffect> *effect = new RewritingEffect<InvertEffect>();
tester.get_chain()->add_effect(effect);
RewritingEffect<InvertEffect> *effect = new RewritingEffect<InvertEffect>();
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());
Node *node = effect->replaced_node;
ASSERT_EQ(1, node->incoming_links.size());
EXPECT_EQ("FlatInput", node->incoming_links[0]->effect->effect_type_id());
EXPECT_EQ("GammaCompressionEffect", node->outgoing_links[0]->effect->effect_type_id());
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) {
}
TEST(EffectChainTest, RewritingWorksAndColorspaceConversionsAreInserted) {
}
} else if (output_linear_gamma) {
assert(type == GL_UNSIGNED_BYTE);
}
} 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) {
} else {
assert(type == GL_UNSIGNED_BYTE);
if (pixel_format == FORMAT_R) {
virtual std::string effect_type_id() const { return "FlatInput"; }
virtual bool can_output_linear_gamma() const {
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 &&
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));
}
(image_format.gamma_curve == GAMMA_LINEAR ||
image_format.gamma_curve == GAMMA_sRGB));
}