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