Files
palemoon27/image/ImageCacheKey.cpp
T
roytam1 cbc917768b import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1266578 - OOM crash if malloc fails in ProcessIncomingMessages(). r=billm (5eca51be20)
- Bug 1261340: Don't refer to |ScopedFreePtrTraits| in |RawDBusConnection|, r=shuang (61996db57c)
- Bug 1246931: Move |DBusWatcher| into its own files, r=shuang (a7fc4a68c3)
- Bug 1246931: Add support for |RefPtr<DBusConnection>| and convert callers, r=shuang (6c07d3e8d3)
- Bug 1246931: Add support for |RefPtr<DBusMessage>|, r=shuang (c0ed14cc2b)
- Bug 1246931: Add support for |RefPtr<DBusPendingCall>|, r=shuang (a007a15699)
- Bug 1246931: Use |DBusConnection| in |DBusWatcher|, r=shuang (11b5eaf535)
- Bug 1246931: Add DBus I/O helpers, r=shuang (be249fa65b)
- Bug 1264398 - Avoid extra assign() on windows in IPC code (r=jld) (0f31b798a3)
- Bug 1261231: Fix shutdown leak in imgLoader::GetInstance. r=gabor (96e5143c41)
- Bug 1256999 - Use nsIDocument for ImageCacheKey. r=bz r=seth (cd4765ce34)
- Bug 1257101. imgFrame::IsImageComplete says whether we've had pixels decoded to the whole image rect, but it's used to check if the frame is finished decoding. These are different things when the image has more than one progress pass. r=seth (06d619410f)
- Bug 1222596. If RasterImage::LookupFrame does (some) sync decoding and encouters an error we don't want to return the surface with an error. r=seth (c4dbc8e0d5)
- Bug 763784 - Make VectorImage::GetAnimated check for CSS animations. r=dholbert (4d0e5b88eb)
- Bug 1210745 - Update CheckProgressConsistency() to match current ImageLib behavior. r=tn (2317b24fcc)
- Bug 1249576. Add crashtest. (485f03120b)
- Bug 1251091. Add crashtest. (7e1682a1e6)
- Bug 1253362. SVGDocumentWrapper::IsAnimated can be called after SVGDocumentWrapper::DestroyViewer so null check mViewer. r=dholbert (2b4a1c4619)
- Bug 1210745. Change image progress asserts to allow transparency to be posted after the size is posted. r=seth (699f3c5496)
- Bug 1209780. Use the DrawResult return value of imgIContainer::Draw in the cocoa code. r=seth (abaea789e3)
- No Bug - Remove some unnecessary SVGImageContext.h includes and add comments. r=sparky (8232661a23)
- cleanup style (de33e4bfa8)
- Bug 860857, support custom datatransfer types using a special type, r=smaug,jmathies,mstange (cf7e19deb6)
- Bug 1248459 - Don't query out-of-bounds selection; r=masayuki (86c127f143)
- Bug 1261671 - ContentEventHandler::ConvertToRootRelativeOffset() should return the root-relative result in the frame's own appUnits, not the root's appUnits in the case when they're different. r=masayuki (2cd72b5ebc)
- Bug 1266702 - Clean up formatting in dom/events/DataTransfer.* and mark some methods const, r=jwatt (bd439cdad5)
2024-07-26 21:49:43 +08:00

