| 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 "core/layout/LayoutImage.h" | 7 #include "core/layout/LayoutImage.h" |
| 8 #include "core/layout/LayoutTestHelper.h" | 8 #include "core/layout/LayoutTestHelper.h" |
| 9 #include "platform/graphics/GraphicsContext.h" | 9 #include "platform/graphics/GraphicsContext.h" |
| 10 #include "platform/graphics/paint/PaintController.h" | 10 #include "platform/graphics/paint/PaintController.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 | 12 |
| 13 namespace blink { | 13 namespace blink { |
| 14 | 14 |
| 15 class ImageQualityControllerTest : public RenderingTest { | 15 class ImageQualityControllerTest : public RenderingTest { |
| 16 protected: | 16 protected: |
| 17 ImageQualityController* controller() { return m_controller; } | 17 ImageQualityController* controller() { return m_controller; } |
| 18 | 18 |
| 19 private: | 19 private: |
| 20 void SetUp() override | 20 void SetUp() override |
| 21 { | 21 { |
| 22 m_controller = ImageQualityController::imageQualityController(); | 22 m_controller = ImageQualityController::imageQualityController(); |
| 23 RenderingTest::SetUp(); | 23 RenderingTest::SetUp(); |
| 24 } | 24 } |
| 25 void TearDown() override | 25 void TearDown() override |
| 26 { | 26 { |
| 27 } | 27 } |
| 28 |
| 28 ImageQualityController* m_controller; | 29 ImageQualityController* m_controller; |
| 29 }; | 30 }; |
| 30 | 31 |
| 31 TEST_F(ImageQualityControllerTest, RegularImage) | 32 TEST_F(ImageQualityControllerTest, RegularImage) |
| 32 { | 33 { |
| 33 setBodyInnerHTML("<img src='myimage'></img>"); | 34 setBodyInnerHTML("<img src='myimage'></img>"); |
| 34 LayoutObject* obj = document().body()->firstChild()->layoutObject(); | 35 LayoutObject* obj = document().body()->firstChild()->layoutObject(); |
| 35 | 36 |
| 36 EXPECT_EQ(InterpolationDefault, controller()->chooseInterpolationQuality(*ob
j, nullptr, nullptr, LayoutSize())); | 37 EXPECT_EQ(InterpolationDefault, controller()->chooseInterpolationQuality(*ob
j, nullptr, nullptr, LayoutSize())); |
| 37 } | 38 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 | 101 |
| 101 TEST_F(ImageQualityControllerTest, MediumQualityFilterForUnscaledImage) | 102 TEST_F(ImageQualityControllerTest, MediumQualityFilterForUnscaledImage) |
| 102 { | 103 { |
| 103 setBodyInnerHTML("<img src='myimage'></img>"); | 104 setBodyInnerHTML("<img src='myimage'></img>"); |
| 104 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); | 105 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); |
| 105 | 106 |
| 106 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 107 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 107 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(*img
, testImage.get(), testImage.get(), LayoutSize(1, 1))); | 108 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(*img
, testImage.get(), testImage.get(), LayoutSize(1, 1))); |
| 108 } | 109 } |
| 109 | 110 |
| 111 class MockTaskRunner : public WebTaskRunner { |
| 112 public: |
| 113 void setTime(double newTime) { m_time = newTime; } |
| 114 |
| 115 MockTaskRunner() |
| 116 : WebTaskRunner(), m_time(0.0), m_currentTask(nullptr) |
| 117 { } |
| 118 |
| 119 virtual ~MockTaskRunner() |
| 120 { |
| 121 if (m_currentTask) |
| 122 delete m_currentTask; |
| 123 } |
| 124 |
| 125 private: |
| 126 void postTask(const WebTraceLocation&, Task*) override { } |
| 127 void postDelayedTask(const WebTraceLocation&, Task* task, double) override |
| 128 { |
| 129 if (m_currentTask) |
| 130 delete m_currentTask; |
| 131 m_currentTask = task; |
| 132 |
| 133 } |
| 134 WebTaskRunner* clone() override { return nullptr; } |
| 135 double virtualTimeSeconds() const override { return 0.0; } |
| 136 double monotonicallyIncreasingVirtualTimeSeconds() const override { return m
_time; } |
| 137 |
| 138 double m_time; |
| 139 Task* m_currentTask; |
| 140 }; |
| 141 |
| 110 class MockTimer : public Timer<ImageQualityController> { | 142 class MockTimer : public Timer<ImageQualityController> { |
| 111 typedef void (ImageQualityController::*TimerFiredFunction)(Timer*); | 143 typedef void (ImageQualityController::*TimerFiredFunction)(Timer*); |
| 112 public: | 144 public: |
| 113 MockTimer(ImageQualityController* o, TimerFiredFunction f) | 145 MockTimer(ImageQualityController* o, TimerFiredFunction f) |
| 114 : Timer<ImageQualityController>(o, f) | 146 : Timer<ImageQualityController>(o, f, &m_taskRunner) |
| 115 { | 147 { |
| 116 } | 148 } |
| 117 | 149 |
| 118 void fire() | 150 void fire() |
| 119 { | 151 { |
| 120 this->Timer<ImageQualityController>::fired(); | 152 this->Timer<ImageQualityController>::fired(); |
| 121 stop(); | 153 stop(); |
| 122 } | 154 } |
| 155 |
| 156 void setTime(double newTime) |
| 157 { |
| 158 m_taskRunner.setTime(newTime); |
| 159 } |
| 160 |
| 161 private: |
| 162 MockTaskRunner m_taskRunner; |
| 123 }; | 163 }; |
| 124 | 164 |
| 125 TEST_F(ImageQualityControllerTest, LowQualityFilterForResizingImage) | 165 TEST_F(ImageQualityControllerTest, LowQualityFilterForResizingImage) |
| 126 { | 166 { |
| 127 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); | 167 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); |
| 128 controller()->setTimer(mockTimer); | 168 controller()->setTimer(mockTimer); |
| 129 setBodyInnerHTML("<img src='myimage'></img>"); | 169 setBodyInnerHTML("<img src='myimage'></img>"); |
| 130 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); | 170 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); |
| 131 | 171 |
| 132 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 172 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); | 236 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 197 | 237 |
| 198 mockTimer->stop(); | 238 mockTimer->stop(); |
| 199 EXPECT_FALSE(mockTimer->isActive()); | 239 EXPECT_FALSE(mockTimer->isActive()); |
| 200 // Painted at the same size, so even though timer is still executing, don't
go to low quality. | 240 // Painted at the same size, so even though timer is still executing, don't
go to low quality. |
| 201 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); | 241 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 202 // Check that the timer was not kicked. It should not have been, since the i
mage was painted at the same size as last time. | 242 // Check that the timer was not kicked. It should not have been, since the i
mage was painted at the same size as last time. |
| 203 EXPECT_FALSE(mockTimer->isActive()); | 243 EXPECT_FALSE(mockTimer->isActive()); |
| 204 } | 244 } |
| 205 | 245 |
| 246 TEST_F(ImageQualityControllerTest, DontRestartTimerUnlessAdvanced) |
| 247 { |
| 248 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); |
| 249 controller()->setTimer(mockTimer); |
| 250 setBodyInnerHTML("<img src='myimage'></img>"); |
| 251 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); |
| 252 |
| 253 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 254 |
| 255 // Paint once. This will kick off a timer to see if we resize it during that
timer's execution. |
| 256 mockTimer->setTime(0.1); |
| 257 EXPECT_EQ(false, controller()->shouldPaintAtLowQuality(*img, testImage.get()
, testImage.get(), LayoutSize(2, 2), 0.1)); |
| 258 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, mockTimer->nextF
ireInterval()); |
| 259 |
| 260 // Go into low-quality mode now that the size changed. |
| 261 double nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold / 2.0
; |
| 262 mockTimer->setTime(nextTime); |
| 263 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality(*img, testImage.get(),
testImage.get(), LayoutSize(3, 3), nextTime)); |
| 264 // The fire interval has decreased, because we have not restarted the timer. |
| 265 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold - ImageQualityCon
troller::cTimerRestartThreshold / 2.0, mockTimer->nextFireInterval()); |
| 266 |
| 267 // This animation is far enough in the future to make the timer restart, sin
ce it is half over. |
| 268 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; |
| 269 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality(*img, testImage.get(),
testImage.get(), LayoutSize(4, 4), nextTime)); |
| 270 // Now the timer has restarted, leading to a larger fire interval. |
| 271 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, mockTimer->nextF
ireInterval()); |
| 272 } |
| 273 |
| 206 #endif | 274 #endif |
| 207 | 275 |
| 208 } // namespace blink | 276 } // namespace blink |
| OLD | NEW |