Commit 723be3e4 authored by Findit's avatar Findit

Revert "Remove SkColorSpaceXform usage from Canvas code"

This reverts commit 267cb8af.

Reason for revert:

Findit (https://goo.gl/kROfz5) identified CL at revision 593674 as the
culprit for failures in the build cycles as shown on:
https://findit-for-me.appspot.com/waterfall/culprit?key=ag9zfmZpbmRpdC1mb3ItbWVyRAsSDVdmU3VzcGVjdGVkQ0wiMWNocm9taXVtLzI2N2NiOGFmMjA0YmVjMGM4YWIxNmI5NTZmZjNiZWZlYzI3OTBmY2EM

Sample Failed Build: https://ci.chromium.org/buildbot/chromium.linux/linux-jumbo-rel/7066

Sample Failed Step: compile

Original change's description:
> Remove SkColorSpaceXform usage from Canvas code
> 
> This is the last CL to remove SkColorSpaceXform call sites from
> third_party/blink. This change also does some refactoring in
> ImageBitmap unit tests, etc.
> 
> TBR=fserb@chromium.org
> 
> Bug: 774520
> Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.blink:linux_trusty_blink_rel
> Change-Id: I8279f1687ef096ae9aa2179c74d5d6cf2364ce9b
> Reviewed-on: https://chromium-review.googlesource.com/1237140
> Reviewed-by: Mohammad Reza Zakerinasab <zakerinasab@chromium.org>
> Reviewed-by: Mike Klein <mtklein@chromium.org>
> Commit-Queue: Mohammad Reza Zakerinasab <zakerinasab@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#593674}

Change-Id: I8fd0d3dcd6e2e5e4eb8251485ce07451bf8f11e2
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 774520
Cq-Include-Trybots: luci.chromium.try:linux_layout_tests_slimming_paint_v2;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.blink:linux_trusty_blink_rel
Reviewed-on: https://chromium-review.googlesource.com/1241762
Cr-Commit-Position: refs/heads/master@{#593706}
parent fca310d9
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/platform/web_task_runner.h" #include "third_party/blink/renderer/platform/web_task_runner.h"
#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/time.h"
#include "third_party/skia/include/core/SkColorSpaceXform.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
namespace blink { namespace blink {
...@@ -233,36 +234,42 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( ...@@ -233,36 +234,42 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator(
skia_image = SkImage::MakeFromRaster(src_data_, nullptr, nullptr); skia_image = SkImage::MakeFromRaster(src_data_, nullptr, nullptr);
} }
DCHECK(skia_image->colorSpace()); DCHECK(skia_image->colorSpace());
skia_image = skia_image->makeColorSpace(blob_color_space);
image_ = StaticBitmapImage::Create(skia_image); image_ = StaticBitmapImage::Create(skia_image);
image_ = image_->ConvertToColorSpace(blob_color_space,
skia_image->colorType());
skia_image = image_->PaintImageForCurrentFrame().GetSkImage();
} }
if (skia_image->peekPixels(&src_data_)) { if (skia_image->peekPixels(&src_data_))
static_bitmap_image_loaded_ = true; static_bitmap_image_loaded_ = true;
// If the source image is 8 bit per channel but the blob is requested in // If the source image is 8 bit per channel but the blob is requested in
// 16 bpc PNG, we need to ensure the color type of the pixmap is // 16 bpc PNG, we need to ensure the color type of the pixmap is
// kRGBA_F16_SkColorType to kick in 16 bit encoding in SkPngEncoder. Since // kRGBA_F16_SkColorType to kick in 16 bit encoding in SkPngEncoder. Since
// SkPixmap only holds a pointer to data, we need a helper data member // SkPixmap only holds a pointer to data, we need a helper data member here.
// here. if (mime_type_ == kMimeTypePng &&
if (mime_type_ == kMimeTypePng && encode_options_.pixelFormat() == kRGBA16ImagePixelFormatName &&
encode_options_.pixelFormat() == kRGBA16ImagePixelFormatName && src_data_.colorType() == kN32_SkColorType) {
src_data_.colorType() == kN32_SkColorType) { size_t data_length = src_data_.width() * src_data_.height() *
size_t data_length = src_data_.width() * src_data_.height() * SkColorTypeBytesPerPixel(kRGBA_F16_SkColorType);
SkColorTypeBytesPerPixel(kRGBA_F16_SkColorType); png_16bit_data_helper_ = SkData::MakeUninitialized(data_length);
png_16bit_data_helper_ = SkData::MakeUninitialized(data_length); SkColorSpaceXform::ColorFormat src_format =
SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
if (kN32_SkColorType == kBGRA_8888_SkColorType)
src_format = SkColorSpaceXform::ColorFormat::kBGRA_8888_ColorFormat;
if (SkColorSpaceXform::Apply(
src_data_.colorSpace(),
SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat,
png_16bit_data_helper_->writable_data(), src_data_.colorSpace(),
src_format, src_data_.addr(),
src_data_.width() * src_data_.height(),
SkColorSpaceXform::AlphaOp::kPreserve_AlphaOp)) {
SkImageInfo info = SkImageInfo::Make( SkImageInfo info = SkImageInfo::Make(
src_data_.width(), src_data_.height(), kRGBA_F16_SkColorType, src_data_.width(), src_data_.height(), kRGBA_F16_SkColorType,
src_data_.alphaType(), src_data_.info().refColorSpace()); src_data_.alphaType(), src_data_.info().refColorSpace());
SkPixmap src_data_f16(info, png_16bit_data_helper_->data(), src_data_.reset(info, png_16bit_data_helper_->data(),
info.minRowBytes()); info.minRowBytes());
src_data_.readPixels(src_data_f16);
src_data_ = src_data_f16;
skia_image = SkImage::MakeFromRaster(src_data_, nullptr, nullptr);
image_ = StaticBitmapImage::Create(skia_image);
} }
skia_image = SkImage::MakeFromRaster(src_data_, nullptr, nullptr);
image_ = StaticBitmapImage::Create(skia_image);
} }
} }
......
...@@ -265,6 +265,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { ...@@ -265,6 +265,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
// The maximum difference locally observed is 3. // The maximum difference locally observed is 3.
const unsigned uint8_color_tolerance = 5; const unsigned uint8_color_tolerance = 5;
const float f16_color_tolerance = 0.01; const float f16_color_tolerance = 0.01;
// The maximum difference locally observed has the order of e^-6.
const float xyz_d50_color_space_component_tolerance = 0.001;
for (auto color_space_param : color_space_params) { for (auto color_space_param : color_space_params) {
for (auto blob_mime_type : blob_mime_types) { for (auto blob_mime_type : blob_mime_types) {
...@@ -304,7 +306,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { ...@@ -304,7 +306,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) {
bool compare_alpha = (blob_mime_type != "image/jpeg"); bool compare_alpha = (blob_mime_type != "image/jpeg");
ASSERT_TRUE(ColorCorrectionTestUtils::MatchSkImages( ASSERT_TRUE(ColorCorrectionTestUtils::MatchSkImages(
ref_image, decoded_img, uint8_color_tolerance, ref_image, decoded_img, uint8_color_tolerance,
f16_color_tolerance, compare_alpha)); f16_color_tolerance, xyz_d50_color_space_component_tolerance,
compare_alpha));
} }
} }
} }
......
...@@ -312,6 +312,47 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) { ...@@ -312,6 +312,47 @@ TEST_F(ImageBitmapTest, AvoidGPUReadback) {
} }
} }
enum class ColorSpaceConversion : uint8_t {
NONE = 0,
DEFAULT_COLOR_CORRECTED = 1,
PRESERVE = 2,
SRGB = 3,
LINEAR_RGB = 4,
P3 = 5,
REC2020 = 6,
LAST = REC2020
};
static ImageBitmapOptions PrepareBitmapOptions(
const ColorSpaceConversion& color_space_conversion) {
// Set the color space conversion in ImageBitmapOptions
ImageBitmapOptions options;
static const Vector<String> kConversions = {
"none", "default", "preserve", "srgb", "linear-rgb", "p3", "rec2020"};
options.setColorSpaceConversion(
kConversions[static_cast<uint8_t>(color_space_conversion)]);
return options;
}
static sk_sp<SkColorSpace> GetColorSpaceForColorSpaceConversion(
ColorSpaceConversion conversion) {
sk_sp<SkColorSpace> color_space = nullptr;
if (conversion == ColorSpaceConversion::DEFAULT_COLOR_CORRECTED ||
conversion == ColorSpaceConversion::SRGB) {
color_space = SkColorSpace::MakeSRGB();
} else if (conversion == ColorSpaceConversion::LINEAR_RGB) {
color_space = SkColorSpace::MakeSRGBLinear();
} else if (conversion == ColorSpaceConversion::P3) {
color_space = SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
SkColorSpace::kDCIP3_D65_Gamut);
} else if (conversion == ColorSpaceConversion::REC2020) {
color_space = SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
SkColorSpace::kRec2020_Gamut);
}
return color_space;
}
TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) { TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
HTMLImageElement* image_element = HTMLImageElement* image_element =
HTMLImageElement::Create(*Document::CreateForTest()); HTMLImageElement::Create(*Document::CreateForTest());
...@@ -336,13 +377,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) { ...@@ -336,13 +377,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
base::Optional<IntRect> crop_rect = base::Optional<IntRect> crop_rect =
IntRect(0, 0, source_image->width(), source_image->height()); IntRect(0, 0, source_image->width(), source_image->height());
for (int conversion_iterator = ColorSpaceConversion::kDefault; for (uint8_t i =
conversion_iterator <= ColorSpaceConversion::kLast; static_cast<uint8_t>(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
conversion_iterator++) { i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
ImageBitmapOptions options; ColorSpaceConversion color_space_conversion =
options.setColorSpaceConversion( static_cast<ColorSpaceConversion>(i);
ColorCorrectionTestUtils::ColorSpaceConversionToString( ImageBitmapOptions options =
static_cast<ColorSpaceConversion>(conversion_iterator))); PrepareBitmapOptions(color_space_conversion);
ImageBitmap* image_bitmap = ImageBitmap::Create( ImageBitmap* image_bitmap = ImageBitmap::Create(
image_element, crop_rect, &(image_element->GetDocument()), options); image_element, crop_rect, &(image_element->GetDocument()), options);
ASSERT_TRUE(image_bitmap); ASSERT_TRUE(image_bitmap);
...@@ -352,7 +393,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) { ...@@ -352,7 +393,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
converted_image->peekPixels(&converted_pixmap); converted_image->peekPixels(&converted_pixmap);
unsigned num_pixels = source_image->width() * source_image->height(); unsigned num_pixels = source_image->width() * source_image->height();
if (conversion_iterator == ColorSpaceConversion::kPreserve) { if (color_space_conversion == ColorSpaceConversion::PRESERVE) {
EXPECT_TRUE( EXPECT_TRUE(
SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace())); SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace()));
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -360,8 +401,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) { ...@@ -360,8 +401,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance); kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
} else { } else {
sk_sp<SkColorSpace> color_space = sk_sp<SkColorSpace> color_space =
ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( GetColorSpaceForColorSpaceConversion(color_space_conversion);
static_cast<ColorSpaceConversion>(conversion_iterator));
EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
converted_image->colorSpace())); converted_image->colorSpace()));
...@@ -372,7 +412,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) { ...@@ -372,7 +412,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionHTMLImageElement) {
expected_image_info.makeColorType(kRGBA_F16_SkColorType); expected_image_info.makeColorType(kRGBA_F16_SkColorType);
} }
SkBitmap expected_bitmap; SkBitmap expected_bitmap;
EXPECT_TRUE(expected_bitmap.tryAllocPixels(expected_image_info)); EXPECT_TRUE(expected_bitmap.tryAllocPixels(
expected_image_info, expected_image_info.minRowBytes()));
source_image->readPixels(expected_bitmap.pixmap(), 0, 0); source_image->readPixels(expected_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -398,20 +439,18 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) { ...@@ -398,20 +439,18 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
base::Optional<IntRect> crop_rect = base::Optional<IntRect> crop_rect =
IntRect(0, 0, source_image->width(), source_image->height()); IntRect(0, 0, source_image->width(), source_image->height());
ImageBitmapOptions options; ImageBitmapOptions options =
options.setColorSpaceConversion( PrepareBitmapOptions(ColorSpaceConversion::PRESERVE);
ColorCorrectionTestUtils::ColorSpaceConversionToString(
ColorSpaceConversion::kPreserve));
ImageBitmap* source_image_bitmap = ImageBitmap::Create( ImageBitmap* source_image_bitmap = ImageBitmap::Create(
StaticBitmapImage::Create(source_image), crop_rect, options); StaticBitmapImage::Create(source_image), crop_rect, options);
ASSERT_TRUE(source_image_bitmap); ASSERT_TRUE(source_image_bitmap);
for (int conversion_iterator = ColorSpaceConversion::kDefault; for (uint8_t i =
conversion_iterator <= ColorSpaceConversion::kLast; static_cast<uint8_t>(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
conversion_iterator++) { i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
options.setColorSpaceConversion( ColorSpaceConversion color_space_conversion =
ColorCorrectionTestUtils::ColorSpaceConversionToString( static_cast<ColorSpaceConversion>(i);
static_cast<ColorSpaceConversion>(conversion_iterator))); options = PrepareBitmapOptions(color_space_conversion);
ImageBitmap* image_bitmap = ImageBitmap* image_bitmap =
ImageBitmap::Create(source_image_bitmap, crop_rect, options); ImageBitmap::Create(source_image_bitmap, crop_rect, options);
ASSERT_TRUE(image_bitmap); ASSERT_TRUE(image_bitmap);
...@@ -421,7 +460,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) { ...@@ -421,7 +460,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
converted_image->peekPixels(&converted_pixmap); converted_image->peekPixels(&converted_pixmap);
unsigned num_pixels = source_image->width() * source_image->height(); unsigned num_pixels = source_image->width() * source_image->height();
if (conversion_iterator == ColorSpaceConversion::kPreserve) { if (color_space_conversion == ColorSpaceConversion::PRESERVE) {
EXPECT_TRUE( EXPECT_TRUE(
SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace())); SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace()));
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -429,8 +468,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) { ...@@ -429,8 +468,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance); kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
} else { } else {
sk_sp<SkColorSpace> color_space = sk_sp<SkColorSpace> color_space =
ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( GetColorSpaceForColorSpaceConversion(color_space_conversion);
static_cast<ColorSpaceConversion>(conversion_iterator));
EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
converted_image->colorSpace())); converted_image->colorSpace()));
...@@ -441,7 +479,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) { ...@@ -441,7 +479,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageBitmap) {
expected_image_info.makeColorType(kRGBA_F16_SkColorType); expected_image_info.makeColorType(kRGBA_F16_SkColorType);
} }
SkBitmap expected_bitmap; SkBitmap expected_bitmap;
EXPECT_TRUE(expected_bitmap.tryAllocPixels(expected_image_info)); EXPECT_TRUE(expected_bitmap.tryAllocPixels(
expected_image_info, expected_image_info.minRowBytes()));
source_image->readPixels(expected_bitmap.pixmap(), 0, 0); source_image->readPixels(expected_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -468,13 +507,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) { ...@@ -468,13 +507,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
base::Optional<IntRect> crop_rect = base::Optional<IntRect> crop_rect =
IntRect(0, 0, source_image->width(), source_image->height()); IntRect(0, 0, source_image->width(), source_image->height());
for (int conversion_iterator = ColorSpaceConversion::kDefault; for (uint8_t i =
conversion_iterator <= ColorSpaceConversion::kLast; static_cast<uint8_t>(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
conversion_iterator++) { i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
ImageBitmapOptions options; ColorSpaceConversion color_space_conversion =
options.setColorSpaceConversion( static_cast<ColorSpaceConversion>(i);
ColorCorrectionTestUtils::ColorSpaceConversionToString( ImageBitmapOptions options =
static_cast<ColorSpaceConversion>(conversion_iterator))); PrepareBitmapOptions(color_space_conversion);
ImageBitmap* image_bitmap = ImageBitmap::Create( ImageBitmap* image_bitmap = ImageBitmap::Create(
StaticBitmapImage::Create(source_image), crop_rect, options); StaticBitmapImage::Create(source_image), crop_rect, options);
ASSERT_TRUE(image_bitmap); ASSERT_TRUE(image_bitmap);
...@@ -484,7 +523,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) { ...@@ -484,7 +523,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
converted_image->peekPixels(&converted_pixmap); converted_image->peekPixels(&converted_pixmap);
unsigned num_pixels = source_image->width() * source_image->height(); unsigned num_pixels = source_image->width() * source_image->height();
if (conversion_iterator == ColorSpaceConversion::kPreserve) { if (color_space_conversion == ColorSpaceConversion::PRESERVE) {
EXPECT_TRUE( EXPECT_TRUE(
SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace())); SkColorSpace::Equals(colorspin.get(), converted_image->colorSpace()));
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -492,8 +531,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) { ...@@ -492,8 +531,7 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance); kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
} else { } else {
sk_sp<SkColorSpace> color_space = sk_sp<SkColorSpace> color_space =
ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( GetColorSpaceForColorSpaceConversion(color_space_conversion);
static_cast<ColorSpaceConversion>(conversion_iterator));
EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
converted_image->colorSpace())); converted_image->colorSpace()));
...@@ -504,7 +542,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) { ...@@ -504,7 +542,8 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionStaticBitmapImage) {
expected_image_info.makeColorType(kRGBA_F16_SkColorType); expected_image_info.makeColorType(kRGBA_F16_SkColorType);
} }
SkBitmap expected_bitmap; SkBitmap expected_bitmap;
EXPECT_TRUE(expected_bitmap.tryAllocPixels(expected_image_info)); EXPECT_TRUE(expected_bitmap.tryAllocPixels(
expected_image_info, expected_image_info.minRowBytes()));
source_image->readPixels(expected_bitmap.pixmap(), 0, 0); source_image->readPixels(expected_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -526,20 +565,21 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) { ...@@ -526,20 +565,21 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kUnpremul_SkAlphaType,
SkColorSpace::MakeSRGB()); SkColorSpace::MakeSRGB());
SkBitmap source_bitmap; SkBitmap source_bitmap;
EXPECT_TRUE(source_bitmap.tryAllocPixels(image_info)); EXPECT_TRUE(
source_bitmap.tryAllocPixels(image_info, image_info.minRowBytes()));
SkPixmap source_pixmap; SkPixmap source_pixmap;
source_pixmap = source_bitmap.pixmap(); source_pixmap = source_bitmap.pixmap();
memcpy(source_pixmap.writable_addr(), image_data->BufferBase()->Data(), 4); memcpy(source_pixmap.writable_addr(), image_data->BufferBase()->Data(), 4);
base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1); base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1);
for (int conversion_iterator = ColorSpaceConversion::kDefault; for (uint8_t i =
conversion_iterator <= ColorSpaceConversion::kLast; static_cast<uint8_t>(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
conversion_iterator++) { i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
ImageBitmapOptions options; ColorSpaceConversion color_space_conversion =
options.setColorSpaceConversion( static_cast<ColorSpaceConversion>(i);
ColorCorrectionTestUtils::ColorSpaceConversionToString( ImageBitmapOptions options =
static_cast<ColorSpaceConversion>(conversion_iterator))); PrepareBitmapOptions(color_space_conversion);
ImageBitmap* image_bitmap = ImageBitmap* image_bitmap =
ImageBitmap::Create(image_data, crop_rect, options); ImageBitmap::Create(image_data, crop_rect, options);
ASSERT_TRUE(image_bitmap); ASSERT_TRUE(image_bitmap);
...@@ -549,12 +589,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) { ...@@ -549,12 +589,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
converted_image->peekPixels(&converted_pixmap); converted_image->peekPixels(&converted_pixmap);
unsigned num_pixels = converted_image->width() * converted_image->height(); unsigned num_pixels = converted_image->width() * converted_image->height();
if (conversion_iterator == ColorSpaceConversion::kPreserve) { if (color_space_conversion == ColorSpaceConversion::PRESERVE) {
// crbug.com/886999 // crbug.com/886999
// EXPECT_TRUE(SkColorSpace::Equals(SkColorSpace::MakeSRGB().get(), // EXPECT_TRUE(SkColorSpace::Equals(SkColorSpace::MakeSRGB().get(),
// converted_image->colorSpace())); // converted_image->colorSpace()));
SkBitmap expected_bitmap; SkBitmap expected_bitmap;
EXPECT_TRUE(expected_bitmap.tryAllocPixels(converted_pixmap.info())); EXPECT_TRUE(expected_bitmap.tryAllocPixels(
converted_pixmap.info(), converted_pixmap.info().minRowBytes()));
source_pixmap.readPixels(expected_bitmap.pixmap(), 0, 0); source_pixmap.readPixels(expected_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -562,13 +603,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) { ...@@ -562,13 +603,13 @@ TEST_F(ImageBitmapTest, ImageBitmapColorSpaceConversionImageData) {
kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance); kPixelFormat_8888, kAlphaMultiplied, kUnpremulRoundTripTolerance);
} else { } else {
sk_sp<SkColorSpace> color_space = sk_sp<SkColorSpace> color_space =
ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( GetColorSpaceForColorSpaceConversion(color_space_conversion);
static_cast<ColorSpaceConversion>(conversion_iterator));
// crbug.com/886999 // crbug.com/886999
// EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), // EXPECT_TRUE(SkColorSpace::Equals(color_space.get(),
// converted_image->colorSpace())); // converted_image->colorSpace()));
SkBitmap expected_bitmap; SkBitmap expected_bitmap;
EXPECT_TRUE(expected_bitmap.tryAllocPixels(converted_pixmap.info())); EXPECT_TRUE(expected_bitmap.tryAllocPixels(
converted_pixmap.info(), converted_pixmap.info().minRowBytes()));
source_pixmap.readPixels(expected_bitmap.pixmap(), 0, 0); source_pixmap.readPixels(expected_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
...@@ -658,13 +699,12 @@ TEST_F(ImageBitmapTest, ...@@ -658,13 +699,12 @@ TEST_F(ImageBitmapTest,
ImageData* image_data = ImageData* image_data =
ImageData::CreateForTest(IntSize(v8::TypedArray::kMaxLength / 16, 1)); ImageData::CreateForTest(IntSize(v8::TypedArray::kMaxLength / 16, 1));
DCHECK(image_data); DCHECK(image_data);
ImageBitmapOptions options; ImageBitmapOptions options =
options.setColorSpaceConversion( PrepareBitmapOptions(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
ColorCorrectionTestUtils::ColorSpaceConversionToString(
ColorSpaceConversion::kDefault));
ImageBitmap* image_bitmap = ImageBitmap::Create( ImageBitmap* image_bitmap = ImageBitmap::Create(
image_data, IntRect(IntPoint(0, 0), image_data->Size()), options); image_data, IntRect(IntPoint(0, 0), image_data->Size()), options);
DCHECK(image_bitmap); DCHECK(image_bitmap);
} }
#undef MAYBE_ImageBitmapColorSpaceConversionHTMLImageElement
} // namespace blink } // namespace blink
...@@ -35,8 +35,10 @@ ...@@ -35,8 +35,10 @@
#include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/skia/include/core/SkColorSpaceXform.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkSwizzle.h"
using testing::_; using testing::_;
using testing::InSequence; using testing::InSequence;
...@@ -809,6 +811,29 @@ TEST_F(CanvasRenderingContext2DTest, ...@@ -809,6 +811,29 @@ TEST_F(CanvasRenderingContext2DTest,
Mock::VerifyAndClearExpectations(surface_ptr); Mock::VerifyAndClearExpectations(surface_ptr);
} }
enum class ColorSpaceConversion : uint8_t {
NONE = 0,
DEFAULT_COLOR_CORRECTED = 1,
SRGB = 2,
LINEAR_RGB = 3,
P3 = 4,
REC2020 = 5,
LAST = REC2020
};
static ImageBitmapOptions PrepareBitmapOptionsAndSetRuntimeFlags(
const ColorSpaceConversion& color_space_conversion) {
// Set the color space conversion in ImageBitmapOptions
ImageBitmapOptions options;
static const Vector<String> kConversions = {
"none", "default", "srgb", "linear-rgb", "p3", "rec2020"};
options.setColorSpaceConversion(
kConversions[static_cast<uint8_t>(color_space_conversion)]);
return options;
}
TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) {
Persistent<HTMLCanvasElement> canvas = Persistent<HTMLCanvasElement> canvas =
Persistent<HTMLCanvasElement>(CanvasElement()); Persistent<HTMLCanvasElement>(CanvasElement());
...@@ -820,62 +845,89 @@ TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { ...@@ -820,62 +845,89 @@ TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) {
StringOrCanvasGradientOrCanvasPattern fill_style; StringOrCanvasGradientOrCanvasPattern fill_style;
fill_style.SetString("#FFC08040"); // 255,192,128,64 fill_style.SetString("#FFC08040"); // 255,192,128,64
context->setFillStyle(fill_style); context->setFillStyle(fill_style);
context->fillRect(0, 0, 1, 1); context->fillRect(0, 0, 4, 4);
scoped_refptr<StaticBitmapImage> snapshot = NonThrowableExceptionState exception_state;
canvas->Snapshot(kFrontBuffer, kPreferNoAcceleration); uint8_t* src_pixel =
ASSERT_TRUE(snapshot); context->getImageData(2, 2, 1, 1, exception_state)->data()->Data();
sk_sp<SkImage> source_image =
snapshot->PaintImageForCurrentFrame().GetSkImage();
SkPixmap source_pixmap;
source_image->peekPixels(&source_pixmap);
// Create and test the ImageBitmap objects. // Create and test the ImageBitmap objects.
base::Optional<IntRect> crop_rect = IntRect(0, 0, 1, 1); base::Optional<IntRect> crop_rect = IntRect(0, 0, 4, 4);
for (int conversion_iterator = ColorSpaceConversion::kDefault; sk_sp<SkColorSpace> color_space = nullptr;
conversion_iterator <= ColorSpaceConversion::kLast; SkColorType color_type = SkColorType::kRGBA_8888_SkColorType;
conversion_iterator++) { SkColorSpaceXform::ColorFormat color_format32 =
SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
SkColorSpaceXform::ColorFormat color_format = color_format32;
sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
for (uint8_t i =
static_cast<uint8_t>(ColorSpaceConversion::DEFAULT_COLOR_CORRECTED);
i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) {
ColorSpaceConversion color_space_conversion =
static_cast<ColorSpaceConversion>(i);
switch (color_space_conversion) {
case ColorSpaceConversion::NONE:
NOTREACHED();
break;
case ColorSpaceConversion::DEFAULT_COLOR_CORRECTED:
case ColorSpaceConversion::SRGB:
color_space = SkColorSpace::MakeSRGB();
color_format = color_format32;
break;
case ColorSpaceConversion::LINEAR_RGB:
color_space = SkColorSpace::MakeSRGBLinear();
color_type = SkColorType::kRGBA_F16_SkColorType;
color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
break;
case ColorSpaceConversion::P3:
color_space =
SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
SkColorSpace::kDCIP3_D65_Gamut);
color_type = SkColorType::kRGBA_F16_SkColorType;
color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
break;
case ColorSpaceConversion::REC2020:
color_space =
SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
SkColorSpace::kRec2020_Gamut);
color_type = SkColorType::kRGBA_F16_SkColorType;
color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
break;
default:
NOTREACHED();
}
// Color convert using ImageBitmap // Color convert using ImageBitmap
ImageBitmapOptions options; ImageBitmapOptions options =
options.setColorSpaceConversion( PrepareBitmapOptionsAndSetRuntimeFlags(color_space_conversion);
ColorCorrectionTestUtils::ColorSpaceConversionToString(
static_cast<ColorSpaceConversion>(conversion_iterator)));
ImageBitmap* image_bitmap = ImageBitmap::Create(canvas, crop_rect, options); ImageBitmap* image_bitmap = ImageBitmap::Create(canvas, crop_rect, options);
ASSERT_TRUE(image_bitmap); ASSERT_TRUE(image_bitmap);
sk_sp<SkImage> converted_image = sk_sp<SkImage> converted_image =
image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage(); image_bitmap->BitmapImage()->PaintImageForCurrentFrame().GetSkImage();
ASSERT_TRUE(converted_image); ASSERT_TRUE(converted_image);
SkPixmap converted_pixmap; SkImageInfo image_info =
converted_image->peekPixels(&converted_pixmap); SkImageInfo::Make(1, 1, color_type, SkAlphaType::kUnpremul_SkAlphaType,
converted_image->refColorSpace());
// Manual color convert for testing std::unique_ptr<uint8_t[]> converted_pixel(
sk_sp<SkColorSpace> color_space = new uint8_t[image_info.bytesPerPixel()]());
ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace( EXPECT_TRUE(converted_image->readPixels(image_info, converted_pixel.get(),
static_cast<ColorSpaceConversion>(conversion_iterator)); image_info.minRowBytes(), 2, 2));
if (conversion_iterator == ColorSpaceConversion::kPreserve)
color_space = SkColorSpace::MakeSRGB(); // Transform the source pixel and check if the image bitmap color conversion
// is done correctly.
// TODO: crbug.com/768855: Remove if statement when CanvasResourceProvider std::unique_ptr<SkColorSpaceXform> color_space_xform =
// does not use SkColorSpaceXformCanvas (which rips off sRGB from SkColorSpaceXform::New(src_rgb_color_space.get(), color_space.get());
// ImageBitmap). std::unique_ptr<uint8_t[]> transformed_pixel(
if (!color_space->isSRGB()) { new uint8_t[image_info.bytesPerPixel()]());
EXPECT_TRUE(SkColorSpace::Equals(color_space.get(), EXPECT_TRUE(color_space_xform->apply(color_format, transformed_pixel.get(),
converted_image->colorSpace())); color_format32, src_pixel, 1,
} SkAlphaType::kUnpremul_SkAlphaType));
SkColorType color_type = SkColorType::kN32_SkColorType;
if (color_space && color_space->gammaIsLinear())
color_type = kRGBA_F16_SkColorType;
SkImageInfo image_info = SkImageInfo::Make(
1, 1, color_type, SkAlphaType::kPremul_SkAlphaType, color_space);
SkBitmap manual_converted_bitmap;
EXPECT_TRUE(manual_converted_bitmap.tryAllocPixels(image_info));
source_pixmap.readPixels(manual_converted_bitmap.pixmap(), 0, 0);
ColorCorrectionTestUtils::CompareColorCorrectedPixels( ColorCorrectionTestUtils::CompareColorCorrectedPixels(
converted_pixmap.addr(), manual_converted_bitmap.pixmap().addr(), 1, converted_pixel.get(), transformed_pixel.get(), 1,
(color_type == kN32_SkColorType) ? kPixelFormat_8888 (color_type == kRGBA_8888_SkColorType) ? kPixelFormat_8888
: kPixelFormat_hhhh, : kPixelFormat_hhhh,
kAlphaMultiplied, kNoUnpremulRoundTripTolerance); kAlphaUnmultiplied, kUnpremulRoundTripTolerance);
} }
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h" #include "third_party/blink/renderer/platform/graphics/color_correction_test_utils.h"
#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h"
#include "third_party/skia/include/core/SkColorSpaceXform.h"
#include "ui/gfx/color_space.h" #include "ui/gfx/color_space.h"
namespace blink { namespace blink {
...@@ -16,20 +17,56 @@ namespace blink { ...@@ -16,20 +17,56 @@ namespace blink {
// to the canvas, the target gfx::ColorSpace is returned by CanvasColorParams:: // to the canvas, the target gfx::ColorSpace is returned by CanvasColorParams::
// GetStorageGfxColorSpace(). This test verifies that the two different color // GetStorageGfxColorSpace(). This test verifies that the two different color
// spaces are approximately the same for different CanvasColorParam objects. // spaces are approximately the same for different CanvasColorParam objects.
// This test does not use SkColorSpace::Equals() since it is sensitive to
// rounding issues (floats don't round-trip perfectly through ICC fixed point).
// Instead, it color converts a pixel and compares the result. Furthermore, this
// test does not include sRGB as target color space since we use
// SkColorSpaceXformCanvas for sRGB targets and GetSkColorSpaceForSkSurfaces()
// returns nullptr for the surface.
TEST(CanvasColorParamsTest, MatchSkColorSpaceWithGfxColorSpace) { TEST(CanvasColorParamsTest, MatchSkColorSpaceWithGfxColorSpace) {
sk_sp<SkColorSpace> src_rgb_color_space = SkColorSpace::MakeSRGB();
std::unique_ptr<uint8_t[]> src_pixel(new uint8_t[4]{32, 96, 160, 255});
CanvasColorSpace canvas_color_spaces[] = { CanvasColorSpace canvas_color_spaces[] = {
kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace, kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace,
}; };
for (int iter_color_space = 0; iter_color_space < 3; iter_color_space++) { for (int iter_color_space = 0; iter_color_space < 3; iter_color_space++) {
CanvasColorParams color_params(canvas_color_spaces[iter_color_space], CanvasColorParams color_params(canvas_color_spaces[iter_color_space],
kF16CanvasPixelFormat, kNonOpaque); kF16CanvasPixelFormat, kNonOpaque);
sk_sp<SkColorSpace> canvas_drawing_color_space =
color_params.GetSkColorSpace(); std::unique_ptr<SkColorSpaceXform> color_space_xform_canvas =
sk_sp<SkColorSpace> canvas_media_color_space = SkColorSpaceXform::New(src_rgb_color_space.get(),
color_params.GetStorageGfxColorSpace().ToSkColorSpace(); color_params.GetSkColorSpace().get());
ASSERT_TRUE(ColorCorrectionTestUtils::MatchColorSpace( std::unique_ptr<SkColorSpaceXform> color_space_xform_media =
canvas_drawing_color_space, canvas_media_color_space)); SkColorSpaceXform::New(
} src_rgb_color_space.get(),
color_params.GetStorageGfxColorSpace().ToSkColorSpace().get());
std::unique_ptr<uint8_t[]> transformed_pixel_canvas(
new uint8_t[color_params.BytesPerPixel()]());
std::unique_ptr<uint8_t[]> transformed_pixel_media(
new uint8_t[color_params.BytesPerPixel()]());
SkColorSpaceXform::ColorFormat transformed_color_format =
color_params.BytesPerPixel() == 4
? SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat
: SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
EXPECT_TRUE(color_space_xform_canvas->apply(
transformed_color_format, transformed_pixel_canvas.get(),
SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat, src_pixel.get(),
1, SkAlphaType::kPremul_SkAlphaType));
EXPECT_TRUE(color_space_xform_media->apply(
transformed_color_format, transformed_pixel_media.get(),
SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat, src_pixel.get(),
1, SkAlphaType::kPremul_SkAlphaType));
ColorCorrectionTestUtils::CompareColorCorrectedPixels(
transformed_pixel_canvas.get(), transformed_pixel_media.get(), 1,
kPixelFormat_hhhh, kAlphaMultiplied, kUnpremulRoundTripTolerance);
}
} }
} // namespace blink } // namespace blink
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "base/sys_byteorder.h" #include "base/sys_byteorder.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/third_party/skcms/skcms.h"
namespace blink { namespace blink {
...@@ -67,32 +66,6 @@ sk_sp<SkColorSpace> ColorCorrectionTestUtils::ColorSpinSkColorSpace() { ...@@ -67,32 +66,6 @@ sk_sp<SkColorSpace> ColorCorrectionTestUtils::ColorSpinSkColorSpace() {
return SkColorSpace::Make(colorspin_profile); return SkColorSpace::Make(colorspin_profile);
} }
sk_sp<SkColorSpace>
ColorCorrectionTestUtils::ColorSpaceConversionToSkColorSpace(
ColorSpaceConversion conversion) {
if (conversion == kDefault || conversion == kSRGB) {
return SkColorSpace::MakeSRGB();
}
if (conversion == kLinearRGB)
return SkColorSpace::MakeSRGBLinear();
if (conversion == kP3) {
return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
SkColorSpace::kDCIP3_D65_Gamut);
}
if (conversion == kRec2020) {
return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma,
SkColorSpace::kRec2020_Gamut);
}
return nullptr;
}
String ColorCorrectionTestUtils::ColorSpaceConversionToString(
ColorSpaceConversion color_space_conversion) {
static const Vector<String> kConversions = {
"none", "default", "preserve", "srgb", "linear-rgb", "p3", "rec2020"};
return kConversions[static_cast<uint8_t>(color_space_conversion)];
}
void ColorCorrectionTestUtils::CompareColorCorrectedPixels( void ColorCorrectionTestUtils::CompareColorCorrectedPixels(
const void* actual_pixels, const void* actual_pixels,
const void* expected_pixels, const void* expected_pixels,
...@@ -254,23 +227,32 @@ bool ColorCorrectionTestUtils::ConvertPixelsToColorSpaceAndPixelFormatForTest( ...@@ -254,23 +227,32 @@ bool ColorCorrectionTestUtils::ConvertPixelsToColorSpaceAndPixelFormatForTest(
} }
bool ColorCorrectionTestUtils::MatchColorSpace( bool ColorCorrectionTestUtils::MatchColorSpace(
sk_sp<SkColorSpace> src_color_space, SkColorSpace* src_color_space,
sk_sp<SkColorSpace> dst_color_space) { SkColorSpace* dst_color_space,
float xyz_d50_component_tolerance) {
if ((!src_color_space && dst_color_space) || if ((!src_color_space && dst_color_space) ||
(src_color_space && !dst_color_space)) (src_color_space && !dst_color_space))
return false; return false;
if (!src_color_space && !dst_color_space) if (src_color_space) {
return true; const SkMatrix44* src_matrix = src_color_space->toXYZD50();
skcms_ICCProfile src_profile, dst_profile; const SkMatrix44* dst_matrix = dst_color_space->toXYZD50();
src_color_space->toProfile(&src_profile); for (int i = 0; i < 4; i++) {
dst_color_space->toProfile(&dst_profile); for (int j = 0; j < 4; j++) {
return skcms_ApproximatelyEqualProfiles(&src_profile, &dst_profile); if (fabs(src_matrix->get(i, j) - dst_matrix->get(i, j)) >
xyz_d50_component_tolerance) {
return false;
}
}
}
}
return true;
} }
bool ColorCorrectionTestUtils::MatchSkImages(sk_sp<SkImage> src_image, bool ColorCorrectionTestUtils::MatchSkImages(sk_sp<SkImage> src_image,
sk_sp<SkImage> dst_image, sk_sp<SkImage> dst_image,
unsigned uint8_tolerance, unsigned uint8_tolerance,
float f16_tolerance, float f16_tolerance,
float xyz_d50_component_tolerance,
bool compare_alpha) { bool compare_alpha) {
if ((!src_image && dst_image) || (src_image && !dst_image)) if ((!src_image && dst_image) || (src_image && !dst_image))
return false; return false;
...@@ -283,10 +265,8 @@ bool ColorCorrectionTestUtils::MatchSkImages(sk_sp<SkImage> src_image, ...@@ -283,10 +265,8 @@ bool ColorCorrectionTestUtils::MatchSkImages(sk_sp<SkImage> src_image,
if (compare_alpha && src_image->alphaType() != dst_image->alphaType()) if (compare_alpha && src_image->alphaType() != dst_image->alphaType())
return false; return false;
// Color type is not checked since the decoded image does not have a specific if (!MatchColorSpace(src_image->colorSpace(), dst_image->colorSpace(),
// color type, unless it is drawn onto a surface or readPixels() is called. xyz_d50_component_tolerance)) {
if (!MatchColorSpace(src_image->refColorSpace(),
dst_image->refColorSpace())) {
return false; return false;
} }
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/third_party/skcms/skcms.h"
namespace blink { namespace blink {
...@@ -31,25 +31,9 @@ enum UnpremulRoundTripTolerance { ...@@ -31,25 +31,9 @@ enum UnpremulRoundTripTolerance {
kUnpremulRoundTripTolerance, kUnpremulRoundTripTolerance,
}; };
enum ColorSpaceConversion {
kNone,
kDefault,
kPreserve,
kSRGB,
kLinearRGB,
kP3,
kRec2020,
kLast = kRec2020,
};
class ColorCorrectionTestUtils { class ColorCorrectionTestUtils {
public: public:
// ImageBitmap color space conversion test utils
static sk_sp<SkColorSpace> ColorSpinSkColorSpace(); static sk_sp<SkColorSpace> ColorSpinSkColorSpace();
static sk_sp<SkColorSpace> ColorSpaceConversionToSkColorSpace(
ColorSpaceConversion conversion);
static String ColorSpaceConversionToString(
ColorSpaceConversion color_space_conversion);
static void CompareColorCorrectedPixels( static void CompareColorCorrectedPixels(
const void* actual_pixels, const void* actual_pixels,
...@@ -69,13 +53,15 @@ class ColorCorrectionTestUtils { ...@@ -69,13 +53,15 @@ class ColorCorrectionTestUtils {
std::unique_ptr<uint8_t[]>& converted_pixels, std::unique_ptr<uint8_t[]>& converted_pixels,
PixelFormat pixel_format_for_f16_canvas); PixelFormat pixel_format_for_f16_canvas);
static bool MatchColorSpace(sk_sp<SkColorSpace> src_color_space, static bool MatchColorSpace(SkColorSpace* src_color_space,
sk_sp<SkColorSpace> dst_color_space); SkColorSpace* dst_color_space,
float xyz_d50_component_tolerance);
static bool MatchSkImages(sk_sp<SkImage> src_image, static bool MatchSkImages(sk_sp<SkImage> src_image,
sk_sp<SkImage> dst_image, sk_sp<SkImage> dst_image,
unsigned uint8_tolerance, unsigned uint8_tolerance,
float f16_tolerance, float f16_tolerance,
float xyz_d50_component_tolerance,
bool compare_alpha); bool compare_alpha);
private: private:
......
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h" #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer_contents.h"
#include "third_party/skia/include/core/SkPixmap.h" #include "third_party/skia/include/core/SkColorSpaceXform.h"
#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
...@@ -1367,15 +1367,15 @@ void DrawingBuffer::ReadBackFramebuffer(unsigned char* pixels, ...@@ -1367,15 +1367,15 @@ void DrawingBuffer::ReadBackFramebuffer(unsigned char* pixels,
} }
if (op == WebGLImageConversion::kAlphaDoPremultiply) { if (op == WebGLImageConversion::kAlphaDoPremultiply) {
auto color_type = kRGBA_8888_SkColorType; std::unique_ptr<SkColorSpaceXform> xform =
SkColorSpaceXform::New(SkColorSpace::MakeSRGBLinear().get(),
SkColorSpace::MakeSRGBLinear().get());
SkColorSpaceXform::ColorFormat color_format =
SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat;
if (data_type != GL_UNSIGNED_BYTE) if (data_type != GL_UNSIGNED_BYTE)
color_type = kRGBA_F16_SkColorType; color_format = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat;
const auto src = xform->apply(color_format, pixels, color_format, pixels, width * height,
SkImageInfo::Make(width, height, color_type, kUnpremul_SkAlphaType); kPremul_SkAlphaType);
const auto dst =
SkImageInfo::Make(width, height, color_type, kPremul_SkAlphaType);
SkPixmap{src, pixels, src.minRowBytes()}.readPixels(
SkPixmap{dst, pixels, dst.minRowBytes()});
} else if (op != WebGLImageConversion::kAlphaDoNothing) { } else if (op != WebGLImageConversion::kAlphaDoNothing) {
NOTREACHED(); NOTREACHED();
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/platform/image-decoders/image_frame.h" #include "third_party/blink/renderer/platform/image-decoders/image_frame.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/third_party/skcms/skcms.h" #include "third_party/skia/include/core/SkColorSpaceXform.h"
namespace blink { namespace blink {
namespace { namespace {
...@@ -26,16 +26,20 @@ class ImageFrameTest : public testing::Test { ...@@ -26,16 +26,20 @@ class ImageFrameTest : public testing::Test {
src_8888 = SkPackARGB32(src_8888_a, src_8888_r, src_8888_g, src_8888_b); src_8888 = SkPackARGB32(src_8888_a, src_8888_r, src_8888_g, src_8888_b);
dst_8888 = SkPackARGB32(0xA0, 0x60, 0x70, 0x80); dst_8888 = SkPackARGB32(0xA0, 0x60, 0x70, 0x80);
pixel_format_n32 = skcms_PixelFormat_RGBA_8888; typedef SkColorSpaceXform::ColorFormat ColorFormat;
color_format_8888 = ColorFormat::kBGRA_8888_ColorFormat;
if (kN32_SkColorType == kRGBA_8888_SkColorType) if (kN32_SkColorType == kRGBA_8888_SkColorType)
pixel_format_n32 = skcms_PixelFormat_BGRA_8888; color_format_8888 = ColorFormat::kRGBA_8888_ColorFormat;
color_format_f16 = ColorFormat::kRGBA_F16_ColorFormat;
skcms_Transform(&src_8888, pixel_format_n32, skcms_AlphaFormat_Unpremul, color_format_f32 = ColorFormat::kRGBA_F32_ColorFormat;
nullptr, &src_f16, skcms_PixelFormat_RGBA_hhhh,
skcms_AlphaFormat_Unpremul, nullptr, 1); sk_sp<SkColorSpace> srgb_linear = SkColorSpace::MakeSRGBLinear();
skcms_Transform(&dst_8888, pixel_format_n32, skcms_AlphaFormat_Unpremul, SkColorSpaceXform::Apply(srgb_linear.get(), color_format_f16, &src_f16,
nullptr, &dst_f16, skcms_PixelFormat_RGBA_hhhh, srgb_linear.get(), color_format_8888, &src_8888, 1,
skcms_AlphaFormat_Unpremul, nullptr, 1); SkColorSpaceXform::AlphaOp::kPreserve_AlphaOp);
SkColorSpaceXform::Apply(srgb_linear.get(), color_format_f16, &dst_f16,
srgb_linear.get(), color_format_8888, &dst_8888, 1,
SkColorSpaceXform::AlphaOp::kPreserve_AlphaOp);
} }
protected: protected:
...@@ -43,19 +47,21 @@ class ImageFrameTest : public testing::Test { ...@@ -43,19 +47,21 @@ class ImageFrameTest : public testing::Test {
unsigned src_8888_a, src_8888_r, src_8888_g, src_8888_b; unsigned src_8888_a, src_8888_r, src_8888_g, src_8888_b;
ImageFrame::PixelData src_8888, dst_8888; ImageFrame::PixelData src_8888, dst_8888;
ImageFrame::PixelDataF16 src_f16, dst_f16; ImageFrame::PixelDataF16 src_f16, dst_f16;
skcms_PixelFormat pixel_format_n32; SkColorSpaceXform::ColorFormat color_format_8888, color_format_f16,
color_format_f32;
void ConvertN32ToF32(float* dst, ImageFrame::PixelData src) { void ConvertN32ToF32(float* dst, ImageFrame::PixelData src) {
skcms_Transform(&src, pixel_format_n32, skcms_AlphaFormat_Unpremul, nullptr, sk_sp<SkColorSpace> srgb_linear = SkColorSpace::MakeSRGBLinear();
dst, skcms_PixelFormat_RGBA_ffff, SkColorSpaceXform::Apply(srgb_linear.get(), color_format_f32, dst,
skcms_AlphaFormat_Unpremul, nullptr, 1); srgb_linear.get(), color_format_8888, &src, 1,
SkColorSpaceXform::AlphaOp::kPreserve_AlphaOp);
} }
void ConvertF16ToF32(float* dst, ImageFrame::PixelDataF16 src) { void ConvertF16ToF32(float* dst, ImageFrame::PixelDataF16 src) {
skcms_Transform(&src, skcms_PixelFormat_RGBA_hhhh, sk_sp<SkColorSpace> srgb_linear = SkColorSpace::MakeSRGBLinear();
skcms_AlphaFormat_Unpremul, nullptr, dst, SkColorSpaceXform::Apply(srgb_linear.get(), color_format_f32, dst,
skcms_PixelFormat_RGBA_ffff, skcms_AlphaFormat_Unpremul, srgb_linear.get(), color_format_f16, &src, 1,
nullptr, 1); SkColorSpaceXform::AlphaOp::kPreserve_AlphaOp);
} }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment