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 |