Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: third_party/WebKit/Source/core/fetch/ImageResource.cpp

Issue 2552653002: Explicitly clear the image in the first updateImage() call (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698