OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "modules/canvas2d/CanvasRenderingContext2D.h" | 5 #include "modules/canvas2d/CanvasRenderingContext2D.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include "bindings/core/v8/V8BindingForCore.h" | 8 #include "bindings/core/v8/V8BindingForCore.h" |
9 #include "bindings/core/v8/V8BindingForTesting.h" | 9 #include "bindings/core/v8/V8BindingForTesting.h" |
10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
37 #include "third_party/skia/include/core/SkColorSpaceXform.h" | 37 #include "third_party/skia/include/core/SkColorSpaceXform.h" |
38 #include "third_party/skia/include/core/SkImage.h" | 38 #include "third_party/skia/include/core/SkImage.h" |
39 #include "third_party/skia/include/core/SkSurface.h" | 39 #include "third_party/skia/include/core/SkSurface.h" |
40 #include "third_party/skia/include/core/SkSwizzle.h" | 40 #include "third_party/skia/include/core/SkSwizzle.h" |
41 | 41 |
42 using ::testing::Mock; | 42 using ::testing::Mock; |
43 | 43 |
44 namespace blink { | 44 namespace blink { |
45 | 45 |
46 namespace { | |
47 | |
48 gfx::ColorSpace AdobeRGBColorSpace() { | |
49 return gfx::ColorSpace(gfx::ColorSpace::PrimaryID::ADOBE_RGB, | |
50 gfx::ColorSpace::TransferID::GAMMA22); | |
51 } | |
52 | |
53 } // namespace | |
54 | |
55 enum BitmapOpacity { kOpaqueBitmap, kTransparentBitmap }; | 46 enum BitmapOpacity { kOpaqueBitmap, kTransparentBitmap }; |
56 | 47 |
57 class FakeImageSource : public CanvasImageSource { | 48 class FakeImageSource : public CanvasImageSource { |
58 public: | 49 public: |
59 FakeImageSource(IntSize, BitmapOpacity); | 50 FakeImageSource(IntSize, BitmapOpacity); |
60 | 51 |
61 PassRefPtr<Image> GetSourceImageForCanvas(SourceImageStatus*, | 52 PassRefPtr<Image> GetSourceImageForCanvas(SourceImageStatus*, |
62 AccelerationHint, | 53 AccelerationHint, |
63 SnapshotReason, | 54 SnapshotReason, |
64 const FloatSize&) override; | 55 const FloatSize&) override; |
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1063 CanvasElement().GetImageBuffer()->DisableAcceleration(); | 1054 CanvasElement().GetImageBuffer()->DisableAcceleration(); |
1064 EXPECT_FALSE(CanvasElement().GetImageBuffer()->IsAccelerated()); | 1055 EXPECT_FALSE(CanvasElement().GetImageBuffer()->IsAccelerated()); |
1065 | 1056 |
1066 context->fillRect(10, 10, 100, 100); | 1057 context->fillRect(10, 10, 100, 100); |
1067 | 1058 |
1068 EXPECT_EQ(0, GetCurrentGPUMemoryUsage()); | 1059 EXPECT_EQ(0, GetCurrentGPUMemoryUsage()); |
1069 EXPECT_EQ(0, GetGlobalGPUMemoryUsage()); | 1060 EXPECT_EQ(0, GetGlobalGPUMemoryUsage()); |
1070 EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount()); | 1061 EXPECT_EQ(0u, GetGlobalAcceleratedImageBufferCount()); |
1071 } | 1062 } |
1072 | 1063 |
1073 TEST_F(CanvasRenderingContext2DTest, | |
1074 LegacyColorSpaceUsesGlobalTargetColorBehavior) { | |
1075 // Set the global target color space to something distinctly recognizable (not | |
1076 // srgb) | |
1077 gfx::ColorSpace saved_global_target_color_space = | |
1078 ColorBehavior::GlobalTargetColorSpace(); | |
1079 ColorBehavior::SetGlobalTargetColorSpaceForTesting(AdobeRGBColorSpace()); | |
1080 bool saved_color_correct_rendering_enabled = | |
1081 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); | |
1082 | |
1083 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(false); | |
1084 CreateContext(kNonOpaque, "legacy-srgb"); | |
1085 ColorBehavior behavior = Context2d()->DrawImageColorBehavior(); | |
1086 EXPECT_TRUE(behavior.IsTransformToTargetColorSpace()); | |
1087 EXPECT_TRUE(ColorBehavior::GlobalTargetColorSpace() == | |
1088 behavior.TargetColorSpace()); | |
1089 | |
1090 // Restore global state to avoid interfering with other tests | |
1091 ColorBehavior::SetGlobalTargetColorSpaceForTesting( | |
1092 saved_global_target_color_space); | |
1093 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( | |
1094 saved_color_correct_rendering_enabled); | |
1095 } | |
1096 | |
1097 TEST_F(CanvasRenderingContext2DTest, | |
1098 LegacyColorSpaceUsesSRGBWhenColorCorrectRenderingEnabled) { | |
1099 // Set the global target color space to something distinctly recognizable (not | |
1100 // srgb) | |
1101 gfx::ColorSpace saved_global_target_color_space = | |
1102 ColorBehavior::GlobalTargetColorSpace(); | |
1103 ColorBehavior::SetGlobalTargetColorSpaceForTesting(AdobeRGBColorSpace()); | |
1104 bool saved_color_correct_rendering_enabled = | |
1105 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); | |
1106 | |
1107 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(true); | |
1108 CreateContext(kNonOpaque, "legacy-srgb"); | |
1109 ColorBehavior behavior = Context2d()->DrawImageColorBehavior(); | |
1110 EXPECT_TRUE(behavior.IsTransformToTargetColorSpace()); | |
1111 EXPECT_TRUE(gfx::ColorSpace::CreateSRGB() == behavior.TargetColorSpace()); | |
1112 | |
1113 // Restore global state to avoid interfering with other tests | |
1114 ColorBehavior::SetGlobalTargetColorSpaceForTesting( | |
1115 saved_global_target_color_space); | |
1116 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( | |
1117 saved_color_correct_rendering_enabled); | |
1118 } | |
1119 | |
1120 TEST_F(CanvasRenderingContext2DTest, | |
1121 SRGBColorSpaceUsesTransformToSRGBColorBehavior) { | |
1122 // Set the global target color space to something distinctly recognizable (not | |
1123 // srgb) | |
1124 gfx::ColorSpace saved_global_target_color_space = | |
1125 ColorBehavior::GlobalTargetColorSpace(); | |
1126 ColorBehavior::SetGlobalTargetColorSpaceForTesting(AdobeRGBColorSpace()); | |
1127 | |
1128 CreateContext(kNonOpaque, "srgb"); | |
1129 ColorBehavior behavior = Context2d()->DrawImageColorBehavior(); | |
1130 EXPECT_TRUE(behavior.IsTransformToTargetColorSpace()); | |
1131 EXPECT_TRUE(gfx::ColorSpace::CreateSRGB() == behavior.TargetColorSpace()); | |
1132 | |
1133 // Restore global state to avoid interfering with other tests | |
1134 ColorBehavior::SetGlobalTargetColorSpaceForTesting( | |
1135 saved_global_target_color_space); | |
1136 } | |
1137 | |
1138 TEST_F(CanvasRenderingContext2DTest, | |
1139 LinearRGBColorSpaceUsesTransformToLinearSRGBColorBehavior) { | |
1140 // Set the global target color space to something distinctly recognizable (not | |
1141 // srgb) | |
1142 gfx::ColorSpace saved_global_target_color_space = | |
1143 ColorBehavior::GlobalTargetColorSpace(); | |
1144 ColorBehavior::SetGlobalTargetColorSpaceForTesting(AdobeRGBColorSpace()); | |
1145 | |
1146 CreateContext(kNonOpaque, "srgb", kLinearPixelMathEnabled); | |
1147 ColorBehavior behavior = Context2d()->DrawImageColorBehavior(); | |
1148 EXPECT_TRUE(behavior.IsTransformToTargetColorSpace()); | |
1149 EXPECT_TRUE(gfx::ColorSpace::CreateSCRGBLinear() == | |
1150 behavior.TargetColorSpace()); | |
1151 | |
1152 // Restore global state to avoid interfering with other tests | |
1153 ColorBehavior::SetGlobalTargetColorSpaceForTesting( | |
1154 saved_global_target_color_space); | |
1155 } | |
1156 | |
1157 enum class ColorSpaceConversion : uint8_t { | 1064 enum class ColorSpaceConversion : uint8_t { |
1158 NONE = 0, | 1065 NONE = 0, |
1159 DEFAULT_NOT_COLOR_CORRECTED = 1, | 1066 DEFAULT_NOT_COLOR_CORRECTED = 1, |
1160 DEFAULT_COLOR_CORRECTED = 2, | 1067 DEFAULT_COLOR_CORRECTED = 2, |
1161 SRGB = 3, | 1068 SRGB = 3, |
1162 LINEAR_RGB = 4, | 1069 LINEAR_RGB = 4, |
1163 | 1070 |
1164 LAST = LINEAR_RGB | 1071 LAST = LINEAR_RGB |
1165 }; | 1072 }; |
1166 | 1073 |
1167 static ImageBitmapOptions PrepareBitmapOptionsAndSetRuntimeFlags( | 1074 static ImageBitmapOptions PrepareBitmapOptionsAndSetRuntimeFlags( |
1168 const ColorSpaceConversion& color_space_conversion) { | 1075 const ColorSpaceConversion& color_space_conversion) { |
1169 // Set the color space conversion in ImageBitmapOptions | 1076 // Set the color space conversion in ImageBitmapOptions |
1170 ImageBitmapOptions options; | 1077 ImageBitmapOptions options; |
1171 static const Vector<String> kConversions = {"none", "default", "default", | 1078 static const Vector<String> kConversions = {"none", "default", "default", |
1172 "srgb", "linear-rgb"}; | 1079 "srgb", "linear-rgb"}; |
1173 options.setColorSpaceConversion( | 1080 options.setColorSpaceConversion( |
1174 kConversions[static_cast<uint8_t>(color_space_conversion)]); | 1081 kConversions[static_cast<uint8_t>(color_space_conversion)]); |
1175 | 1082 |
1176 // Set the runtime flags | 1083 // Set the runtime flags |
1177 bool flag = (color_space_conversion != | 1084 bool flag = (color_space_conversion != |
1178 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED); | 1085 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED); |
1179 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true); | 1086 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true); |
1180 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(flag); | 1087 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(flag); |
1181 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled(!flag); | 1088 RuntimeEnabledFeatures::setColorCanvasExtensionsEnabled(true); |
1182 | |
1183 return options; | 1089 return options; |
1184 } | 1090 } |
1185 | 1091 |
1186 TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { | 1092 TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { |
1187 bool experimental_canvas_features_runtime_flag = | 1093 bool experimental_canvas_features_runtime_flag = |
1188 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); | 1094 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); |
1189 bool color_correct_rendering_runtime_flag = | 1095 bool color_correct_rendering_runtime_flag = |
1190 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); | 1096 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); |
1191 bool color_correct_rendering_default_mode_runtime_flag = | 1097 bool color_canvas_extensions_flag = |
1192 RuntimeEnabledFeatures::colorCorrectRenderingDefaultModeEnabled(); | 1098 RuntimeEnabledFeatures::colorCanvasExtensionsEnabled(); |
1193 | 1099 |
1194 Persistent<HTMLCanvasElement> canvas = | 1100 Persistent<HTMLCanvasElement> canvas = |
1195 Persistent<HTMLCanvasElement>(CanvasElement()); | 1101 Persistent<HTMLCanvasElement>(CanvasElement()); |
1196 CanvasContextCreationAttributes attributes; | 1102 CanvasContextCreationAttributes attributes; |
1197 attributes.setAlpha(true); | 1103 attributes.setAlpha(true); |
1198 attributes.setColorSpace("srgb"); | 1104 attributes.setColorSpace("srgb"); |
1199 CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>( | 1105 CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>( |
1200 canvas->GetCanvasRenderingContext("2d", attributes)); | 1106 canvas->GetCanvasRenderingContext("2d", attributes)); |
1201 StringOrCanvasGradientOrCanvasPattern fill_style; | 1107 StringOrCanvasGradientOrCanvasPattern fill_style; |
1202 fill_style.setString("#FF0000"); | 1108 fill_style.setString("#FF0000"); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1273 | 1179 |
1274 int compare = std::memcmp(converted_pixel.get(), transformed_pixel.get(), | 1180 int compare = std::memcmp(converted_pixel.get(), transformed_pixel.get(), |
1275 image_info.bytesPerPixel()); | 1181 image_info.bytesPerPixel()); |
1276 ASSERT_EQ(compare, 0); | 1182 ASSERT_EQ(compare, 0); |
1277 } | 1183 } |
1278 | 1184 |
1279 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( | 1185 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( |
1280 experimental_canvas_features_runtime_flag); | 1186 experimental_canvas_features_runtime_flag); |
1281 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( | 1187 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( |
1282 color_correct_rendering_runtime_flag); | 1188 color_correct_rendering_runtime_flag); |
1283 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled( | 1189 RuntimeEnabledFeatures::setColorCanvasExtensionsEnabled( |
1284 color_correct_rendering_default_mode_runtime_flag); | 1190 color_canvas_extensions_flag); |
1285 } | 1191 } |
1286 | 1192 |
1287 bool ConvertPixelsToColorSpaceAndPixelFormatForTest( | 1193 bool ConvertPixelsToColorSpaceAndPixelFormatForTest( |
1288 DOMArrayBufferView* data_array, | 1194 DOMArrayBufferView* data_array, |
1289 CanvasColorSpace src_color_space, | 1195 CanvasColorSpace src_color_space, |
1290 CanvasColorSpace dst_color_space, | 1196 CanvasColorSpace dst_color_space, |
1291 CanvasPixelFormat dst_pixel_format, | 1197 CanvasPixelFormat dst_pixel_format, |
1292 std::unique_ptr<uint8_t[]>& converted_pixels) { | 1198 std::unique_ptr<uint8_t[]>& converted_pixels) { |
1293 // Setting SkColorSpaceXform::apply parameters | 1199 // Setting SkColorSpaceXform::apply parameters |
1294 SkColorSpaceXform::ColorFormat src_color_format = | 1200 SkColorSpaceXform::ColorFormat src_color_format = |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 // This test verifies the correct behavior of putImageData member function in | 1281 // This test verifies the correct behavior of putImageData member function in |
1376 // color managed mode. | 1282 // color managed mode. |
1377 void TestPutImageDataOnCanvasWithColorSpaceSettings( | 1283 void TestPutImageDataOnCanvasWithColorSpaceSettings( |
1378 HTMLCanvasElement& canvas_element, | 1284 HTMLCanvasElement& canvas_element, |
1379 CanvasColorSpaceSettings canvas_colorspace_setting, | 1285 CanvasColorSpaceSettings canvas_colorspace_setting, |
1380 float color_tolerance) { | 1286 float color_tolerance) { |
1381 bool experimental_canvas_features_runtime_flag = | 1287 bool experimental_canvas_features_runtime_flag = |
1382 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); | 1288 RuntimeEnabledFeatures::experimentalCanvasFeaturesEnabled(); |
1383 bool color_correct_rendering_runtime_flag = | 1289 bool color_correct_rendering_runtime_flag = |
1384 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); | 1290 RuntimeEnabledFeatures::colorCorrectRenderingEnabled(); |
| 1291 bool color_canvas_extensions_flag = |
| 1292 RuntimeEnabledFeatures::colorCanvasExtensionsEnabled(); |
1385 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true); | 1293 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true); |
1386 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(true); | 1294 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(true); |
| 1295 RuntimeEnabledFeatures::setColorCanvasExtensionsEnabled(true); |
1387 | 1296 |
1388 bool test_passed = true; | 1297 bool test_passed = true; |
1389 unsigned num_image_data_color_spaces = 3; | 1298 unsigned num_image_data_color_spaces = 3; |
1390 CanvasColorSpace image_data_color_spaces[] = { | 1299 CanvasColorSpace image_data_color_spaces[] = { |
1391 kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace, | 1300 kSRGBCanvasColorSpace, kRec2020CanvasColorSpace, kP3CanvasColorSpace, |
1392 }; | 1301 }; |
1393 | 1302 |
1394 unsigned num_image_data_storage_formats = 3; | 1303 unsigned num_image_data_storage_formats = 3; |
1395 ImageDataStorageFormat image_data_storage_formats[] = { | 1304 ImageDataStorageFormat image_data_storage_formats[] = { |
1396 kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat, | 1305 kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat, |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1539 } | 1448 } |
1540 } | 1449 } |
1541 } | 1450 } |
1542 delete[] u16_pixels; | 1451 delete[] u16_pixels; |
1543 delete[] f32_pixels; | 1452 delete[] f32_pixels; |
1544 | 1453 |
1545 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( | 1454 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled( |
1546 experimental_canvas_features_runtime_flag); | 1455 experimental_canvas_features_runtime_flag); |
1547 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( | 1456 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled( |
1548 color_correct_rendering_runtime_flag); | 1457 color_correct_rendering_runtime_flag); |
| 1458 RuntimeEnabledFeatures::setColorCanvasExtensionsEnabled( |
| 1459 color_canvas_extensions_flag); |
1549 } | 1460 } |
1550 | 1461 |
1551 TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) { | 1462 TEST_F(CanvasRenderingContext2DTest, ColorManagedPutImageDataOnSRGBCanvas) { |
1552 TestPutImageDataOnCanvasWithColorSpaceSettings( | 1463 TestPutImageDataOnCanvasWithColorSpaceSettings( |
1553 CanvasElement(), CanvasColorSpaceSettings::CANVAS_SRGB, 0); | 1464 CanvasElement(), CanvasColorSpaceSettings::CANVAS_SRGB, 0); |
1554 } | 1465 } |
1555 | 1466 |
1556 TEST_F(CanvasRenderingContext2DTest, | 1467 TEST_F(CanvasRenderingContext2DTest, |
1557 ColorManagedPutImageDataOnLinearSRGBCanvas) { | 1468 ColorManagedPutImageDataOnLinearSRGBCanvas) { |
1558 TestPutImageDataOnCanvasWithColorSpaceSettings( | 1469 TestPutImageDataOnCanvasWithColorSpaceSettings( |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1639 | 1550 |
1640 // Wake up again, which should request a compositing update synchronously. | 1551 // Wake up again, which should request a compositing update synchronously. |
1641 GetDocument().GetPage()->SetVisibilityState(kPageVisibilityStateVisible, | 1552 GetDocument().GetPage()->SetVisibilityState(kPageVisibilityStateVisible, |
1642 false); | 1553 false); |
1643 EXPECT_EQ(!!CANVAS2D_HIBERNATION_ENABLED, | 1554 EXPECT_EQ(!!CANVAS2D_HIBERNATION_ENABLED, |
1644 layer->NeedsCompositingInputsUpdate()); | 1555 layer->NeedsCompositingInputsUpdate()); |
1645 RunUntilIdle(); // Clear task queue. | 1556 RunUntilIdle(); // Clear task queue. |
1646 } | 1557 } |
1647 | 1558 |
1648 } // namespace blink | 1559 } // namespace blink |
OLD | NEW |