| OLD | NEW |
| 1 /* | 1 /* |
| 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) | 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) |
| 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) | 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) |
| 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) | 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) |
| 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) | 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) |
| 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. | 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. |
| 7 | 7 |
| 8 This library is free software; you can redistribute it and/or | 8 This library is free software; you can redistribute it and/or |
| 9 modify it under the terms of the GNU Library General Public | 9 modify it under the terms of the GNU Library General Public |
| 10 License as published by the Free Software Foundation; either | 10 License as published by the Free Software Foundation; either |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 | 230 |
| 231 // Don't notify observers and clients of completion if this ImageResource is | 231 // Don't notify observers and clients of completion if this ImageResource is |
| 232 // about to be reloaded. | 232 // about to be reloaded. |
| 233 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder()) | 233 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder()) |
| 234 return; | 234 return; |
| 235 | 235 |
| 236 Resource::didAddClient(client); | 236 Resource::didAddClient(client); |
| 237 } | 237 } |
| 238 | 238 |
| 239 void ImageResource::destroyDecodedDataForFailedRevalidation() { | 239 void ImageResource::destroyDecodedDataForFailedRevalidation() { |
| 240 getContent()->updateImage(nullptr, ImageResourceContent::ClearExistingImage, | 240 updateImage(nullptr, ImageResourceContent::ClearExistingImage, false); |
| 241 false); | |
| 242 setDecodedSize(0); | 241 setDecodedSize(0); |
| 243 } | 242 } |
| 244 | 243 |
| 245 void ImageResource::destroyDecodedDataIfPossible() { | 244 void ImageResource::destroyDecodedDataIfPossible() { |
| 246 getContent()->destroyDecodedData(); | 245 getContent()->destroyDecodedData(); |
| 247 if (getContent()->hasImage() && !isPreloaded() && | 246 if (getContent()->hasImage() && !isPreloaded() && |
| 248 getContent()->isRefetchableDataFromDiskCache()) { | 247 getContent()->isRefetchableDataFromDiskCache()) { |
| 249 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize", | 248 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize", |
| 250 encodedSize() / 1024); | 249 encodedSize() / 1024); |
| 251 } | 250 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 } else { | 282 } else { |
| 284 Resource::appendData(data, length); | 283 Resource::appendData(data, length); |
| 285 | 284 |
| 286 // If we don't have the size available yet, then update immediately since | 285 // If we don't have the size available yet, then update immediately since |
| 287 // we need to know the image size as soon as possible. Likewise for | 286 // we need to know the image size as soon as possible. Likewise for |
| 288 // animated images, update right away since we shouldn't throttle animated | 287 // animated images, update right away since we shouldn't throttle animated |
| 289 // images. | 288 // images. |
| 290 if (!getContent()->isSizeAvailable() || | 289 if (!getContent()->isSizeAvailable() || |
| 291 (getContent()->hasImage() && | 290 (getContent()->hasImage() && |
| 292 getContent()->getImage()->maybeAnimated())) { | 291 getContent()->getImage()->maybeAnimated())) { |
| 293 getContent()->updateImage(this->data(), | 292 updateImage(this->data(), ImageResourceContent::KeepExistingImage, false); |
| 294 ImageResourceContent::KeepExistingImage, false); | |
| 295 return; | 293 return; |
| 296 } | 294 } |
| 297 | 295 |
| 298 // For other cases, only update at |kFlushDelaySeconds| intervals. This | 296 // For other cases, only update at |kFlushDelaySeconds| intervals. This |
| 299 // throttles how frequently we update |m_image| and how frequently we | 297 // throttles how frequently we update |m_image| and how frequently we |
| 300 // inform the clients which causes an invalidation of this image. In other | 298 // inform the clients which causes an invalidation of this image. In other |
| 301 // words, we only invalidate this image every |kFlushDelaySeconds| seconds | 299 // words, we only invalidate this image every |kFlushDelaySeconds| seconds |
| 302 // while loading. | 300 // while loading. |
| 303 if (!m_flushTimer.isActive()) { | 301 if (!m_flushTimer.isActive()) { |
| 304 double now = WTF::monotonicallyIncreasingTime(); | 302 double now = WTF::monotonicallyIncreasingTime(); |
| 305 if (!m_lastFlushTime) | 303 if (!m_lastFlushTime) |
| 306 m_lastFlushTime = now; | 304 m_lastFlushTime = now; |
| 307 | 305 |
| 308 DCHECK_LE(m_lastFlushTime, now); | 306 DCHECK_LE(m_lastFlushTime, now); |
| 309 double flushDelay = m_lastFlushTime - now + kFlushDelaySeconds; | 307 double flushDelay = m_lastFlushTime - now + kFlushDelaySeconds; |
| 310 if (flushDelay < 0.) | 308 if (flushDelay < 0.) |
| 311 flushDelay = 0.; | 309 flushDelay = 0.; |
| 312 m_flushTimer.startOneShot(flushDelay, BLINK_FROM_HERE); | 310 m_flushTimer.startOneShot(flushDelay, BLINK_FROM_HERE); |
| 313 } | 311 } |
| 314 } | 312 } |
| 315 } | 313 } |
| 316 | 314 |
| 317 void ImageResource::flushImageIfNeeded(TimerBase*) { | 315 void ImageResource::flushImageIfNeeded(TimerBase*) { |
| 318 // We might have already loaded the image fully, in which case we don't need | 316 // We might have already loaded the image fully, in which case we don't need |
| 319 // to call |updateImage()|. | 317 // to call |updateImage()|. |
| 320 if (isLoading()) { | 318 if (isLoading()) { |
| 321 m_lastFlushTime = WTF::monotonicallyIncreasingTime(); | 319 m_lastFlushTime = WTF::monotonicallyIncreasingTime(); |
| 322 getContent()->updateImage(this->data(), | 320 updateImage(this->data(), ImageResourceContent::KeepExistingImage, false); |
| 323 ImageResourceContent::KeepExistingImage, false); | |
| 324 } | 321 } |
| 325 } | 322 } |
| 326 | 323 |
| 327 bool ImageResource::willPaintBrokenImage() const { | 324 bool ImageResource::willPaintBrokenImage() const { |
| 328 return errorOccurred(); | 325 return errorOccurred(); |
| 329 } | 326 } |
| 330 | 327 |
| 331 void ImageResource::decodeError(bool allDataReceived) { | 328 void ImageResource::decodeError(bool allDataReceived) { |
| 332 size_t size = encodedSize(); | 329 size_t size = encodedSize(); |
| 333 | 330 |
| 334 clearData(); | 331 clearData(); |
| 335 setEncodedSize(0); | 332 setEncodedSize(0); |
| 336 if (!errorOccurred()) | 333 if (!errorOccurred()) |
| 337 setStatus(DecodeError); | 334 setStatus(DecodeError); |
| 338 | 335 |
| 339 if (!allDataReceived && loader()) { | 336 if (!allDataReceived && loader()) { |
| 340 // TODO(hiroshige): Do not call didFinishLoading() directly. | 337 // TODO(hiroshige): Do not call didFinishLoading() directly. |
| 341 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); | 338 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); |
| 342 } | 339 } |
| 343 | 340 |
| 344 memoryCache()->remove(this); | 341 memoryCache()->remove(this); |
| 345 } | 342 } |
| 346 | 343 |
| 347 void ImageResource::updateImageAndClearBuffer() { | 344 void ImageResource::updateImageAndClearBuffer() { |
| 348 getContent()->updateImage(data(), ImageResourceContent::ClearExistingImage, | 345 updateImage(data(), ImageResourceContent::ClearExistingImage, true); |
| 349 true); | |
| 350 clearData(); | 346 clearData(); |
| 351 } | 347 } |
| 352 | 348 |
| 353 void ImageResource::finish(double loadFinishTime) { | 349 void ImageResource::finish(double loadFinishTime) { |
| 354 if (m_multipartParser) { | 350 if (m_multipartParser) { |
| 355 m_multipartParser->finish(); | 351 m_multipartParser->finish(); |
| 356 if (data()) | 352 if (data()) |
| 357 updateImageAndClearBuffer(); | 353 updateImageAndClearBuffer(); |
| 358 } else { | 354 } else { |
| 359 getContent()->updateImage(data(), ImageResourceContent::KeepExistingImage, | 355 updateImage(data(), ImageResourceContent::KeepExistingImage, true); |
| 360 true); | |
| 361 // As encoded image data can be created from m_image (see | 356 // As encoded image data can be created from m_image (see |
| 362 // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's | 357 // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's |
| 363 // clear this. As for the lifetimes of m_image and m_data, see this | 358 // clear this. As for the lifetimes of m_image and m_data, see this |
| 364 // document: | 359 // document: |
| 365 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1Vsqpxo
L7aciY/edit?usp=sharing | 360 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1Vsqpxo
L7aciY/edit?usp=sharing |
| 366 clearData(); | 361 clearData(); |
| 367 } | 362 } |
| 368 Resource::finish(loadFinishTime); | 363 Resource::finish(loadFinishTime); |
| 369 } | 364 } |
| 370 | 365 |
| 371 void ImageResource::error(const ResourceError& error) { | 366 void ImageResource::error(const ResourceError& error) { |
| 372 if (m_multipartParser) | 367 if (m_multipartParser) |
| 373 m_multipartParser->cancel(); | 368 m_multipartParser->cancel(); |
| 374 clearData(); | 369 clearData(); |
| 375 Resource::error(error); | 370 Resource::error(error); |
| 376 getContent()->updateImage(nullptr, ImageResourceContent::ClearExistingImage, | 371 updateImage(nullptr, ImageResourceContent::ClearExistingImage, true); |
| 377 true); | |
| 378 } | 372 } |
| 379 | 373 |
| 380 void ImageResource::responseReceived( | 374 void ImageResource::responseReceived( |
| 381 const ResourceResponse& response, | 375 const ResourceResponse& response, |
| 382 std::unique_ptr<WebDataConsumerHandle> handle) { | 376 std::unique_ptr<WebDataConsumerHandle> handle) { |
| 383 DCHECK(!handle); | 377 DCHECK(!handle); |
| 384 DCHECK(!m_multipartParser); | 378 DCHECK(!m_multipartParser); |
| 385 // If there's no boundary, just handle the request normally. | 379 // If there's no boundary, just handle the request normally. |
| 386 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) { | 380 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) { |
| 387 m_multipartParser = new MultipartImageResourceParser( | 381 m_multipartParser = new MultipartImageResourceParser( |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 } | 427 } |
| 434 | 428 |
| 435 if (isLoading()) { | 429 if (isLoading()) { |
| 436 loader()->cancel(); | 430 loader()->cancel(); |
| 437 // Canceling the loader causes error() to be called, which in turn calls | 431 // Canceling the loader causes error() to be called, which in turn calls |
| 438 // clear() and notifyObservers(), so there's no need to call these again | 432 // clear() and notifyObservers(), so there's no need to call these again |
| 439 // here. | 433 // here. |
| 440 } else { | 434 } else { |
| 441 clearData(); | 435 clearData(); |
| 442 setEncodedSize(0); | 436 setEncodedSize(0); |
| 443 getContent()->updateImage(nullptr, ImageResourceContent::ClearExistingImage, | 437 updateImage(nullptr, ImageResourceContent::ClearExistingImage, false); |
| 444 false); | |
| 445 } | 438 } |
| 446 | 439 |
| 447 setStatus(NotStarted); | 440 setStatus(NotStarted); |
| 448 | 441 |
| 449 DCHECK(m_isSchedulingReload); | 442 DCHECK(m_isSchedulingReload); |
| 450 m_isSchedulingReload = false; | 443 m_isSchedulingReload = false; |
| 451 | 444 |
| 452 fetcher->startLoad(this); | 445 fetcher->startLoad(this); |
| 453 } | 446 } |
| 454 | 447 |
| 455 void ImageResource::onePartInMultipartReceived( | 448 void ImageResource::onePartInMultipartReceived( |
| 456 const ResourceResponse& response) { | 449 const ResourceResponse& response) { |
| 457 DCHECK(m_multipartParser); | 450 DCHECK(m_multipartParser); |
| 458 | 451 |
| 459 setResponse(response); | 452 setResponse(response); |
| 460 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { | 453 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { |
| 461 // We have nothing to do because we don't have any data. | 454 // We have nothing to do because we don't have any data. |
| 462 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; | 455 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; |
| 463 return; | 456 return; |
| 464 } | 457 } |
| 465 updateImageAndClearBuffer(); | 458 updateImageAndClearBuffer(); |
| 459 m_isUpdateImageCalled = false; |
| 466 | 460 |
| 467 if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) { | 461 if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) { |
| 468 m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart; | 462 m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart; |
| 469 // Notify finished when the first part ends. | 463 // Notify finished when the first part ends. |
| 470 if (!errorOccurred()) | 464 if (!errorOccurred()) |
| 471 setStatus(Cached); | 465 setStatus(Cached); |
| 472 // We notify clients and observers of finish in checkNotify() and | 466 // We notify clients and observers of finish in checkNotify() and |
| 473 // updateImageAndClearBuffer(), respectively, and they will not be | 467 // updateImageAndClearBuffer(), respectively, and they will not be |
| 474 // notified again in Resource::finish()/error(). | 468 // notified again in Resource::finish()/error(). |
| 475 checkNotify(); | 469 checkNotify(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 498 } | 492 } |
| 499 | 493 |
| 500 ImageResourceContent* ImageResource::getContent() const { | 494 ImageResourceContent* ImageResource::getContent() const { |
| 501 return m_content; | 495 return m_content; |
| 502 } | 496 } |
| 503 | 497 |
| 504 ResourcePriority ImageResource::priorityFromObservers() { | 498 ResourcePriority ImageResource::priorityFromObservers() { |
| 505 return getContent()->priorityFromObservers(); | 499 return getContent()->priorityFromObservers(); |
| 506 } | 500 } |
| 507 | 501 |
| 502 void ImageResource::updateImage( |
| 503 PassRefPtr<SharedBuffer> sharedBuffer, |
| 504 ImageResourceContent::ClearImageOption clearImageOption, |
| 505 bool allDataReceived) { |
| 506 if (!m_isUpdateImageCalled) |
| 507 clearImageOption = ImageResourceContent::ClearExistingImage; |
| 508 m_isUpdateImageCalled = true; |
| 509 getContent()->updateImage(std::move(sharedBuffer), clearImageOption, |
| 510 allDataReceived); |
| 511 } |
| 512 |
| 508 } // namespace blink | 513 } // namespace blink |
| OLD | NEW |