Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 2 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. | 3 * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 if (time < frameAfterNextStartTime) | 492 if (time < frameAfterNextStartTime) |
| 493 break; | 493 break; |
| 494 | 494 |
| 495 // Yes; skip over it without notifying our observers. | 495 // Yes; skip over it without notifying our observers. |
| 496 if (!internalAdvanceAnimation(true)) | 496 if (!internalAdvanceAnimation(true)) |
| 497 return; | 497 return; |
| 498 m_desiredFrameStartTime = frameAfterNextStartTime; | 498 m_desiredFrameStartTime = frameAfterNextStartTime; |
| 499 nextFrame = frameAfterNext; | 499 nextFrame = frameAfterNext; |
| 500 } | 500 } |
| 501 | 501 |
| 502 // Draw the next frame immediately. Note that m_desiredFrameStartTime | 502 // Post a task to advance the frame immediately. m_desiredFrameStartTime |
| 503 // may be in the past, meaning the next time through this function we'll | 503 // may be in the past, meaning the next time through this function we'll |
| 504 // kick off the next advancement sooner than this frame's duration would | 504 // kick off the next advancement sooner than this frame's duration would |
| 505 // suggest. | 505 // suggest. |
| 506 if (internalAdvanceAnimation(false)) { | 506 m_frameTimer = adoptPtr(new Timer<BitmapImage>(this, &BitmapImage::advan ceAnimationWithoutCatchUp)); |
|
chrishtr
2016/06/04 06:39:49
It seems it might be possible for startAnimation()
pdr.
2016/06/04 15:05:34
It's safe because startAnimation bails out if ther
| |
| 507 // The image region has been marked dirty, but once we return to our | 507 m_frameTimer->startOneShot(0, BLINK_FROM_HERE); |
| 508 // caller, draw() will clear it, and nothing will cause the | |
| 509 // animation to advance again. We need to start the timer for the | |
| 510 // next frame running, or the animation can hang. (Compare this | |
| 511 // with when advanceAnimation() is called, and the region is dirtied | |
| 512 // while draw() is not in the callstack, meaning draw() gets called | |
| 513 // to update the region and thus startAnimation() is reached again.) | |
| 514 // NOTE: For large images with slow or heavily-loaded systems, | |
| 515 // throwing away data as we go (see destroyDecodedData()) means we | |
| 516 // can spend so much time re-decoding data above that by the time we | |
| 517 // reach here we're behind again. If we let startAnimation() run | |
| 518 // the catch-up code again, we can get long delays without painting | |
| 519 // as we race the timer, or even infinite recursion. In this | |
| 520 // situation the best we can do is to simply change frames as fast | |
| 521 // as possible, so force startAnimation() to set a zero-delay timer | |
| 522 // and bail out if we're not caught up. | |
| 523 startAnimation(DoNotCatchUp); | |
| 524 } | |
| 525 } | 508 } |
| 526 } | 509 } |
| 527 | 510 |
| 528 void BitmapImage::stopAnimation() | 511 void BitmapImage::stopAnimation() |
| 529 { | 512 { |
| 530 // This timer is used to animate all occurrences of this image. Don't inval idate | 513 // This timer is used to animate all occurrences of this image. Don't inval idate |
| 531 // the timer unless all renderers have stopped drawing. | 514 // the timer unless all renderers have stopped drawing. |
| 532 m_frameTimer.reset(); | 515 m_frameTimer.reset(); |
| 533 } | 516 } |
| 534 | 517 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 561 } | 544 } |
| 562 | 545 |
| 563 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) | 546 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) |
| 564 { | 547 { |
| 565 internalAdvanceAnimation(false); | 548 internalAdvanceAnimation(false); |
| 566 // At this point the image region has been marked dirty, and if it's | 549 // At this point the image region has been marked dirty, and if it's |
| 567 // onscreen, we'll soon make a call to draw(), which will call | 550 // onscreen, we'll soon make a call to draw(), which will call |
| 568 // startAnimation() again to keep the animation moving. | 551 // startAnimation() again to keep the animation moving. |
| 569 } | 552 } |
| 570 | 553 |
| 554 void BitmapImage::advanceAnimationWithoutCatchUp(Timer<BitmapImage>*) | |
| 555 { | |
| 556 if (internalAdvanceAnimation(false)) | |
| 557 startAnimation(DoNotCatchUp); | |
| 558 } | |
| 559 | |
| 571 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) | 560 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) |
| 572 { | 561 { |
| 573 // Stop the animation. | 562 // Stop the animation. |
| 574 stopAnimation(); | 563 stopAnimation(); |
| 575 | 564 |
| 576 // See if anyone is still paying attention to this animation. If not, we do n't | 565 // See if anyone is still paying attention to this animation. If not, we do n't |
| 577 // advance and will remain suspended at the current frame until the animatio n is resumed. | 566 // advance and will remain suspended at the current frame until the animatio n is resumed. |
| 578 if (!skippingFrames && getImageObserver()->shouldPauseAnimation(this)) | 567 if (!skippingFrames && getImageObserver()->shouldPauseAnimation(this)) |
| 579 return false; | 568 return false; |
| 580 | 569 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 600 | 589 |
| 601 // We need to draw this frame if we advanced to it while not skipping, or if | 590 // We need to draw this frame if we advanced to it while not skipping, or if |
| 602 // while trying to skip frames we hit the last frame and thus had to stop. | 591 // while trying to skip frames we hit the last frame and thus had to stop. |
| 603 if (skippingFrames != advancedAnimation) | 592 if (skippingFrames != advancedAnimation) |
| 604 getImageObserver()->animationAdvanced(this); | 593 getImageObserver()->animationAdvanced(this); |
| 605 | 594 |
| 606 return advancedAnimation; | 595 return advancedAnimation; |
| 607 } | 596 } |
| 608 | 597 |
| 609 } // namespace blink | 598 } // namespace blink |
| OLD | NEW |