Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/BitmapImageTest.cpp

Issue 1925533003: High CPU and increased memory usage fix for high-res (GIF, WEBP...) animations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebasing. DCHECK. Thanks fmalita@. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 BitmapImageTest(bool enableDeferredDecoding) : m_enableDeferredDecoding(enab leDeferredDecoding) { } 70 BitmapImageTest(bool enableDeferredDecoding) : m_enableDeferredDecoding(enab leDeferredDecoding) { }
71 71
72 static PassRefPtr<SharedBuffer> readFile(const char* fileName) 72 static PassRefPtr<SharedBuffer> readFile(const char* fileName)
73 { 73 {
74 String filePath = testing::blinkRootDir(); 74 String filePath = testing::blinkRootDir();
75 filePath.append(fileName); 75 filePath.append(fileName);
76 return testing::readFromFile(filePath); 76 return testing::readFromFile(filePath);
77 } 77 }
78 78
79 // Accessors to BitmapImage's protected methods. 79 // Accessors to BitmapImage's protected methods.
80 void destroyDecodedData(bool destroyAll) { m_image->destroyDecodedData(destr oyAll); } 80 void destroyDecodedData() { m_image->destroyDecodedData(); }
81 size_t frameCount() { return m_image->frameCount(); } 81 size_t frameCount() { return m_image->frameCount(); }
82 void frameAtIndex(size_t index) 82 PassRefPtr<SkImage> frameAtIndex(size_t index)
83 { 83 {
84 m_image->frameAtIndex(index); 84 return m_image->frameAtIndex(index);
85 } 85 }
86 void setCurrentFrame(size_t frame) { m_image->m_currentFrame = frame; } 86 void setCurrentFrame(size_t frame) { m_image->m_currentFrame = frame; }
87 size_t frameDecodedSize(size_t frame) { return m_image->m_frames[frame].m_fr ameBytes; } 87 size_t frameDecodedSize(size_t frame) { return m_image->m_frames[frame].m_fr ameBytes; }
88 size_t decodedFramesCount() const { return m_image->m_frames.size(); } 88 size_t decodedFramesCount() const { return m_image->m_frames.size(); }
89 89
90 void setFirstFrameNotComplete() { m_image->m_frames[0].m_isComplete = false; } 90 void setFirstFrameNotComplete() { m_image->m_frames[0].m_isComplete = false; }
91 91
92 void loadImage(const char* fileName, bool loadAllFrames = true) 92 void loadImage(const char* fileName, bool loadAllFrames = true)
93 { 93 {
94 RefPtr<SharedBuffer> imageData = readFile(fileName); 94 RefPtr<SharedBuffer> imageData = readFile(fileName);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 int animationFinished() 131 int animationFinished()
132 { 132 {
133 return m_image->m_animationFinished; 133 return m_image->m_animationFinished;
134 } 134 }
135 135
136 PassRefPtr<Image> imageForDefaultFrame() 136 PassRefPtr<Image> imageForDefaultFrame()
137 { 137 {
138 return m_image->imageForDefaultFrame(); 138 return m_image->imageForDefaultFrame();
139 } 139 }
140 140
141 int lastDecodedSizeChange()
142 {
143 return m_imageObserver->m_lastDecodedSizeChangedDelta;
144 }
145
141 protected: 146 protected:
142 void SetUp() override 147 void SetUp() override
143 { 148 {
144 DeferredImageDecoder::setEnabled(m_enableDeferredDecoding); 149 DeferredImageDecoder::setEnabled(m_enableDeferredDecoding);
145 m_imageObserver = new FakeImageObserver; 150 m_imageObserver = new FakeImageObserver;
146 m_image = BitmapImage::create(m_imageObserver.get()); 151 m_image = BitmapImage::create(m_imageObserver.get());
147 } 152 }
148 153
149 Persistent<FakeImageObserver> m_imageObserver; 154 Persistent<FakeImageObserver> m_imageObserver;
150 RefPtr<BitmapImage> m_image; 155 RefPtr<BitmapImage> m_image;
151 156
152 private: 157 private:
153 bool m_enableDeferredDecoding; 158 bool m_enableDeferredDecoding;
154 }; 159 };
155 160
156 TEST_F(BitmapImageTest, destroyDecodedDataExceptCurrentFrame) 161 TEST_F(BitmapImageTest, destroyDecodedData)
157 {
158 loadImage("/LayoutTests/fast/images/resources/animated-10color.gif");
159 size_t totalSize = decodedSize();
160 size_t frame = frameCount() / 2;
161 setCurrentFrame(frame);
162 size_t size = frameDecodedSize(frame);
163 destroyDecodedData(false);
164 EXPECT_LT(m_imageObserver->m_lastDecodedSizeChangedDelta, 0);
165 EXPECT_GE(m_imageObserver->m_lastDecodedSizeChangedDelta, -static_cast<int>( totalSize - size));
166 }
167
168 TEST_F(BitmapImageTest, destroyAllDecodedData)
169 { 162 {
170 loadImage("/LayoutTests/fast/images/resources/animated-10color.gif"); 163 loadImage("/LayoutTests/fast/images/resources/animated-10color.gif");
171 size_t totalSize = decodedSize(); 164 size_t totalSize = decodedSize();
172 EXPECT_GT(totalSize, 0u); 165 EXPECT_GT(totalSize, 0u);
173 destroyDecodedData(true); 166 destroyDecodedData();
174 EXPECT_EQ(-static_cast<int>(totalSize), m_imageObserver->m_lastDecodedSizeCh angedDelta); 167 EXPECT_EQ(-static_cast<int>(totalSize), lastDecodedSizeChange());
175 EXPECT_EQ(0u, decodedSize()); 168 EXPECT_EQ(0u, decodedSize());
176 } 169 }
177 170
178 TEST_F(BitmapImageTest, maybeAnimated) 171 TEST_F(BitmapImageTest, maybeAnimated)
179 { 172 {
180 loadImage("/LayoutTests/fast/images/resources/gif-loop-count.gif"); 173 loadImage("/LayoutTests/fast/images/resources/gif-loop-count.gif");
181 for (size_t i = 0; i < frameCount(); ++i) { 174 for (size_t i = 0; i < frameCount(); ++i) {
182 EXPECT_TRUE(m_image->maybeAnimated()); 175 EXPECT_TRUE(m_image->maybeAnimated());
183 advanceAnimation(); 176 advanceAnimation();
184 } 177 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 } 259 }
267 260
268 TEST_F(BitmapImageTest, correctDecodedDataSize) 261 TEST_F(BitmapImageTest, correctDecodedDataSize)
269 { 262 {
270 // When requesting a frame of a multi-frame GIF causes another frame to be 263 // When requesting a frame of a multi-frame GIF causes another frame to be
271 // decoded as well, both frames' sizes should be reported by the source and 264 // decoded as well, both frames' sizes should be reported by the source and
272 // thus included in the decoded size changed notification. 265 // thus included in the decoded size changed notification.
273 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); 266 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false);
274 frameAtIndex(1); 267 frameAtIndex(1);
275 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); 268 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData));
276 EXPECT_EQ(frameSize * 2, m_imageObserver->m_lastDecodedSizeChangedDelta); 269 EXPECT_EQ(frameSize * 2, lastDecodedSizeChange());
277
278 // Trying to destroy all data except an undecoded frame should cause the
279 // decoder to seek backwards and preserve the most recent previous frame
280 // necessary to decode that undecoded frame, and destroy all other frames.
281 setCurrentFrame(2);
282 destroyDecodedData(false);
283 EXPECT_EQ(-frameSize, m_imageObserver->m_lastDecodedSizeChangedDelta);
284 } 270 }
285 271
286 TEST_F(BitmapImageTest, recachingFrameAfterDataChanged) 272 TEST_F(BitmapImageTest, recachingFrameAfterDataChanged)
287 { 273 {
288 loadImage("/LayoutTests/fast/images/resources/green.jpg"); 274 loadImage("/LayoutTests/fast/images/resources/green.jpg");
289 setFirstFrameNotComplete(); 275 setFirstFrameNotComplete();
290 EXPECT_GT(m_imageObserver->m_lastDecodedSizeChangedDelta, 0); 276 EXPECT_GT(lastDecodedSizeChange(), 0);
291 m_imageObserver->m_lastDecodedSizeChangedDelta = 0; 277 m_imageObserver->m_lastDecodedSizeChangedDelta = 0;
292 278
293 // Calling dataChanged causes the cache to flush, but doesn't affect the 279 // Calling dataChanged causes the cache to flush, but doesn't affect the
294 // source's decoded frames. It shouldn't affect decoded size. 280 // source's decoded frames. It shouldn't affect decoded size.
295 m_image->dataChanged(true); 281 m_image->dataChanged(true);
296 EXPECT_EQ(0, m_imageObserver->m_lastDecodedSizeChangedDelta); 282 EXPECT_EQ(0, lastDecodedSizeChange());
297 // Recaching the first frame also shouldn't affect decoded size. 283 // Recaching the first frame also shouldn't affect decoded size.
298 m_image->imageForCurrentFrame(); 284 m_image->imageForCurrentFrame();
299 EXPECT_EQ(0, m_imageObserver->m_lastDecodedSizeChangedDelta); 285 EXPECT_EQ(0, lastDecodedSizeChange());
300 } 286 }
301 287
302 class BitmapImageDeferredDecodingTest : public BitmapImageTest { 288 class BitmapImageDeferredDecodingTest : public BitmapImageTest {
303 public: 289 public:
304 BitmapImageDeferredDecodingTest() : BitmapImageTest(true) { } 290 BitmapImageDeferredDecodingTest() : BitmapImageTest(true) { }
305 }; 291 };
306 292
307 TEST_F(BitmapImageDeferredDecodingTest, correctDecodedDataSize) 293 TEST_F(BitmapImageDeferredDecodingTest, correctDecodedDataSize)
308 { 294 {
309 // When deferred decoding is enabled, requesting any one frame shouldn't 295 // When deferred decoding is enabled, requesting any one frame shouldn't
310 // result in decoding any other frames. 296 // result in decoding any other frames.
311 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false); 297 loadImage("/LayoutTests/fast/images/resources/anim_none.gif", false);
312 frameAtIndex(1); 298 frameAtIndex(1);
313 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData)); 299 int frameSize = static_cast<int>(m_image->size().area() * sizeof(ImageFrame: :PixelData));
314 EXPECT_EQ(frameSize, m_imageObserver->m_lastDecodedSizeChangedDelta); 300 EXPECT_EQ(frameSize, lastDecodedSizeChange());
315 frameAtIndex(0);
316
317 // Trying to destroy all data except an undecoded frame should go ahead and
318 // destroy all other frames.
319 setCurrentFrame(2);
320 destroyDecodedData(false);
321 EXPECT_EQ(-frameSize * 2, m_imageObserver->m_lastDecodedSizeChangedDelta);
322 } 301 }
323 302
324 template <typename HistogramEnumType> 303 template <typename HistogramEnumType>
325 struct HistogramTestParams { 304 struct HistogramTestParams {
326 const char* filename; 305 const char* filename;
327 HistogramEnumType type; 306 HistogramEnumType type;
328 }; 307 };
329 308
330 template <typename HistogramEnumType> 309 template <typename HistogramEnumType>
331 class BitmapHistogramTest 310 class BitmapHistogramTest
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 {"/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg", OriginLeftT op}, 353 {"/LayoutTests/fast/images/resources/exif-orientation-5-lu.jpg", OriginLeftT op},
375 {"/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg", OriginRight Top}, 354 {"/LayoutTests/fast/images/resources/exif-orientation-6-ru.jpg", OriginRight Top},
376 {"/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg", OriginRight Bottom}, 355 {"/LayoutTests/fast/images/resources/exif-orientation-7-rl.jpg", OriginRight Bottom},
377 {"/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg", OriginLeft Bottom} 356 {"/LayoutTests/fast/images/resources/exif-orientation-8-llo.jpg", OriginLeft Bottom}
378 }; 357 };
379 358
380 INSTANTIATE_TEST_CASE_P(DecodedImageOrientationHistogramTest, DecodedImageOrient ationHistogramTest, 359 INSTANTIATE_TEST_CASE_P(DecodedImageOrientationHistogramTest, DecodedImageOrient ationHistogramTest,
381 ::testing::ValuesIn(kDecodedImageOrientationHistogramTestParams)); 360 ::testing::ValuesIn(kDecodedImageOrientationHistogramTestParams));
382 361
383 } // namespace blink 362 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698