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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 // Clears the image, as we must create a new image for the failed | 240 // Clears the image, as we must create a new image for the failed |
241 // revalidation response. | 241 // revalidation response. |
242 getContent()->updateImage(nullptr, ImageResourceContent::ClearAndUpdateImage, | 242 updateImage(nullptr, ImageResourceContent::ClearAndUpdateImage, false); |
243 false); | |
244 setDecodedSize(0); | 243 setDecodedSize(0); |
245 } | 244 } |
246 | 245 |
247 void ImageResource::destroyDecodedDataIfPossible() { | 246 void ImageResource::destroyDecodedDataIfPossible() { |
248 getContent()->destroyDecodedData(); | 247 getContent()->destroyDecodedData(); |
249 if (getContent()->hasImage() && !isPreloaded() && | 248 if (getContent()->hasImage() && !isPreloaded() && |
250 getContent()->isRefetchableDataFromDiskCache()) { | 249 getContent()->isRefetchableDataFromDiskCache()) { |
251 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize", | 250 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize", |
252 encodedSize() / 1024); | 251 encodedSize() / 1024); |
253 } | 252 } |
(...skipping 24 matching lines...) Expand all Loading... |
278 | 277 |
279 void ImageResource::appendData(const char* data, size_t length) { | 278 void ImageResource::appendData(const char* data, size_t length) { |
280 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); | 279 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); |
281 if (m_multipartParser) { | 280 if (m_multipartParser) { |
282 m_multipartParser->appendData(data, length); | 281 m_multipartParser->appendData(data, length); |
283 } else { | 282 } else { |
284 Resource::appendData(data, length); | 283 Resource::appendData(data, length); |
285 | 284 |
286 // Update the image immediately if needed. | 285 // Update the image immediately if needed. |
287 if (getContent()->shouldUpdateImageImmediately()) { | 286 if (getContent()->shouldUpdateImageImmediately()) { |
288 getContent()->updateImage(this->data(), ImageResourceContent::UpdateImage, | 287 updateImage(this->data(), ImageResourceContent::UpdateImage, false); |
289 false); | |
290 return; | 288 return; |
291 } | 289 } |
292 | 290 |
293 // For other cases, only update at |kFlushDelaySeconds| intervals. This | 291 // For other cases, only update at |kFlushDelaySeconds| intervals. This |
294 // throttles how frequently we update |m_image| and how frequently we | 292 // throttles how frequently we update |m_image| and how frequently we |
295 // inform the clients which causes an invalidation of this image. In other | 293 // inform the clients which causes an invalidation of this image. In other |
296 // words, we only invalidate this image every |kFlushDelaySeconds| seconds | 294 // words, we only invalidate this image every |kFlushDelaySeconds| seconds |
297 // while loading. | 295 // while loading. |
298 if (!m_flushTimer.isActive()) { | 296 if (!m_flushTimer.isActive()) { |
299 double now = WTF::monotonicallyIncreasingTime(); | 297 double now = WTF::monotonicallyIncreasingTime(); |
300 if (!m_lastFlushTime) | 298 if (!m_lastFlushTime) |
301 m_lastFlushTime = now; | 299 m_lastFlushTime = now; |
302 | 300 |
303 DCHECK_LE(m_lastFlushTime, now); | 301 DCHECK_LE(m_lastFlushTime, now); |
304 double flushDelay = m_lastFlushTime - now + kFlushDelaySeconds; | 302 double flushDelay = m_lastFlushTime - now + kFlushDelaySeconds; |
305 if (flushDelay < 0.) | 303 if (flushDelay < 0.) |
306 flushDelay = 0.; | 304 flushDelay = 0.; |
307 m_flushTimer.startOneShot(flushDelay, BLINK_FROM_HERE); | 305 m_flushTimer.startOneShot(flushDelay, BLINK_FROM_HERE); |
308 } | 306 } |
309 } | 307 } |
310 } | 308 } |
311 | 309 |
312 void ImageResource::flushImageIfNeeded(TimerBase*) { | 310 void ImageResource::flushImageIfNeeded(TimerBase*) { |
313 // We might have already loaded the image fully, in which case we don't need | 311 // We might have already loaded the image fully, in which case we don't need |
314 // to call |updateImage()|. | 312 // to call |updateImage()|. |
315 if (isLoading()) { | 313 if (isLoading()) { |
316 m_lastFlushTime = WTF::monotonicallyIncreasingTime(); | 314 m_lastFlushTime = WTF::monotonicallyIncreasingTime(); |
317 getContent()->updateImage(this->data(), ImageResourceContent::UpdateImage, | 315 updateImage(this->data(), ImageResourceContent::UpdateImage, false); |
318 false); | |
319 } | 316 } |
320 } | 317 } |
321 | 318 |
322 bool ImageResource::willPaintBrokenImage() const { | 319 bool ImageResource::willPaintBrokenImage() const { |
323 return errorOccurred(); | 320 return errorOccurred(); |
324 } | 321 } |
325 | 322 |
326 void ImageResource::decodeError(bool allDataReceived) { | 323 void ImageResource::decodeError(bool allDataReceived) { |
327 size_t size = encodedSize(); | 324 size_t size = encodedSize(); |
328 | 325 |
329 clearData(); | 326 clearData(); |
330 setEncodedSize(0); | 327 setEncodedSize(0); |
331 if (!errorOccurred()) | 328 if (!errorOccurred()) |
332 setStatus(DecodeError); | 329 setStatus(DecodeError); |
333 | 330 |
334 if (!allDataReceived && loader()) { | 331 if (!allDataReceived && loader()) { |
335 // TODO(hiroshige): Do not call didFinishLoading() directly. | 332 // TODO(hiroshige): Do not call didFinishLoading() directly. |
336 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); | 333 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); |
337 } | 334 } |
338 | 335 |
339 memoryCache()->remove(this); | 336 memoryCache()->remove(this); |
340 } | 337 } |
341 | 338 |
342 void ImageResource::updateImageAndClearBuffer() { | 339 void ImageResource::updateImageAndClearBuffer() { |
343 getContent()->updateImage(data(), ImageResourceContent::ClearAndUpdateImage, | 340 updateImage(data(), ImageResourceContent::ClearAndUpdateImage, true); |
344 true); | |
345 clearData(); | 341 clearData(); |
346 } | 342 } |
347 | 343 |
348 void ImageResource::finish(double loadFinishTime) { | 344 void ImageResource::finish(double loadFinishTime) { |
349 if (m_multipartParser) { | 345 if (m_multipartParser) { |
350 m_multipartParser->finish(); | 346 m_multipartParser->finish(); |
351 if (data()) | 347 if (data()) |
352 updateImageAndClearBuffer(); | 348 updateImageAndClearBuffer(); |
353 } else { | 349 } else { |
354 getContent()->updateImage(data(), ImageResourceContent::UpdateImage, true); | 350 updateImage(data(), ImageResourceContent::UpdateImage, true); |
355 // As encoded image data can be created from m_image (see | 351 // As encoded image data can be created from m_image (see |
356 // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's | 352 // ImageResource::resourceBuffer(), we don't have to keep m_data. Let's |
357 // clear this. As for the lifetimes of m_image and m_data, see this | 353 // clear this. As for the lifetimes of m_image and m_data, see this |
358 // document: | 354 // document: |
359 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1Vsqpxo
L7aciY/edit?usp=sharing | 355 // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1Vsqpxo
L7aciY/edit?usp=sharing |
360 clearData(); | 356 clearData(); |
361 } | 357 } |
362 Resource::finish(loadFinishTime); | 358 Resource::finish(loadFinishTime); |
363 } | 359 } |
364 | 360 |
365 void ImageResource::error(const ResourceError& error) { | 361 void ImageResource::error(const ResourceError& error) { |
366 if (m_multipartParser) | 362 if (m_multipartParser) |
367 m_multipartParser->cancel(); | 363 m_multipartParser->cancel(); |
368 // TODO(hiroshige): Move setEncodedSize() call to Resource::error() if it | 364 // TODO(hiroshige): Move setEncodedSize() call to Resource::error() if it |
369 // is really needed, or remove it otherwise. | 365 // is really needed, or remove it otherwise. |
370 setEncodedSize(0); | 366 setEncodedSize(0); |
371 Resource::error(error); | 367 Resource::error(error); |
372 getContent()->updateImage( | 368 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers, |
373 nullptr, ImageResourceContent::ClearImageAndNotifyObservers, true); | 369 true); |
374 } | 370 } |
375 | 371 |
376 void ImageResource::responseReceived( | 372 void ImageResource::responseReceived( |
377 const ResourceResponse& response, | 373 const ResourceResponse& response, |
378 std::unique_ptr<WebDataConsumerHandle> handle) { | 374 std::unique_ptr<WebDataConsumerHandle> handle) { |
379 DCHECK(!handle); | 375 DCHECK(!handle); |
380 DCHECK(!m_multipartParser); | 376 DCHECK(!m_multipartParser); |
381 // If there's no boundary, just handle the request normally. | 377 // If there's no boundary, just handle the request normally. |
382 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) { | 378 if (response.isMultipart() && !response.multipartBoundary().isEmpty()) { |
383 m_multipartParser = new MultipartImageResourceParser( | 379 m_multipartParser = new MultipartImageResourceParser( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 } | 430 } |
435 | 431 |
436 if (isLoading()) { | 432 if (isLoading()) { |
437 loader()->cancel(); | 433 loader()->cancel(); |
438 // Canceling the loader causes error() to be called, which in turn calls | 434 // Canceling the loader causes error() to be called, which in turn calls |
439 // clear() and notifyObservers(), so there's no need to call these again | 435 // clear() and notifyObservers(), so there's no need to call these again |
440 // here. | 436 // here. |
441 } else { | 437 } else { |
442 clearData(); | 438 clearData(); |
443 setEncodedSize(0); | 439 setEncodedSize(0); |
444 getContent()->updateImage( | 440 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers, |
445 nullptr, ImageResourceContent::ClearImageAndNotifyObservers, false); | 441 false); |
446 } | 442 } |
447 | 443 |
448 setStatus(NotStarted); | 444 setStatus(NotStarted); |
449 | 445 |
450 DCHECK(m_isSchedulingReload); | 446 DCHECK(m_isSchedulingReload); |
451 m_isSchedulingReload = false; | 447 m_isSchedulingReload = false; |
452 | 448 |
453 fetcher->startLoad(this); | 449 fetcher->startLoad(this); |
454 } | 450 } |
455 | 451 |
456 void ImageResource::onePartInMultipartReceived( | 452 void ImageResource::onePartInMultipartReceived( |
457 const ResourceResponse& response) { | 453 const ResourceResponse& response) { |
458 DCHECK(m_multipartParser); | 454 DCHECK(m_multipartParser); |
459 | 455 |
460 setResponse(response); | 456 setResponse(response); |
461 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { | 457 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { |
462 // We have nothing to do because we don't have any data. | 458 // We have nothing to do because we don't have any data. |
463 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; | 459 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; |
464 return; | 460 return; |
465 } | 461 } |
466 updateImageAndClearBuffer(); | 462 updateImageAndClearBuffer(); |
| 463 // We should create a new image again when the data for the next part arrive. |
| 464 m_shouldEnforceClearImage = true; |
467 | 465 |
468 if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) { | 466 if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) { |
469 m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart; | 467 m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart; |
470 // Notify finished when the first part ends. | 468 // Notify finished when the first part ends. |
471 if (!errorOccurred()) | 469 if (!errorOccurred()) |
472 setStatus(Cached); | 470 setStatus(Cached); |
473 // We notify clients and observers of finish in checkNotify() and | 471 // We notify clients and observers of finish in checkNotify() and |
474 // updateImageAndClearBuffer(), respectively, and they will not be | 472 // updateImageAndClearBuffer(), respectively, and they will not be |
475 // notified again in Resource::finish()/error(). | 473 // notified again in Resource::finish()/error(). |
476 checkNotify(); | 474 checkNotify(); |
(...skipping 28 matching lines...) Expand all Loading... |
505 } | 503 } |
506 | 504 |
507 const ImageResourceContent* ImageResource::getContent() const { | 505 const ImageResourceContent* ImageResource::getContent() const { |
508 return m_content; | 506 return m_content; |
509 } | 507 } |
510 | 508 |
511 ResourcePriority ImageResource::priorityFromObservers() { | 509 ResourcePriority ImageResource::priorityFromObservers() { |
512 return getContent()->priorityFromObservers(); | 510 return getContent()->priorityFromObservers(); |
513 } | 511 } |
514 | 512 |
| 513 void ImageResource::updateImage( |
| 514 PassRefPtr<SharedBuffer> sharedBuffer, |
| 515 ImageResourceContent::UpdateImageOption updateImageOption, |
| 516 bool allDataReceived) { |
| 517 if (m_shouldEnforceClearImage && |
| 518 updateImageOption == ImageResourceContent::UpdateImage) |
| 519 updateImageOption = ImageResourceContent::ClearAndUpdateImage; |
| 520 m_shouldEnforceClearImage = false; |
| 521 getContent()->updateImage(std::move(sharedBuffer), updateImageOption, |
| 522 allDataReceived); |
| 523 } |
| 524 |
515 } // namespace blink | 525 } // namespace blink |
OLD | NEW |