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 |