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

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, 7 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 493
496 void BitmapImage::resetAnimation() 494 void BitmapImage::resetAnimation()
497 { 495 {
498 stopAnimation(); 496 stopAnimation();
499 m_currentFrame = 0; 497 m_currentFrame = 0;
500 m_repetitionsComplete = 0; 498 m_repetitionsComplete = 0;
501 m_desiredFrameStartTime = 0; 499 m_desiredFrameStartTime = 0;
502 m_animationFinished = false; 500 m_animationFinished = false;
503 501
504 // For extremely large animations, when the animation is reset, we just thro w everything away. 502 // For extremely large animations, when the animation is reset, we just thro w everything away.
505 destroyDecodedDataIfNecessary(true); 503 destroyDecodedDataIfNecessary(true);
Peter Kasting 2013/05/24 03:15:22 Since we're resetting m_currentFrame to 0 here, an
Xianzhu 2013/05/28 22:54:21 Done.
506 } 504 }
507 505
508 unsigned BitmapImage::decodedSize() const 506 unsigned BitmapImage::decodedSize() const
509 { 507 {
510 return m_decodedSize; 508 return m_decodedSize;
511 } 509 }
512 510
513 511
514 512
515 void BitmapImage::advanceAnimation(Timer<BitmapImage>*) 513 void BitmapImage::advanceAnimation(Timer<BitmapImage>*)
516 { 514 {
517 internalAdvanceAnimation(false); 515 internalAdvanceAnimation(false);
518 // At this point the image region has been marked dirty, and if it's 516 // At this point the image region has been marked dirty, and if it's
519 // onscreen, we'll soon make a call to draw(), which will call 517 // onscreen, we'll soon make a call to draw(), which will call
520 // startAnimation() again to keep the animation moving. 518 // startAnimation() again to keep the animation moving.
521 } 519 }
522 520
523 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) 521 bool BitmapImage::internalAdvanceAnimation(bool skippingFrames)
524 { 522 {
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698