162 lines
4.5 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ImageCacheKey.h"
#include "mozilla/Move.h"
#include "File.h"
#include "ImageURL.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsString.h"
#include "mozilla/dom/workers/ServiceWorkerManager.h"
#include "nsIDocument.h"
#include "nsPrintfCString.h"
namespace mozilla {
using namespace dom;
namespace image {
bool
URISchemeIs(ImageURL* aURI, const char* aScheme)
{
bool schemeMatches = false;
if (NS_WARN_IF(NS_FAILED(aURI->SchemeIs(aScheme, &schemeMatches)))) {
return false;
}
return schemeMatches;
}
static Maybe<uint64_t>
BlobSerial(ImageURL* aURI)
{
nsAutoCString spec;
aURI->GetSpec(spec);
RefPtr<BlobImpl> blob;
if (NS_SUCCEEDED(NS_GetBlobForBlobURISpec(spec, getter_AddRefs(blob))) &&
blob) {
return Some(blob->GetSerialNumber());
}
return Nothing();
}
ImageCacheKey::ImageCacheKey(nsIURI* aURI, nsIDocument* aDocument)
: mURI(new ImageURL(aURI))
, mControlledDocument(GetControlledDocumentToken(aDocument))
, mIsChrome(URISchemeIs(mURI, "chrome"))
{
MOZ_ASSERT(NS_IsMainThread());
if (URISchemeIs(mURI, "blob")) {
mBlobSerial = BlobSerial(mURI);
}
mHash = ComputeHash(mURI, mBlobSerial, mControlledDocument);
}
ImageCacheKey::ImageCacheKey(ImageURL* aURI, nsIDocument* aDocument)
: mURI(aURI)
, mControlledDocument(GetControlledDocumentToken(aDocument))
, mIsChrome(URISchemeIs(mURI, "chrome"))
{
MOZ_ASSERT(aURI);
if (URISchemeIs(mURI, "blob")) {
mBlobSerial = BlobSerial(mURI);
}
mHash = ComputeHash(mURI, mBlobSerial, mControlledDocument);
}
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
: mURI(aOther.mURI)
, mBlobSerial(aOther.mBlobSerial)
, mControlledDocument(aOther.mControlledDocument)
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
: mURI(Move(aOther.mURI))
, mBlobSerial(Move(aOther.mBlobSerial))
, mControlledDocument(aOther.mControlledDocument)
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
bool
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
{
// Don't share the image cache between a controlled document and anything else.
if (mControlledDocument != aOther.mControlledDocument) {
return false;
}
if (mBlobSerial || aOther.mBlobSerial) {
// If at least one of us has a blob serial, just compare the blob serial and
// the ref portion of the URIs.
return mBlobSerial == aOther.mBlobSerial &&
mURI->HasSameRef(*aOther.mURI);
}
// For non-blob URIs, compare the URIs.
return *mURI == *aOther.mURI;
}
const char*
ImageCacheKey::Spec() const
{
return mURI->Spec();
}
/* static */ uint32_t
ImageCacheKey::ComputeHash(ImageURL* aURI,
const Maybe<uint64_t>& aBlobSerial,
void* aControlledDocument)
{
// Since we frequently call Hash() several times in a row on the same
// ImageCacheKey, as an optimization we compute our hash once and store it.
nsPrintfCString ptr("%p", aControlledDocument);
if (aBlobSerial) {
// For blob URIs, we hash the serial number of the underlying blob, so that
// different blob URIs which point to the same blob share a cache entry. We
// also include the ref portion of the URI to support -moz-samplesize and
// -moz-resolution, which require us to create different Image objects even
// if the source data is the same.
nsAutoCString ref;
aURI->GetRef(ref);
return HashGeneric(*aBlobSerial, HashString(ref + ptr));
}
// For non-blob URIs, we hash the URI spec.
nsAutoCString spec;
aURI->GetSpec(spec);
return HashString(spec + ptr);
}
/* static */ void*
ImageCacheKey::GetControlledDocumentToken(nsIDocument* aDocument)
{
// For non-controlled documents, we just return null. For controlled
// documents, we cast the pointer into a void* to avoid dereferencing
// it (since we only use it for comparisons), and return it.
void* pointer = nullptr;
using dom::workers::ServiceWorkerManager;
RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
if (aDocument && swm) {
ErrorResult rv;
if (swm->IsControlled(aDocument, rv)) {
pointer = aDocument;
}
}
return pointer;
}
} // namespace image
} // namespace mozilla