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

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

Issue 2552653002: Explicitly clear the image in the first updateImage() call (Closed)
Patch Set: Rebase Created 3 years, 11 months 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
« no previous file with comments | « third_party/WebKit/Source/core/loader/resource/ImageResource.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/loader/resource/ImageResource.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698