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 |