Chromium Code Reviews| 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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 m_frames.grow(numFrames); | 156 m_frames.grow(numFrames); |
| 157 | 157 |
| 158 int deltaBytes = totalFrameBytes(); | 158 int deltaBytes = totalFrameBytes(); |
| 159 | 159 |
| 160 // We are caching frame snapshots. This is OK even for partially decoded fr ames, | 160 // We are caching frame snapshots. This is OK even for partially decoded fr ames, |
| 161 // as they are cleared by dataChanged() when new data arrives. | 161 // as they are cleared by dataChanged() when new data arrives. |
| 162 m_frames[index].m_frame = m_source.createFrameAtIndex(index); | 162 m_frames[index].m_frame = m_source.createFrameAtIndex(index); |
| 163 | 163 |
| 164 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 164 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| 165 m_frames[index].m_haveMetadata = true; | 165 m_frames[index].m_haveMetadata = true; |
| 166 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 166 m_frames[index].m_isComplete = m_source.frameIsFullyReceivedAtIndex(index); |
|
Peter Kasting
2016/05/10 00:00:13
This field should be renamed m_isFullyReceived.
.
aleksandar.stojiljkovic
2016/05/10 21:59:30
The reason I left the name is because of work ongo
| |
| 167 if (repetitionCount(false) != cAnimationNone) | 167 if (repetitionCount(false) != cAnimationNone) |
| 168 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 168 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
| 169 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 169 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 170 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); | 170 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); |
| 171 | 171 |
| 172 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); | 172 const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size); |
| 173 if (frameSize != m_size) | 173 if (frameSize != m_size) |
| 174 m_hasUniformFrameSize = false; | 174 m_hasUniformFrameSize = false; |
| 175 | 175 |
| 176 // We need to check the total bytes before and after the decode call, not | 176 // We need to check the total bytes before and after the decode call, not |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 // With ICOs, on the other hand, we may ask for arbitrary frames at | 222 // With ICOs, on the other hand, we may ask for arbitrary frames at |
| 223 // different times (e.g. because we're displaying a higher-resolution image | 223 // different times (e.g. because we're displaying a higher-resolution image |
| 224 // in the content area and using a lower-resolution one for the favicon), | 224 // in the content area and using a lower-resolution one for the favicon), |
| 225 // and the frames aren't even guaranteed to appear in the file in the same | 225 // and the frames aren't even guaranteed to appear in the file in the same |
| 226 // order as in the directory, so an arbitrary number of the frames might be | 226 // order as in the directory, so an arbitrary number of the frames might be |
| 227 // incomplete (if we ask for frames for which we've not yet reached the | 227 // incomplete (if we ask for frames for which we've not yet reached the |
| 228 // start of the frame data), and any or none of them might be the particular | 228 // start of the frame data), and any or none of them might be the particular |
| 229 // frame affected by appending new data here. Thus we have to clear all the | 229 // frame affected by appending new data here. Thus we have to clear all the |
| 230 // incomplete frames to be safe. | 230 // incomplete frames to be safe. |
| 231 for (size_t i = 0; i < m_frames.size(); ++i) { | 231 for (size_t i = 0; i < m_frames.size(); ++i) { |
| 232 // NOTE: Don't call frameIsCompleteAtIndex() here, that will try to | 232 // NOTE: Don't call frameIsFullyReceivedAtIndex() here, that will try to |
|
scroggo_chromium
2016/05/09 21:54:33
Is this comment true?
Peter Kasting
2016/05/10 00:00:13
I don't think so.
aleksandar.stojiljkovic
2016/05/10 21:59:30
Removed.
Seems that it was once the case and that
| |
| 233 // decode any uncached (i.e. never-decoded or | 233 // decode any uncached (i.e. never-decoded or |
| 234 // cleared-on-a-previous-pass) frames! | 234 // cleared-on-a-previous-pass) frames! |
| 235 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) | 235 if (m_frames[i].m_haveMetadata && !m_frames[i].m_isComplete) |
| 236 m_frames[i].clear(true); | 236 m_frames[i].clear(true); |
| 237 } | 237 } |
| 238 | 238 |
| 239 // Feed all the data we've seen so far to the image decoder. | 239 // Feed all the data we've seen so far to the image decoder. |
| 240 m_allDataReceived = allDataReceived; | 240 m_allDataReceived = allDataReceived; |
| 241 ASSERT(data()); | 241 ASSERT(data()); |
| 242 m_source.setData(*data(), allDataReceived); | 242 m_source.setData(*data(), allDataReceived); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 351 } | 351 } |
| 352 | 352 |
| 353 PassRefPtr<SkImage> BitmapImage::frameAtIndex(size_t index) | 353 PassRefPtr<SkImage> BitmapImage::frameAtIndex(size_t index) |
| 354 { | 354 { |
| 355 if (!ensureFrameIsCached(index)) | 355 if (!ensureFrameIsCached(index)) |
| 356 return nullptr; | 356 return nullptr; |
| 357 | 357 |
| 358 return m_frames[index].m_frame; | 358 return m_frames[index].m_frame; |
| 359 } | 359 } |
| 360 | 360 |
| 361 bool BitmapImage::frameIsCompleteAtIndex(size_t index) | 361 bool BitmapImage::frameIsFullyReceivedAtIndex(size_t index) |
| 362 { | 362 { |
| 363 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in dex].m_isComplete) | 363 if (index < m_frames.size() && m_frames[index].m_haveMetadata && m_frames[in dex].m_isComplete) |
| 364 return true; | 364 return true; |
| 365 | 365 |
| 366 return m_source.frameIsCompleteAtIndex(index); | 366 return m_source.frameIsFullyReceivedAtIndex(index); |
| 367 } | 367 } |
| 368 | 368 |
| 369 float BitmapImage::frameDurationAtIndex(size_t index) | 369 float BitmapImage::frameDurationAtIndex(size_t index) |
| 370 { | 370 { |
| 371 if (index < m_frames.size() && m_frames[index].m_haveMetadata) | 371 if (index < m_frames.size() && m_frames[index].m_haveMetadata) |
| 372 return m_frames[index].m_duration; | 372 return m_frames[index].m_duration; |
| 373 | 373 |
| 374 return m_source.frameDurationAtIndex(index); | 374 return m_source.frameDurationAtIndex(index); |
| 375 } | 375 } |
| 376 | 376 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 404 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) | 404 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) |
| 405 { | 405 { |
| 406 if (metadataMode == PreCacheMetadata) { | 406 if (metadataMode == PreCacheMetadata) { |
| 407 // frameHasAlphaAtIndex() conservatively returns false for uncached fram es. To increase the | 407 // frameHasAlphaAtIndex() conservatively returns false for uncached fram es. To increase the |
| 408 // chance of an accurate answer, pre-cache the current frame metadata. | 408 // chance of an accurate answer, pre-cache the current frame metadata. |
| 409 frameAtIndex(currentFrame()); | 409 frameAtIndex(currentFrame()); |
| 410 } | 410 } |
| 411 return !frameHasAlphaAtIndex(currentFrame()); | 411 return !frameHasAlphaAtIndex(currentFrame()); |
| 412 } | 412 } |
| 413 | 413 |
| 414 bool BitmapImage::currentFrameIsComplete() | 414 bool BitmapImage::currentFrameIsFullyReceived() |
| 415 { | 415 { |
| 416 return frameIsCompleteAtIndex(currentFrame()); | 416 return frameIsFullyReceivedAtIndex(currentFrame()); |
| 417 } | 417 } |
| 418 | 418 |
| 419 bool BitmapImage::currentFrameIsLazyDecoded() | 419 bool BitmapImage::currentFrameIsLazyDecoded() |
| 420 { | 420 { |
| 421 RefPtr<SkImage> image = frameAtIndex(currentFrame()); | 421 RefPtr<SkImage> image = frameAtIndex(currentFrame()); |
| 422 return image && image->isLazyGenerated(); | 422 return image && image->isLazyGenerated(); |
| 423 } | 423 } |
| 424 | 424 |
| 425 ImageOrientation BitmapImage::currentFrameOrientation() | 425 ImageOrientation BitmapImage::currentFrameOrientation() |
| 426 { | 426 { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 464 if (m_frameTimer || !shouldAnimate() || frameCount() <= 1) | 464 if (m_frameTimer || !shouldAnimate() || frameCount() <= 1) |
| 465 return; | 465 return; |
| 466 | 466 |
| 467 // If we aren't already animating, set now as the animation start time. | 467 // If we aren't already animating, set now as the animation start time. |
| 468 const double time = monotonicallyIncreasingTime(); | 468 const double time = monotonicallyIncreasingTime(); |
| 469 if (!m_desiredFrameStartTime) | 469 if (!m_desiredFrameStartTime) |
| 470 m_desiredFrameStartTime = time; | 470 m_desiredFrameStartTime = time; |
| 471 | 471 |
| 472 // Don't advance the animation to an incomplete frame. | 472 // Don't advance the animation to an incomplete frame. |
| 473 size_t nextFrame = (m_currentFrame + 1) % frameCount(); | 473 size_t nextFrame = (m_currentFrame + 1) % frameCount(); |
| 474 if (!m_allDataReceived && !frameIsCompleteAtIndex(nextFrame)) | 474 if (!m_allDataReceived && !frameIsFullyReceivedAtIndex(nextFrame)) |
| 475 return; | 475 return; |
| 476 | 476 |
| 477 // Don't advance past the last frame if we haven't decoded the whole image | 477 // Don't advance past the last frame if we haven't decoded the whole image |
| 478 // yet and our repetition count is potentially unset. The repetition count | 478 // yet and our repetition count is potentially unset. The repetition count |
| 479 // in a GIF can potentially come after all the rest of the image data, so | 479 // in a GIF can potentially come after all the rest of the image data, so |
| 480 // wait on it. | 480 // wait on it. |
| 481 if (!m_allDataReceived | 481 if (!m_allDataReceived |
| 482 && (repetitionCount(false) == cAnimationLoopOnce || m_animationPolicy == ImageAnimationPolicyAnimateOnce) | 482 && (repetitionCount(false) == cAnimationLoopOnce || m_animationPolicy == ImageAnimationPolicyAnimateOnce) |
| 483 && m_currentFrame >= (frameCount() - 1)) | 483 && m_currentFrame >= (frameCount() - 1)) |
| 484 return; | 484 return; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 511 | 511 |
| 512 if (catchUpIfNecessary == DoNotCatchUp || time < m_desiredFrameStartTime) { | 512 if (catchUpIfNecessary == DoNotCatchUp || time < m_desiredFrameStartTime) { |
| 513 // Haven't yet reached time for next frame to start; delay until then. | 513 // Haven't yet reached time for next frame to start; delay until then. |
| 514 m_frameTimer = adoptPtr(new Timer<BitmapImage>(this, &BitmapImage::advan ceAnimation)); | 514 m_frameTimer = adoptPtr(new Timer<BitmapImage>(this, &BitmapImage::advan ceAnimation)); |
| 515 m_frameTimer->startOneShot(std::max(m_desiredFrameStartTime - time, 0.), BLINK_FROM_HERE); | 515 m_frameTimer->startOneShot(std::max(m_desiredFrameStartTime - time, 0.), BLINK_FROM_HERE); |
| 516 } else { | 516 } else { |
| 517 // We've already reached or passed the time for the next frame to start. | 517 // We've already reached or passed the time for the next frame to start. |
| 518 // See if we've also passed the time for frames after that to start, in | 518 // See if we've also passed the time for frames after that to start, in |
| 519 // case we need to skip some frames entirely. Remember not to advance | 519 // case we need to skip some frames entirely. Remember not to advance |
| 520 // to an incomplete frame. | 520 // to an incomplete frame. |
| 521 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsComp leteAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount()) { | 521 for (size_t frameAfterNext = (nextFrame + 1) % frameCount(); frameIsFull yReceivedAtIndex(frameAfterNext); frameAfterNext = (nextFrame + 1) % frameCount( )) { |
| 522 // Should we skip the next frame? | 522 // Should we skip the next frame? |
| 523 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDura tionAtIndex(nextFrame); | 523 double frameAfterNextStartTime = m_desiredFrameStartTime + frameDura tionAtIndex(nextFrame); |
| 524 if (time < frameAfterNextStartTime) | 524 if (time < frameAfterNextStartTime) |
| 525 break; | 525 break; |
| 526 | 526 |
| 527 // Yes; skip over it without notifying our observers. | 527 // Yes; skip over it without notifying our observers. |
| 528 if (!internalAdvanceAnimation(true)) | 528 if (!internalAdvanceAnimation(true)) |
| 529 return; | 529 return; |
| 530 m_desiredFrameStartTime = frameAfterNextStartTime; | 530 m_desiredFrameStartTime = frameAfterNextStartTime; |
| 531 nextFrame = frameAfterNext; | 531 nextFrame = frameAfterNext; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 634 destroyDecodedDataIfNecessary(); | 634 destroyDecodedDataIfNecessary(); |
| 635 | 635 |
| 636 // We need to draw this frame if we advanced to it while not skipping, or if | 636 // 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. | 637 // while trying to skip frames we hit the last frame and thus had to stop. |
| 638 if (skippingFrames != advancedAnimation) | 638 if (skippingFrames != advancedAnimation) |
| 639 getImageObserver()->animationAdvanced(this); | 639 getImageObserver()->animationAdvanced(this); |
| 640 return advancedAnimation; | 640 return advancedAnimation; |
| 641 } | 641 } |
| 642 | 642 |
| 643 } // namespace blink | 643 } // namespace blink |
| OLD | NEW |