Chromium Code Reviews| Index: cc/output/renderer_pixeltest.cc |
| diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc |
| index ca3bb6d247ec22eb3ceb9bc854ce2ceab8f46f1b..0a7a762654b472430f87d9aec169c564186328cc 100644 |
| --- a/cc/output/renderer_pixeltest.cc |
| +++ b/cc/output/renderer_pixeltest.cc |
| @@ -27,7 +27,9 @@ |
| #include "third_party/skia/include/core/SkSurface.h" |
| #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |
| #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
| +#include "ui/gfx/color_transform.h" |
| #include "ui/gfx/geometry/rect_conversions.h" |
| +#include "ui/gfx/test/icc_profiles.h" |
| using gpu::gles2::GLES2Interface; |
| @@ -3383,6 +3385,191 @@ TEST_F(GLRendererPixelTestWithOverdrawFeedback, TranslucentRectangles) { |
| ExactPixelComparator(true))); |
| } |
| +typedef std::tr1::tuple<gfx::ColorSpace, gfx::ColorSpace> ColorSpacePair; |
| + |
| +class ColorTransformPixelTest |
| + : public GLRendererPixelTest, |
| + public testing::WithParamInterface<ColorSpacePair> { |
| + public: |
| + ColorTransformPixelTest() { |
| + settings_.renderer_settings.enable_color_correct_rendering = true; |
| + device_viewport_size_ = gfx::Size(16, 1); |
| + src_color_space_ = std::tr1::get<0>(GetParam()); |
| + dst_color_space_ = std::tr1::get<1>(GetParam()); |
| + if (!src_color_space_.IsValid()) { |
| + src_color_space_ = |
| + gfx::ICCProfileForTestingNoAnalyticTrFn().GetColorSpace(); |
| + } |
| + if (!dst_color_space_.IsValid()) { |
| + dst_color_space_ = |
| + gfx::ICCProfileForTestingNoAnalyticTrFn().GetColorSpace(); |
| + } |
| + } |
| + gfx::ColorSpace src_color_space_; |
| + gfx::ColorSpace dst_color_space_; |
| +}; |
| + |
| +TEST_P(ColorTransformPixelTest, Basic) { |
| + gfx::Rect rect(this->device_viewport_size_); |
| + std::vector<uint8_t> input_colors(4 * rect.width() * rect.height(), 0); |
| + std::vector<SkColor> expected_output_colors(rect.width() * rect.height()); |
| + |
| + // Set the input data to be: |
| + // Row 0: Gradient of red from 0 to 255 |
| + // Row 1: Gradient of green from 0 to 255 |
| + // Row 2: Gradient of blue from 0 to 255 |
| + // Row 3: Gradient of grey from 0 to 255 |
| + for (int x = 0; x < rect.width(); ++x) { |
| + int v = (x * 255) / (input_colors.size() - 1); |
| + for (int y = 0; y < rect.height(); ++y) { |
| + for (int c = 0; c < 3; ++c) { |
| + if (y == c || y == rect.height() - 1) { |
| + input_colors[c + 4 * (x + rect.width() * y)] = v; |
| + } |
| + } |
| + input_colors[3 + 4 * (x + rect.width() * y)] = 255; |
| + } |
| + } |
| + |
| + std::unique_ptr<gfx::ColorTransform> transform = |
| + gfx::ColorTransform::NewColorTransform( |
| + src_color_space_, dst_color_space_, |
| + gfx::ColorTransform::Intent::INTENT_PERCEPTUAL); |
| + |
| + for (size_t i = 0; i < expected_output_colors.size(); ++i) { |
| + gfx::ColorTransform::TriStim color; |
| + color.set_x(input_colors[4 * i + 0] / 255.f); |
| + color.set_y(input_colors[4 * i + 1] / 255.f); |
| + color.set_z(input_colors[4 * i + 2] / 255.f); |
| + transform->Transform(&color, 1); |
| + color.set_x(std::min(std::max(0.f, color.x()), 1.f)); |
| + color.set_y(std::min(std::max(0.f, color.y()), 1.f)); |
| + color.set_z(std::min(std::max(0.f, color.z()), 1.f)); |
| + expected_output_colors[i] = |
| + SkColorSetARGBInline(255, static_cast<size_t>(255.f * color.x() + 0.5f), |
| + static_cast<size_t>(255.f * color.y() + 0.5f), |
| + static_cast<size_t>(255.f * color.z() + 0.5f)); |
| + } |
| + |
| + int id = 1; |
| + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| + pass->color_space = dst_color_space_; |
| + |
| + { |
| + SharedQuadState* shared_state = |
| + CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| + |
| + ResourceId resource = resource_provider_->CreateResource( |
| + rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, |
| + src_color_space_); |
| + resource_provider_->CopyToResource(resource, input_colors.data(), |
| + rect.size()); |
| + |
| + const gfx::PointF uv_top_left(0.0f, 0.0f); |
| + const gfx::PointF uv_bottom_right(1.0f, 1.0f); |
| + const bool flipped = false; |
| + const bool nearest_neighbor = false; |
| + const bool premultiplied_alpha = false; |
| + TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
| + |
| + float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| + quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, |
| + premultiplied_alpha, uv_top_left, uv_bottom_right, |
| + SK_ColorBLACK, vertex_opacity, flipped, nearest_neighbor, |
| + false); |
| + |
| + SolidColorDrawQuad* color_quad = |
| + pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); |
| + color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); |
| + } |
| + |
| + RenderPassList pass_list; |
| + pass_list.push_back(std::move(pass)); |
| + |
| + // Allow a difference of 2 bytes in comparison. |
| + FuzzyPixelComparator comparator(false, 100.f, 0.f, 2.f, 2, 0); |
| + EXPECT_TRUE(RunPixelTest(&pass_list, &expected_output_colors, comparator)); |
| +} |
| + |
| +typedef gfx::ColorSpace::PrimaryID PrimaryID; |
| +typedef gfx::ColorSpace::TransferID TransferID; |
| +typedef gfx::ColorSpace::MatrixID MatrixID; |
| +typedef gfx::ColorSpace::RangeID RangeID; |
| + |
| +gfx::ColorSpace src_color_spaces[] = { |
| + // This will be replaced by an ICC-based space (which can't be initialized |
| + // here). |
| + gfx::ColorSpace(), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT709), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA22), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA24), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA28), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE170M), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE240M), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG_SQRT), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_4), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT1361_ECG), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_10), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_12), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST2084), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST428_1), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::ARIB_STD_B67), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1_HDR), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR), |
| + gfx::ColorSpace(PrimaryID::BT709, |
| + TransferID::BT2020_10, |
| + MatrixID::BT2020_CL, |
| + RangeID::FULL), |
| +}; |
| + |
| +gfx::ColorSpace dst_color_spaces[] = { |
| + // This will be replaced by an ICC-based space (which can't be initialized |
| + // here). |
| + // TODO(ccameron): Shaders that fall back to using a LUT are not accurate |
| + // enough for this test to pass (unless the LUT resolution is very large, |
| + // more than 64x64x64), so leave this test disabled for now. |
| + // gfx::ColorSpace(), |
|
ccameron
2017/03/23 06:41:40
The errors in this case were very large (like ~16/
hubbe
2017/03/23 18:09:33
The LUTs are inherently less accurate, but 16/255
ccameron
2017/03/23 19:21:51
I found that if I change the test image to be 17x4
hubbe
2017/03/23 19:30:40
One thing that we really should do is to adjust th
|
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT709), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA22), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA24), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA28), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE170M), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE240M), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG_SQRT), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_4), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT1361_ECG), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_10), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_12), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST2084), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST428_1), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::ARIB_STD_B67), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1_HDR), |
| + gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR), |
| +}; |
| + |
| +gfx::ColorSpace intermediate_color_spaces[] = { |
| + gfx::ColorSpace(PrimaryID::XYZ_D50, TransferID::LINEAR), |
| + gfx::ColorSpace(PrimaryID::XYZ_D50, TransferID::IEC61966_2_1_HDR), |
| +}; |
| + |
| +INSTANTIATE_TEST_CASE_P( |
| + FromColorSpace, |
| + ColorTransformPixelTest, |
| + testing::Combine(testing::ValuesIn(src_color_spaces), |
| + testing::ValuesIn(intermediate_color_spaces))); |
| + |
| +INSTANTIATE_TEST_CASE_P( |
| + ToColorSpace, |
| + ColorTransformPixelTest, |
| + testing::Combine(testing::ValuesIn(intermediate_color_spaces), |
| + testing::ValuesIn(dst_color_spaces))); |
| + |
| #endif // !defined(OS_ANDROID) |
| } // namespace |