| Index: ui/gfx/color_transform_unittest.cc
|
| diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc
|
| index 36e3ab21e958862b229fd21559793cb1c818f4f3..1ccfe753115e01e92bdcfe8585ec18cba2089695 100644
|
| --- a/ui/gfx/color_transform_unittest.cc
|
| +++ b/ui/gfx/color_transform_unittest.cc
|
| @@ -82,6 +82,46 @@ TEST(SimpleColorSpace, BT709toSRGB) {
|
| EXPECT_GT(tmp.z(), tmp.y());
|
| }
|
|
|
| +TEST(SimpleColorSpace, TransferFnCancel) {
|
| + ColorSpace::PrimaryID primary = ColorSpace::PrimaryID::BT709;
|
| + ColorSpace::MatrixID matrix = ColorSpace::MatrixID::RGB;
|
| + ColorSpace::RangeID range = ColorSpace::RangeID::FULL;
|
| +
|
| + // BT709 has a gamma of 2.2222 (with some adjustments)
|
| + ColorSpace bt709(primary, ColorSpace::TransferID::BT709, matrix, range);
|
| +
|
| + // IEC61966_2_1 has the sRGB gamma of 2.4 (with some adjustments)
|
| + ColorSpace srgb(primary, ColorSpace::TransferID::IEC61966_2_1, matrix, range);
|
| +
|
| + // gamma28 is a simple exponential
|
| + ColorSpace gamma28(primary, ColorSpace::TransferID::GAMMA28, matrix, range);
|
| +
|
| + // gamma24 is a simple exponential
|
| + ColorSpace gamma24(primary, ColorSpace::TransferID::GAMMA24, matrix, range);
|
| +
|
| + // BT709 source is common for video and sRGB destination is common for
|
| + // monitors. The two transfer functions are very close, and should cancel
|
| + // out (so the transfer between them should be the identity). This particular
|
| + // case is important for power reasons.
|
| + std::unique_ptr<ColorTransform> bt709_to_srgb(
|
| + ColorTransform::NewColorTransform(
|
| + bt709, srgb, ColorTransform::Intent::INTENT_PERCEPTUAL));
|
| + EXPECT_EQ(bt709_to_srgb->NumberOfStepsForTesting(), 0u);
|
| +
|
| + // Gamma 2.8 isn't even close to BT709 and won't cancel out (so we will have
|
| + // two steps in the transform -- to-linear and from-linear).
|
| + std::unique_ptr<ColorTransform> bt709_to_gamma28(
|
| + ColorTransform::NewColorTransform(
|
| + bt709, gamma28, ColorTransform::Intent::INTENT_PERCEPTUAL));
|
| + EXPECT_EQ(bt709_to_gamma28->NumberOfStepsForTesting(), 2u);
|
| +
|
| + // Gamma 2.4 is closer to BT709, but not close enough to actually cancel out.
|
| + std::unique_ptr<ColorTransform> bt709_to_gamma24(
|
| + ColorTransform::NewColorTransform(
|
| + bt709, gamma24, ColorTransform::Intent::INTENT_PERCEPTUAL));
|
| + EXPECT_EQ(bt709_to_gamma24->NumberOfStepsForTesting(), 2u);
|
| +}
|
| +
|
| TEST(SimpleColorSpace, SRGBFromICCAndNotICC) {
|
| float kEpsilon = 0.001f;
|
| ColorTransform::TriStim value_fromicc;
|
| @@ -232,6 +272,112 @@ TEST(SimpleColorSpace, DefaultToSRGB) {
|
| EXPECT_EQ(t2->NumberOfStepsForTesting(), 0u);
|
| }
|
|
|
| +// This tests to make sure that we don't emit the "if" or "pow" parts of a
|
| +// transfer function unless necessary.
|
| +TEST(SimpleColorSpace, ShaderSourceTrFnOptimizations) {
|
| + SkMatrix44 primaries;
|
| + gfx::ColorSpace::CreateSRGB().GetPrimaryMatrix(&primaries);
|
| +
|
| + SkColorSpaceTransferFn fn_no_pow_no_if = {
|
| + 1.f, 2.f, 0.f, 1.f, 0.f, 0.f, 0.f,
|
| + };
|
| + SkColorSpaceTransferFn fn_no_pow_yes_if = {
|
| + 1.f, 2.f, 0.f, 1.f, 0.5f, 0.f, 0.f,
|
| + };
|
| + SkColorSpaceTransferFn fn_yes_pow_no_if = {
|
| + 2.f, 2.f, 0.f, 1.f, 0.f, 0.f, 0.f,
|
| + };
|
| + SkColorSpaceTransferFn fn_yes_pow_yes_if = {
|
| + 2.f, 2.f, 0.f, 1.f, 0.5f, 0.f, 0.f,
|
| + };
|
| +
|
| + gfx::ColorSpace src;
|
| + gfx::ColorSpace dst = gfx::ColorSpace::CreateXYZD50();
|
| + std::string shader_string;
|
| +
|
| + src = gfx::ColorSpace::CreateCustom(primaries, fn_no_pow_no_if);
|
| + shader_string = ColorTransform::NewColorTransform(
|
| + src, dst, ColorTransform::Intent::INTENT_PERCEPTUAL)
|
| + ->GetShaderSource();
|
| + EXPECT_EQ(shader_string.find("if ("), std::string::npos);
|
| + EXPECT_EQ(shader_string.find("pow("), std::string::npos);
|
| +
|
| + src = gfx::ColorSpace::CreateCustom(primaries, fn_no_pow_yes_if);
|
| + shader_string = ColorTransform::NewColorTransform(
|
| + src, dst, ColorTransform::Intent::INTENT_PERCEPTUAL)
|
| + ->GetShaderSource();
|
| + EXPECT_NE(shader_string.find("if ("), std::string::npos);
|
| + EXPECT_EQ(shader_string.find("pow("), std::string::npos);
|
| +
|
| + src = gfx::ColorSpace::CreateCustom(primaries, fn_yes_pow_no_if);
|
| + shader_string = ColorTransform::NewColorTransform(
|
| + src, dst, ColorTransform::Intent::INTENT_PERCEPTUAL)
|
| + ->GetShaderSource();
|
| + EXPECT_EQ(shader_string.find("if ("), std::string::npos);
|
| + EXPECT_NE(shader_string.find("pow("), std::string::npos);
|
| +
|
| + src = gfx::ColorSpace::CreateCustom(primaries, fn_yes_pow_yes_if);
|
| + shader_string = ColorTransform::NewColorTransform(
|
| + src, dst, ColorTransform::Intent::INTENT_PERCEPTUAL)
|
| + ->GetShaderSource();
|
| + EXPECT_NE(shader_string.find("if ("), std::string::npos);
|
| + EXPECT_NE(shader_string.find("pow("), std::string::npos);
|
| +}
|
| +
|
| +// Note: This is not actually "testing" anything -- the goal of this test is to
|
| +// to make reviewing shader code simpler by giving an example of the resulting
|
| +// shader source. This should be updated whenever shader generation is updated.
|
| +// This test produces slightly different results on Android.
|
| +#if defined(OS_ANDROID)
|
| +#define MAYBE_SampleShaderSource DISABLED_SampleShaderSource
|
| +#else
|
| +#define MAYBE_SampleShaderSource SampleShaderSource
|
| +#endif
|
| +TEST(SimpleColorSpace, MAYBE_SampleShaderSource) {
|
| + ColorSpace bt709 = ColorSpace::CreateREC709();
|
| + ColorSpace output(ColorSpace::PrimaryID::BT2020,
|
| + ColorSpace::TransferID::GAMMA28);
|
| + std::string source =
|
| + ColorTransform::NewColorTransform(
|
| + bt709, output, ColorTransform::Intent::INTENT_PERCEPTUAL)
|
| + ->GetShaderSource();
|
| + std::string expected =
|
| + "vec3 DoColorConversion(vec3 color) {\n"
|
| + " color = mat3(+1.16438353e+00, +1.16438353e+00, +1.16438353e+00,\n"
|
| + " -2.28029018e-09, -2.13248596e-01, +2.11240172e+00,\n"
|
| + " +1.79274118e+00, -5.32909274e-01, -5.96049432e-10)"
|
| + " * color;\n"
|
| + " color = vec3(-9.69429970e-01, +3.00019622e-01, -1.12926030e+00)"
|
| + " + color;\n"
|
| + " if (color.r < 0.040450)\n"
|
| + " color.r = +7.73993805e-02 * color.r;\n"
|
| + " else\n"
|
| + " color.r = pow(+9.47867334e-01 * color.r + +5.21326549e-02, "
|
| + "+2.40000010e+00);\n"
|
| + " if (color.g < 0.040450)\n"
|
| + " color.g = +7.73993805e-02 * color.g;\n"
|
| + " else\n"
|
| + " color.g = pow(+9.47867334e-01 * color.g + +5.21326549e-02, "
|
| + "+2.40000010e+00);\n"
|
| + " if (color.b < 0.040450)\n"
|
| + " color.b = +7.73993805e-02 * color.b;\n"
|
| + " else\n"
|
| + " color.b = pow(+9.47867334e-01 * color.b + +5.21326549e-02, "
|
| + "+2.40000010e+00);\n"
|
| + " color = mat3(+6.27403915e-01, +6.90973178e-02, +1.63914412e-02,\n"
|
| + " +3.29283148e-01, +9.19540286e-01, +8.80132914e-02,\n"
|
| + " +4.33131084e-02, +1.13623003e-02, +8.95595253e-01) "
|
| + "* color;\n"
|
| + " color = vec3(+0.00000000e+00, +0.00000000e+00, +0.00000000e+00) "
|
| + "+ color;\n"
|
| + " color.r = pow(color.r, +3.57142866e-01);\n"
|
| + " color.g = pow(color.g, +3.57142866e-01);\n"
|
| + " color.b = pow(color.b, +3.57142866e-01);\n"
|
| + " return color;\n"
|
| + "}\n";
|
| + EXPECT_EQ(source, expected);
|
| +}
|
| +
|
| class TransferTest : public testing::TestWithParam<ColorSpace::TransferID> {};
|
|
|
| TEST_P(TransferTest, basicTest) {
|
|
|