| 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 13 matching lines...) Expand all Loading... |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #include "platform/graphics/BitmapImage.h" | 27 #include "platform/graphics/BitmapImage.h" |
| 28 | 28 |
| 29 #include "platform/PlatformInstrumentation.h" | 29 #include "platform/PlatformInstrumentation.h" |
| 30 #include "platform/Timer.h" | 30 #include "platform/Timer.h" |
| 31 #include "platform/TraceEvent.h" | 31 #include "platform/TraceEvent.h" |
| 32 #include "platform/geometry/FloatRect.h" | 32 #include "platform/geometry/FloatRect.h" |
| 33 #include "platform/graphics/BitmapImageMetrics.h" | 33 #include "platform/graphics/BitmapImageMetrics.h" |
| 34 #include "platform/graphics/ColorSpaceFilter.h" |
| 35 #include "platform/graphics/ColorSpaceProfile.h" |
| 34 #include "platform/graphics/DeferredImageDecoder.h" | 36 #include "platform/graphics/DeferredImageDecoder.h" |
| 37 #include "platform/graphics/GraphicsContext.h" |
| 38 #include "platform/graphics/GraphicsScreen.h" |
| 39 #include "platform/graphics/ImageBuffer.h" |
| 35 #include "platform/graphics/ImageObserver.h" | 40 #include "platform/graphics/ImageObserver.h" |
| 36 #include "platform/graphics/StaticBitmapImage.h" | 41 #include "platform/graphics/StaticBitmapImage.h" |
| 37 #include "platform/graphics/skia/SkiaUtils.h" | 42 #include "platform/graphics/skia/SkiaUtils.h" |
| 38 #include "third_party/skia/include/core/SkCanvas.h" | 43 #include "third_party/skia/include/core/SkCanvas.h" |
| 44 #include "third_party/skia/include/core/SkColorFilter.h" |
| 45 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" |
| 39 #include "wtf/PassRefPtr.h" | 46 #include "wtf/PassRefPtr.h" |
| 47 #include "wtf/RefPtr.h" |
| 40 #include "wtf/text/WTFString.h" | 48 #include "wtf/text/WTFString.h" |
| 41 | 49 |
| 42 namespace blink { | 50 namespace blink { |
| 43 | 51 |
| 44 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting(const SkBit
map& bitmap, ImageOrientation orientation) | 52 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting(const SkBit
map& bitmap, ImageOrientation orientation) |
| 45 { | 53 { |
| 46 if (bitmap.isNull()) { | 54 if (bitmap.isNull()) |
| 47 return BitmapImage::create(); | 55 return BitmapImage::create(); |
| 48 } | |
| 49 | 56 |
| 50 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); | 57 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); |
| 51 result->m_frames[0].m_orientation = orientation; | 58 result->m_frames[0].m_orientation = orientation; |
| 52 if (orientation.usesWidthAsHeight()) | 59 if (orientation.usesWidthAsHeight()) |
| 53 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); | 60 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); |
| 54 return result.release(); | 61 return result.release(); |
| 55 } | 62 } |
| 56 | 63 |
| 57 BitmapImage::BitmapImage(ImageObserver* observer) | 64 BitmapImage::BitmapImage(ImageObserver* observer) |
| 58 : Image(observer) | 65 : Image(observer) |
| 59 , m_currentFrame(0) | 66 , m_currentFrame(0) |
| 60 , m_repetitionCount(cAnimationNone) | 67 , m_repetitionCount(cAnimationNone) |
| 61 , m_repetitionCountStatus(Unknown) | 68 , m_repetitionCountStatus(Unknown) |
| 62 , m_repetitionsComplete(0) | 69 , m_repetitionsComplete(0) |
| 63 , m_desiredFrameStartTime(0) | 70 , m_desiredFrameStartTime(0) |
| 64 , m_frameCount(0) | 71 , m_frameCount(0) |
| 65 , m_animationPolicy(ImageAnimationPolicyAllowed) | 72 , m_animationPolicy(ImageAnimationPolicyAllowed) |
| 66 , m_animationFinished(false) | 73 , m_animationFinished(false) |
| 67 , m_allDataReceived(false) | 74 , m_allDataReceived(false) |
| 68 , m_haveSize(false) | 75 , m_haveSize(false) |
| 69 , m_sizeAvailable(false) | 76 , m_sizeAvailable(false) |
| 70 , m_hasUniformFrameSize(true) | 77 , m_hasUniformFrameSize(true) |
| 71 , m_haveFrameCount(false) | 78 , m_haveFrameCount(false) |
| 79 , m_drawingToCanvasElement(false) |
| 72 { | 80 { |
| 73 } | 81 } |
| 74 | 82 |
| 75 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) | 83 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| 76 : Image(observer) | 84 : Image(observer) |
| 77 , m_size(bitmap.width(), bitmap.height()) | 85 , m_size(bitmap.width(), bitmap.height()) |
| 78 , m_currentFrame(0) | 86 , m_currentFrame(0) |
| 79 , m_repetitionCount(cAnimationNone) | 87 , m_repetitionCount(cAnimationNone) |
| 80 , m_repetitionCountStatus(Unknown) | 88 , m_repetitionCountStatus(Unknown) |
| 81 , m_repetitionsComplete(0) | 89 , m_repetitionsComplete(0) |
| 82 , m_frameCount(1) | 90 , m_frameCount(1) |
| 83 , m_animationPolicy(ImageAnimationPolicyAllowed) | 91 , m_animationPolicy(ImageAnimationPolicyAllowed) |
| 84 , m_animationFinished(true) | 92 , m_animationFinished(true) |
| 85 , m_allDataReceived(true) | 93 , m_allDataReceived(true) |
| 86 , m_haveSize(true) | 94 , m_haveSize(true) |
| 87 , m_sizeAvailable(true) | 95 , m_sizeAvailable(true) |
| 88 , m_haveFrameCount(true) | 96 , m_haveFrameCount(true) |
| 97 , m_drawingToCanvasElement(false) |
| 89 { | 98 { |
| 90 // Since we don't have a decoder, we can't figure out the image orientation. | 99 // Since we don't have a decoder, we can't figure out the image orientation. |
| 91 // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. | 100 // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. |
| 92 m_sizeRespectingOrientation = m_size; | 101 m_sizeRespectingOrientation = m_size; |
| 93 | 102 |
| 94 m_frames.grow(1); | 103 m_frames.grow(1); |
| 95 m_frames[0].m_hasAlpha = !bitmap.isOpaque(); | 104 m_frames[0].m_hasAlpha = !bitmap.isOpaque(); |
| 96 m_frames[0].m_frame = adoptRef(SkImage::NewFromBitmap(bitmap)); | 105 m_frames[0].m_frame = adoptRef(SkImage::NewFromBitmap(bitmap)); |
| 97 m_frames[0].m_haveMetadata = true; | 106 m_frames[0].m_haveMetadata = true; |
| 98 } | 107 } |
| 99 | 108 |
| 100 BitmapImage::~BitmapImage() | 109 BitmapImage::~BitmapImage() |
| 101 { | 110 { |
| 102 stopAnimation(); | 111 stopAnimation(); |
| 103 } | 112 } |
| 104 | 113 |
| 105 bool BitmapImage::isBitmapImage() const | |
| 106 { | |
| 107 return true; | |
| 108 } | |
| 109 | |
| 110 bool BitmapImage::currentFrameHasSingleSecurityOrigin() const | |
| 111 { | |
| 112 return true; | |
| 113 } | |
| 114 | |
| 115 int BitmapImage::totalFrameBytes() | 114 int BitmapImage::totalFrameBytes() |
| 116 { | 115 { |
| 117 const size_t numFrames = frameCount(); | 116 const size_t numFrames = frameCount(); |
| 118 size_t totalBytes = 0; | 117 size_t totalBytes = 0; |
| 119 for (size_t i = 0; i < numFrames; ++i) | 118 for (size_t i = 0; i < numFrames; ++i) |
| 120 totalBytes += m_source.frameBytesAtIndex(i); | 119 totalBytes += m_source.frameBytesAtIndex(i); |
| 121 return safeCast<int>(totalBytes); | 120 return safeCast<int>(totalBytes); |
| 122 } | 121 } |
| 123 | 122 |
| 124 void BitmapImage::destroyDecodedData(bool destroyAll) | 123 void BitmapImage::destroyDecodedData(bool destroyAll) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 135 | 134 |
| 136 void BitmapImage::destroyDecodedDataIfNecessary() | 135 void BitmapImage::destroyDecodedDataIfNecessary() |
| 137 { | 136 { |
| 138 // Animated images >5MB are considered large enough that we'll only hang on | 137 // Animated images >5MB are considered large enough that we'll only hang on |
| 139 // to one frame at a time. | 138 // to one frame at a time. |
| 140 static const size_t cLargeAnimationCutoff = 5242880; | 139 static const size_t cLargeAnimationCutoff = 5242880; |
| 141 size_t allFrameBytes = 0; | 140 size_t allFrameBytes = 0; |
| 142 for (size_t i = 0; i < m_frames.size(); ++i) | 141 for (size_t i = 0; i < m_frames.size(); ++i) |
| 143 allFrameBytes += m_frames[i].m_frameBytes; | 142 allFrameBytes += m_frames[i].m_frameBytes; |
| 144 | 143 |
| 145 if (allFrameBytes > cLargeAnimationCutoff) { | 144 if (allFrameBytes > cLargeAnimationCutoff) |
| 146 destroyDecodedData(false); | 145 destroyDecodedData(false); |
| 147 } | |
| 148 } | 146 } |
| 149 | 147 |
| 150 void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared) | 148 void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared) |
| 151 { | 149 { |
| 152 if (frameBytesCleared && imageObserver()) | 150 if (frameBytesCleared && imageObserver()) |
| 153 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesClear
ed)); | 151 imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesClear
ed)); |
| 154 } | 152 } |
| 155 | 153 |
| 156 void BitmapImage::cacheFrame(size_t index) | 154 void BitmapImage::cacheFrame(size_t index) |
| 157 { | 155 { |
| 158 size_t numFrames = frameCount(); | 156 size_t numFrames = frameCount(); |
| 159 if (m_frames.size() < numFrames) | 157 if (m_frames.size() < numFrames) |
| 160 m_frames.grow(numFrames); | 158 m_frames.grow(numFrames); |
| 161 | 159 |
| 162 int deltaBytes = totalFrameBytes(); | 160 int deltaBytes = totalFrameBytes(); |
| 163 | 161 |
| 164 | |
| 165 // We are caching frame snapshots. This is OK even for partially decoded fr
ames, | 162 // We are caching frame snapshots. This is OK even for partially decoded fr
ames, |
| 166 // as they are cleared by dataChanged() when new data arrives. | 163 // as they are cleared by dataChanged() when new data arrives. |
| 167 m_frames[index].m_frame = m_source.createFrameAtIndex(index); | 164 m_frames[index].m_frame = m_source.createFrameAtIndex(index); |
| 168 | 165 |
| 169 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 166 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| 170 m_frames[index].m_haveMetadata = true; | 167 m_frames[index].m_haveMetadata = true; |
| 171 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 168 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); |
| 172 if (repetitionCount(false) != cAnimationNone) | 169 if (repetitionCount(false) != cAnimationNone) |
| 173 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 170 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
| 174 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 171 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 259 |
| 263 String BitmapImage::filenameExtension() const | 260 String BitmapImage::filenameExtension() const |
| 264 { | 261 { |
| 265 return m_source.filenameExtension(); | 262 return m_source.filenameExtension(); |
| 266 } | 263 } |
| 267 | 264 |
| 268 void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect&
dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImag
eOrientation, ImageClampingMode clampMode) | 265 void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect&
dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImag
eOrientation, ImageClampingMode clampMode) |
| 269 { | 266 { |
| 270 TRACE_EVENT0("skia", "BitmapImage::draw"); | 267 TRACE_EVENT0("skia", "BitmapImage::draw"); |
| 271 | 268 |
| 272 RefPtr<SkImage> image = imageForCurrentFrame(); | 269 RefPtr<SkImage> skImage = imageForCurrentFrame(); |
| 273 if (!image) | 270 if (!skImage) |
| 274 return; // It's too early and we don't have an image yet. | 271 return; // Bail: we don't have an image yet. |
| 275 | 272 |
| 276 FloatRect adjustedSrcRect = srcRect; | 273 FloatRect adjustedSrcRect = srcRect; |
| 277 adjustedSrcRect.intersect(FloatRect(0, 0, image->width(), image->height())); | 274 adjustedSrcRect.intersect(FloatRect(0, 0, skImage->width(), skImage->height(
))); |
| 278 | |
| 279 if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) | 275 if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) |
| 280 return; // Nothing to draw. | 276 return; // Nothing to draw. |
| 277 FloatRect adjustedDstRect = dstRect; |
| 281 | 278 |
| 282 ImageOrientation orientation = DefaultImageOrientation; | 279 ImageOrientation orientation = DefaultImageOrientation; |
| 283 if (shouldRespectImageOrientation == RespectImageOrientation) | 280 if (shouldRespectImageOrientation == RespectImageOrientation) |
| 284 orientation = frameOrientationAtIndex(m_currentFrame); | 281 orientation = frameOrientationAtIndex(m_currentFrame); |
| 285 | 282 |
| 283 SkCanvas::SrcRectConstraint srcRectConstraint = WebCoreClampingModeToSkiaRec
tConstraint(clampMode); |
| 284 |
| 286 int initialSaveCount = canvas->getSaveCount(); | 285 int initialSaveCount = canvas->getSaveCount(); |
| 287 FloatRect adjustedDstRect = dstRect; | 286 |
| 288 if (orientation != DefaultImageOrientation) { | 287 if (orientation != DefaultImageOrientation) { |
| 289 canvas->save(); | 288 canvas->save(); |
| 290 | 289 |
| 291 // ImageOrientation expects the origin to be at (0, 0) | 290 // ImageOrientation expects the origin to be at (0, 0) |
| 292 canvas->translate(adjustedDstRect.x(), adjustedDstRect.y()); | 291 canvas->translate(adjustedDstRect.x(), adjustedDstRect.y()); |
| 293 adjustedDstRect.setLocation(FloatPoint()); | 292 adjustedDstRect.setLocation(FloatPoint()); |
| 294 | 293 |
| 295 canvas->concat(affineTransformToSkMatrix(orientation.transformFromDefaul
t(adjustedDstRect.size()))); | 294 canvas->concat(affineTransformToSkMatrix(orientation.transformFromDefaul
t(adjustedDstRect.size()))); |
| 296 | 295 |
| 297 if (orientation.usesWidthAsHeight()) { | 296 if (orientation.usesWidthAsHeight()) { |
| 298 // The destination rect will have it's width and height already reve
rsed for the orientation of | 297 // The destination rect will have it's width and height already reve
rsed for the orientation of |
| 299 // the image, as it was needed for page layout, so we need to revers
e it back here. | 298 // the image, as it was needed for page layout, so we need to revers
e it back here. |
| 300 adjustedDstRect = FloatRect(adjustedDstRect.x(), adjustedDstRect.y()
, adjustedDstRect.height(), adjustedDstRect.width()); | 299 adjustedDstRect = FloatRect(adjustedDstRect.x(), adjustedDstRect.y()
, adjustedDstRect.height(), adjustedDstRect.width()); |
| 301 } | 300 } |
| 302 } | 301 } |
| 303 | 302 |
| 304 SkRect skSrcRect = adjustedSrcRect; | 303 RefPtr<SkColorFilter> transform; |
| 305 canvas->drawImageRect(image.get(), skSrcRect, adjustedDstRect, &paint, | 304 if (imageColorProfilesEnabled() && hasColorProfile()) |
| 306 WebCoreClampingModeToSkiaRectConstraint(clampMode)); | 305 transform = imageColorTransform(); |
| 306 |
| 307 if (!transform) { |
| 308 canvas->drawImageRect(skImage.get(), adjustedSrcRect, adjustedDstRect, &
paint, srcRectConstraint); |
| 309 |
| 310 canvas->restoreToCount(initialSaveCount); |
| 311 if (skImage->isLazyGenerated()) |
| 312 PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID()); |
| 313 this->didDraw(); |
| 314 return; |
| 315 } |
| 316 |
| 317 float srcArea = adjustedSrcRect.width() * adjustedSrcRect.height(); |
| 318 float dstArea = adjustedDstRect.width() * adjustedDstRect.height(); |
| 319 |
| 320 if (dstArea <= srcArea) { |
| 321 SkPaint transformPaint = paint; |
| 322 transformPaint.setColorFilter(transform.get()); |
| 323 canvas->drawImageRect(skImage.get(), adjustedSrcRect, adjustedDstRect, &
transformPaint, srcRectConstraint); |
| 324 |
| 325 canvas->restoreToCount(initialSaveCount); |
| 326 if (skImage->isLazyGenerated()) |
| 327 PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID()); |
| 328 this->didDraw(); |
| 329 return; |
| 330 } |
| 331 |
| 332 RefPtr<SkImage> image = skImage; // skImage might be indirectly drawn here (
due to transforms). |
| 333 |
| 334 if (RefPtr<SkImageFilter> imageFilter = adoptRef(SkColorFilterImageFilter::C
reate(transform.get()))) |
| 335 image = adoptRef(image->applyFilter(imageFilter.get(), nullptr, true)); |
| 336 |
| 337 canvas->drawImageRect(image.get(), adjustedSrcRect, adjustedDstRect, &paint,
srcRectConstraint); |
| 338 |
| 307 canvas->restoreToCount(initialSaveCount); | 339 canvas->restoreToCount(initialSaveCount); |
| 340 if (skImage->isLazyGenerated()) |
| 341 PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID()); |
| 342 this->didDraw(); |
| 343 return; |
| 344 } |
| 308 | 345 |
| 309 if (currentFrameIsLazyDecoded()) | 346 void BitmapImage::didDraw() |
| 310 PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID()); | 347 { |
| 311 | |
| 312 if (ImageObserver* observer = imageObserver()) | 348 if (ImageObserver* observer = imageObserver()) |
| 313 observer->didDraw(this); | 349 observer->didDraw(this); |
| 314 | 350 |
| 315 startAnimation(); | 351 startAnimation(); |
| 316 } | 352 } |
| 317 | 353 |
| 318 size_t BitmapImage::frameCount() | 354 size_t BitmapImage::frameCount() |
| 319 { | 355 { |
| 320 if (!m_haveFrameCount) { | 356 if (!m_haveFrameCount) { |
| 321 m_frameCount = m_source.frameCount(); | 357 m_frameCount = m_source.frameCount(); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 { | 427 { |
| 392 if (frameCount() > 1) { | 428 if (frameCount() > 1) { |
| 393 RefPtr<SkImage> firstFrame = frameAtIndex(0); | 429 RefPtr<SkImage> firstFrame = frameAtIndex(0); |
| 394 if (firstFrame) | 430 if (firstFrame) |
| 395 return StaticBitmapImage::create(firstFrame); | 431 return StaticBitmapImage::create(firstFrame); |
| 396 } | 432 } |
| 397 | 433 |
| 398 return Image::imageForDefaultFrame(); | 434 return Image::imageForDefaultFrame(); |
| 399 } | 435 } |
| 400 | 436 |
| 437 PassRefPtr<SkColorFilter> BitmapImage::imageColorTransform() |
| 438 { |
| 439 if (currentScreenId()) // FIXME: remove these <canvas> code asserts. |
| 440 RELEASE_ASSERT(!drawingToCanvasElement()); |
| 441 else |
| 442 RELEASE_ASSERT(drawingToCanvasElement()); // sRGB render target. |
| 443 |
| 444 return createColorSpaceFilter(colorProfile().get(), screenColorProfile(curre
ntScreenId()).get()); |
| 445 } |
| 446 |
| 401 bool BitmapImage::frameHasAlphaAtIndex(size_t index) | 447 bool BitmapImage::frameHasAlphaAtIndex(size_t index) |
| 402 { | 448 { |
| 403 if (m_frames.size() <= index) | 449 if (m_frames.size() <= index) |
| 404 return true; | 450 return true; |
| 405 | 451 |
| 406 if (m_frames[index].m_haveMetadata) | 452 if (m_frames[index].m_haveMetadata) |
| 407 return m_frames[index].m_hasAlpha; | 453 return m_frames[index].m_hasAlpha; |
| 408 | 454 |
| 409 return m_source.frameHasAlphaAtIndex(index); | 455 return m_source.frameHasAlphaAtIndex(index); |
| 410 } | 456 } |
| 411 | 457 |
| 412 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) | 458 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) |
| 413 { | 459 { |
| 414 if (metadataMode == PreCacheMetadata) { | 460 if (metadataMode == PreCacheMetadata) { |
| 415 // frameHasAlphaAtIndex() conservatively returns false for uncached fram
es. To increase the | 461 // frameHasAlphaAtIndex() conservatively returns false for uncached fram
es. To increase the |
| 416 // chance of an accurate answer, pre-cache the current frame metadata. | 462 // chance of an accurate answer, pre-cache the current frame metadata. |
| 417 frameAtIndex(currentFrame()); | 463 frameAtIndex(currentFrame()); |
| 418 } | 464 } |
| 465 |
| 419 return !frameHasAlphaAtIndex(currentFrame()); | 466 return !frameHasAlphaAtIndex(currentFrame()); |
| 420 } | 467 } |
| 421 | 468 |
| 422 bool BitmapImage::currentFrameIsComplete() | 469 bool BitmapImage::currentFrameIsComplete() |
| 423 { | 470 { |
| 424 return frameIsCompleteAtIndex(currentFrame()); | 471 return frameIsCompleteAtIndex(currentFrame()); |
| 425 } | 472 } |
| 426 | 473 |
| 427 bool BitmapImage::currentFrameIsLazyDecoded() | 474 bool BitmapImage::currentFrameIsLazyDecoded() |
| 428 { | 475 { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 destroyDecodedDataIfNecessary(); | 689 destroyDecodedDataIfNecessary(); |
| 643 | 690 |
| 644 // We need to draw this frame if we advanced to it while not skipping, or if | 691 // We need to draw this frame if we advanced to it while not skipping, or if |
| 645 // while trying to skip frames we hit the last frame and thus had to stop. | 692 // while trying to skip frames we hit the last frame and thus had to stop. |
| 646 if (skippingFrames != advancedAnimation) | 693 if (skippingFrames != advancedAnimation) |
| 647 imageObserver()->animationAdvanced(this); | 694 imageObserver()->animationAdvanced(this); |
| 648 return advancedAnimation; | 695 return advancedAnimation; |
| 649 } | 696 } |
| 650 | 697 |
| 651 } // namespace blink | 698 } // namespace blink |
| OLD | NEW |