| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 : Image(observer), | 73 : Image(observer), |
| 74 current_frame_(0), | 74 current_frame_(0), |
| 75 cached_frame_index_(0), | 75 cached_frame_index_(0), |
| 76 animation_policy_(kImageAnimationPolicyAllowed), | 76 animation_policy_(kImageAnimationPolicyAllowed), |
| 77 animation_finished_(false), | 77 animation_finished_(false), |
| 78 all_data_received_(false), | 78 all_data_received_(false), |
| 79 have_size_(false), | 79 have_size_(false), |
| 80 size_available_(false), | 80 size_available_(false), |
| 81 have_frame_count_(false), | 81 have_frame_count_(false), |
| 82 repetition_count_status_(kUnknown), | 82 repetition_count_status_(kUnknown), |
| 83 repetition_count_(kAnimationNone), | 83 repetition_count_(kCAnimationNone), |
| 84 repetitions_complete_(0), | 84 repetitions_complete_(0), |
| 85 desired_frame_start_time_(0), | 85 desired_frame_start_time_(0), |
| 86 frame_count_(0) {} | 86 frame_count_(0) {} |
| 87 | 87 |
| 88 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) | 88 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| 89 : Image(observer), | 89 : Image(observer), |
| 90 size_(bitmap.width(), bitmap.height()), | 90 size_(bitmap.width(), bitmap.height()), |
| 91 current_frame_(0), | 91 current_frame_(0), |
| 92 cached_frame_(SkImage::MakeFromBitmap(bitmap)), | 92 cached_frame_(SkImage::MakeFromBitmap(bitmap)), |
| 93 cached_frame_index_(0), | 93 cached_frame_index_(0), |
| 94 animation_policy_(kImageAnimationPolicyAllowed), | 94 animation_policy_(kImageAnimationPolicyAllowed), |
| 95 animation_finished_(true), | 95 animation_finished_(true), |
| 96 all_data_received_(true), | 96 all_data_received_(true), |
| 97 have_size_(true), | 97 have_size_(true), |
| 98 size_available_(true), | 98 size_available_(true), |
| 99 have_frame_count_(true), | 99 have_frame_count_(true), |
| 100 repetition_count_status_(kUnknown), | 100 repetition_count_status_(kUnknown), |
| 101 repetition_count_(kAnimationNone), | 101 repetition_count_(kCAnimationNone), |
| 102 repetitions_complete_(0), | 102 repetitions_complete_(0), |
| 103 frame_count_(1) { | 103 frame_count_(1) { |
| 104 // Since we don't have a decoder, we can't figure out the image orientation. | 104 // Since we don't have a decoder, we can't figure out the image orientation. |
| 105 // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. | 105 // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. |
| 106 size_respecting_orientation_ = size_; | 106 size_respecting_orientation_ = size_; |
| 107 | 107 |
| 108 frames_.Grow(1); | 108 frames_.Grow(1); |
| 109 frames_[0].has_alpha_ = !bitmap.isOpaque(); | 109 frames_[0].has_alpha_ = !bitmap.isOpaque(); |
| 110 frames_[0].have_metadata_ = true; | 110 frames_[0].have_metadata_ = true; |
| 111 } | 111 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 // We are caching frame snapshots. This is OK even for partially decoded | 151 // We are caching frame snapshots. This is OK even for partially decoded |
| 152 // frames, as they are cleared by dataChanged() when new data arrives. | 152 // frames, as they are cleared by dataChanged() when new data arrives. |
| 153 sk_sp<SkImage> image = | 153 sk_sp<SkImage> image = |
| 154 source_.CreateFrameAtIndex(index, DefaultColorBehavior()); | 154 source_.CreateFrameAtIndex(index, DefaultColorBehavior()); |
| 155 cached_frame_ = image; | 155 cached_frame_ = image; |
| 156 cached_frame_index_ = index; | 156 cached_frame_index_ = index; |
| 157 | 157 |
| 158 frames_[index].orientation_ = source_.OrientationAtIndex(index); | 158 frames_[index].orientation_ = source_.OrientationAtIndex(index); |
| 159 frames_[index].have_metadata_ = true; | 159 frames_[index].have_metadata_ = true; |
| 160 frames_[index].is_complete_ = source_.FrameIsCompleteAtIndex(index); | 160 frames_[index].is_complete_ = source_.FrameIsCompleteAtIndex(index); |
| 161 if (RepetitionCount(false) != kAnimationNone) | 161 if (RepetitionCount(false) != kCAnimationNone) |
| 162 frames_[index].duration_ = source_.FrameDurationAtIndex(index); | 162 frames_[index].duration_ = source_.FrameDurationAtIndex(index); |
| 163 frames_[index].has_alpha_ = source_.FrameHasAlphaAtIndex(index); | 163 frames_[index].has_alpha_ = source_.FrameHasAlphaAtIndex(index); |
| 164 frames_[index].frame_bytes_ = source_.FrameBytesAtIndex(index); | 164 frames_[index].frame_bytes_ = source_.FrameBytesAtIndex(index); |
| 165 | 165 |
| 166 NotifyMemoryChanged(); | 166 NotifyMemoryChanged(); |
| 167 return image; | 167 return image; |
| 168 } | 168 } |
| 169 | 169 |
| 170 void BitmapImage::UpdateSize() const { | 170 void BitmapImage::UpdateSize() const { |
| 171 if (!size_available_ || have_size_) | 171 if (!size_available_ || have_size_) |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 int BitmapImage::RepetitionCount(bool image_known_to_be_complete) { | 434 int BitmapImage::RepetitionCount(bool image_known_to_be_complete) { |
| 435 if ((repetition_count_status_ == kUnknown) || | 435 if ((repetition_count_status_ == kUnknown) || |
| 436 ((repetition_count_status_ == kUncertain) && | 436 ((repetition_count_status_ == kUncertain) && |
| 437 image_known_to_be_complete)) { | 437 image_known_to_be_complete)) { |
| 438 // Snag the repetition count. If |imageKnownToBeComplete| is false, the | 438 // Snag the repetition count. If |imageKnownToBeComplete| is false, the |
| 439 // repetition count may not be accurate yet for GIFs; in this case the | 439 // repetition count may not be accurate yet for GIFs; in this case the |
| 440 // decoder will default to cAnimationLoopOnce, and we'll try and read | 440 // decoder will default to cAnimationLoopOnce, and we'll try and read |
| 441 // the count again once the whole image is decoded. | 441 // the count again once the whole image is decoded. |
| 442 repetition_count_ = source_.RepetitionCount(); | 442 repetition_count_ = source_.RepetitionCount(); |
| 443 repetition_count_status_ = | 443 repetition_count_status_ = |
| 444 (image_known_to_be_complete || repetition_count_ == kAnimationNone) | 444 (image_known_to_be_complete || repetition_count_ == kCAnimationNone) |
| 445 ? kCertain | 445 ? kCertain |
| 446 : kUncertain; | 446 : kUncertain; |
| 447 } | 447 } |
| 448 return repetition_count_; | 448 return repetition_count_; |
| 449 } | 449 } |
| 450 | 450 |
| 451 bool BitmapImage::ShouldAnimate() { | 451 bool BitmapImage::ShouldAnimate() { |
| 452 bool animated = RepetitionCount(false) != kAnimationNone && | 452 bool animated = RepetitionCount(false) != kCAnimationNone && |
| 453 !animation_finished_ && GetImageObserver(); | 453 !animation_finished_ && GetImageObserver(); |
| 454 if (animated && animation_policy_ == kImageAnimationPolicyNoAnimation) | 454 if (animated && animation_policy_ == kImageAnimationPolicyNoAnimation) |
| 455 animated = false; | 455 animated = false; |
| 456 return animated; | 456 return animated; |
| 457 } | 457 } |
| 458 | 458 |
| 459 void BitmapImage::StartAnimation(CatchUpAnimation catch_up_if_necessary) { | 459 void BitmapImage::StartAnimation(CatchUpAnimation catch_up_if_necessary) { |
| 460 if (frame_timer_ || !ShouldAnimate() || FrameCount() <= 1) | 460 if (frame_timer_ || !ShouldAnimate() || FrameCount() <= 1) |
| 461 return; | 461 return; |
| 462 | 462 |
| 463 // If we aren't already animating, set now as the animation start time. | 463 // If we aren't already animating, set now as the animation start time. |
| 464 const double time = MonotonicallyIncreasingTime(); | 464 const double time = MonotonicallyIncreasingTime(); |
| 465 if (!desired_frame_start_time_) | 465 if (!desired_frame_start_time_) |
| 466 desired_frame_start_time_ = time; | 466 desired_frame_start_time_ = time; |
| 467 | 467 |
| 468 // Don't advance the animation to an incomplete frame. | 468 // Don't advance the animation to an incomplete frame. |
| 469 size_t next_frame = (current_frame_ + 1) % FrameCount(); | 469 size_t next_frame = (current_frame_ + 1) % FrameCount(); |
| 470 if (!all_data_received_ && !FrameIsCompleteAtIndex(next_frame)) | 470 if (!all_data_received_ && !FrameIsCompleteAtIndex(next_frame)) |
| 471 return; | 471 return; |
| 472 | 472 |
| 473 // Don't advance past the last frame if we haven't decoded the whole image | 473 // Don't advance past the last frame if we haven't decoded the whole image |
| 474 // yet and our repetition count is potentially unset. The repetition count | 474 // yet and our repetition count is potentially unset. The repetition count |
| 475 // in a GIF can potentially come after all the rest of the image data, so | 475 // in a GIF can potentially come after all the rest of the image data, so |
| 476 // wait on it. | 476 // wait on it. |
| 477 if (!all_data_received_ && | 477 if (!all_data_received_ && |
| 478 (RepetitionCount(false) == kAnimationLoopOnce || | 478 (RepetitionCount(false) == kCAnimationLoopOnce || |
| 479 animation_policy_ == kImageAnimationPolicyAnimateOnce) && | 479 animation_policy_ == kImageAnimationPolicyAnimateOnce) && |
| 480 current_frame_ >= (FrameCount() - 1)) | 480 current_frame_ >= (FrameCount() - 1)) |
| 481 return; | 481 return; |
| 482 | 482 |
| 483 // Determine time for next frame to start. By ignoring paint and timer lag | 483 // Determine time for next frame to start. By ignoring paint and timer lag |
| 484 // in this calculation, we make the animation appear to run at its desired | 484 // in this calculation, we make the animation appear to run at its desired |
| 485 // rate regardless of how fast it's being repainted. | 485 // rate regardless of how fast it's being repainted. |
| 486 const double current_duration = FrameDurationAtIndex(current_frame_); | 486 const double current_duration = FrameDurationAtIndex(current_frame_); |
| 487 desired_frame_start_time_ += current_duration; | 487 desired_frame_start_time_ += current_duration; |
| 488 | 488 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 animation_finished_ = false; | 561 animation_finished_ = false; |
| 562 cached_frame_.reset(); | 562 cached_frame_.reset(); |
| 563 } | 563 } |
| 564 | 564 |
| 565 bool BitmapImage::MaybeAnimated() { | 565 bool BitmapImage::MaybeAnimated() { |
| 566 if (animation_finished_) | 566 if (animation_finished_) |
| 567 return false; | 567 return false; |
| 568 if (FrameCount() > 1) | 568 if (FrameCount() > 1) |
| 569 return true; | 569 return true; |
| 570 | 570 |
| 571 return source_.RepetitionCount() != kAnimationNone; | 571 return source_.RepetitionCount() != kCAnimationNone; |
| 572 } | 572 } |
| 573 | 573 |
| 574 void BitmapImage::AdvanceTime(double delta_time_in_seconds) { | 574 void BitmapImage::AdvanceTime(double delta_time_in_seconds) { |
| 575 if (desired_frame_start_time_) | 575 if (desired_frame_start_time_) |
| 576 desired_frame_start_time_ -= delta_time_in_seconds; | 576 desired_frame_start_time_ -= delta_time_in_seconds; |
| 577 else | 577 else |
| 578 desired_frame_start_time_ = | 578 desired_frame_start_time_ = |
| 579 MonotonicallyIncreasingTime() - delta_time_in_seconds; | 579 MonotonicallyIncreasingTime() - delta_time_in_seconds; |
| 580 } | 580 } |
| 581 | 581 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 605 if (current_frame_ + 1 < FrameCount()) { | 605 if (current_frame_ + 1 < FrameCount()) { |
| 606 current_frame_++; | 606 current_frame_++; |
| 607 } else { | 607 } else { |
| 608 repetitions_complete_++; | 608 repetitions_complete_++; |
| 609 | 609 |
| 610 // Get the repetition count again. If we weren't able to get a | 610 // Get the repetition count again. If we weren't able to get a |
| 611 // repetition count before, we should have decoded the whole image by | 611 // repetition count before, we should have decoded the whole image by |
| 612 // now, so it should now be available. | 612 // now, so it should now be available. |
| 613 // We don't need to special-case cAnimationLoopOnce here because it is | 613 // We don't need to special-case cAnimationLoopOnce here because it is |
| 614 // 0 (see comments on its declaration in ImageAnimation.h). | 614 // 0 (see comments on its declaration in ImageAnimation.h). |
| 615 if ((RepetitionCount(true) != kAnimationLoopInfinite && | 615 if ((RepetitionCount(true) != kCAnimationLoopInfinite && |
| 616 repetitions_complete_ > repetition_count_) || | 616 repetitions_complete_ > repetition_count_) || |
| 617 animation_policy_ == kImageAnimationPolicyAnimateOnce) { | 617 animation_policy_ == kImageAnimationPolicyAnimateOnce) { |
| 618 animation_finished_ = true; | 618 animation_finished_ = true; |
| 619 desired_frame_start_time_ = 0; | 619 desired_frame_start_time_ = 0; |
| 620 | 620 |
| 621 // We skipped to the last frame and cannot advance further. The | 621 // We skipped to the last frame and cannot advance further. The |
| 622 // observer will not receive animationAdvanced notifications while | 622 // observer will not receive animationAdvanced notifications while |
| 623 // skipping but we still need to notify the observer to draw the | 623 // skipping but we still need to notify the observer to draw the |
| 624 // last frame. Skipping frames occurs while painting so we do not | 624 // last frame. Skipping frames occurs while painting so we do not |
| 625 // synchronously notify the observer which could cause a layout. | 625 // synchronously notify the observer which could cause a layout. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 641 GetImageObserver()->AnimationAdvanced(this); | 641 GetImageObserver()->AnimationAdvanced(this); |
| 642 | 642 |
| 643 return true; | 643 return true; |
| 644 } | 644 } |
| 645 | 645 |
| 646 void BitmapImage::NotifyObserversOfAnimationAdvance(TimerBase*) { | 646 void BitmapImage::NotifyObserversOfAnimationAdvance(TimerBase*) { |
| 647 GetImageObserver()->AnimationAdvanced(this); | 647 GetImageObserver()->AnimationAdvanced(this); |
| 648 } | 648 } |
| 649 | 649 |
| 650 } // namespace blink | 650 } // namespace blink |
| OLD | NEW |