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 "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
8 #include "core/fetch/MemoryCache.h" | 8 #include "core/fetch/MemoryCache.h" |
9 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
10 #include "core/frame/ImageBitmap.h" | 10 #include "core/frame/ImageBitmap.h" |
11 #include "core/html/HTMLCanvasElement.h" | 11 #include "core/html/HTMLCanvasElement.h" |
12 #include "core/html/ImageData.h" | 12 #include "core/html/ImageData.h" |
13 #include "core/imagebitmap/ImageBitmapOptions.h" | 13 #include "core/imagebitmap/ImageBitmapOptions.h" |
14 #include "core/loader/EmptyClients.h" | 14 #include "core/loader/EmptyClients.h" |
15 #include "core/testing/DummyPageHolder.h" | 15 #include "core/testing/DummyPageHolder.h" |
16 #include "modules/canvas2d/CanvasGradient.h" | 16 #include "modules/canvas2d/CanvasGradient.h" |
17 #include "modules/canvas2d/CanvasPattern.h" | 17 #include "modules/canvas2d/CanvasPattern.h" |
18 #include "modules/webgl/WebGLRenderingContext.h" | 18 #include "modules/webgl/WebGLRenderingContext.h" |
19 #include "platform/graphics/Canvas2DImageBufferSurface.h" | 19 #include "platform/graphics/Canvas2DImageBufferSurface.h" |
20 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" | 20 #include "platform/graphics/ExpensiveCanvasHeuristicParameters.h" |
21 #include "platform/graphics/RecordingImageBufferSurface.h" | 21 #include "platform/graphics/RecordingImageBufferSurface.h" |
22 #include "platform/graphics/StaticBitmapImage.h" | 22 #include "platform/graphics/StaticBitmapImage.h" |
23 #include "platform/graphics/UnacceleratedImageBufferSurface.h" | 23 #include "platform/graphics/UnacceleratedImageBufferSurface.h" |
24 #include "platform/graphics/test/FakeGLES2Interface.h" | 24 #include "platform/graphics/test/FakeGLES2Interface.h" |
25 #include "platform/graphics/test/FakeWebGraphicsContext3DProvider.h" | 25 #include "platform/graphics/test/FakeWebGraphicsContext3DProvider.h" |
26 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
27 #include "testing/gtest/include/gtest/gtest.h" | 27 #include "testing/gtest/include/gtest/gtest.h" |
28 #include "third_party/skia/include/core/SkColorSpaceXform.h" | |
29 #include "third_party/skia/include/core/SkImage.h" | |
28 #include "third_party/skia/include/core/SkSurface.h" | 30 #include "third_party/skia/include/core/SkSurface.h" |
29 #include "wtf/PtrUtil.h" | 31 #include "wtf/PtrUtil.h" |
30 #include <memory> | 32 #include <memory> |
31 | 33 |
32 using ::testing::Mock; | 34 using ::testing::Mock; |
33 | 35 |
34 namespace blink { | 36 namespace blink { |
35 | 37 |
36 enum BitmapOpacity { OpaqueBitmap, TransparentBitmap }; | 38 enum BitmapOpacity { OpaqueBitmap, TransparentBitmap }; |
37 | 39 |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1164 canvasElement().buffer()->disableAcceleration(); | 1166 canvasElement().buffer()->disableAcceleration(); |
1165 EXPECT_FALSE(canvasElement().buffer()->isAccelerated()); | 1167 EXPECT_FALSE(canvasElement().buffer()->isAccelerated()); |
1166 | 1168 |
1167 context->fillRect(10, 10, 100, 100); | 1169 context->fillRect(10, 10, 100, 100); |
1168 | 1170 |
1169 EXPECT_EQ(0, getCurrentGPUMemoryUsage()); | 1171 EXPECT_EQ(0, getCurrentGPUMemoryUsage()); |
1170 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); | 1172 EXPECT_EQ(0, getGlobalGPUMemoryUsage()); |
1171 EXPECT_EQ(0u, getGlobalAcceleratedImageBufferCount()); | 1173 EXPECT_EQ(0u, getGlobalAcceleratedImageBufferCount()); |
1172 } | 1174 } |
1173 | 1175 |
1176 enum class ColorSpaceConversion : uint8_t { | |
1177 NONE = 0, | |
1178 DEFAULT_NOT_COLOR_CORRECTED = 1, | |
1179 DEFAULT_COLOR_CORRECTED = 2, | |
1180 SRGB = 3, | |
1181 LINEAR_RGB = 4, | |
1182 | |
1183 LAST = LINEAR_RGB | |
1184 }; | |
1185 | |
1186 static ImageBitmapOptions prepareBitmapOptionsAndSetRuntimeFlags( | |
1187 const ColorSpaceConversion& colorSpaceConversion) { | |
1188 // Set the color space conversion in ImageBitmapOptions | |
1189 ImageBitmapOptions options; | |
1190 static const Vector<String> conversions = {"none", "default", "default", | |
1191 "srgb", "linear-rgb"}; | |
1192 options.setColorSpaceConversion( | |
1193 conversions[static_cast<uint8_t>(colorSpaceConversion)]); | |
1194 | |
1195 // Set the runtime flags | |
1196 bool flag = (colorSpaceConversion != | |
1197 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED); | |
1198 RuntimeEnabledFeatures::setExperimentalCanvasFeaturesEnabled(true); | |
1199 RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(flag); | |
1200 RuntimeEnabledFeatures::setColorCorrectRenderingDefaultModeEnabled(!flag); | |
Justin Novosad
2016/12/14 20:53:46
RuntimeEnabledFeatures is a global state object. W
zakerinasab1
2016/12/16 20:25:35
Done.
| |
1201 | |
1202 return options; | |
1203 } | |
1204 | |
1205 TEST_F(CanvasRenderingContext2DTest, ImageBitmapColorSpaceConversion) { | |
1206 Persistent<HTMLCanvasElement> canvas = | |
1207 Persistent<HTMLCanvasElement>(canvasElement()); | |
1208 CanvasContextCreationAttributes attributes; | |
1209 attributes.setAlpha(true); | |
1210 attributes.setColorSpace("srgb"); | |
1211 CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>( | |
1212 canvas->getCanvasRenderingContext("2d", attributes)); | |
1213 StringOrCanvasGradientOrCanvasPattern fillStyle; | |
1214 fillStyle.setString("#FF0000"); | |
1215 context->setFillStyle(fillStyle); | |
1216 context->fillRect(0, 0, 10, 10); | |
1217 NonThrowableExceptionState exceptionState; | |
1218 uint8_t* srcPixel = | |
1219 context->getImageData(5, 5, 1, 1, exceptionState)->data()->data(); | |
1220 // Swizzle if needed | |
1221 if (kN32_SkColorType == kBGRA_8888_SkColorType) | |
1222 std::swap(srcPixel[0], srcPixel[2]); | |
1223 | |
1224 // Create and test the ImageBitmap objects. | |
1225 Optional<IntRect> cropRect = IntRect(0, 0, 10, 10); | |
1226 sk_sp<SkColorSpace> colorSpace = nullptr; | |
1227 SkColorType colorType = SkColorType::kN32_SkColorType; | |
1228 SkColorSpaceXform::ColorFormat colorFormat32 = | |
1229 (colorType == kBGRA_8888_SkColorType) | |
1230 ? SkColorSpaceXform::ColorFormat::kBGRA_8888_ColorFormat | |
1231 : SkColorSpaceXform::ColorFormat::kRGBA_8888_ColorFormat; | |
1232 SkColorSpaceXform::ColorFormat colorFormat = colorFormat32; | |
1233 sk_sp<SkColorSpace> srcRGBColorSpace = | |
1234 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); | |
1235 | |
1236 for (uint8_t i = static_cast<uint8_t>( | |
1237 ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED); | |
1238 i <= static_cast<uint8_t>(ColorSpaceConversion::LAST); i++) { | |
1239 ColorSpaceConversion colorSpaceConversion = | |
1240 static_cast<ColorSpaceConversion>(i); | |
1241 ImageBitmapOptions options = | |
1242 prepareBitmapOptionsAndSetRuntimeFlags(colorSpaceConversion); | |
1243 ImageBitmap* imageBitmap = ImageBitmap::create(canvas, cropRect, options); | |
1244 SkImage* convertedImage = | |
1245 imageBitmap->bitmapImage() | |
1246 ->imageForCurrentFrame(ColorBehavior::ignore()) | |
1247 .get(); | |
1248 | |
1249 switch (colorSpaceConversion) { | |
1250 case ColorSpaceConversion::NONE: | |
1251 NOTREACHED(); | |
1252 break; | |
1253 case ColorSpaceConversion::DEFAULT_NOT_COLOR_CORRECTED: | |
1254 // TODO(zakerinasab): Replace sRGB with a call to | |
1255 // ImageDecoder::globalTargetColorSpace() when the crash problem on Mac | |
1256 // is fixed. crbug.com/668546. | |
1257 colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); | |
1258 colorFormat = colorFormat32; | |
1259 break; | |
1260 case ColorSpaceConversion::DEFAULT_COLOR_CORRECTED: | |
1261 case ColorSpaceConversion::SRGB: | |
1262 colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); | |
1263 colorFormat = colorFormat32; | |
1264 break; | |
1265 case ColorSpaceConversion::LINEAR_RGB: | |
1266 colorSpace = SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named); | |
1267 colorType = SkColorType::kRGBA_F16_SkColorType; | |
1268 colorFormat = SkColorSpaceXform::ColorFormat::kRGBA_F16_ColorFormat; | |
1269 break; | |
1270 default: | |
1271 NOTREACHED(); | |
1272 } | |
1273 | |
1274 SkImageInfo imageInfo = SkImageInfo::Make( | |
1275 1, 1, colorType, SkAlphaType::kPremul_SkAlphaType, colorSpace); | |
1276 std::unique_ptr<uint8_t[]> convertedPixel( | |
1277 new uint8_t[imageInfo.bytesPerPixel()]()); | |
1278 convertedImage->readPixels( | |
1279 imageInfo, convertedPixel.get(), | |
1280 convertedImage->width() * imageInfo.bytesPerPixel(), 5, 5); | |
1281 | |
1282 // Transform the source pixel and check if the image bitmap color conversion | |
1283 // is done correctly. | |
1284 std::unique_ptr<SkColorSpaceXform> colorSpaceXform = | |
1285 SkColorSpaceXform::New(srcRGBColorSpace.get(), colorSpace.get()); | |
1286 std::unique_ptr<uint8_t[]> transformedPixel( | |
1287 new uint8_t[imageInfo.bytesPerPixel()]()); | |
1288 colorSpaceXform->apply(colorFormat, transformedPixel.get(), colorFormat32, | |
1289 srcPixel, 1, SkAlphaType::kPremul_SkAlphaType); | |
1290 | |
1291 int compare = std::memcmp(convertedPixel.get(), transformedPixel.get(), | |
1292 imageInfo.bytesPerPixel()); | |
1293 ASSERT_EQ(compare, 0); | |
1294 } | |
1295 } | |
1296 | |
1174 } // namespace blink | 1297 } // namespace blink |
OLD | NEW |