| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "cc/base/math_util.h" | 10 #include "cc/base/math_util.h" |
| 11 #include "cc/output/gl_renderer.h" | 11 #include "cc/output/gl_renderer.h" |
| 12 #include "cc/paint/paint_flags.h" | 12 #include "cc/paint/paint_flags.h" |
| 13 #include "cc/paint/skia_paint_canvas.h" | 13 #include "cc/paint/skia_paint_canvas.h" |
| 14 #include "cc/quads/draw_quad.h" | 14 #include "cc/quads/draw_quad.h" |
| 15 #include "cc/quads/picture_draw_quad.h" | 15 #include "cc/quads/picture_draw_quad.h" |
| 16 #include "cc/quads/texture_draw_quad.h" | 16 #include "cc/quads/texture_draw_quad.h" |
| 17 #include "cc/resources/video_resource_updater.h" | 17 #include "cc/resources/video_resource_updater.h" |
| 18 #include "cc/test/fake_raster_source.h" | 18 #include "cc/test/fake_raster_source.h" |
| 19 #include "cc/test/fake_recording_source.h" | 19 #include "cc/test/fake_recording_source.h" |
| 20 #include "cc/test/pixel_test.h" | 20 #include "cc/test/pixel_test.h" |
| 21 #include "gpu/command_buffer/client/gles2_interface.h" | 21 #include "gpu/command_buffer/client/gles2_interface.h" |
| 22 #include "media/base/video_frame.h" | 22 #include "media/base/video_frame.h" |
| 23 #include "third_party/skia/include/core/SkColorPriv.h" | 23 #include "third_party/skia/include/core/SkColorPriv.h" |
| 24 #include "third_party/skia/include/core/SkImageFilter.h" | 24 #include "third_party/skia/include/core/SkImageFilter.h" |
| 25 #include "third_party/skia/include/core/SkMatrix.h" | 25 #include "third_party/skia/include/core/SkMatrix.h" |
| 26 #include "third_party/skia/include/core/SkRefCnt.h" | 26 #include "third_party/skia/include/core/SkRefCnt.h" |
| 27 #include "third_party/skia/include/core/SkSurface.h" | 27 #include "third_party/skia/include/core/SkSurface.h" |
| 28 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" | 28 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |
| 29 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" | 29 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" |
| 30 #include "ui/gfx/color_transform.h" |
| 30 #include "ui/gfx/geometry/rect_conversions.h" | 31 #include "ui/gfx/geometry/rect_conversions.h" |
| 32 #include "ui/gfx/test/icc_profiles.h" |
| 31 | 33 |
| 32 using gpu::gles2::GLES2Interface; | 34 using gpu::gles2::GLES2Interface; |
| 33 | 35 |
| 34 namespace cc { | 36 namespace cc { |
| 35 namespace { | 37 namespace { |
| 36 | 38 |
| 37 #if !defined(OS_ANDROID) | 39 #if !defined(OS_ANDROID) |
| 38 std::unique_ptr<RenderPass> CreateTestRootRenderPass(int id, | 40 std::unique_ptr<RenderPass> CreateTestRootRenderPass(int id, |
| 39 const gfx::Rect& rect) { | 41 const gfx::Rect& rect) { |
| 40 std::unique_ptr<RenderPass> pass = RenderPass::Create(); | 42 std::unique_ptr<RenderPass> pass = RenderPass::Create(); |
| (...skipping 3335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3376 bg->SetNew(bg_shared_state, rect, rect, SK_ColorBLACK, false); | 3378 bg->SetNew(bg_shared_state, rect, rect, SK_ColorBLACK, false); |
| 3377 | 3379 |
| 3378 RenderPassList pass_list; | 3380 RenderPassList pass_list; |
| 3379 pass_list.push_back(std::move(pass)); | 3381 pass_list.push_back(std::move(pass)); |
| 3380 | 3382 |
| 3381 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(FILE_PATH_LITERAL( | 3383 EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(FILE_PATH_LITERAL( |
| 3382 "translucent_rectangles.png")), | 3384 "translucent_rectangles.png")), |
| 3383 ExactPixelComparator(true))); | 3385 ExactPixelComparator(true))); |
| 3384 } | 3386 } |
| 3385 | 3387 |
| 3388 typedef std::tr1::tuple<gfx::ColorSpace, gfx::ColorSpace> ColorSpacePair; |
| 3389 |
| 3390 class ColorTransformPixelTest |
| 3391 : public GLRendererPixelTest, |
| 3392 public testing::WithParamInterface<ColorSpacePair> { |
| 3393 public: |
| 3394 ColorTransformPixelTest() { |
| 3395 settings_.renderer_settings.enable_color_correct_rendering = true; |
| 3396 // Note that this size of 17 is not random -- it is chosen to match the |
| 3397 // size of LUTs that are created. If we did not match the LUT size exactly, |
| 3398 // then the error for LUT based transforms is much larger. |
| 3399 device_viewport_size_ = gfx::Size(17, 4); |
| 3400 src_color_space_ = std::tr1::get<0>(GetParam()); |
| 3401 dst_color_space_ = std::tr1::get<1>(GetParam()); |
| 3402 if (!src_color_space_.IsValid()) { |
| 3403 src_color_space_ = |
| 3404 gfx::ICCProfileForTestingNoAnalyticTrFn().GetColorSpace(); |
| 3405 } |
| 3406 if (!dst_color_space_.IsValid()) { |
| 3407 dst_color_space_ = |
| 3408 gfx::ICCProfileForTestingNoAnalyticTrFn().GetColorSpace(); |
| 3409 } |
| 3410 } |
| 3411 gfx::ColorSpace src_color_space_; |
| 3412 gfx::ColorSpace dst_color_space_; |
| 3413 }; |
| 3414 |
| 3415 TEST_P(ColorTransformPixelTest, Basic) { |
| 3416 gfx::Rect rect(this->device_viewport_size_); |
| 3417 std::vector<uint8_t> input_colors(4 * rect.width() * rect.height(), 0); |
| 3418 std::vector<SkColor> expected_output_colors(rect.width() * rect.height()); |
| 3419 |
| 3420 // Set the input data to be: |
| 3421 // Row 0: Gradient of red from 0 to 255 |
| 3422 // Row 1: Gradient of green from 0 to 255 |
| 3423 // Row 2: Gradient of blue from 0 to 255 |
| 3424 // Row 3: Gradient of grey from 0 to 255 |
| 3425 for (int x = 0; x < rect.width(); ++x) { |
| 3426 int v = (x * 255) / (rect.width() - 1); |
| 3427 for (int y = 0; y < rect.height(); ++y) { |
| 3428 for (int c = 0; c < 3; ++c) { |
| 3429 if (y == c || y == rect.height() - 1) { |
| 3430 input_colors[c + 4 * (x + rect.width() * y)] = v; |
| 3431 } |
| 3432 } |
| 3433 input_colors[3 + 4 * (x + rect.width() * y)] = 255; |
| 3434 } |
| 3435 } |
| 3436 |
| 3437 std::unique_ptr<gfx::ColorTransform> transform = |
| 3438 gfx::ColorTransform::NewColorTransform( |
| 3439 src_color_space_, dst_color_space_, |
| 3440 gfx::ColorTransform::Intent::INTENT_PERCEPTUAL); |
| 3441 |
| 3442 for (size_t i = 0; i < expected_output_colors.size(); ++i) { |
| 3443 gfx::ColorTransform::TriStim color; |
| 3444 color.set_x(input_colors[4 * i + 0] / 255.f); |
| 3445 color.set_y(input_colors[4 * i + 1] / 255.f); |
| 3446 color.set_z(input_colors[4 * i + 2] / 255.f); |
| 3447 transform->Transform(&color, 1); |
| 3448 color.set_x(std::min(std::max(0.f, color.x()), 1.f)); |
| 3449 color.set_y(std::min(std::max(0.f, color.y()), 1.f)); |
| 3450 color.set_z(std::min(std::max(0.f, color.z()), 1.f)); |
| 3451 expected_output_colors[i] = |
| 3452 SkColorSetARGBInline(255, static_cast<size_t>(255.f * color.x() + 0.5f), |
| 3453 static_cast<size_t>(255.f * color.y() + 0.5f), |
| 3454 static_cast<size_t>(255.f * color.z() + 0.5f)); |
| 3455 } |
| 3456 |
| 3457 int id = 1; |
| 3458 std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); |
| 3459 pass->color_space = dst_color_space_; |
| 3460 |
| 3461 { |
| 3462 SharedQuadState* shared_state = |
| 3463 CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); |
| 3464 |
| 3465 ResourceId resource = resource_provider_->CreateResource( |
| 3466 rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, |
| 3467 src_color_space_); |
| 3468 resource_provider_->CopyToResource(resource, input_colors.data(), |
| 3469 rect.size()); |
| 3470 |
| 3471 const gfx::PointF uv_top_left(0.0f, 0.0f); |
| 3472 const gfx::PointF uv_bottom_right(1.0f, 1.0f); |
| 3473 const bool flipped = false; |
| 3474 const bool nearest_neighbor = false; |
| 3475 const bool premultiplied_alpha = false; |
| 3476 TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); |
| 3477 |
| 3478 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; |
| 3479 quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource, |
| 3480 premultiplied_alpha, uv_top_left, uv_bottom_right, |
| 3481 SK_ColorBLACK, vertex_opacity, flipped, nearest_neighbor, |
| 3482 false); |
| 3483 |
| 3484 SolidColorDrawQuad* color_quad = |
| 3485 pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>(); |
| 3486 color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false); |
| 3487 } |
| 3488 |
| 3489 RenderPassList pass_list; |
| 3490 pass_list.push_back(std::move(pass)); |
| 3491 |
| 3492 // Allow a difference of 2 bytes in comparison for shader-based transforms, |
| 3493 // and 4 bytes for LUT-based transforms (determined empirically). |
| 3494 FuzzyPixelComparator comparator(false, 100.f, 0.f, 2.f, 2, 0); |
| 3495 if (!transform->CanGetShaderSource()) |
| 3496 comparator = FuzzyPixelComparator(false, 100.f, 0.f, 4.f, 4, 0); |
| 3497 EXPECT_TRUE(RunPixelTest(&pass_list, &expected_output_colors, comparator)); |
| 3498 } |
| 3499 |
| 3500 typedef gfx::ColorSpace::PrimaryID PrimaryID; |
| 3501 typedef gfx::ColorSpace::TransferID TransferID; |
| 3502 typedef gfx::ColorSpace::MatrixID MatrixID; |
| 3503 typedef gfx::ColorSpace::RangeID RangeID; |
| 3504 |
| 3505 gfx::ColorSpace src_color_spaces[] = { |
| 3506 // This will be replaced by an ICC-based space (which can't be initialized |
| 3507 // here). |
| 3508 gfx::ColorSpace(), |
| 3509 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT709), |
| 3510 gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA22), |
| 3511 gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA24), |
| 3512 gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA28), |
| 3513 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE170M), |
| 3514 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE240M), |
| 3515 gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR), |
| 3516 gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG), |
| 3517 gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG_SQRT), |
| 3518 gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_4), |
| 3519 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT1361_ECG), |
| 3520 gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1), |
| 3521 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_10), |
| 3522 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_12), |
| 3523 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST2084), |
| 3524 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST428_1), |
| 3525 gfx::ColorSpace(PrimaryID::BT709, TransferID::ARIB_STD_B67), |
| 3526 gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1_HDR), |
| 3527 gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR), |
| 3528 gfx::ColorSpace(PrimaryID::BT709, |
| 3529 TransferID::BT2020_10, |
| 3530 MatrixID::BT2020_CL, |
| 3531 RangeID::FULL), |
| 3532 }; |
| 3533 |
| 3534 gfx::ColorSpace dst_color_spaces[] = { |
| 3535 // This will be replaced by an ICC-based space (which can't be initialized |
| 3536 // here). |
| 3537 gfx::ColorSpace(), |
| 3538 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT709), |
| 3539 gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA22), |
| 3540 gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA24), |
| 3541 gfx::ColorSpace(PrimaryID::BT709, TransferID::GAMMA28), |
| 3542 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE170M), |
| 3543 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTE240M), |
| 3544 gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR), |
| 3545 gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG), |
| 3546 gfx::ColorSpace(PrimaryID::BT709, TransferID::LOG_SQRT), |
| 3547 gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_4), |
| 3548 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT1361_ECG), |
| 3549 gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1), |
| 3550 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_10), |
| 3551 gfx::ColorSpace(PrimaryID::BT709, TransferID::BT2020_12), |
| 3552 gfx::ColorSpace(PrimaryID::BT709, TransferID::SMPTEST2084), |
| 3553 gfx::ColorSpace(PrimaryID::BT709, TransferID::ARIB_STD_B67), |
| 3554 gfx::ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1_HDR), |
| 3555 gfx::ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR), |
| 3556 }; |
| 3557 |
| 3558 gfx::ColorSpace intermediate_color_spaces[] = { |
| 3559 gfx::ColorSpace(PrimaryID::XYZ_D50, TransferID::LINEAR), |
| 3560 gfx::ColorSpace(PrimaryID::XYZ_D50, TransferID::IEC61966_2_1_HDR), |
| 3561 }; |
| 3562 |
| 3563 INSTANTIATE_TEST_CASE_P( |
| 3564 FromColorSpace, |
| 3565 ColorTransformPixelTest, |
| 3566 testing::Combine(testing::ValuesIn(src_color_spaces), |
| 3567 testing::ValuesIn(intermediate_color_spaces))); |
| 3568 |
| 3569 INSTANTIATE_TEST_CASE_P( |
| 3570 ToColorSpace, |
| 3571 ColorTransformPixelTest, |
| 3572 testing::Combine(testing::ValuesIn(intermediate_color_spaces), |
| 3573 testing::ValuesIn(dst_color_spaces))); |
| 3574 |
| 3386 #endif // !defined(OS_ANDROID) | 3575 #endif // !defined(OS_ANDROID) |
| 3387 | 3576 |
| 3388 } // namespace | 3577 } // namespace |
| 3389 } // namespace cc | 3578 } // namespace cc |
| OLD | NEW |