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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 { | 105 { |
106 return true; | 106 return true; |
107 } | 107 } |
108 | 108 |
109 bool BitmapImage::hasSingleSecurityOrigin() const | 109 bool BitmapImage::hasSingleSecurityOrigin() const |
110 { | 110 { |
111 return true; | 111 return true; |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 void BitmapImage::destroyDecodedData(bool destroyAll) | 115 void BitmapImage::destroyDecodedData() |
116 { | 116 { |
117 unsigned frameBytesCleared = 0; | 117 for (size_t i = 0; i < m_frames.size(); ++i) { |
118 const size_t clearBeforeFrame = destroyAll ? m_frames.size() : m_currentFram
e; | |
119 | |
120 // Because we can advance frames without always needing to decode the actual | |
121 // bitmap data, |m_currentFrame| may be larger than m_frames.size(); | |
122 // make sure not to walk off the end of the container in this case. | |
123 for (size_t i = 0; i < std::min(clearBeforeFrame, m_frames.size()); ++i) { | |
124 // The underlying frame isn't actually changing (we're just trying to | 118 // The underlying frame isn't actually changing (we're just trying to |
125 // save the memory for the framebuffer data), so we don't need to clear | 119 // save the memory for the framebuffer data), so we don't need to clear |
126 // the metadata. | 120 // the metadata. |
127 unsigned frameBytes = m_frames[i].m_frameBytes; | 121 m_frames[i].clear(false); |
128 if (m_frames[i].clear(false)) | |
129 frameBytesCleared += frameBytes; | |
130 } | 122 } |
131 | 123 |
132 destroyMetadataAndNotify(frameBytesCleared); | 124 destroyMetadataAndNotify(m_source.clearCacheExceptFrame(m_currentFrame)); |
133 | |
134 m_source.clear(destroyAll, clearBeforeFrame, data(), m_allDataReceived); | |
135 return; | |
136 } | 125 } |
137 | 126 |
138 void BitmapImage::destroyDecodedDataIfNecessary(bool destroyAll) | 127 void BitmapImage::destroyDecodedDataIfNecessary() |
139 { | 128 { |
140 // Animated images >5MB are considered large enough that we'll only hang on | 129 // Animated images >5MB are considered large enough that we'll only hang on |
141 // to one frame at a time. | 130 // to one frame at a time. |
142 static const unsigned cLargeAnimationCutoff = 5242880; | 131 static const size_t cLargeAnimationCutoff = 5242880; |
143 unsigned allFrameBytes = 0; | 132 size_t allFrameBytes = 0; |
144 for (size_t i = 0; i < m_frames.size(); ++i) | 133 for (size_t i = 0; i < m_frames.size(); ++i) |
145 allFrameBytes += m_frames[i].m_frameBytes; | 134 allFrameBytes += m_frames[i].m_frameBytes; |
146 | 135 |
147 if (allFrameBytes > cLargeAnimationCutoff) | 136 if (allFrameBytes > cLargeAnimationCutoff) |
148 destroyDecodedData(destroyAll); | 137 destroyDecodedData(); |
149 } | 138 } |
150 | 139 |
151 void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared) | 140 void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared) |
152 { | 141 { |
153 m_isSolidColor = false; | 142 m_isSolidColor = false; |
154 m_checkedForSolidColor = false; | 143 m_checkedForSolidColor = false; |
155 | 144 |
156 ASSERT(m_decodedSize >= frameBytesCleared); | 145 ASSERT(m_decodedSize >= frameBytesCleared); |
157 m_decodedSize -= frameBytesCleared; | 146 m_decodedSize -= frameBytesCleared; |
158 if (frameBytesCleared > 0) { | 147 if (frameBytesCleared > 0) { |
159 frameBytesCleared += m_decodedPropertiesSize; | 148 frameBytesCleared += m_decodedPropertiesSize; |
160 m_decodedPropertiesSize = 0; | 149 m_decodedPropertiesSize = 0; |
161 } | 150 } |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 | 564 |
576 void BitmapImage::resetAnimation() | 565 void BitmapImage::resetAnimation() |
577 { | 566 { |
578 stopAnimation(); | 567 stopAnimation(); |
579 m_currentFrame = 0; | 568 m_currentFrame = 0; |
580 m_repetitionsComplete = 0; | 569 m_repetitionsComplete = 0; |
581 m_desiredFrameStartTime = 0; | 570 m_desiredFrameStartTime = 0; |
582 m_animationFinished = false; | 571 m_animationFinished = false; |
583 | 572 |
584 // For extremely large animations, when the animation is reset, we just thro
w everything away. | 573 // For extremely large animations, when the animation is reset, we just thro
w everything away. |
585 destroyDecodedDataIfNecessary(true); | 574 destroyDecodedDataIfNecessary(); |
586 } | 575 } |
587 | 576 |
588 unsigned BitmapImage::decodedSize() const | 577 unsigned BitmapImage::decodedSize() const |
589 { | 578 { |
590 return m_decodedSize; | 579 return m_decodedSize; |
591 } | 580 } |
592 | 581 |
593 | 582 |
594 | 583 |
595 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) | 584 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) |
596 { | 585 { |
597 internalAdvanceAnimation(false); | 586 internalAdvanceAnimation(false); |
598 // At this point the image region has been marked dirty, and if it's | 587 // At this point the image region has been marked dirty, and if it's |
599 // onscreen, we'll soon make a call to draw(), which will call | 588 // onscreen, we'll soon make a call to draw(), which will call |
600 // startAnimation() again to keep the animation moving. | 589 // startAnimation() again to keep the animation moving. |
601 } | 590 } |
602 | 591 |
603 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) | 592 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) |
604 { | 593 { |
605 // Stop the animation. | 594 // Stop the animation. |
606 stopAnimation(); | 595 stopAnimation(); |
607 | 596 |
608 // See if anyone is still paying attention to this animation. If not, we do
n't | 597 // See if anyone is still paying attention to this animation. If not, we do
n't |
609 // advance and will remain suspended at the current frame until the animatio
n is resumed. | 598 // advance and will remain suspended at the current frame until the animatio
n is resumed. |
610 if (!skippingFrames && imageObserver()->shouldPauseAnimation(this)) | 599 if (!skippingFrames && imageObserver()->shouldPauseAnimation(this)) |
611 return false; | 600 return false; |
612 | 601 |
613 ++m_currentFrame; | 602 ++m_currentFrame; |
614 bool advancedAnimation = true; | 603 bool advancedAnimation = true; |
615 bool destroyAll = false; | |
616 if (m_currentFrame >= frameCount()) { | 604 if (m_currentFrame >= frameCount()) { |
617 ++m_repetitionsComplete; | 605 ++m_repetitionsComplete; |
618 | 606 |
619 // Get the repetition count again. If we weren't able to get a | 607 // Get the repetition count again. If we weren't able to get a |
620 // repetition count before, we should have decoded the whole image by | 608 // repetition count before, we should have decoded the whole image by |
621 // now, so it should now be available. | 609 // now, so it should now be available. |
622 // Note that we don't need to special-case cAnimationLoopOnce here | 610 // Note that we don't need to special-case cAnimationLoopOnce here |
623 // because it is 0 (see comments on its declaration in ImageSource.h). | 611 // because it is 0 (see comments on its declaration in ImageSource.h). |
624 if (repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsComp
lete > m_repetitionCount) { | 612 if (repetitionCount(true) != cAnimationLoopInfinite && m_repetitionsComp
lete > m_repetitionCount) { |
625 m_animationFinished = true; | 613 m_animationFinished = true; |
626 m_desiredFrameStartTime = 0; | 614 m_desiredFrameStartTime = 0; |
627 --m_currentFrame; | 615 --m_currentFrame; |
628 advancedAnimation = false; | 616 advancedAnimation = false; |
629 } else { | 617 } else |
630 m_currentFrame = 0; | 618 m_currentFrame = 0; |
631 destroyAll = true; | |
632 } | |
633 } | 619 } |
634 destroyDecodedDataIfNecessary(destroyAll); | 620 destroyDecodedDataIfNecessary(); |
635 | 621 |
636 // We need to draw this frame if we advanced to it while not skipping, or if | 622 // We need to draw this frame if we advanced to it while not skipping, or if |
637 // while trying to skip frames we hit the last frame and thus had to stop. | 623 // while trying to skip frames we hit the last frame and thus had to stop. |
638 if (skippingFrames != advancedAnimation) | 624 if (skippingFrames != advancedAnimation) |
639 imageObserver()->animationAdvanced(this); | 625 imageObserver()->animationAdvanced(this); |
640 return advancedAnimation; | 626 return advancedAnimation; |
641 } | 627 } |
642 | 628 |
643 void BitmapImage::checkForSolidColor() | 629 void BitmapImage::checkForSolidColor() |
644 { | 630 { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 } | 671 } |
686 | 672 |
687 void FrameData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const | 673 void FrameData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const |
688 { | 674 { |
689 MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Image); | 675 MemoryClassInfo info(memoryObjectInfo, this, PlatformMemoryTypes::Image); |
690 memoryObjectInfo->setClassName("FrameData"); | 676 memoryObjectInfo->setClassName("FrameData"); |
691 info.addMember(m_frame, "frame", WTF::RetainingPointer); | 677 info.addMember(m_frame, "frame", WTF::RetainingPointer); |
692 } | 678 } |
693 | 679 |
694 } | 680 } |
OLD | NEW |