Chromium Code Reviews| 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 |