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

Unified Diff: third_party/WebKit/Source/core/fetch/ImageResource.cpp

Issue 2527353002: Phase II Step 3: Reload LoFi/placeholder images via new ImageResource
Patch Set: tests 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/fetch/ImageResource.cpp
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
index 861ca24e5593d5c717342eeda851d9ba20e75a74..e7dcdd2f23549d8a231cc76eec1f997832dc2652 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -36,6 +36,7 @@
#include "platform/SharedBuffer.h"
#include "platform/tracing/TraceEvent.h"
#include "public/platform/Platform.h"
+#include "public/platform/WebCachePolicy.h"
#include "wtf/CurrentTime.h"
#include "wtf/HashCountedSet.h"
#include "wtf/StdLibExtras.h"
@@ -67,9 +68,6 @@ class ImageResource::ImageResourceInfoImpl final
private:
const KURL& url() const override { return m_resource->url(); }
- bool isSchedulingReload() const override {
- return m_resource->m_isSchedulingReload;
- }
bool hasDevicePixelRatioHeaderValue() const override {
return m_resource->m_hasDevicePixelRatioHeaderValue;
}
@@ -86,9 +84,8 @@ class ImageResource::ImageResourceInfoImpl final
bool isCacheValidator() const override {
return m_resource->isCacheValidator();
}
- bool schedulingReloadOrShouldReloadBrokenPlaceholder() const override {
- return m_resource->m_isSchedulingReload ||
- m_resource->shouldReloadBrokenPlaceholder();
+ bool shouldReloadBrokenPlaceholder() const override {
+ return m_resource->shouldReloadBrokenPlaceholder();
}
bool isAccessAllowed(
SecurityOrigin* securityOrigin,
@@ -102,6 +99,7 @@ class ImageResource::ImageResourceInfoImpl final
const ResourceError& resourceError() const override {
return m_resource->resourceError();
}
+ ImageResource* resourceForTest() const override { return m_resource; }
void decodeError(bool allDataReceived) override {
m_resource->decodeError(allDataReceived);
@@ -123,6 +121,9 @@ class ImageResource::ImageResourceInfoImpl final
WebURLRequest::RequestContextImage,
initiatorName);
}
+ bool reloadIfLoFiOrPlaceholder(ResourceFetcher* fetcherForReload) override {
+ return m_resource->reloadIfLoFiOrPlaceholder(fetcherForReload);
+ }
Member<ImageResource> m_resource;
};
@@ -173,8 +174,10 @@ ImageResource* ImageResource::fetch(FetchRequest& request,
// If the image is a placeholder, but this fetch doesn't allow a
// placeholder, then load the original image. Note that the cache is not
// bypassed here - it should be fine to use a cached copy if possible.
- resource->reloadIfLoFiOrPlaceholder(fetcher,
- ReloadCachePolicy::UseExistingPolicy);
+ ImageResource* reloadingResource = resource->reloadIfLoFiOrPlaceholder(
+ fetcher, ReloadCachePolicy::UseExistingPolicy);
+ if (reloadingResource)
+ resource = reloadingResource;
}
return resource;
}
@@ -192,7 +195,6 @@ ImageResource::ImageResource(const ResourceRequest& resourceRequest,
m_content(content),
m_devicePixelRatioHeaderValue(1.0),
m_hasDevicePixelRatioHeaderValue(false),
- m_isSchedulingReload(false),
m_isPlaceholder(isPlaceholder),
m_flushTimer(this, &ImageResource::flushImageIfNeeded) {
DCHECK(getContent());
@@ -211,28 +213,14 @@ DEFINE_TRACE(ImageResource) {
MultipartImageResourceParser::Client::trace(visitor);
}
-void ImageResource::checkNotify() {
- // Don't notify clients of completion if this ImageResource is
- // about to be reloaded.
- if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
- return;
-
- Resource::checkNotify();
-}
-
bool ImageResource::hasClientsOrObservers() const {
- return Resource::hasClientsOrObservers() || getContent()->hasObservers();
+ return Resource::hasClientsOrObservers() ||
+ (getContent() && getContent()->hasObservers());
}
void ImageResource::didAddClient(ResourceClient* client) {
DCHECK((m_multipartParser && isLoading()) || !data() ||
- getContent()->hasImage());
-
- // Don't notify observers and clients of completion if this ImageResource is
- // about to be reloaded.
- if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
- return;
-
+ (getContent() && getContent()->hasImage()));
Resource::didAddClient(client);
}
@@ -242,6 +230,8 @@ void ImageResource::destroyDecodedDataForFailedRevalidation() {
}
void ImageResource::destroyDecodedDataIfPossible() {
+ if (!getContent())
+ return;
getContent()->destroyDecodedData();
if (getContent()->hasImage() && !isPreloaded() &&
getContent()->isRefetchableDataFromDiskCache()) {
@@ -251,16 +241,18 @@ void ImageResource::destroyDecodedDataIfPossible() {
}
void ImageResource::allClientsAndObserversRemoved() {
- CHECK(!getContent()->hasImage() || !errorOccurred());
+ CHECK(!getContent() || !getContent()->hasImage() || !errorOccurred());
// If possible, delay the resetting until back at the event loop. Doing so
// after a conservative GC prevents resetAnimation() from upsetting ongoing
// animation updates (crbug.com/613709)
- if (!ThreadHeap::willObjectBeLazilySwept(this)) {
- Platform::current()->currentThread()->getWebTaskRunner()->postTask(
- BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation,
- wrapWeakPersistent(getContent())));
- } else {
- getContent()->doResetAnimation();
+ if (getContent()) {
+ if (!ThreadHeap::willObjectBeLazilySwept(this)) {
+ Platform::current()->currentThread()->getWebTaskRunner()->postTask(
+ BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation,
+ wrapWeakPersistent(getContent())));
+ } else {
+ getContent()->doResetAnimation();
+ }
}
if (m_multipartParser)
m_multipartParser->cancel();
@@ -270,7 +262,7 @@ void ImageResource::allClientsAndObserversRemoved() {
PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const {
if (data())
return data();
- if (getContent()->hasImage())
+ if (getContent() && getContent()->hasImage())
return getContent()->getImage()->data();
return nullptr;
}
@@ -282,6 +274,9 @@ void ImageResource::appendData(const char* data, size_t length) {
} else {
Resource::appendData(data, length);
+ if (!getContent())
+ return;
+
// If we don't have the size available yet, then update immediately since
// we need to know the image size as soon as possible. Likewise for
// animated images, update right away since we shouldn't throttle animated
@@ -346,13 +341,15 @@ void ImageResource::updateImageAndClearBuffer() {
clearData();
}
-void ImageResource::finish(double loadFinishTime) {
+void ImageResource::finish(double loadFinishTime,
+ ResourceFetcher* fetcherForReload) {
if (m_multipartParser) {
m_multipartParser->finish();
if (data())
updateImageAndClearBuffer();
} else {
- updateImage(data(), ImageResourceContent::KeepExistingImage, true);
+ updateImage(data(), ImageResourceContent::KeepExistingImage, true,
+ fetcherForReload);
// As encoded image data can be created from m_image (see
// ImageResource::resourceBuffer(), we don't have to keep m_data. Let's
// clear this. As for the lifetimes of m_image and m_data, see this
@@ -360,15 +357,17 @@ void ImageResource::finish(double loadFinishTime) {
// https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1VsqpxoL7aciY/edit?usp=sharing
clearData();
}
- Resource::finish(loadFinishTime);
+ Resource::finish(loadFinishTime, fetcherForReload);
}
-void ImageResource::error(const ResourceError& error) {
+void ImageResource::error(const ResourceError& error,
+ ResourceFetcher* fetcherForReload) {
if (m_multipartParser)
m_multipartParser->cancel();
clearData();
- Resource::error(error);
- updateImage(nullptr, ImageResourceContent::ClearExistingImage, true);
+ Resource::error(error, fetcherForReload);
+ updateImage(nullptr, ImageResourceContent::ClearExistingImage, true,
+ fetcherForReload);
}
void ImageResource::responseReceived(
@@ -404,45 +403,44 @@ static bool isLoFiImage(const ImageResource& resource) {
.contains("empty-image");
}
-void ImageResource::reloadIfLoFiOrPlaceholder(
+void ImageResource::detachContent() {
+ bool hasObservers = getContent() && getContent()->hasObservers();
+
+ m_content = nullptr;
+ clearData();
+ memoryCache()->remove(this);
+
+ if (hasObservers)
+ didRemoveClientOrObserver();
+}
+
+ImageResource* ImageResource::reloadIfLoFiOrPlaceholder(
ResourceFetcher* fetcher,
ReloadCachePolicy reloadCachePolicy) {
+ if (!fetcher)
+ return nullptr;
if (!m_isPlaceholder && !isLoFiImage(*this))
- return;
-
- // Prevent clients and observers from being notified of completion while the
- // reload is being scheduled, so that e.g. canceling an existing load in
- // progress doesn't cause clients and observers to be notified of completion
- // prematurely.
- DCHECK(!m_isSchedulingReload);
- m_isSchedulingReload = true;
+ return nullptr;
+ ImageResourceContent* content = getContent();
+ if (!content)
+ return nullptr;
+ // Creates request/options for new ImageResource for reloading.
+ ResourceRequest reloadingRequest = resourceRequest();
+ ResourceLoaderOptions reloadingOptions = options();
if (reloadCachePolicy == ReloadCachePolicy::BypassCache)
- setCachePolicyBypassingCache();
- setLoFiStateOff();
-
- if (m_isPlaceholder) {
- m_isPlaceholder = false;
- clearRangeRequestHeader();
- }
-
- if (isLoading()) {
- loader()->cancel();
- // Canceling the loader causes error() to be called, which in turn calls
- // clear() and notifyObservers(), so there's no need to call these again
- // here.
- } else {
- clearData();
- setEncodedSize(0);
- updateImage(nullptr, ImageResourceContent::ClearExistingImage, false);
- }
-
- setStatus(NotStarted);
-
- DCHECK(m_isSchedulingReload);
- m_isSchedulingReload = false;
-
- fetcher->startLoad(this);
+ reloadingRequest.setCachePolicy(WebCachePolicy::BypassingCache);
+ reloadingRequest.setLoFiState(WebURLRequest::LoFiOff);
+ if (m_isPlaceholder)
+ reloadingRequest.clearHTTPHeaderField("range");
+
+ detachContent();
+ // Do not touch |this| after this point.
+
+ ImageResource* reloadingResource =
+ new ImageResource(reloadingRequest, reloadingOptions, content, false);
+ fetcher->startLoad(reloadingResource);
+ return reloadingResource;
}
void ImageResource::onePartInMultipartReceived(
@@ -496,18 +494,24 @@ ImageResourceContent* ImageResource::getContent() const {
}
ResourcePriority ImageResource::priorityFromObservers() {
+ if (!getContent())
+ return ResourcePriority();
+
return getContent()->priorityFromObservers();
}
void ImageResource::updateImage(
PassRefPtr<SharedBuffer> sharedBuffer,
ImageResourceContent::ClearImageOption clearImageOption,
- bool allDataReceived) {
+ bool allDataReceived,
+ ResourceFetcher* fetcherForReload) {
if (!m_isUpdateImageCalled)
clearImageOption = ImageResourceContent::ClearExistingImage;
m_isUpdateImageCalled = true;
- getContent()->updateImage(std::move(sharedBuffer), clearImageOption,
- allDataReceived);
+ if (getContent()) {
+ getContent()->updateImage(std::move(sharedBuffer), clearImageOption,
+ allDataReceived, fetcherForReload);
+ }
}
} // namespace blink

Powered by Google App Engine
This is Rietveld 408576698