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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 bool BitmapImage::hasSingleSecurityOrigin() const | 78 bool BitmapImage::hasSingleSecurityOrigin() const |
79 { | 79 { |
80 return true; | 80 return true; |
81 } | 81 } |
82 | 82 |
83 | 83 |
84 void BitmapImage::destroyDecodedData(bool destroyAll) | 84 void BitmapImage::destroyDecodedData(bool destroyAll) |
85 { | 85 { |
86 unsigned frameBytesCleared = 0; | 86 unsigned frameBytesCleared = 0; |
87 const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFram
e; | 87 for (size_t i = 0; i < m_frames.size(); ++i) { |
| 88 if (!destroyAll && i == m_currentFrame) |
| 89 continue; |
88 | 90 |
89 // Because we can advance frames without always needing to decode the actual | |
90 // bitmap data, |m_currentFrame| may be larger than m_frames.size(); | |
91 // make sure not to walk off the end of the container in this case. | |
92 for (size_t i = 0; i < std::min(clearBeforeFrame, m_frames.size()); ++i) { | |
93 // The underlying frame isn't actually changing (we're just trying to | 91 // The underlying frame isn't actually changing (we're just trying to |
94 // save the memory for the framebuffer data), so we don't need to clear | 92 // save the memory for the framebuffer data), so we don't need to clear |
95 // the metadata. | 93 // the metadata. |
96 unsigned frameBytes = m_frames[i].m_frameBytes; | 94 unsigned frameBytes = m_frames[i].m_frameBytes; |
97 if (m_frames[i].clear(false)) | 95 if (m_frames[i].clear(false)) |
98 frameBytesCleared += frameBytes; | 96 frameBytesCleared += frameBytes; |
99 } | 97 } |
100 | 98 |
101 destroyMetadataAndNotify(frameBytesCleared); | 99 destroyMetadataAndNotify(frameBytesCleared); |
102 | 100 |
103 m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived); | 101 m_source.clear(destroyAll, m_currentFrame, data(), m_allDataReceived); |
104 return; | 102 return; |
105 } | 103 } |
106 | 104 |
107 void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) | 105 void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) |
108 { | 106 { |
109 // Animated images >5MB are considered large enough that we'll only hang on | 107 // Animated images >5MB are considered large enough that we'll only hang on |
110 // to one frame at a time. | 108 // to one frame at a time. |
111 static const unsigned cLargeAnimationCutoff = 5242880; | 109 static const unsigned cLargeAnimationCutoff = 5242880; |
112 unsigned allFrameBytes = 0; | 110 unsigned allFrameBytes = 0; |
113 for (size_t i = 0; i < m_frames.size(); ++i) | 111 for (size_t i = 0; i < m_frames.size(); ++i) |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 // Stop the animation. | 523 // Stop the animation. |
526 stopAnimation(); | 524 stopAnimation(); |
527 | 525 |
528 // See if anyone is still paying attention to this animation. If not, we do
n't | 526 // See if anyone is still paying attention to this animation. If not, we do
n't |
529 // advance and will remain suspended at the current frame until the animatio
n is resumed. | 527 // advance and will remain suspended at the current frame until the animatio
n is resumed. |
530 if (!skippingFrames && imageObserver()->shouldPauseAnimation(this)) | 528 if (!skippingFrames && imageObserver()->shouldPauseAnimation(this)) |
531 return false; | 529 return false; |
532 | 530 |
533 ++m_currentFrame; | 531 ++m_currentFrame; |
534 bool advancedAnimation = true; | 532 bool advancedAnimation = true; |
535 bool destroyAll = false; | |
536 if (m_currentFrame >= frameCount()) { | 533 if (m_currentFrame >= frameCount()) { |
537 ++m_repetitionsComplete; | 534 ++m_repetitionsComplete; |
538 | 535 |
539 // Get the repetition count again. If we weren't able to get a | 536 // Get the repetition count again. If we weren't able to get a |
540 // repetition count before, we should have decoded the whole image by | 537 // repetition count before, we should have decoded the whole image by |
541 // now, so it should now be available. | 538 // now, so it should now be available. |
542 // Note that we don't need to special-case cAnimationLoopOnce here | 539 // Note that we don't need to special-case cAnimationLoopOnce here |
543 // because it is 0 (see comments on its declaration in ImageSource.h). | 540 // because it is 0 (see comments on its declaration in ImageSource.h). |
544 if (repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsComp
lete > m_repetitionCount) { | 541 if (repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsComp
lete > m_repetitionCount) { |
545 m_animationFinished = true; | 542 m_animationFinished = true; |
546 m_desiredFrameStartTime = 0; | 543 m_desiredFrameStartTime = 0; |
547 --m_currentFrame; | 544 --m_currentFrame; |
548 advancedAnimation = false; | 545 advancedAnimation = false; |
549 } else { | 546 } else |
550 m_currentFrame = 0; | 547 m_currentFrame = 0; |
551 destroyAll = true; | |
552 } | |
553 } | 548 } |
554 destroyDecodedDataIfNecessary(destroyAll); | 549 destroyDecodedDataIfNecessary(false); |
555 | 550 |
556 // We need to draw this frame if we advanced to it while not skipping, or if | 551 // We need to draw this frame if we advanced to it while not skipping, or if |
557 // while trying to skip frames we hit the last frame and thus had to stop. | 552 // while trying to skip frames we hit the last frame and thus had to stop. |
558 if (skippingFrames != advancedAnimation) | 553 if (skippingFrames != advancedAnimation) |
559 imageObserver()->animationAdvanced(this); | 554 imageObserver()->animationAdvanced(this); |
560 return advancedAnimation; | 555 return advancedAnimation; |
561 } | 556 } |
562 | 557 |
563 bool BitmapImage::mayFillWithSolidColor() | 558 bool BitmapImage::mayFillWithSolidColor() |
564 { | 559 { |
(...skipping 20 matching lines...) Expand all Loading... |
585 } | 580 } |
586 | 581 |
587 void FrameData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | 582 void FrameData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
588 { | 583 { |
589 MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Image); | 584 MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Image); |
590 memoryObjectInfo->setClassName("FrameData"); | 585 memoryObjectInfo->setClassName("FrameData"); |
591 info.addMember(m_frame, "frame", WTF::RetainingPointer); | 586 info.addMember(m_frame, "frame", WTF::RetainingPointer); |
592 } | 587 } |
593 | 588 |
594 } | 589 } |
OLD | NEW |