Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: Source/core/platform/graphics/BitmapImage.cpp

Issue 15350006: Decode GIF image frames on demand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebased Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « Source/core/platform/graphics/BitmapImage.h ('k') | Source/core/platform/graphics/GeneratedImage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698