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

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

Powered by Google App Engine
This is Rietveld 408576698