| 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 "core/layout/ImageQualityController.h" | 5 #include "core/layout/ImageQualityController.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include "core/layout/LayoutImage.h" | 8 #include "core/layout/LayoutImage.h" |
| 9 #include "core/layout/LayoutTestHelper.h" | 9 #include "core/layout/LayoutTestHelper.h" |
| 10 #include "platform/graphics/GraphicsContext.h" | 10 #include "platform/graphics/GraphicsContext.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 RenderingTest::SetUp(); | 25 RenderingTest::SetUp(); |
| 26 } | 26 } |
| 27 | 27 |
| 28 ImageQualityController* m_controller; | 28 ImageQualityController* m_controller; |
| 29 }; | 29 }; |
| 30 | 30 |
| 31 TEST_F(ImageQualityControllerTest, RegularImage) { | 31 TEST_F(ImageQualityControllerTest, RegularImage) { |
| 32 setBodyInnerHTML("<img src='myimage'></img>"); | 32 setBodyInnerHTML("<img src='myimage'></img>"); |
| 33 LayoutObject* obj = document().body()->firstChild()->layoutObject(); | 33 LayoutObject* obj = document().body()->firstChild()->layoutObject(); |
| 34 | 34 |
| 35 EXPECT_EQ(InterpolationDefault, controller()->chooseInterpolationQuality( | 35 EXPECT_EQ(InterpolationDefault, |
| 36 *obj, nullptr, nullptr, LayoutSize())); | 36 controller()->chooseInterpolationQuality(*obj, nullptr, nullptr, |
| 37 LayoutSize())); |
| 37 } | 38 } |
| 38 | 39 |
| 39 TEST_F(ImageQualityControllerTest, ImageRenderingPixelated) { | 40 TEST_F(ImageQualityControllerTest, ImageRenderingPixelated) { |
| 40 setBodyInnerHTML( | 41 setBodyInnerHTML( |
| 41 "<img src='myimage' style='image-rendering: pixelated'></img>"); | 42 "<img src='myimage' style='image-rendering: pixelated'></img>"); |
| 42 LayoutObject* obj = document().body()->firstChild()->layoutObject(); | 43 LayoutObject* obj = document().body()->firstChild()->layoutObject(); |
| 43 | 44 |
| 44 EXPECT_EQ(InterpolationNone, controller()->chooseInterpolationQuality( | 45 EXPECT_EQ(InterpolationNone, |
| 45 *obj, nullptr, nullptr, LayoutSize())); | 46 controller()->chooseInterpolationQuality(*obj, nullptr, nullptr, |
| 47 LayoutSize())); |
| 46 } | 48 } |
| 47 | 49 |
| 48 #if !USE(LOW_QUALITY_IMAGE_INTERPOLATION) | 50 #if !USE(LOW_QUALITY_IMAGE_INTERPOLATION) |
| 49 | 51 |
| 50 class TestImageAnimated : public Image { | 52 class TestImageAnimated : public Image { |
| 51 public: | 53 public: |
| 52 bool maybeAnimated() override { return true; } | 54 bool maybeAnimated() override { return true; } |
| 53 bool currentFrameKnownToBeOpaque(MetadataMode = UseCurrentMetadata) override { | 55 bool currentFrameKnownToBeOpaque(MetadataMode = UseCurrentMetadata) override { |
| 54 return false; | 56 return false; |
| 55 } | 57 } |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 document().getElementById("myAnimatingImage")->layoutObject()); | 231 document().getElementById("myAnimatingImage")->layoutObject()); |
| 230 LayoutImage* nonAnimatingImage = toLayoutImage( | 232 LayoutImage* nonAnimatingImage = toLayoutImage( |
| 231 document().getElementById("myNonAnimatingImage")->layoutObject()); | 233 document().getElementById("myNonAnimatingImage")->layoutObject()); |
| 232 | 234 |
| 233 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 235 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 234 std::unique_ptr<PaintController> paintController = PaintController::create(); | 236 std::unique_ptr<PaintController> paintController = PaintController::create(); |
| 235 GraphicsContext context(*paintController); | 237 GraphicsContext context(*paintController); |
| 236 | 238 |
| 237 // Paint once. This will kick off a timer to see if we resize it during that | 239 // Paint once. This will kick off a timer to see if we resize it during that |
| 238 // timer's execution. | 240 // timer's execution. |
| 239 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 241 EXPECT_EQ( |
| 240 *animatingImage, testImage.get(), | 242 InterpolationMedium, |
| 241 testImage.get(), LayoutSize(2, 2))); | 243 controller()->chooseInterpolationQuality( |
| 244 *animatingImage, testImage.get(), testImage.get(), LayoutSize(2, 2))); |
| 242 | 245 |
| 243 // Go into low-quality mode now that the size changed. | 246 // Go into low-quality mode now that the size changed. |
| 244 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality( | 247 EXPECT_EQ( |
| 245 *animatingImage, testImage.get(), | 248 InterpolationLow, |
| 246 testImage.get(), LayoutSize(3, 3))); | 249 controller()->chooseInterpolationQuality( |
| 250 *animatingImage, testImage.get(), testImage.get(), LayoutSize(3, 3))); |
| 247 | 251 |
| 248 // The non-animating image receives a medium-quality filter, even though the | 252 // The non-animating image receives a medium-quality filter, even though the |
| 249 // other one is animating. | 253 // other one is animating. |
| 250 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 254 EXPECT_EQ(InterpolationMedium, |
| 251 *nonAnimatingImage, testImage.get(), | 255 controller()->chooseInterpolationQuality( |
| 252 testImage.get(), LayoutSize(4, 4))); | 256 *nonAnimatingImage, testImage.get(), testImage.get(), |
| 257 LayoutSize(4, 4))); |
| 253 | 258 |
| 254 // Now the second image has animated, so it also gets painted with a | 259 // Now the second image has animated, so it also gets painted with a |
| 255 // low-quality filter. | 260 // low-quality filter. |
| 256 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality( | 261 EXPECT_EQ(InterpolationLow, |
| 257 *nonAnimatingImage, testImage.get(), | 262 controller()->chooseInterpolationQuality( |
| 258 testImage.get(), LayoutSize(3, 3))); | 263 *nonAnimatingImage, testImage.get(), testImage.get(), |
| 264 LayoutSize(3, 3))); |
| 259 | 265 |
| 260 mockTimer->fire(); | 266 mockTimer->fire(); |
| 261 // The timer fired before painting at another size, so this doesn't count as | 267 // The timer fired before painting at another size, so this doesn't count as |
| 262 // animation. Therefore not painting at low quality for any image. | 268 // animation. Therefore not painting at low quality for any image. |
| 263 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 269 EXPECT_EQ( |
| 264 *animatingImage, testImage.get(), | 270 InterpolationMedium, |
| 265 testImage.get(), LayoutSize(4, 4))); | 271 controller()->chooseInterpolationQuality( |
| 266 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 272 *animatingImage, testImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 267 *nonAnimatingImage, testImage.get(), | 273 EXPECT_EQ(InterpolationMedium, |
| 268 testImage.get(), LayoutSize(4, 4))); | 274 controller()->chooseInterpolationQuality( |
| 275 *nonAnimatingImage, testImage.get(), testImage.get(), |
| 276 LayoutSize(4, 4))); |
| 269 } | 277 } |
| 270 | 278 |
| 271 TEST_F(ImageQualityControllerTest, | 279 TEST_F(ImageQualityControllerTest, |
| 272 DontKickTheAnimationTimerWhenPaintingAtTheSameSize) { | 280 DontKickTheAnimationTimerWhenPaintingAtTheSameSize) { |
| 273 MockTimer* mockTimer = | 281 MockTimer* mockTimer = |
| 274 MockTimer::create(controller(), | 282 MockTimer::create(controller(), |
| 275 &ImageQualityController::highQualityRepaintTimerFired) | 283 &ImageQualityController::highQualityRepaintTimerFired) |
| 276 .release(); | 284 .release(); |
| 277 controller()->setTimer(WTF::wrapUnique(mockTimer)); | 285 controller()->setTimer(WTF::wrapUnique(mockTimer)); |
| 278 setBodyInnerHTML("<img src='myimage'></img>"); | 286 setBodyInnerHTML("<img src='myimage'></img>"); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 // timer's execution. | 333 // timer's execution. |
| 326 mockTimer->setTime(0.1); | 334 mockTimer->setTime(0.1); |
| 327 EXPECT_FALSE(controller()->shouldPaintAtLowQuality( | 335 EXPECT_FALSE(controller()->shouldPaintAtLowQuality( |
| 328 *img, testImage.get(), testImage.get(), LayoutSize(2, 2), 0.1)); | 336 *img, testImage.get(), testImage.get(), LayoutSize(2, 2), 0.1)); |
| 329 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, | 337 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, |
| 330 mockTimer->nextFireInterval()); | 338 mockTimer->nextFireInterval()); |
| 331 | 339 |
| 332 // Go into low-quality mode now that the size changed. | 340 // Go into low-quality mode now that the size changed. |
| 333 double nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold / 2.0; | 341 double nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold / 2.0; |
| 334 mockTimer->setTime(nextTime); | 342 mockTimer->setTime(nextTime); |
| 335 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality( | 343 EXPECT_EQ( |
| 336 *img, testImage.get(), testImage.get(), LayoutSize(3, 3), | 344 true, |
| 337 nextTime)); | 345 controller()->shouldPaintAtLowQuality( |
| 346 *img, testImage.get(), testImage.get(), LayoutSize(3, 3), nextTime)); |
| 338 // The fire interval has decreased, because we have not restarted the timer. | 347 // The fire interval has decreased, because we have not restarted the timer. |
| 339 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold - | 348 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold - |
| 340 ImageQualityController::cTimerRestartThreshold / 2.0, | 349 ImageQualityController::cTimerRestartThreshold / 2.0, |
| 341 mockTimer->nextFireInterval()); | 350 mockTimer->nextFireInterval()); |
| 342 | 351 |
| 343 // This animation is far enough in the future to make the timer restart, since | 352 // This animation is far enough in the future to make the timer restart, since |
| 344 // it is half over. | 353 // it is half over. |
| 345 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; | 354 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; |
| 346 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality( | 355 EXPECT_EQ( |
| 347 *img, testImage.get(), testImage.get(), LayoutSize(4, 4), | 356 true, |
| 348 nextTime)); | 357 controller()->shouldPaintAtLowQuality( |
| 358 *img, testImage.get(), testImage.get(), LayoutSize(4, 4), nextTime)); |
| 349 // Now the timer has restarted, leading to a larger fire interval. | 359 // Now the timer has restarted, leading to a larger fire interval. |
| 350 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, | 360 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, |
| 351 mockTimer->nextFireInterval()); | 361 mockTimer->nextFireInterval()); |
| 352 } | 362 } |
| 353 | 363 |
| 354 #endif | 364 #endif |
| 355 | 365 |
| 356 } // namespace blink | 366 } // namespace blink |
| OLD | NEW |