Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013, Google Inc. All rights reserved. | 2 * Copyright (c) 2013, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "platform/graphics/BitmapImage.h" | 31 #include "platform/graphics/BitmapImage.h" |
| 32 | 32 |
| 33 #include "platform/SharedBuffer.h" | 33 #include "platform/SharedBuffer.h" |
| 34 #include "platform/graphics/BitmapImageMetrics.h" | 34 #include "platform/graphics/BitmapImageMetrics.h" |
| 35 #include "platform/graphics/DeferredImageDecoder.h" | 35 #include "platform/graphics/DeferredImageDecoder.h" |
| 36 #include "platform/graphics/ImageObserver.h" | 36 #include "platform/graphics/ImageObserver.h" |
| 37 #include "platform/testing/HistogramTester.h" | 37 #include "platform/testing/HistogramTester.h" |
| 38 #include "platform/testing/UnitTestHelpers.h" | 38 #include "platform/testing/UnitTestHelpers.h" |
| 39 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
| 40 | 40 |
| 41 #define BITMAP_IMAGE_TEST 1 | |
|
Peter Kasting
2016/04/28 23:07:54
Don't add this.
aleksandar.stojiljkovic
2016/04/29 17:17:43
Done.
| |
| 42 | |
| 41 namespace blink { | 43 namespace blink { |
| 42 | 44 |
| 43 class BitmapImageTest : public ::testing::Test { | 45 class BitmapImageTest : public ::testing::Test { |
| 44 public: | 46 public: |
| 45 class FakeImageObserver : public GarbageCollectedFinalized<FakeImageObserver >, public ImageObserver { | 47 class FakeImageObserver : public GarbageCollectedFinalized<FakeImageObserver >, public ImageObserver { |
| 46 USING_GARBAGE_COLLECTED_MIXIN(FakeImageObserver); | 48 USING_GARBAGE_COLLECTED_MIXIN(FakeImageObserver); |
| 47 public: | 49 public: |
| 48 FakeImageObserver() : m_lastDecodedSizeChangedDelta(0) { } | 50 FakeImageObserver() : m_lastDecodedSizeChangedDelta(0) { } |
| 49 | 51 |
| 50 virtual void decodedSizeChanged(const Image*, int delta) | 52 virtual void decodedSizeChanged(const Image*, int delta) |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 64 BitmapImageTest(bool enableDeferredDecoding) : m_enableDeferredDecoding(enab leDeferredDecoding) { } | 66 BitmapImageTest(bool enableDeferredDecoding) : m_enableDeferredDecoding(enab leDeferredDecoding) { } |
| 65 | 67 |
| 66 static PassRefPtr<SharedBuffer> readFile(const char* fileName) | 68 static PassRefPtr<SharedBuffer> readFile(const char* fileName) |
| 67 { | 69 { |
| 68 String filePath = testing::blinkRootDir(); | 70 String filePath = testing::blinkRootDir(); |
| 69 filePath.append(fileName); | 71 filePath.append(fileName); |
| 70 return testing::readFromFile(filePath); | 72 return testing::readFromFile(filePath); |
| 71 } | 73 } |
| 72 | 74 |
| 73 // Accessors to BitmapImage's protected methods. | 75 // Accessors to BitmapImage's protected methods. |
| 74 void destroyDecodedData(bool destroyAll) { m_image->destroyDecodedData(destr oyAll); } | 76 void destroyDecodedData() { m_image->destroyDecodedData(); } |
| 75 size_t frameCount() { return m_image->frameCount(); } | 77 size_t frameCount() { return m_image->frameCount(); } |
| 76 void frameAtIndex(size_t index) | 78 PassRefPtr<SkImage> frameAtIndex(size_t index) |
| 77 { | 79 { |
| 78 m_image->frameAtIndex(index); | 80 return m_image->frameAtIndex(index); |
| 79 } | 81 } |
| 80 void setCurrentFrame(size_t frame) { m_image->m_currentFrame = frame; } | 82 void setCurrentFrame(size_t frame) { m_image->m_currentFrame = frame; } |
| 81 size_t frameDecodedSize(size_t frame) { return m_image->m_frames[frame].m_fr ameBytes; } | 83 size_t frameDecodedSize(size_t frame) { return m_image->m_frames[frame].m_fr ameBytes; } |
| 82 size_t decodedFramesCount() const { return m_image->m_frames.size(); } | 84 size_t decodedFramesCount() const { return m_image->m_frames.size(); } |
| 83 | 85 |
| 84 void setFirstFrameNotComplete() { m_image->m_frames[0].m_isComplete = false; } | 86 void setFirstFrameNotComplete() { m_image->m_frames[0].m_isComplete = false; } |
| 85 | 87 |
| 86 void loadImage(const char* fileName, bool loadAllFrames = true) | 88 void loadImage(const char* fileName, bool loadAllFrames = true) |
| 87 { | 89 { |
| 88 RefPtr<SharedBuffer> imageData = readFile(fileName); | 90 RefPtr<SharedBuffer> imageData = readFile(fileName); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 int animationFinished() | 127 int animationFinished() |
| 126 { | 128 { |
| 127 return m_image->m_animationFinished; | 129 return m_image->m_animationFinished; |
| 128 } | 130 } |
| 129 | 131 |
| 130 PassRefPtr<Image> imageForDefaultFrame() | 132 PassRefPtr<Image> imageForDefaultFrame() |
| 131 { | 133 { |
| 132 return m_image->imageForDefaultFrame(); | 134 return m_image->imageForDefaultFrame(); |
| 133 } | 135 } |
| 134 | 136 |
| 137 void setAnimationCacheSizeForTesting(size_t maxCacheSize, size_t maxAnimatio nSizeInCache) | |
| 138 { | |
| 139 BitmapImage::setAnimationCacheSizeForTesting(maxCacheSize, maxAnimationS izeInCache); | |
| 140 } | |
| 141 | |
| 142 int lastDecodedSizeChange() | |
| 143 { | |
| 144 return m_imageObserver->m_lastDecodedSizeChangedDelta; | |
| 145 } | |
| 146 | |
| 135 protected: | 147 protected: |
| 136 void SetUp() override | 148 void SetUp() override |
| 137 { | 149 { |
| 138 DeferredImageDecoder::setEnabled(m_enableDeferredDecoding); | 150 DeferredImageDecoder::setEnabled(m_enableDeferredDecoding); |
| 139 m_imageObserver = new FakeImageObserver; | 151 m_imageObserver = new FakeImageObserver; |
| 140 m_image = BitmapImage::create(m_imageObserver.get()); | 152 m_image = BitmapImage::create(m_imageObserver.get()); |
| 141 } | 153 } |
| 142 | 154 |
| 143 Persistent<FakeImageObserver> m_imageObserver; | 155 Persistent<FakeImageObserver> m_imageObserver; |
| 144 RefPtr<BitmapImage> m_image; | 156 RefPtr<BitmapImage> m_image; |
| 145 | 157 |
| 146 private: | 158 private: |
| 147 bool m_enableDeferredDecoding; | 159 bool m_enableDeferredDecoding; |
| 148 }; | 160 }; |
| 149 | 161 |
| 150 TEST_F(BitmapImageTest, destroyDecodedDataExceptCurrentFrame) | |
| 151 { | |
| 152 loadImage("/LayoutTests/fast/images/resources/animated-10color.gif"); | |
| 153 size_t totalSize = decodedSize(); | |
| 154 size_t frame = frameCount() / 2; | |
| 155 setCurrentFrame(frame); | |
| 156 size_t size = frameDecodedSize(frame); | |
| 157 destroyDecodedData(false); | |
| 158 EXPECT_LT(m_imageObserver->m_lastDecodedSizeChangedDelta, 0); | |
| 159 EXPECT_GE(m_imageObserver->m_lastDecodedSizeChangedDelta, -static_cast<int>( totalSize - size)); | |
| 160 } | |
| 161 | |
| 162 TEST_F(BitmapImageTest, destroyAllDecodedData) | 162 TEST_F(BitmapImageTest, destroyAllDecodedData) |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Remove "All"?
aleksandar.stojiljkovic
2016/04/29 17:17:43
Done.
| |
| 163 { | 163 { |
| 164 loadImage("/LayoutTests/fast/images/resources/animated-10color.gif"); | 164 loadImage("/LayoutTests/fast/images/resources/animated-10color.gif"); |
| 165 size_t totalSize = decodedSize(); | 165 size_t totalSize = decodedSize(); |
| 166 EXPECT_GT(totalSize, 0u); | 166 EXPECT_GT(totalSize, 0u); |
| 167 destroyDecodedData(true); | 167 destroyDecodedData(); |
| 168 EXPECT_EQ(-static_cast<int>(totalSize), m_imageObserver->m_lastDecodedSizeCh angedDelta); | 168 EXPECT_EQ(-static_cast<int>(totalSize), lastDecodedSizeChange()); |
| 169 EXPECT_EQ(0u, decodedSize()); | 169 EXPECT_EQ(0u, decodedSize()); |
| 170 } | 170 } |
| 171 | 171 |
| 172 TEST_F(BitmapImageTest, maybeAnimated) | 172 TEST_F(BitmapImageTest, maybeAnimated) |
| 173 { | 173 { |
| 174 loadImage("/LayoutTests/fast/images/resources/gif-loop-count.gif"); | 174 loadImage("/LayoutTests/fast/images/resources/gif-loop-count.gif"); |
| 175 for (size_t i = 0; i < frameCount(); ++i) { | 175 for (size_t i = 0; i < frameCount(); ++i) { |
| 176 EXPECT_TRUE(m_image->maybeAnimated()); | 176 EXPECT_TRUE(m_image->maybeAnimated()); |
| 177 advanceAnimation(); | 177 advanceAnimation(); |
| 178 } | 178 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 260 } | 260 } |
| 261 | 261 |
| 262 TEST_F(BitmapImageTest, correctDecodedDataSize) | 262 TEST_F(BitmapImageTest, correctDecodedDataSize) |
| 263 { | 263 { |
| 264 // When requesting a frame of a multi-frame GIF causes another frame to be | 264 // When requesting a frame of a multi-frame GIF causes another frame to be |
| 265 // decoded as well, both frames' sizes should be reported by the source and | 265 // decoded as well, both frames' sizes should be reported by the source and |
| 266 // thus included in the decoded size changed notification. | 266 // thus included in the decoded size changed notification. |
| 267 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); | 267 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); |
| 268 frameAtIndex(1); | 268 frameAtIndex(1); |
| 269 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); | 269 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); |
| 270 EXPECT_EQ(frameSize * 2, m_imageObserver->m_lastDecodedSizeChangedDelta); | 270 EXPECT_EQ(frameSize * 2, lastDecodedSizeChange()); |
| 271 | |
| 272 // Trying to destroy all data except an undecoded frame should cause the | |
| 273 // decoder to seek backwards and preserve the most recent previous frame | |
| 274 // necessary to decode that undecoded frame, and destroy all other frames. | |
| 275 setCurrentFrame(2); | |
| 276 destroyDecodedData(false); | |
| 277 EXPECT_EQ(-frameSize, m_imageObserver->m_lastDecodedSizeChangedDelta); | |
| 278 } | 271 } |
| 279 | 272 |
| 280 TEST_F(BitmapImageTest, recachingFrameAfterDataChanged) | 273 TEST_F(BitmapImageTest, recachingFrameAfterDataChanged) |
| 281 { | 274 { |
| 282 loadImage("/LayoutTests/fast/images/resources/green.jpg"); | 275 loadImage("/LayoutTests/fast/images/resources/green.jpg"); |
| 283 setFirstFrameNotComplete(); | 276 setFirstFrameNotComplete(); |
| 284 EXPECT_GT(m_imageObserver->m_lastDecodedSizeChangedDelta, 0); | 277 EXPECT_GT(lastDecodedSizeChange(), 0); |
| 285 m_imageObserver->m_lastDecodedSizeChangedDelta = 0; | 278 m_imageObserver->m_lastDecodedSizeChangedDelta = 0; |
| 286 | 279 |
| 287 // Calling dataChanged causes the cache to flush, but doesn't affect the | 280 // Calling dataChanged causes the cache to flush, but doesn't affect the |
| 288 // source's decoded frames. It shouldn't affect decoded size. | 281 // source's decoded frames. It shouldn't affect decoded size. |
| 289 m_image->dataChanged(true); | 282 m_image->dataChanged(true); |
| 290 EXPECT_EQ(0, m_imageObserver->m_lastDecodedSizeChangedDelta); | 283 EXPECT_EQ(0, lastDecodedSizeChange()); |
| 291 // Recaching the first frame also shouldn't affect decoded size. | 284 // Recaching the first frame also shouldn't affect decoded size. |
| 292 m_image->imageForCurrentFrame(); | 285 m_image->imageForCurrentFrame(); |
| 293 EXPECT_EQ(0, m_imageObserver->m_lastDecodedSizeChangedDelta); | 286 EXPECT_EQ(0, lastDecodedSizeChange()); |
| 294 } | 287 } |
| 295 | 288 |
| 296 class BitmapImageDeferredDecodingTest : public BitmapImageTest { | 289 class BitmapImageDeferredDecodingTest : public BitmapImageTest { |
| 297 public: | 290 public: |
| 298 BitmapImageDeferredDecodingTest() : BitmapImageTest(true) { } | 291 BitmapImageDeferredDecodingTest() : BitmapImageTest(true) { } |
| 299 }; | 292 }; |
| 300 | 293 |
| 294 class BitmapImageTestEmptyImpl : public BitmapImageTest { | |
| 295 public: | |
| 296 BitmapImageTestEmptyImpl() : BitmapImageTest(true) | |
| 297 { | |
| 298 SetUp(); | |
| 299 } | |
| 300 | |
| 301 void TestBody() override | |
| 302 { | |
| 303 } | |
| 304 }; | |
| 305 | |
| 306 TEST_F(BitmapImageDeferredDecodingTest, animationBitmapImageCacheMaxPerAnimation ) | |
| 307 { | |
| 308 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); | |
| 309 uint32_t image0 = frameAtIndex(0)->uniqueID(); | |
| 310 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Should be size_t with no cast since that's wh
aleksandar.stojiljkovic
2016/04/29 17:17:43
This method is removed in patch#2 so Done applies
| |
| 311 setAnimationCacheSizeForTesting(frameSize * 4, frameSize * 2); | |
| 312 | |
| 313 uint32_t image1 = frameAtIndex(1)->uniqueID(); | |
| 314 uint32_t image0v1 = frameAtIndex(0)->uniqueID(); | |
|
Peter Kasting
2016/04/28 23:07:55
Nit: Inline into next statement
| |
| 315 EXPECT_EQ(image0, image0v1); | |
| 316 uint32_t image2 = frameAtIndex(2)->uniqueID(); | |
| 317 uint32_t image1v1 = frameAtIndex(1)->uniqueID(); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Inline into next statement
| |
| 318 // It is expected that 0 and 1 is kept in the cache, and 2 is not cached | |
| 319 // as only first two frames are cached. | |
| 320 EXPECT_EQ(image1, image1v1); | |
| 321 uint32_t image2v1 = frameAtIndex(2)->uniqueID(); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Inline into next statement
| |
| 322 EXPECT_NE(image2, image2v1); | |
| 323 } | |
| 324 | |
| 325 TEST_F(BitmapImageDeferredDecodingTest, animationBitmapImageCacheEvict) | |
| 326 { | |
| 327 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); | |
| 328 uint32_t image0 = frameAtIndex(0)->uniqueID(); | |
| 329 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); | |
| 330 setAnimationCacheSizeForTesting(frameSize * 2, frameSize * 2); | |
| 331 | |
| 332 // Load another animation that would evict first animation frames | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Trailing period
| |
| 333 BitmapImageTestEmptyImpl second; | |
| 334 second.loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); | |
| 335 uint32_t second0 = second.frameAtIndex(0)->uniqueID(); | |
| 336 | |
| 337 uint32_t image0v1 = frameAtIndex(0)->uniqueID(); | |
| 338 EXPECT_EQ(image0, image0v1); | |
| 339 | |
| 340 uint32_t second0v1 = second.frameAtIndex(0)->uniqueID(); | |
| 341 EXPECT_EQ(second0, second0v1); | |
| 342 second.frameAtIndex(1); | |
| 343 | |
| 344 // Second 0 and second 1 are now in the cache. | |
| 345 uint32_t image0v2 = frameAtIndex(0)->uniqueID(); | |
| 346 EXPECT_NE(image0v1, image0v2); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Compare to |image0| so |image0v1| above can b
| |
| 347 | |
| 348 // Second was evicted as original frame 0 + second 2 frames are above cache | |
| 349 // size even second itself is under per animation limit size. | |
|
Peter Kasting
2016/04/28 23:07:55
This sentence has grammar issues severe enough tha
| |
| 350 uint32_t second0v2 = second.frameAtIndex(0)->uniqueID(); | |
| 351 EXPECT_NE(second0v1, second0v2); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Compare to |second0| so |second0v1| above can
| |
| 352 | |
| 353 uint32_t image0v3 = frameAtIndex(0)->uniqueID(); | |
| 354 EXPECT_EQ(image0v2, image0v3); | |
| 355 uint32_t second0v3 = second.frameAtIndex(0)->uniqueID(); | |
| 356 EXPECT_EQ(second0v2, second0v3); | |
| 357 | |
| 358 // By setAnimationCacheSizeForTesting it is defined to keep in cache first | |
| 359 // two frames per animation. Other frames, like frame 2 is cached only | |
| 360 // temporarily, until access to some other frame. | |
| 361 // When making space for frame 2 it in cache, the very same ImageBitmap that | |
| 362 // contains this frame will first get cleared and removed from cache (as it | |
| 363 // is first for removal in MRU cache), frame index 2 added to it and cached. | |
|
Peter Kasting
2016/04/28 23:07:54
Similarly this whole comment has significant gramm
| |
| 364 frameAtIndex(2); | |
| 365 uint32_t image0v4 = frameAtIndex(0)->uniqueID(); | |
| 366 EXPECT_NE(image0v3, image0v4); | |
|
Peter Kasting
2016/04/28 23:07:55
Nit: Compare to |image0v2| so |image0v3| above can
| |
| 367 uint32_t second0v4 = second.frameAtIndex(0)->uniqueID(); | |
| 368 EXPECT_EQ(second0v3, second0v4); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Compare to |second0v2| so |second0v3| above c
| |
| 369 | |
| 370 BitmapImageTestEmptyImpl third; | |
| 371 third.loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); | |
| 372 third.frameAtIndex(0); // It should evict image0v4. | |
| 373 uint32_t image0v5 = frameAtIndex(0)->uniqueID(); | |
|
Peter Kasting
2016/04/28 23:07:54
Nit: Inline into next statement
| |
| 374 EXPECT_NE(image0v4, image0v5); | |
| 375 } | |
| 376 | |
| 301 TEST_F(BitmapImageDeferredDecodingTest, correctDecodedDataSize) | 377 TEST_F(BitmapImageDeferredDecodingTest, correctDecodedDataSize) |
| 302 { | 378 { |
| 303 // When deferred decoding is enabled, requesting any one frame shouldn't | 379 // When deferred decoding is enabled, requesting any one frame shouldn't |
| 304 // result in decoding any other frames. | 380 // result in decoding any other frames. |
| 305 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); | 381 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); |
| 306 frameAtIndex(1); | 382 frameAtIndex(1); |
| 307 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); | 383 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); |
| 308 EXPECT_EQ(frameSize, m_imageObserver->m_lastDecodedSizeChangedDelta); | 384 EXPECT_EQ(frameSize, lastDecodedSizeChange()); |
| 309 frameAtIndex(0); | |
| 310 | |
| 311 // Trying to destroy all data except an undecoded frame should go ahead and | |
| 312 // destroy all other frames. | |
| 313 setCurrentFrame(2); | |
| 314 destroyDecodedData(false); | |
| 315 EXPECT_EQ(-frameSize * 2, m_imageObserver->m_lastDecodedSizeChangedDelta); | |
| 316 } | 385 } |
| 317 | 386 |
| 318 template <typename HistogramEnumType> | 387 template <typename HistogramEnumType> |
| 319 struct HistogramTestParams { | 388 struct HistogramTestParams { |
| 320 const char* filename; | 389 const char* filename; |
| 321 HistogramEnumType type; | 390 HistogramEnumType type; |
| 322 }; | 391 }; |
| 323 | 392 |
| 324 template <typename HistogramEnumType> | 393 template <typename HistogramEnumType> |
| 325 class BitmapHistogramTest | 394 class BitmapHistogramTest |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 368 {"/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg", OriginLeftT op}, | 437 {"/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg", OriginLeftT op}, |
| 369 {"/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg", OriginRight Top}, | 438 {"/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg", OriginRight Top}, |
| 370 {"/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg", OriginRight Bottom}, | 439 {"/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg", OriginRight Bottom}, |
| 371 {"/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg", OriginLeft Bottom} | 440 {"/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg", OriginLeft Bottom} |
| 372 }; | 441 }; |
| 373 | 442 |
| 374 INSTANTIATE_TEST_CASE_P(DecodedImageOrientationHistogramTest, DecodedImageOrient ationHistogramTest, | 443 INSTANTIATE_TEST_CASE_P(DecodedImageOrientationHistogramTest, DecodedImageOrient ationHistogramTest, |
| 375 ::testing::ValuesIn(kDecodedImageOrientationHistogramTestParams)); | 444 ::testing::ValuesIn(kDecodedImageOrientationHistogramTestParams)); |
| 376 | 445 |
| 377 } // namespace blink | 446 } // namespace blink |
| OLD | NEW |