| 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" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 .release(); | 176 .release(); |
| 177 controller()->setTimer(wrapUnique(mockTimer)); | 177 controller()->setTimer(wrapUnique(mockTimer)); |
| 178 setBodyInnerHTML("<img src='myimage'></img>"); | 178 setBodyInnerHTML("<img src='myimage'></img>"); |
| 179 LayoutImage* img = | 179 LayoutImage* img = |
| 180 toLayoutImage(document().body()->firstChild()->layoutObject()); | 180 toLayoutImage(document().body()->firstChild()->layoutObject()); |
| 181 | 181 |
| 182 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 182 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 183 std::unique_ptr<PaintController> paintController = PaintController::create(); | 183 std::unique_ptr<PaintController> paintController = PaintController::create(); |
| 184 GraphicsContext context(*paintController); | 184 GraphicsContext context(*paintController); |
| 185 | 185 |
| 186 // Paint once. This will kick off a timer to see if we resize it during that t
imer's execution. | 186 // Paint once. This will kick off a timer to see if we resize it during that |
| 187 // timer's execution. |
| 187 EXPECT_EQ(InterpolationMedium, | 188 EXPECT_EQ(InterpolationMedium, |
| 188 controller()->chooseInterpolationQuality( | 189 controller()->chooseInterpolationQuality( |
| 189 *img, testImage.get(), testImage.get(), LayoutSize(2, 2))); | 190 *img, testImage.get(), testImage.get(), LayoutSize(2, 2))); |
| 190 | 191 |
| 191 // Go into low-quality mode now that the size changed. | 192 // Go into low-quality mode now that the size changed. |
| 192 EXPECT_EQ(InterpolationLow, | 193 EXPECT_EQ(InterpolationLow, |
| 193 controller()->chooseInterpolationQuality( | 194 controller()->chooseInterpolationQuality( |
| 194 *img, testImage.get(), testImage.get(), LayoutSize(3, 3))); | 195 *img, testImage.get(), testImage.get(), LayoutSize(3, 3))); |
| 195 | 196 |
| 196 // Stay in low-quality mode since the size changed again. | 197 // Stay in low-quality mode since the size changed again. |
| 197 EXPECT_EQ(InterpolationLow, | 198 EXPECT_EQ(InterpolationLow, |
| 198 controller()->chooseInterpolationQuality( | 199 controller()->chooseInterpolationQuality( |
| 199 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); | 200 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 200 | 201 |
| 201 mockTimer->fire(); | 202 mockTimer->fire(); |
| 202 // The timer fired before painting at another size, so this doesn't count as a
nimation. Therefore not painting at low quality. | 203 // The timer fired before painting at another size, so this doesn't count as |
| 204 // animation. Therefore not painting at low quality. |
| 203 EXPECT_EQ(InterpolationMedium, | 205 EXPECT_EQ(InterpolationMedium, |
| 204 controller()->chooseInterpolationQuality( | 206 controller()->chooseInterpolationQuality( |
| 205 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); | 207 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 206 } | 208 } |
| 207 | 209 |
| 208 TEST_F(ImageQualityControllerTest, | 210 TEST_F(ImageQualityControllerTest, |
| 209 MediumQualityFilterForNotAnimatedWhileAnotherAnimates) { | 211 MediumQualityFilterForNotAnimatedWhileAnotherAnimates) { |
| 210 MockTimer* mockTimer = | 212 MockTimer* mockTimer = |
| 211 MockTimer::create(controller(), | 213 MockTimer::create(controller(), |
| 212 &ImageQualityController::highQualityRepaintTimerFired) | 214 &ImageQualityController::highQualityRepaintTimerFired) |
| 213 .release(); | 215 .release(); |
| 214 controller()->setTimer(wrapUnique(mockTimer)); | 216 controller()->setTimer(wrapUnique(mockTimer)); |
| 215 setBodyInnerHTML( | 217 setBodyInnerHTML( |
| 216 "<img id='myAnimatingImage' src='myimage'></img> <img " | 218 "<img id='myAnimatingImage' src='myimage'></img> <img " |
| 217 "id='myNonAnimatingImage' src='myimage2'></img>"); | 219 "id='myNonAnimatingImage' src='myimage2'></img>"); |
| 218 LayoutImage* animatingImage = toLayoutImage( | 220 LayoutImage* animatingImage = toLayoutImage( |
| 219 document().getElementById("myAnimatingImage")->layoutObject()); | 221 document().getElementById("myAnimatingImage")->layoutObject()); |
| 220 LayoutImage* nonAnimatingImage = toLayoutImage( | 222 LayoutImage* nonAnimatingImage = toLayoutImage( |
| 221 document().getElementById("myNonAnimatingImage")->layoutObject()); | 223 document().getElementById("myNonAnimatingImage")->layoutObject()); |
| 222 | 224 |
| 223 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 225 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 224 std::unique_ptr<PaintController> paintController = PaintController::create(); | 226 std::unique_ptr<PaintController> paintController = PaintController::create(); |
| 225 GraphicsContext context(*paintController); | 227 GraphicsContext context(*paintController); |
| 226 | 228 |
| 227 // Paint once. This will kick off a timer to see if we resize it during that t
imer's execution. | 229 // Paint once. This will kick off a timer to see if we resize it during that |
| 230 // timer's execution. |
| 228 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 231 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( |
| 229 *animatingImage, testImage.get(), | 232 *animatingImage, testImage.get(), |
| 230 testImage.get(), LayoutSize(2, 2))); | 233 testImage.get(), LayoutSize(2, 2))); |
| 231 | 234 |
| 232 // Go into low-quality mode now that the size changed. | 235 // Go into low-quality mode now that the size changed. |
| 233 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality( | 236 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality( |
| 234 *animatingImage, testImage.get(), | 237 *animatingImage, testImage.get(), |
| 235 testImage.get(), LayoutSize(3, 3))); | 238 testImage.get(), LayoutSize(3, 3))); |
| 236 | 239 |
| 237 // The non-animating image receives a medium-quality filter, even though the o
ther one is animating. | 240 // The non-animating image receives a medium-quality filter, even though the |
| 241 // other one is animating. |
| 238 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 242 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( |
| 239 *nonAnimatingImage, testImage.get(), | 243 *nonAnimatingImage, testImage.get(), |
| 240 testImage.get(), LayoutSize(4, 4))); | 244 testImage.get(), LayoutSize(4, 4))); |
| 241 | 245 |
| 242 // Now the second image has animated, so it also gets painted with a low-quali
ty filter. | 246 // Now the second image has animated, so it also gets painted with a |
| 247 // low-quality filter. |
| 243 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality( | 248 EXPECT_EQ(InterpolationLow, controller()->chooseInterpolationQuality( |
| 244 *nonAnimatingImage, testImage.get(), | 249 *nonAnimatingImage, testImage.get(), |
| 245 testImage.get(), LayoutSize(3, 3))); | 250 testImage.get(), LayoutSize(3, 3))); |
| 246 | 251 |
| 247 mockTimer->fire(); | 252 mockTimer->fire(); |
| 248 // The timer fired before painting at another size, so this doesn't count as a
nimation. Therefore not painting at low quality for any image. | 253 // The timer fired before painting at another size, so this doesn't count as |
| 254 // animation. Therefore not painting at low quality for any image. |
| 249 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 255 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( |
| 250 *animatingImage, testImage.get(), | 256 *animatingImage, testImage.get(), |
| 251 testImage.get(), LayoutSize(4, 4))); | 257 testImage.get(), LayoutSize(4, 4))); |
| 252 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( | 258 EXPECT_EQ(InterpolationMedium, controller()->chooseInterpolationQuality( |
| 253 *nonAnimatingImage, testImage.get(), | 259 *nonAnimatingImage, testImage.get(), |
| 254 testImage.get(), LayoutSize(4, 4))); | 260 testImage.get(), LayoutSize(4, 4))); |
| 255 } | 261 } |
| 256 | 262 |
| 257 TEST_F(ImageQualityControllerTest, | 263 TEST_F(ImageQualityControllerTest, |
| 258 DontKickTheAnimationTimerWhenPaintingAtTheSameSize) { | 264 DontKickTheAnimationTimerWhenPaintingAtTheSameSize) { |
| 259 MockTimer* mockTimer = | 265 MockTimer* mockTimer = |
| 260 MockTimer::create(controller(), | 266 MockTimer::create(controller(), |
| 261 &ImageQualityController::highQualityRepaintTimerFired) | 267 &ImageQualityController::highQualityRepaintTimerFired) |
| 262 .release(); | 268 .release(); |
| 263 controller()->setTimer(wrapUnique(mockTimer)); | 269 controller()->setTimer(wrapUnique(mockTimer)); |
| 264 setBodyInnerHTML("<img src='myimage'></img>"); | 270 setBodyInnerHTML("<img src='myimage'></img>"); |
| 265 LayoutImage* img = | 271 LayoutImage* img = |
| 266 toLayoutImage(document().body()->firstChild()->layoutObject()); | 272 toLayoutImage(document().body()->firstChild()->layoutObject()); |
| 267 | 273 |
| 268 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 274 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 269 | 275 |
| 270 // Paint once. This will kick off a timer to see if we resize it during that t
imer's execution. | 276 // Paint once. This will kick off a timer to see if we resize it during that |
| 277 // timer's execution. |
| 271 EXPECT_EQ(InterpolationMedium, | 278 EXPECT_EQ(InterpolationMedium, |
| 272 controller()->chooseInterpolationQuality( | 279 controller()->chooseInterpolationQuality( |
| 273 *img, testImage.get(), testImage.get(), LayoutSize(2, 2))); | 280 *img, testImage.get(), testImage.get(), LayoutSize(2, 2))); |
| 274 | 281 |
| 275 // Go into low-quality mode now that the size changed. | 282 // Go into low-quality mode now that the size changed. |
| 276 EXPECT_EQ(InterpolationLow, | 283 EXPECT_EQ(InterpolationLow, |
| 277 controller()->chooseInterpolationQuality( | 284 controller()->chooseInterpolationQuality( |
| 278 *img, testImage.get(), testImage.get(), LayoutSize(3, 3))); | 285 *img, testImage.get(), testImage.get(), LayoutSize(3, 3))); |
| 279 | 286 |
| 280 // Stay in low-quality mode since the size changed again. | 287 // Stay in low-quality mode since the size changed again. |
| 281 EXPECT_EQ(InterpolationLow, | 288 EXPECT_EQ(InterpolationLow, |
| 282 controller()->chooseInterpolationQuality( | 289 controller()->chooseInterpolationQuality( |
| 283 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); | 290 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 284 | 291 |
| 285 mockTimer->stop(); | 292 mockTimer->stop(); |
| 286 EXPECT_FALSE(mockTimer->isActive()); | 293 EXPECT_FALSE(mockTimer->isActive()); |
| 287 // Painted at the same size, so even though timer is still executing, don't go
to low quality. | 294 // Painted at the same size, so even though timer is still executing, don't go |
| 295 // to low quality. |
| 288 EXPECT_EQ(InterpolationLow, | 296 EXPECT_EQ(InterpolationLow, |
| 289 controller()->chooseInterpolationQuality( | 297 controller()->chooseInterpolationQuality( |
| 290 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); | 298 *img, testImage.get(), testImage.get(), LayoutSize(4, 4))); |
| 291 // Check that the timer was not kicked. It should not have been, since the ima
ge was painted at the same size as last time. | 299 // Check that the timer was not kicked. It should not have been, since the |
| 300 // image was painted at the same size as last time. |
| 292 EXPECT_FALSE(mockTimer->isActive()); | 301 EXPECT_FALSE(mockTimer->isActive()); |
| 293 } | 302 } |
| 294 | 303 |
| 295 TEST_F(ImageQualityControllerTest, DontRestartTimerUnlessAdvanced) { | 304 TEST_F(ImageQualityControllerTest, DontRestartTimerUnlessAdvanced) { |
| 296 MockTimer* mockTimer = | 305 MockTimer* mockTimer = |
| 297 MockTimer::create(controller(), | 306 MockTimer::create(controller(), |
| 298 &ImageQualityController::highQualityRepaintTimerFired) | 307 &ImageQualityController::highQualityRepaintTimerFired) |
| 299 .release(); | 308 .release(); |
| 300 controller()->setTimer(wrapUnique(mockTimer)); | 309 controller()->setTimer(wrapUnique(mockTimer)); |
| 301 setBodyInnerHTML("<img src='myimage'></img>"); | 310 setBodyInnerHTML("<img src='myimage'></img>"); |
| 302 LayoutImage* img = | 311 LayoutImage* img = |
| 303 toLayoutImage(document().body()->firstChild()->layoutObject()); | 312 toLayoutImage(document().body()->firstChild()->layoutObject()); |
| 304 | 313 |
| 305 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); | 314 RefPtr<TestImageLowQuality> testImage = adoptRef(new TestImageLowQuality); |
| 306 | 315 |
| 307 // Paint once. This will kick off a timer to see if we resize it during that t
imer's execution. | 316 // Paint once. This will kick off a timer to see if we resize it during that |
| 317 // timer's execution. |
| 308 mockTimer->setTime(0.1); | 318 mockTimer->setTime(0.1); |
| 309 EXPECT_FALSE(controller()->shouldPaintAtLowQuality( | 319 EXPECT_FALSE(controller()->shouldPaintAtLowQuality( |
| 310 *img, testImage.get(), testImage.get(), LayoutSize(2, 2), 0.1)); | 320 *img, testImage.get(), testImage.get(), LayoutSize(2, 2), 0.1)); |
| 311 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, | 321 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, |
| 312 mockTimer->nextFireInterval()); | 322 mockTimer->nextFireInterval()); |
| 313 | 323 |
| 314 // Go into low-quality mode now that the size changed. | 324 // Go into low-quality mode now that the size changed. |
| 315 double nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold / 2.0; | 325 double nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold / 2.0; |
| 316 mockTimer->setTime(nextTime); | 326 mockTimer->setTime(nextTime); |
| 317 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality( | 327 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality( |
| 318 *img, testImage.get(), testImage.get(), LayoutSize(3, 3), | 328 *img, testImage.get(), testImage.get(), LayoutSize(3, 3), |
| 319 nextTime)); | 329 nextTime)); |
| 320 // The fire interval has decreased, because we have not restarted the timer. | 330 // The fire interval has decreased, because we have not restarted the timer. |
| 321 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold - | 331 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold - |
| 322 ImageQualityController::cTimerRestartThreshold / 2.0, | 332 ImageQualityController::cTimerRestartThreshold / 2.0, |
| 323 mockTimer->nextFireInterval()); | 333 mockTimer->nextFireInterval()); |
| 324 | 334 |
| 325 // This animation is far enough in the future to make the timer restart, since
it is half over. | 335 // This animation is far enough in the future to make the timer restart, since |
| 336 // it is half over. |
| 326 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; | 337 nextTime = 0.1 + ImageQualityController::cTimerRestartThreshold + 0.01; |
| 327 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality( | 338 EXPECT_EQ(true, controller()->shouldPaintAtLowQuality( |
| 328 *img, testImage.get(), testImage.get(), LayoutSize(4, 4), | 339 *img, testImage.get(), testImage.get(), LayoutSize(4, 4), |
| 329 nextTime)); | 340 nextTime)); |
| 330 // Now the timer has restarted, leading to a larger fire interval. | 341 // Now the timer has restarted, leading to a larger fire interval. |
| 331 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, | 342 EXPECT_EQ(ImageQualityController::cLowQualityTimeThreshold, |
| 332 mockTimer->nextFireInterval()); | 343 mockTimer->nextFireInterval()); |
| 333 } | 344 } |
| 334 | 345 |
| 335 #endif | 346 #endif |
| 336 | 347 |
| 337 } // namespace blink | 348 } // namespace blink |
| OLD | NEW |