| Index: third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
|
| diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
|
| similarity index 31%
|
| copy from third_party/WebKit/Source/core/fetch/ImageResource.cpp
|
| copy to third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
|
| index 0a454391815e5909ea81d4e931931a92341c7884..99a6f3886488709f929b59f067e4e8b7ae9747cf 100644
|
| --- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
|
| +++ b/third_party/WebKit/Source/core/fetch/ImageResourceContent.cpp
|
| @@ -1,34 +1,11 @@
|
| -/*
|
| - Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
|
| - Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
|
| - Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
|
| - Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
|
| - Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
|
| -
|
| - This library is free software; you can redistribute it and/or
|
| - modify it under the terms of the GNU Library General Public
|
| - License as published by the Free Software Foundation; either
|
| - version 2 of the License, or (at your option) any later version.
|
| -
|
| - This library is distributed in the hope that it will be useful,
|
| - but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
| - Library General Public License for more details.
|
| -
|
| - You should have received a copy of the GNU Library General Public License
|
| - along with this library; see the file COPYING.LIB. If not, write to
|
| - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
| - Boston, MA 02110-1301, USA.
|
| -*/
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
|
|
| -#include "core/fetch/ImageResource.h"
|
| +#include "core/fetch/ImageResourceContent.h"
|
|
|
| +#include "core/fetch/ImageResource.h"
|
| #include "core/fetch/ImageResourceObserver.h"
|
| -#include "core/fetch/MemoryCache.h"
|
| -#include "core/fetch/ResourceClient.h"
|
| -#include "core/fetch/ResourceFetcher.h"
|
| -#include "core/fetch/ResourceLoader.h"
|
| -#include "core/fetch/ResourceLoadingLog.h"
|
| #include "core/svg/graphics/SVGImage.h"
|
| #include "platform/Histogram.h"
|
| #include "platform/RuntimeEnabledFeatures.h"
|
| @@ -37,9 +14,6 @@
|
| #include "platform/graphics/BitmapImage.h"
|
| #include "platform/graphics/PlaceholderImage.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"
|
| #include "wtf/Vector.h"
|
| @@ -48,161 +22,98 @@
|
|
|
| namespace blink {
|
| namespace {
|
| -// The amount of time to wait before informing the clients that the image has
|
| -// been updated (in seconds). This effectively throttles invalidations that
|
| -// result from new data arriving for this image.
|
| -constexpr double kFlushDelaySeconds = 1.;
|
| -} // namespace
|
| -
|
| -class ImageResource::ImageResourceFactory : public ResourceFactory {
|
| - STACK_ALLOCATED();
|
| +class NullImageResourceInfo final
|
| + : public GarbageCollectedFinalized<NullImageResourceInfo>,
|
| + public ImageResourceInfo {
|
| + USING_GARBAGE_COLLECTED_MIXIN(NullImageResourceInfo);
|
|
|
| public:
|
| - ImageResourceFactory(const FetchRequest& fetchRequest)
|
| - : ResourceFactory(Resource::Image), m_fetchRequest(&fetchRequest) {}
|
| -
|
| - Resource* create(const ResourceRequest& request,
|
| - const ResourceLoaderOptions& options,
|
| - const String&) const override {
|
| - return new ImageResource(request, options,
|
| - m_fetchRequest->placeholderImageRequestType() ==
|
| - FetchRequest::AllowPlaceholder);
|
| - }
|
| + NullImageResourceInfo() {}
|
|
|
| - private:
|
| - // Weak, unowned pointer. Must outlive |this|.
|
| - const FetchRequest* m_fetchRequest;
|
| -};
|
| + DEFINE_INLINE_VIRTUAL_TRACE() { ImageResourceInfo::trace(visitor); }
|
|
|
| -ImageResource* ImageResource::fetch(FetchRequest& request,
|
| - ResourceFetcher* fetcher) {
|
| - if (request.resourceRequest().requestContext() ==
|
| - WebURLRequest::RequestContextUnspecified) {
|
| - request.mutableResourceRequest().setRequestContext(
|
| - WebURLRequest::RequestContextImage);
|
| + private:
|
| + const KURL& url() const override { return m_url; }
|
| + bool isSchedulingReload() const override { return false; }
|
| + bool hasDevicePixelRatioHeaderValue() const override { return false; }
|
| + float devicePixelRatioHeaderValue() const override { return 1.0; }
|
| + const ResourceResponse& response() const override { return m_response; }
|
| + ResourceStatus getStatus() const override { return ResourceStatus::Cached; }
|
| + bool isPlaceholder() const override { return false; }
|
| + bool isCacheValidator() const override { return false; }
|
| + bool schedulingReloadOrShouldReloadBrokenPlaceholder() const override {
|
| + return false;
|
| }
|
| - if (fetcher->context().pageDismissalEventBeingDispatched()) {
|
| - KURL requestURL = request.resourceRequest().url();
|
| - if (requestURL.isValid() &&
|
| - fetcher->context().canRequest(Resource::Image,
|
| - request.resourceRequest(), requestURL,
|
| - request.options(), request.forPreload(),
|
| - request.getOriginRestriction()))
|
| - fetcher->context().sendImagePing(requestURL);
|
| - return nullptr;
|
| + bool isAccessAllowed(
|
| + SecurityOrigin*,
|
| + bool doesCurrentFrameHasSingleSecurityOrigin) const override {
|
| + return true;
|
| }
|
| + bool hasCacheControlNoStoreHeader() const override { return false; }
|
| + const ResourceError& resourceError() const override { return m_error; }
|
|
|
| - ImageResource* resource = toImageResource(
|
| - fetcher->requestResource(request, ImageResourceFactory(request)));
|
| - if (resource &&
|
| - request.placeholderImageRequestType() != FetchRequest::AllowPlaceholder &&
|
| - resource->m_isPlaceholder) {
|
| - // 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);
|
| - }
|
| - return resource;
|
| -}
|
| -
|
| -ImageResource::ImageResource(const ResourceRequest& resourceRequest,
|
| - const ResourceLoaderOptions& options,
|
| - bool isPlaceholder)
|
| - : Resource(resourceRequest, Image, options),
|
| - m_devicePixelRatioHeaderValue(1.0),
|
| - m_image(nullptr),
|
| - m_hasDevicePixelRatioHeaderValue(false),
|
| - m_isSchedulingReload(false),
|
| - m_isPlaceholder(isPlaceholder),
|
| - m_flushTimer(this, &ImageResource::flushImageIfNeeded),
|
| - m_isRefetchableDataFromDiskCache(true) {
|
| - RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this;
|
| -}
|
| -
|
| -ImageResource::ImageResource(blink::Image* image,
|
| - const ResourceLoaderOptions& options)
|
| - : Resource(ResourceRequest(""), Image, options),
|
| - m_devicePixelRatioHeaderValue(1.0),
|
| - m_image(image),
|
| - m_hasDevicePixelRatioHeaderValue(false),
|
| - m_isSchedulingReload(false),
|
| - m_isPlaceholder(false),
|
| - m_flushTimer(this, &ImageResource::flushImageIfNeeded),
|
| - m_isRefetchableDataFromDiskCache(true) {
|
| - RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this;
|
| - setStatus(Cached);
|
| -}
|
| -
|
| -ImageResource::~ImageResource() {
|
| - RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this;
|
| - clearImage();
|
| -}
|
| -
|
| -DEFINE_TRACE(ImageResource) {
|
| - visitor->trace(m_multipartParser);
|
| - Resource::trace(visitor);
|
| - ImageObserver::trace(visitor);
|
| - MultipartImageResourceParser::Client::trace(visitor);
|
| + const KURL m_url;
|
| + const ResourceResponse m_response;
|
| + const ResourceError m_error;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class ResourceFetcher;
|
| +
|
| +ImageResourceContent::ImageResourceContent(PassRefPtr<blink::Image> image)
|
| + : m_image(image), m_isRefetchableDataFromDiskCache(true) {
|
| + DEFINE_STATIC_LOCAL(NullImageResourceInfo, nullInfo,
|
| + (new NullImageResourceInfo()));
|
| + m_info = &nullInfo;
|
| }
|
|
|
| -void ImageResource::checkNotify() {
|
| - // Don't notify clients of completion if this ImageResource is
|
| - // about to be reloaded.
|
| - if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
|
| - return;
|
| +ImageResourceContent* ImageResourceContent::fetch(FetchRequest& request,
|
| + ResourceFetcher* fetcher) {
|
| + ImageResource* resource = ImageResource::fetch(request, fetcher);
|
| + if (!resource)
|
| + return nullptr;
|
| + return resource->getRealContent();
|
| +}
|
| +
|
| +void ImageResourceContent::setImageResourceInfo(ImageResourceInfo* info) {
|
| + m_info = info;
|
| +}
|
|
|
| - Resource::checkNotify();
|
| +DEFINE_TRACE(ImageResourceContent) {
|
| + visitor->trace(m_info);
|
| + ImageObserver::trace(visitor);
|
| + ImageResourceContentInterface::trace(visitor);
|
| }
|
|
|
| -void ImageResource::markObserverFinished(ImageResourceObserver* observer) {
|
| +void ImageResourceContent::markObserverFinished(
|
| + ImageResourceObserver* observer) {
|
| if (m_observers.contains(observer)) {
|
| m_finishedObservers.add(observer);
|
| m_observers.remove(observer);
|
| }
|
| }
|
|
|
| -void ImageResource::didAddClient(ResourceClient* client) {
|
| - DCHECK((m_multipartParser && isLoading()) || !data() || m_image);
|
| -
|
| - // Don't notify observers and clients of completion if this ImageResource is
|
| - // about to be reloaded.
|
| - if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
|
| - return;
|
| -
|
| - Resource::didAddClient(client);
|
| -}
|
| -
|
| -void ImageResource::addObserver(ImageResourceObserver* observer) {
|
| - willAddClientOrObserver(MarkAsReferenced);
|
| +void ImageResourceContent::addObserver(ImageResourceObserver* observer) {
|
| + m_info->willAddClientOrObserver();
|
|
|
| m_observers.add(observer);
|
|
|
| - if (isCacheValidator())
|
| + if (m_info->isCacheValidator())
|
| return;
|
|
|
| - // When the response is not multipart, if |data()| exists, |m_image| must be
|
| - // created. This is assured that |updateImage()| is called when |appendData()|
|
| - // is called.
|
| - //
|
| - // On the other hand, when the response is multipart, |updateImage()| is not
|
| - // called in |appendData()|, which means |m_image| might not be created even
|
| - // when |data()| exists. This is intentional since creating a |m_image| on
|
| - // receiving data might destroy an existing image in a previous part.
|
| - DCHECK((m_multipartParser && isLoading()) || !data() || m_image);
|
| -
|
| if (m_image && !m_image->isNull()) {
|
| observer->imageChanged(this);
|
| }
|
|
|
| - if (isLoaded() && m_observers.contains(observer) && !m_isSchedulingReload &&
|
| - !shouldReloadBrokenPlaceholder()) {
|
| + if (isLoaded() && m_observers.contains(observer) &&
|
| + !m_info->schedulingReloadOrShouldReloadBrokenPlaceholder()) {
|
| markObserverFinished(observer);
|
| observer->imageNotifyFinished(this);
|
| }
|
| }
|
|
|
| -void ImageResource::removeObserver(ImageResourceObserver* observer) {
|
| +void ImageResourceContent::removeObserver(ImageResourceObserver* observer) {
|
| DCHECK(observer);
|
|
|
| if (m_observers.contains(observer))
|
| @@ -212,7 +123,7 @@ void ImageResource::removeObserver(ImageResourceObserver* observer) {
|
| else
|
| NOTREACHED();
|
|
|
| - didRemoveClientOrObserver();
|
| + m_info->didRemoveClientOrObserver();
|
| }
|
|
|
| static void priorityFromObserver(const ImageResourceObserver* observer,
|
| @@ -224,7 +135,7 @@ static void priorityFromObserver(const ImageResourceObserver* observer,
|
| priority.intraPriorityValue += nextPriority.intraPriorityValue;
|
| }
|
|
|
| -ResourcePriority ImageResource::priorityFromObservers() {
|
| +ResourcePriority ImageResourceContent::priorityFromObservers() const {
|
| ResourcePriority priority;
|
|
|
| for (auto* observer : m_finishedObservers.asVector()) {
|
| @@ -239,100 +150,19 @@ ResourcePriority ImageResource::priorityFromObservers() {
|
| return priority;
|
| }
|
|
|
| -void ImageResource::destroyDecodedDataForFailedRevalidation() {
|
| - clearImage();
|
| - setDecodedSize(0);
|
| -}
|
| -
|
| -void ImageResource::destroyDecodedDataIfPossible() {
|
| +void ImageResourceContent::destroyDecodedData() {
|
| if (!m_image)
|
| return;
|
| CHECK(!errorOccurred());
|
| m_image->destroyDecodedData();
|
| - if (!isPreloaded() && m_isRefetchableDataFromDiskCache) {
|
| - UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize",
|
| - encodedSize() / 1024);
|
| - }
|
| }
|
|
|
| -void ImageResource::doResetAnimation() {
|
| +void ImageResourceContent::doResetAnimation() {
|
| if (m_image)
|
| m_image->resetAnimation();
|
| }
|
|
|
| -void ImageResource::allClientsAndObserversRemoved() {
|
| - if (m_image) {
|
| - CHECK(!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(&ImageResource::doResetAnimation,
|
| - wrapWeakPersistent(this)));
|
| - } else {
|
| - m_image->resetAnimation();
|
| - }
|
| - }
|
| - if (m_multipartParser)
|
| - m_multipartParser->cancel();
|
| - Resource::allClientsAndObserversRemoved();
|
| -}
|
| -
|
| -PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const {
|
| - if (data())
|
| - return data();
|
| - if (m_image)
|
| - return m_image->data();
|
| - return nullptr;
|
| -}
|
| -
|
| -void ImageResource::appendData(const char* data, size_t length) {
|
| - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length);
|
| - if (m_multipartParser) {
|
| - m_multipartParser->appendData(data, length);
|
| - } else {
|
| - Resource::appendData(data, length);
|
| -
|
| - // 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
|
| - // images.
|
| - if (m_sizeAvailable == Image::SizeUnavailable ||
|
| - (m_image && m_image->maybeAnimated())) {
|
| - updateImage(false);
|
| - return;
|
| - }
|
| -
|
| - // For other cases, only update at |kFlushDelaySeconds| intervals. This
|
| - // throttles how frequently we update |m_image| and how frequently we
|
| - // inform the clients which causes an invalidation of this image. In other
|
| - // words, we only invalidate this image every |kFlushDelaySeconds| seconds
|
| - // while loading.
|
| - if (!m_flushTimer.isActive()) {
|
| - double now = WTF::monotonicallyIncreasingTime();
|
| - if (!m_lastFlushTime)
|
| - m_lastFlushTime = now;
|
| -
|
| - DCHECK_LE(m_lastFlushTime, now);
|
| - double flushDelay = m_lastFlushTime - now + kFlushDelaySeconds;
|
| - if (flushDelay < 0.)
|
| - flushDelay = 0.;
|
| - m_flushTimer.startOneShot(flushDelay, BLINK_FROM_HERE);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ImageResource::flushImageIfNeeded(TimerBase*) {
|
| - // We might have already loaded the image fully, in which case we don't need
|
| - // to call |updateImage()|.
|
| - if (isLoading()) {
|
| - m_lastFlushTime = WTF::monotonicallyIncreasingTime();
|
| - updateImage(false);
|
| - }
|
| -}
|
| -
|
| -std::pair<blink::Image*, float> ImageResource::brokenImage(
|
| +std::pair<blink::Image*, float> ImageResourceContent::brokenImage(
|
| float deviceScaleFactor) {
|
| if (deviceScaleFactor >= 2) {
|
| DEFINE_STATIC_REF(blink::Image, brokenImageHiRes,
|
| @@ -345,15 +175,11 @@ std::pair<blink::Image*, float> ImageResource::brokenImage(
|
| return std::make_pair(brokenImageLoRes, 1);
|
| }
|
|
|
| -bool ImageResource::willPaintBrokenImage() const {
|
| - return errorOccurred();
|
| -}
|
| -
|
| -blink::Image* ImageResource::getImage() {
|
| +blink::Image* ImageResourceContent::getImage() const {
|
| if (errorOccurred()) {
|
| // Returning the 1x broken image is non-ideal, but we cannot reliably access
|
| // the appropriate deviceScaleFactor from here. It is critical that callers
|
| - // use ImageResource::brokenImage() when they need the real,
|
| + // use ImageResourceContent::brokenImage() when they need the real,
|
| // deviceScaleFactor-appropriate broken image icon.
|
| return brokenImage(1).first;
|
| }
|
| @@ -364,21 +190,21 @@ blink::Image* ImageResource::getImage() {
|
| return blink::Image::nullImage();
|
| }
|
|
|
| -bool ImageResource::usesImageContainerSize() const {
|
| +bool ImageResourceContent::usesImageContainerSize() const {
|
| if (m_image)
|
| return m_image->usesContainerSize();
|
|
|
| return false;
|
| }
|
|
|
| -bool ImageResource::imageHasRelativeSize() const {
|
| +bool ImageResourceContent::imageHasRelativeSize() const {
|
| if (m_image)
|
| return m_image->hasRelativeSize();
|
|
|
| return false;
|
| }
|
|
|
| -LayoutSize ImageResource::imageSize(
|
| +LayoutSize ImageResourceContent::imageSize(
|
| RespectImageOrientationEnum shouldRespectImageOrientation,
|
| float multiplier,
|
| SizeType sizeType) {
|
| @@ -395,9 +221,9 @@ LayoutSize ImageResource::imageSize(
|
| size = LayoutSize(m_image->size());
|
| }
|
|
|
| - if (sizeType == IntrinsicCorrectedToDPR && m_hasDevicePixelRatioHeaderValue &&
|
| - m_devicePixelRatioHeaderValue > 0)
|
| - multiplier = 1 / m_devicePixelRatioHeaderValue;
|
| + if (sizeType == IntrinsicCorrectedToDPR && hasDevicePixelRatioHeaderValue() &&
|
| + devicePixelRatioHeaderValue() > 0)
|
| + multiplier = 1 / devicePixelRatioHeaderValue();
|
|
|
| if (multiplier == 1 || m_image->hasRelativeSize())
|
| return size;
|
| @@ -411,8 +237,9 @@ LayoutSize ImageResource::imageSize(
|
| return size;
|
| }
|
|
|
| -void ImageResource::notifyObservers(NotifyFinishOption notifyingFinishOption,
|
| - const IntRect* changeRect) {
|
| +void ImageResourceContent::notifyObservers(
|
| + NotifyFinishOption notifyingFinishOption,
|
| + const IntRect* changeRect) {
|
| for (auto* observer : m_finishedObservers.asVector()) {
|
| if (m_finishedObservers.contains(observer))
|
| observer->imageChanged(this, changeRect);
|
| @@ -421,8 +248,8 @@ void ImageResource::notifyObservers(NotifyFinishOption notifyingFinishOption,
|
| if (m_observers.contains(observer)) {
|
| observer->imageChanged(this, changeRect);
|
| if (notifyingFinishOption == ShouldNotifyFinish &&
|
| - m_observers.contains(observer) && !m_isSchedulingReload &&
|
| - !shouldReloadBrokenPlaceholder()) {
|
| + m_observers.contains(observer) &&
|
| + !m_info->schedulingReloadOrShouldReloadBrokenPlaceholder()) {
|
| markObserverFinished(observer);
|
| observer->imageNotifyFinished(this);
|
| }
|
| @@ -430,25 +257,13 @@ void ImageResource::notifyObservers(NotifyFinishOption notifyingFinishOption,
|
| }
|
| }
|
|
|
| -void ImageResource::clear() {
|
| - clearImage();
|
| - clearData();
|
| - setEncodedSize(0);
|
| +inline PassRefPtr<Image> ImageResourceContent::createImage() {
|
| + if (m_info->response().mimeType() == "image/svg+xml")
|
| + return SVGImage::create(this);
|
| + return BitmapImage::create(this);
|
| }
|
|
|
| -inline void ImageResource::createImage() {
|
| - // Create the image if it doesn't yet exist.
|
| - if (m_image)
|
| - return;
|
| -
|
| - if (response().mimeType() == "image/svg+xml") {
|
| - m_image = SVGImage::create(this);
|
| - } else {
|
| - m_image = BitmapImage::create(this);
|
| - }
|
| -}
|
| -
|
| -inline void ImageResource::clearImage() {
|
| +inline void ImageResourceContent::clearImage() {
|
| if (!m_image)
|
| return;
|
| int64_t length = m_image->data() ? m_image->data()->size() : 0;
|
| @@ -461,18 +276,23 @@ inline void ImageResource::clearImage() {
|
| m_sizeAvailable = Image::SizeUnavailable;
|
| }
|
|
|
| -void ImageResource::updateImage(bool allDataReceived) {
|
| - TRACE_EVENT0("blink", "ImageResource::updateImage");
|
| +void ImageResourceContent::updateImage(PassRefPtr<SharedBuffer> data,
|
| + ClearImageOption clearImageOption,
|
| + bool allDataReceived) {
|
| + TRACE_EVENT0("blink", "ImageResourceContent::updateImage");
|
|
|
| - if (data())
|
| - createImage();
|
| + if (clearImageOption == ImageResourceContent::ClearExistingImage) {
|
| + clearImage();
|
| + }
|
|
|
| // Have the image update its data from its internal buffer. It will not do
|
| // anything now, but will delay decoding until queried for info (like size or
|
| // specific image frames).
|
| - if (data()) {
|
| + if (data) {
|
| + if (!m_image)
|
| + m_image = createImage();
|
| DCHECK(m_image);
|
| - m_sizeAvailable = m_image->setData(data(), allDataReceived);
|
| + m_sizeAvailable = m_image->setData(std::move(data), allDataReceived);
|
| }
|
|
|
| // Go ahead and tell our observers to try to draw if we have either received
|
| @@ -481,12 +301,14 @@ void ImageResource::updateImage(bool allDataReceived) {
|
| if (m_sizeAvailable == Image::SizeUnavailable && !allDataReceived)
|
| return;
|
|
|
| - if (m_isPlaceholder && allDataReceived && m_image && !m_image->isNull()) {
|
| + if (m_info->isPlaceholder() && allDataReceived && m_image &&
|
| + !m_image->isNull()) {
|
| if (m_sizeAvailable == Image::SizeAvailable) {
|
| // TODO(sclittle): Show the original image if the response consists of the
|
| // entire image, such as if the entire image response body is smaller than
|
| // the requested range.
|
| IntSize dimensions = m_image->size();
|
| +
|
| clearImage();
|
| m_image = PlaceholderImage::create(this, dimensions);
|
| } else {
|
| @@ -497,14 +319,8 @@ void ImageResource::updateImage(bool allDataReceived) {
|
| }
|
|
|
| if (!m_image || m_image->isNull()) {
|
| - size_t size = encodedSize();
|
| - clear();
|
| - if (!errorOccurred())
|
| - setStatus(DecodeError);
|
| - if (!allDataReceived && loader()) {
|
| - loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size);
|
| - }
|
| - memoryCache()->remove(this);
|
| + clearImage();
|
| + m_info->decodeError(allDataReceived);
|
| }
|
|
|
| // It would be nice to only redraw the decoded band of the image, but with the
|
| @@ -512,70 +328,14 @@ void ImageResource::updateImage(bool allDataReceived) {
|
| notifyObservers(allDataReceived ? ShouldNotifyFinish : DoNotNotifyFinish);
|
| }
|
|
|
| -void ImageResource::updateImageAndClearBuffer() {
|
| - clearImage();
|
| - updateImage(true);
|
| - clearData();
|
| -}
|
| -
|
| -void ImageResource::finish(double loadFinishTime) {
|
| - if (m_multipartParser) {
|
| - m_multipartParser->finish();
|
| - if (data())
|
| - updateImageAndClearBuffer();
|
| - } else {
|
| - updateImage(true);
|
| - // 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
|
| - // document:
|
| - // https://docs.google.com/document/d/1v0yTAZ6wkqX2U_M6BNIGUJpM1s0TIw1VsqpxoL7aciY/edit?usp=sharing
|
| - clearData();
|
| - }
|
| - Resource::finish(loadFinishTime);
|
| -}
|
| -
|
| -void ImageResource::error(const ResourceError& error) {
|
| - if (m_multipartParser)
|
| - m_multipartParser->cancel();
|
| - clear();
|
| - Resource::error(error);
|
| - notifyObservers(ShouldNotifyFinish);
|
| -}
|
| -
|
| -void ImageResource::responseReceived(
|
| - const ResourceResponse& response,
|
| - std::unique_ptr<WebDataConsumerHandle> handle) {
|
| - DCHECK(!handle);
|
| - DCHECK(!m_multipartParser);
|
| - // If there's no boundary, just handle the request normally.
|
| - if (response.isMultipart() && !response.multipartBoundary().isEmpty()) {
|
| - m_multipartParser = new MultipartImageResourceParser(
|
| - response, response.multipartBoundary(), this);
|
| - }
|
| - Resource::responseReceived(response, std::move(handle));
|
| - if (RuntimeEnabledFeatures::clientHintsEnabled()) {
|
| - m_devicePixelRatioHeaderValue =
|
| - this->response()
|
| - .httpHeaderField(HTTPNames::Content_DPR)
|
| - .toFloat(&m_hasDevicePixelRatioHeaderValue);
|
| - if (!m_hasDevicePixelRatioHeaderValue ||
|
| - m_devicePixelRatioHeaderValue <= 0.0) {
|
| - m_devicePixelRatioHeaderValue = 1.0;
|
| - m_hasDevicePixelRatioHeaderValue = false;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ImageResource::decodedSizeChangedTo(const blink::Image* image,
|
| - size_t newSize) {
|
| +void ImageResourceContent::decodedSizeChangedTo(const blink::Image* image,
|
| + size_t newSize) {
|
| if (!image || image != m_image)
|
| return;
|
| -
|
| - setDecodedSize(newSize);
|
| + m_info->setDecodedSize(newSize);
|
| }
|
|
|
| -bool ImageResource::shouldPauseAnimation(const blink::Image* image) {
|
| +bool ImageResourceContent::shouldPauseAnimation(const blink::Image* image) {
|
| if (!image || image != m_image)
|
| return false;
|
|
|
| @@ -592,13 +352,13 @@ bool ImageResource::shouldPauseAnimation(const blink::Image* image) {
|
| return true;
|
| }
|
|
|
| -void ImageResource::animationAdvanced(const blink::Image* image) {
|
| +void ImageResourceContent::animationAdvanced(const blink::Image* image) {
|
| if (!image || image != m_image)
|
| return;
|
| notifyObservers(DoNotNotifyFinish);
|
| }
|
|
|
| -void ImageResource::updateImageAnimationPolicy() {
|
| +void ImageResourceContent::updateImageAnimationPolicy() {
|
| if (!m_image)
|
| return;
|
|
|
| @@ -620,103 +380,71 @@ void ImageResource::updateImageAnimationPolicy() {
|
| }
|
| }
|
|
|
| -static bool isLoFiImage(const ImageResource& resource) {
|
| - if (resource.resourceRequest().loFiState() != WebURLRequest::LoFiOn)
|
| - return false;
|
| - return !resource.isLoaded() ||
|
| - resource.response()
|
| - .httpHeaderField("chrome-proxy-content-transform")
|
| - .contains("empty-image");
|
| +void ImageResourceContent::changedInRect(const blink::Image* image,
|
| + const IntRect& rect) {
|
| + if (!image || image != m_image)
|
| + return;
|
| + notifyObservers(DoNotNotifyFinish, &rect);
|
| }
|
|
|
| -void ImageResource::reloadIfLoFiOrPlaceholder(
|
| - ResourceFetcher* fetcher,
|
| - ReloadCachePolicy reloadCachePolicy) {
|
| - if (!m_isPlaceholder && !isLoFiImage(*this))
|
| - return;
|
| +bool ImageResourceContent::isAccessAllowed(
|
| + SecurityOrigin* securityOrigin) const {
|
| + return m_info->isAccessAllowed(
|
| + securityOrigin, getImage()->currentFrameHasSingleSecurityOrigin());
|
| +}
|
|
|
| - // 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;
|
| +void ImageResourceContent::emulateLoadStartedForInspector(
|
| + ResourceFetcher* fetcher,
|
| + const KURL& url,
|
| + const AtomicString& initiatorName) {
|
| + m_info->emulateLoadStartedForInspector(fetcher, url, initiatorName);
|
| +}
|
|
|
| - if (reloadCachePolicy == ReloadCachePolicy::BypassCache)
|
| - setCachePolicyBypassingCache();
|
| - setLoFiStateOff();
|
| +// TODO(hiroshige): Consider removing the following methods, or stoping
|
| +// redirecting to ImageResource.
|
| +bool ImageResourceContent::isLoaded() const {
|
| + return getStatus() > ResourceStatus::Pending;
|
| +}
|
|
|
| - if (m_isPlaceholder) {
|
| - m_isPlaceholder = false;
|
| - clearRangeRequestHeader();
|
| - }
|
| +bool ImageResourceContent::isLoading() const {
|
| + return getStatus() == ResourceStatus::Pending;
|
| +}
|
|
|
| - 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 {
|
| - clear();
|
| - notifyObservers(DoNotNotifyFinish);
|
| - }
|
| +bool ImageResourceContent::errorOccurred() const {
|
| + return getStatus() == ResourceStatus::LoadError ||
|
| + getStatus() == ResourceStatus::DecodeError;
|
| +}
|
|
|
| - setStatus(NotStarted);
|
| +bool ImageResourceContent::loadFailedOrCanceled() const {
|
| + return getStatus() == ResourceStatus::LoadError;
|
| +}
|
|
|
| - DCHECK(m_isSchedulingReload);
|
| - m_isSchedulingReload = false;
|
| +ResourceStatus ImageResourceContent::getStatus() const {
|
| + return m_info->getStatus();
|
| +}
|
|
|
| - fetcher->startLoad(this);
|
| +const KURL& ImageResourceContent::url() const {
|
| + return m_info->url();
|
| }
|
|
|
| -void ImageResource::changedInRect(const blink::Image* image,
|
| - const IntRect& rect) {
|
| - if (!image || image != m_image)
|
| - return;
|
| - notifyObservers(DoNotNotifyFinish, &rect);
|
| +bool ImageResourceContent::hasCacheControlNoStoreHeader() const {
|
| + return m_info->hasCacheControlNoStoreHeader();
|
| }
|
|
|
| -void ImageResource::onePartInMultipartReceived(
|
| - const ResourceResponse& response) {
|
| - DCHECK(m_multipartParser);
|
| +float ImageResourceContent::devicePixelRatioHeaderValue() const {
|
| + return m_info->devicePixelRatioHeaderValue();
|
| +}
|
|
|
| - setResponse(response);
|
| - if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) {
|
| - // We have nothing to do because we don't have any data.
|
| - m_multipartParsingState = MultipartParsingState::ParsingFirstPart;
|
| - return;
|
| - }
|
| - updateImageAndClearBuffer();
|
| -
|
| - if (m_multipartParsingState == MultipartParsingState::ParsingFirstPart) {
|
| - m_multipartParsingState = MultipartParsingState::FinishedParsingFirstPart;
|
| - // Notify finished when the first part ends.
|
| - if (!errorOccurred())
|
| - setStatus(Cached);
|
| - // We notify clients and observers of finish in checkNotify() and
|
| - // updateImageAndClearBuffer(), respectively, and they will not be
|
| - // notified again in Resource::finish()/error().
|
| - checkNotify();
|
| - if (loader())
|
| - loader()->didFinishLoadingFirstPartInMultipart();
|
| - }
|
| +bool ImageResourceContent::hasDevicePixelRatioHeaderValue() const {
|
| + return m_info->hasDevicePixelRatioHeaderValue();
|
| }
|
|
|
| -void ImageResource::multipartDataReceived(const char* bytes, size_t size) {
|
| - DCHECK(m_multipartParser);
|
| - Resource::appendData(bytes, size);
|
| +const ResourceResponse& ImageResourceContent::response() const {
|
| + return m_info->response();
|
| }
|
|
|
| -bool ImageResource::isAccessAllowed(SecurityOrigin* securityOrigin) {
|
| - if (response().wasFetchedViaServiceWorker()) {
|
| - return response().serviceWorkerResponseType() !=
|
| - WebServiceWorkerResponseTypeOpaque;
|
| - }
|
| - if (!getImage()->currentFrameHasSingleSecurityOrigin())
|
| - return false;
|
| - if (passesAccessControlCheck(securityOrigin))
|
| - return true;
|
| - return !securityOrigin->taintsCanvas(response().url());
|
| +const ResourceError& ImageResourceContent::resourceError() const {
|
| + return m_info->resourceError();
|
| }
|
|
|
| } // namespace blink
|
|
|