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 "platform/scheduler/test/fake_web_task_runner.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "wtf/PtrUtil.h" | 13 #include "wtf/PtrUtil.h" |
13 #include <memory> | 14 #include <memory> |
14 | 15 |
15 namespace blink { | 16 namespace blink { |
16 | 17 |
17 class ImageQualityControllerTest : public RenderingTest { | 18 class ImageQualityControllerTest : public RenderingTest { |
18 protected: | 19 protected: |
19 ImageQualityController* controller() { return m_controller; } | 20 ImageQualityController* controller() { return m_controller; } |
20 | 21 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 | 104 |
104 TEST_F(ImageQualityControllerTest, MediumQualityFilterForUnscaledImage) | 105 TEST_F(ImageQualityControllerTest, MediumQualityFilterForUnscaledImage) |
105 { | 106 { |
106 setBodyInnerHTML("<img src='myimage'></img>"); | 107 setBodyInnerHTML("<img src='myimage'></img>"); |
107 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); | 108 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); |
108 | 109 |
109 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 110 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
110 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(*img
, testImage.get(), testImage.get(), LayoutSize(1, 1))); | 111 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality(*img
, testImage.get(), testImage.get(), LayoutSize(1, 1))); |
111 } | 112 } |
112 | 113 |
113 class MockTaskRunner : public WebTaskRunner { | 114 // TODO(alexclarke): Remove this when possible. |
114 public: | |
115 void setTime(double newTime) { m_time = newTime; } | |
116 | |
117 MockTaskRunner() | |
118 : WebTaskRunner(), m_time(0.0), m_currentTask(nullptr) | |
119 { } | |
120 | |
121 virtual ~MockTaskRunner() | |
122 { | |
123 if (m_currentTask) | |
124 delete m_currentTask; | |
125 } | |
126 | |
127 private: | |
128 void postTask(const WebTraceLocation&, Task*) override { } | |
129 void postDelayedTask(const WebTraceLocation&, Task* task, double) override | |
130 { | |
131 if (m_currentTask) | |
132 delete m_currentTask; | |
133 m_currentTask = task; | |
134 | |
135 } | |
136 bool runsTasksOnCurrentThread() override { return true; } | |
137 std::unique_ptr<WebTaskRunner> clone() override { return nullptr; } | |
138 double virtualTimeSeconds() const override { return 0.0; } | |
139 double monotonicallyIncreasingVirtualTimeSeconds() const override { return m
_time; } | |
140 SingleThreadTaskRunner* taskRunner() override { return nullptr; } | |
141 | |
142 double m_time; | |
143 Task* m_currentTask; | |
144 }; | |
145 | |
146 class MockTimer : public TaskRunnerTimer<ImageQualityController> { | 115 class MockTimer : public TaskRunnerTimer<ImageQualityController> { |
147 public: | 116 public: |
148 using TimerFiredFunction = typename TaskRunnerTimer<ImageQualityController>:
:TimerFiredFunction; | 117 using TimerFiredFunction = typename TaskRunnerTimer<ImageQualityController>:
:TimerFiredFunction; |
149 | 118 |
150 MockTimer(ImageQualityController* o, TimerFiredFunction f) | 119 MockTimer(ImageQualityController* o, TimerFiredFunction f) |
151 : TaskRunnerTimer(&m_taskRunner, o, f) | 120 : TaskRunnerTimer(&m_taskRunner, o, f) |
152 { | 121 { |
153 } | 122 } |
154 | 123 |
155 void fire() | 124 void fire() |
156 { | 125 { |
157 fired(); | 126 fired(); |
158 stop(); | 127 stop(); |
159 } | 128 } |
160 | 129 |
161 void setTime(double newTime) | 130 void setTime(double newTime) |
162 { | 131 { |
163 m_taskRunner.setTime(newTime); | 132 m_taskRunner.setTime(newTime); |
164 } | 133 } |
165 | 134 |
166 private: | 135 private: |
167 MockTaskRunner m_taskRunner; | 136 scheduler::FakeWebTaskRunner m_taskRunner; |
168 }; | 137 }; |
169 | 138 |
170 TEST_F(ImageQualityControllerTest, LowQualityFilterForResizingImage) | 139 TEST_F(ImageQualityControllerTest, LowQualityFilterForResizingImage) |
171 { | 140 { |
172 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); | 141 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); |
173 controller()->setTimer(wrapUnique(mockTimer)); | 142 controller()->setTimer(wrapUnique(mockTimer)); |
174 setBodyInnerHTML("<img src='myimage'></img>"); | 143 setBodyInnerHTML("<img src='myimage'></img>"); |
175 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); | 144 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); |
176 | 145 |
177 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 146 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); | 210 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); |
242 | 211 |
243 mockTimer->stop(); | 212 mockTimer->stop(); |
244 EXPECT_FALSE(mockTimer->isActive()); | 213 EXPECT_FALSE(mockTimer->isActive()); |
245 // Painted at the same size, so even though timer is still executing, don't
go to low quality. | 214 // Painted at the same size, so even though timer is still executing, don't
go to low quality. |
246 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); | 215 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality(*img, t
estImage.get(), testImage.get(), LayoutSize(4, 4))); |
247 // 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. | 216 // 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. |
248 EXPECT_FALSE(mockTimer->isActive()); | 217 EXPECT_FALSE(mockTimer->isActive()); |
249 } | 218 } |
250 | 219 |
| 220 // TODO(chrishtr): Cancellable timers now exist (see WebTaskRunner::postCancella
bleDelayedTask), maybe revisit? |
251 TEST_F(ImageQualityControllerTest, DontRestartTimerUnlessAdvanced) | 221 TEST_F(ImageQualityControllerTest, DontRestartTimerUnlessAdvanced) |
252 { | 222 { |
253 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); | 223 MockTimer* mockTimer = new MockTimer(controller(), &ImageQualityController::
highQualityRepaintTimerFired); |
254 controller()->setTimer(wrapUnique(mockTimer)); | 224 controller()->setTimer(wrapUnique(mockTimer)); |
255 setBodyInnerHTML("<img src='myimage'></img>"); | 225 setBodyInnerHTML("<img src='myimage'></img>"); |
256 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); | 226 LayoutImage* img = toLayoutImage(document().body()->firstChild()->layoutObje
ct()); |
257 | 227 |
258 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 228 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
259 | 229 |
260 // Paint once. This will kick off a timer to see if we resize it during that
timer's execution. | 230 // Paint once. This will kick off a timer to see if we resize it during that
timer's execution. |
(...skipping 11 matching lines...) Expand all Loading... |
272 // This animation is far enough in the future to make the timer restart, sin
ce it is half over. | 242 // This animation is far enough in the future to make the timer restart, sin
ce it is half over. |
273 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; | 243 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; |
274 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality(*img, testImage.get(),
testImage.get(), LayoutSize(4, 4), nextTime)); | 244 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality(*img, testImage.get(),
testImage.get(), LayoutSize(4, 4), nextTime)); |
275 // Now the timer has restarted, leading to a larger fire interval. | 245 // Now the timer has restarted, leading to a larger fire interval. |
276 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, mockTimer->nextF
ireInterval()); | 246 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, mockTimer->nextF
ireInterval()); |
277 } | 247 } |
278 | 248 |
279 #endif | 249 #endif |
280 | 250 |
281 } // namespace blink | 251 } // namespace blink |
OLD | NEW |