| 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 29 matching lines...) Expand all Loading... |
| 40 #include "platform/instrumentation/tracing/TraceEvent.h" | 40 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 41 #include "wtf/PassRefPtr.h" | 41 #include "wtf/PassRefPtr.h" |
| 42 #include "wtf/PtrUtil.h" | 42 #include "wtf/PtrUtil.h" |
| 43 #include "wtf/text/WTFString.h" | 43 #include "wtf/text/WTFString.h" |
| 44 | 44 |
| 45 namespace blink { | 45 namespace blink { |
| 46 | 46 |
| 47 namespace { | 47 namespace { |
| 48 | 48 |
| 49 ColorBehavior defaultColorBehavior() { | 49 ColorBehavior defaultColorBehavior() { |
| 50 // TODO(ccameron): ColorBehavior should be specified by the caller requesting | |
| 51 // SkImages. | |
| 52 // https://crbug.com/667420 | |
| 53 if (RuntimeEnabledFeatures::trueColorRenderingEnabled()) | 50 if (RuntimeEnabledFeatures::trueColorRenderingEnabled()) |
| 54 return ColorBehavior::tag(); | 51 return ColorBehavior::tag(); |
| 55 return ColorBehavior::transformToGlobalTarget(); | 52 return ColorBehavior::transformToGlobalTarget(); |
| 56 } | 53 } |
| 57 | 54 |
| 58 } // namespace | 55 } // namespace |
| 59 | 56 |
| 60 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting( | 57 PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting( |
| 61 const SkBitmap& bitmap, | 58 const SkBitmap& bitmap, |
| 62 ImageOrientation orientation) { | 59 ImageOrientation orientation) { |
| 63 if (bitmap.isNull()) { | 60 if (bitmap.isNull()) { |
| 64 return BitmapImage::create(); | 61 return BitmapImage::create(); |
| 65 } | 62 } |
| 66 | 63 |
| 67 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); | 64 RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap)); |
| 68 result->m_frames[0].m_orientation = orientation; | 65 result->m_frames[0].m_orientation = orientation; |
| 69 if (orientation.usesWidthAsHeight()) | 66 if (orientation.usesWidthAsHeight()) |
| 70 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); | 67 result->m_sizeRespectingOrientation = result->m_size.transposedSize(); |
| 71 return result.release(); | 68 return result.release(); |
| 72 } | 69 } |
| 73 | 70 |
| 74 BitmapImage::BitmapImage(ImageObserver* observer) | 71 BitmapImage::BitmapImage(ImageObserver* observer) |
| 75 : Image(observer), | 72 : Image(observer), |
| 76 m_currentFrame(0), | 73 m_currentFrame(0), |
| 77 m_cachedFrameIndex(0), | 74 m_cachedFrameIndex(0), |
| 78 m_cachedFrameColorBehavior(defaultColorBehavior()), | |
| 79 m_repetitionCount(cAnimationNone), | 75 m_repetitionCount(cAnimationNone), |
| 80 m_repetitionCountStatus(Unknown), | 76 m_repetitionCountStatus(Unknown), |
| 81 m_repetitionsComplete(0), | 77 m_repetitionsComplete(0), |
| 82 m_desiredFrameStartTime(0), | 78 m_desiredFrameStartTime(0), |
| 83 m_frameCount(0), | 79 m_frameCount(0), |
| 84 m_animationPolicy(ImageAnimationPolicyAllowed), | 80 m_animationPolicy(ImageAnimationPolicyAllowed), |
| 85 m_animationFinished(false), | 81 m_animationFinished(false), |
| 86 m_allDataReceived(false), | 82 m_allDataReceived(false), |
| 87 m_haveSize(false), | 83 m_haveSize(false), |
| 88 m_sizeAvailable(false), | 84 m_sizeAvailable(false), |
| 89 m_haveFrameCount(false) {} | 85 m_haveFrameCount(false) {} |
| 90 | 86 |
| 91 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) | 87 BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| 92 : Image(observer), | 88 : Image(observer), |
| 93 m_size(bitmap.width(), bitmap.height()), | 89 m_size(bitmap.width(), bitmap.height()), |
| 94 m_currentFrame(0), | 90 m_currentFrame(0), |
| 95 m_cachedFrame(SkImage::MakeFromBitmap(bitmap)), | 91 m_cachedFrame(SkImage::MakeFromBitmap(bitmap)), |
| 96 m_cachedFrameIndex(0), | 92 m_cachedFrameIndex(0), |
| 97 m_cachedFrameColorBehavior(defaultColorBehavior()), | |
| 98 m_repetitionCount(cAnimationNone), | 93 m_repetitionCount(cAnimationNone), |
| 99 m_repetitionCountStatus(Unknown), | 94 m_repetitionCountStatus(Unknown), |
| 100 m_repetitionsComplete(0), | 95 m_repetitionsComplete(0), |
| 101 m_frameCount(1), | 96 m_frameCount(1), |
| 102 m_animationPolicy(ImageAnimationPolicyAllowed), | 97 m_animationPolicy(ImageAnimationPolicyAllowed), |
| 103 m_animationFinished(true), | 98 m_animationFinished(true), |
| 104 m_allDataReceived(true), | 99 m_allDataReceived(true), |
| 105 m_haveSize(true), | 100 m_haveSize(true), |
| 106 m_sizeAvailable(true), | 101 m_sizeAvailable(true), |
| 107 m_haveFrameCount(true) { | 102 m_haveFrameCount(true) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 } | 135 } |
| 141 | 136 |
| 142 size_t BitmapImage::totalFrameBytes() { | 137 size_t BitmapImage::totalFrameBytes() { |
| 143 const size_t numFrames = frameCount(); | 138 const size_t numFrames = frameCount(); |
| 144 size_t totalBytes = 0; | 139 size_t totalBytes = 0; |
| 145 for (size_t i = 0; i < numFrames; ++i) | 140 for (size_t i = 0; i < numFrames; ++i) |
| 146 totalBytes += m_source.frameBytesAtIndex(i); | 141 totalBytes += m_source.frameBytesAtIndex(i); |
| 147 return totalBytes; | 142 return totalBytes; |
| 148 } | 143 } |
| 149 | 144 |
| 150 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame( | 145 sk_sp<SkImage> BitmapImage::decodeAndCacheFrame(size_t index) { |
| 151 size_t index, | |
| 152 const ColorBehavior& colorBehavior) { | |
| 153 size_t numFrames = frameCount(); | 146 size_t numFrames = frameCount(); |
| 154 if (m_frames.size() < numFrames) | 147 if (m_frames.size() < numFrames) |
| 155 m_frames.grow(numFrames); | 148 m_frames.grow(numFrames); |
| 156 | 149 |
| 157 // We are caching frame snapshots. This is OK even for partially decoded | 150 // We are caching frame snapshots. This is OK even for partially decoded |
| 158 // frames, as they are cleared by dataChanged() when new data arrives. | 151 // frames, as they are cleared by dataChanged() when new data arrives. |
| 159 sk_sp<SkImage> image = m_source.createFrameAtIndex(index, colorBehavior); | 152 sk_sp<SkImage> image = |
| 153 m_source.createFrameAtIndex(index, defaultColorBehavior()); |
| 160 m_cachedFrame = image; | 154 m_cachedFrame = image; |
| 161 m_cachedFrameIndex = index; | 155 m_cachedFrameIndex = index; |
| 162 m_cachedFrameColorBehavior = colorBehavior; | |
| 163 | 156 |
| 164 m_frames[index].m_orientation = m_source.orientationAtIndex(index); | 157 m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| 165 m_frames[index].m_haveMetadata = true; | 158 m_frames[index].m_haveMetadata = true; |
| 166 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); | 159 m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index); |
| 167 if (repetitionCount(false) != cAnimationNone) | 160 if (repetitionCount(false) != cAnimationNone) |
| 168 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); | 161 m_frames[index].m_duration = m_source.frameDurationAtIndex(index); |
| 169 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); | 162 m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 170 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); | 163 m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index); |
| 171 | 164 |
| 172 notifyMemoryChanged(); | 165 notifyMemoryChanged(); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 | 255 |
| 263 void BitmapImage::draw( | 256 void BitmapImage::draw( |
| 264 PaintCanvas* canvas, | 257 PaintCanvas* canvas, |
| 265 const PaintFlags& flags, | 258 const PaintFlags& flags, |
| 266 const FloatRect& dstRect, | 259 const FloatRect& dstRect, |
| 267 const FloatRect& srcRect, | 260 const FloatRect& srcRect, |
| 268 RespectImageOrientationEnum shouldRespectImageOrientation, | 261 RespectImageOrientationEnum shouldRespectImageOrientation, |
| 269 ImageClampingMode clampMode) { | 262 ImageClampingMode clampMode) { |
| 270 TRACE_EVENT0("skia", "BitmapImage::draw"); | 263 TRACE_EVENT0("skia", "BitmapImage::draw"); |
| 271 | 264 |
| 272 sk_sp<SkImage> image = | 265 sk_sp<SkImage> image = imageForCurrentFrame(); |
| 273 imageForCurrentFrame(ColorBehavior::transformToGlobalTarget()); | |
| 274 if (!image) | 266 if (!image) |
| 275 return; // It's too early and we don't have an image yet. | 267 return; // It's too early and we don't have an image yet. |
| 276 | 268 |
| 277 FloatRect adjustedSrcRect = srcRect; | 269 FloatRect adjustedSrcRect = srcRect; |
| 278 adjustedSrcRect.intersect(SkRect::Make(image->bounds())); | 270 adjustedSrcRect.intersect(SkRect::Make(image->bounds())); |
| 279 | 271 |
| 280 if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) | 272 if (adjustedSrcRect.isEmpty() || dstRect.isEmpty()) |
| 281 return; // Nothing to draw. | 273 return; // Nothing to draw. |
| 282 | 274 |
| 283 ImageOrientation orientation = DefaultImageOrientation; | 275 ImageOrientation orientation = DefaultImageOrientation; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 if (m_sizeAvailable && hasVisibleImageSize(size())) { | 331 if (m_sizeAvailable && hasVisibleImageSize(size())) { |
| 340 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); | 332 BitmapImageMetrics::countDecodedImageType(m_source.filenameExtension()); |
| 341 if (m_source.filenameExtension() == "jpg") | 333 if (m_source.filenameExtension() == "jpg") |
| 342 BitmapImageMetrics::countImageOrientation( | 334 BitmapImageMetrics::countImageOrientation( |
| 343 m_source.orientationAtIndex(0).orientation()); | 335 m_source.orientationAtIndex(0).orientation()); |
| 344 } | 336 } |
| 345 | 337 |
| 346 return m_sizeAvailable; | 338 return m_sizeAvailable; |
| 347 } | 339 } |
| 348 | 340 |
| 349 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index, | 341 sk_sp<SkImage> BitmapImage::frameAtIndex(size_t index) { |
| 350 const ColorBehavior& colorBehavior) { | |
| 351 if (index >= frameCount()) | 342 if (index >= frameCount()) |
| 352 return nullptr; | 343 return nullptr; |
| 353 | 344 |
| 354 if (index == m_cachedFrameIndex && m_cachedFrame && | 345 if (index == m_cachedFrameIndex && m_cachedFrame) |
| 355 m_cachedFrameColorBehavior == colorBehavior) | |
| 356 return m_cachedFrame; | 346 return m_cachedFrame; |
| 357 | 347 |
| 358 return decodeAndCacheFrame(index, colorBehavior); | 348 return decodeAndCacheFrame(index); |
| 359 } | 349 } |
| 360 | 350 |
| 361 bool BitmapImage::frameIsCompleteAtIndex(size_t index) const { | 351 bool BitmapImage::frameIsCompleteAtIndex(size_t index) const { |
| 362 if (index < m_frames.size() && m_frames[index].m_haveMetadata && | 352 if (index < m_frames.size() && m_frames[index].m_haveMetadata && |
| 363 m_frames[index].m_isComplete) | 353 m_frames[index].m_isComplete) |
| 364 return true; | 354 return true; |
| 365 | 355 |
| 366 return m_source.frameIsCompleteAtIndex(index); | 356 return m_source.frameIsCompleteAtIndex(index); |
| 367 } | 357 } |
| 368 | 358 |
| 369 float BitmapImage::frameDurationAtIndex(size_t index) const { | 359 float BitmapImage::frameDurationAtIndex(size_t index) const { |
| 370 if (index < m_frames.size() && m_frames[index].m_haveMetadata) | 360 if (index < m_frames.size() && m_frames[index].m_haveMetadata) |
| 371 return m_frames[index].m_duration; | 361 return m_frames[index].m_duration; |
| 372 | 362 |
| 373 return m_source.frameDurationAtIndex(index); | 363 return m_source.frameDurationAtIndex(index); |
| 374 } | 364 } |
| 375 | 365 |
| 376 sk_sp<SkImage> BitmapImage::imageForCurrentFrame( | 366 sk_sp<SkImage> BitmapImage::imageForCurrentFrame() { |
| 377 const ColorBehavior& colorBehavior) { | 367 return frameAtIndex(currentFrame()); |
| 378 return frameAtIndex(currentFrame(), colorBehavior); | |
| 379 } | 368 } |
| 380 | 369 |
| 381 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() { | 370 PassRefPtr<Image> BitmapImage::imageForDefaultFrame() { |
| 382 // TODO(ccameron): Determine the appropriate ColorBehavior for this situation. | |
| 383 // https://crbug.com/667420 | |
| 384 const ColorBehavior& colorBehavior = m_cachedFrameColorBehavior; | |
| 385 if (frameCount() > 1) { | 371 if (frameCount() > 1) { |
| 386 sk_sp<SkImage> firstFrame = frameAtIndex(0, colorBehavior); | 372 sk_sp<SkImage> firstFrame = frameAtIndex(0); |
| 387 if (firstFrame) | 373 if (firstFrame) |
| 388 return StaticBitmapImage::create(std::move(firstFrame)); | 374 return StaticBitmapImage::create(std::move(firstFrame)); |
| 389 } | 375 } |
| 390 | 376 |
| 391 return Image::imageForDefaultFrame(); | 377 return Image::imageForDefaultFrame(); |
| 392 } | 378 } |
| 393 | 379 |
| 394 bool BitmapImage::frameHasAlphaAtIndex(size_t index) { | 380 bool BitmapImage::frameHasAlphaAtIndex(size_t index) { |
| 395 if (m_frames.size() <= index) | 381 if (m_frames.size() <= index) |
| 396 return true; | 382 return true; |
| 397 | 383 |
| 398 if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha) | 384 if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha) |
| 399 return false; | 385 return false; |
| 400 | 386 |
| 401 // m_hasAlpha may change after m_haveMetadata is set to true, so always ask | 387 // m_hasAlpha may change after m_haveMetadata is set to true, so always ask |
| 402 // ImageSource for the value if the cached value is the default value. | 388 // ImageSource for the value if the cached value is the default value. |
| 403 bool hasAlpha = m_source.frameHasAlphaAtIndex(index); | 389 bool hasAlpha = m_source.frameHasAlphaAtIndex(index); |
| 404 | 390 |
| 405 if (m_frames[index].m_haveMetadata) | 391 if (m_frames[index].m_haveMetadata) |
| 406 m_frames[index].m_hasAlpha = hasAlpha; | 392 m_frames[index].m_hasAlpha = hasAlpha; |
| 407 | 393 |
| 408 return hasAlpha; | 394 return hasAlpha; |
| 409 } | 395 } |
| 410 | 396 |
| 411 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) { | 397 bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode) { |
| 412 if (metadataMode == PreCacheMetadata) { | 398 if (metadataMode == PreCacheMetadata) { |
| 413 // frameHasAlphaAtIndex() conservatively returns false for uncached frames. | 399 // frameHasAlphaAtIndex() conservatively returns false for uncached frames. |
| 414 // To increase the chance of an accurate answer, pre-cache the current frame | 400 // To increase the chance of an accurate answer, pre-cache the current frame |
| 415 // metadata. Because ColorBehavior does not affect this result, use | 401 // metadata. |
| 416 // whatever ColorBehavior was last used (if any). | 402 frameAtIndex(currentFrame()); |
| 417 frameAtIndex(currentFrame(), m_cachedFrameColorBehavior); | |
| 418 } | 403 } |
| 419 return !frameHasAlphaAtIndex(currentFrame()); | 404 return !frameHasAlphaAtIndex(currentFrame()); |
| 420 } | 405 } |
| 421 | 406 |
| 422 bool BitmapImage::currentFrameIsComplete() { | 407 bool BitmapImage::currentFrameIsComplete() { |
| 423 return frameIsCompleteAtIndex(currentFrame()); | 408 return frameIsCompleteAtIndex(currentFrame()); |
| 424 } | 409 } |
| 425 | 410 |
| 426 bool BitmapImage::currentFrameIsLazyDecoded() { | 411 bool BitmapImage::currentFrameIsLazyDecoded() { |
| 427 // Because ColorBehavior does not affect this result, use whatever | 412 sk_sp<SkImage> image = frameAtIndex(currentFrame()); |
| 428 // ColorBehavior was last used (if any). | |
| 429 sk_sp<SkImage> image = | |
| 430 frameAtIndex(currentFrame(), m_cachedFrameColorBehavior); | |
| 431 return image && image->isLazyGenerated(); | 413 return image && image->isLazyGenerated(); |
| 432 } | 414 } |
| 433 | 415 |
| 434 ImageOrientation BitmapImage::currentFrameOrientation() { | 416 ImageOrientation BitmapImage::currentFrameOrientation() { |
| 435 return frameOrientationAtIndex(currentFrame()); | 417 return frameOrientationAtIndex(currentFrame()); |
| 436 } | 418 } |
| 437 | 419 |
| 438 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) { | 420 ImageOrientation BitmapImage::frameOrientationAtIndex(size_t index) { |
| 439 if (m_frames.size() <= index) | 421 if (m_frames.size() <= index) |
| 440 return DefaultImageOrientation; | 422 return DefaultImageOrientation; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 getImageObserver()->animationAdvanced(this); | 635 getImageObserver()->animationAdvanced(this); |
| 654 | 636 |
| 655 return true; | 637 return true; |
| 656 } | 638 } |
| 657 | 639 |
| 658 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) { | 640 void BitmapImage::notifyObserversOfAnimationAdvance(TimerBase*) { |
| 659 getImageObserver()->animationAdvanced(this); | 641 getImageObserver()->animationAdvanced(this); |
| 660 } | 642 } |
| 661 | 643 |
| 662 } // namespace blink | 644 } // namespace blink |
| OLD | NEW |