mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1065818 - Clean up memory reports and use of decoded size for image cache entries. r=tn,njn
This commit is contained in:
parent
7cb3650347
commit
5a483e9cb1
@ -43,41 +43,17 @@ DynamicImage::FrameRect(uint32_t aWhichFrame)
|
||||
return nsIntRect(0, 0, size.width, size.height);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
DynamicImage::SizeOfData()
|
||||
{
|
||||
// We don't know the answer to this (and the same goes for the other
|
||||
// memory-related methods) since gfxDrawable doesn't expose a way to check.
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicImage::HeapSizeOfSourceWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
DynamicImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicImage::HeapSizeOfDecodedWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicImage::NonHeapSizeOfDecoded() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicImage::OutOfProcessSizeOfDecoded() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
DynamicImage::HeapSizeOfVectorImageDocument(nsACString* aDocURL) const
|
||||
DynamicImage::SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// We don't know the answer since gfxDrawable doesn't expose this information.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -37,12 +37,9 @@ public:
|
||||
virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
|
||||
virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
|
||||
|
||||
virtual uint32_t SizeOfData() MOZ_OVERRIDE;
|
||||
virtual size_t HeapSizeOfSourceWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t HeapSizeOfDecodedWithComputedFallback(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t NonHeapSizeOfDecoded() const MOZ_OVERRIDE;
|
||||
virtual size_t OutOfProcessSizeOfDecoded() const MOZ_OVERRIDE;
|
||||
virtual size_t HeapSizeOfVectorImageDocument(nsACString* aDocURL = nullptr) const MOZ_OVERRIDE;
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
|
||||
virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
|
@ -563,26 +563,23 @@ FrameBlender::Discard()
|
||||
}
|
||||
|
||||
size_t
|
||||
FrameBlender::SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
FrameBlender::SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
for (uint32_t i = 0; i < mFrames.Length(); ++i) {
|
||||
n += mFrames[i]->SizeOfExcludingThisWithComputedFallbackIfHeap(aLocation,
|
||||
aMallocSizeOf);
|
||||
n += mFrames[i]->SizeOfExcludingThis(aLocation, aMallocSizeOf);
|
||||
}
|
||||
|
||||
if (mAnim) {
|
||||
if (mAnim->compositingFrame) {
|
||||
n += mAnim->compositingFrame
|
||||
->SizeOfExcludingThisWithComputedFallbackIfHeap(aLocation,
|
||||
aMallocSizeOf);
|
||||
->SizeOfExcludingThis(aLocation, aMallocSizeOf);
|
||||
}
|
||||
if (mAnim->compositingPrevFrame) {
|
||||
n += mAnim->compositingPrevFrame
|
||||
->SizeOfExcludingThisWithComputedFallbackIfHeap(aLocation,
|
||||
aMallocSizeOf);
|
||||
->SizeOfExcludingThis(aLocation, aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,8 +72,8 @@ public:
|
||||
|
||||
void SetSize(nsIntSize aSize) { mSize = aSize; }
|
||||
|
||||
size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const;
|
||||
size_t SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
void ResetAnimation();
|
||||
|
||||
|
@ -24,21 +24,6 @@ ImageResource::ImageResource(ImageURL* aURI) :
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ImageResource::SizeOfData()
|
||||
{
|
||||
if (mError)
|
||||
return 0;
|
||||
|
||||
// This is not used by memory reporters, but for sizing the cache, which is
|
||||
// why it uses |moz_malloc_size_of| rather than a
|
||||
// |MOZ_DEFINE_MALLOC_SIZE_OF|.
|
||||
return uint32_t(HeapSizeOfSourceWithComputedFallback(moz_malloc_size_of) +
|
||||
HeapSizeOfDecodedWithComputedFallback(moz_malloc_size_of) +
|
||||
NonHeapSizeOfDecoded() +
|
||||
OutOfProcessSizeOfDecoded());
|
||||
}
|
||||
|
||||
// Translates a mimetype into a concrete decoder
|
||||
Image::eDecoderType
|
||||
Image::GetDecoderType(const char *aMimeType)
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define MOZILLA_IMAGELIB_IMAGE_H_
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "gfx2DGlue.h" // for gfxMemoryLocation
|
||||
#include "imgIContainer.h"
|
||||
#include "ProgressTracker.h"
|
||||
#include "ImageURL.h"
|
||||
@ -72,25 +73,17 @@ public:
|
||||
virtual nsIntRect FrameRect(uint32_t aWhichFrame) = 0;
|
||||
|
||||
/**
|
||||
* The size, in bytes, occupied by the significant data portions of the image.
|
||||
* This includes both compressed source data and decoded frames.
|
||||
* The size, in bytes, occupied by the compressed source data of the image.
|
||||
* If MallocSizeOf does not work on this platform, uses a fallback approach to
|
||||
* ensure that something reasonable is always returned.
|
||||
*/
|
||||
virtual uint32_t SizeOfData() = 0;
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const = 0;
|
||||
|
||||
/**
|
||||
* The components that make up SizeOfData().
|
||||
* The size, in bytes, occupied by the image's decoded data.
|
||||
*/
|
||||
virtual size_t HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const = 0;
|
||||
virtual size_t HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const = 0;
|
||||
virtual size_t NonHeapSizeOfDecoded() const = 0;
|
||||
virtual size_t OutOfProcessSizeOfDecoded() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the size of the memory taken up for the parsed vector image's
|
||||
* document (e.g. SVGDocument), and returns the document's URL via the
|
||||
* aDocURL outparam.
|
||||
*/
|
||||
virtual size_t HeapSizeOfVectorImageDocument(nsACString* aDocURL = nullptr) const = 0;
|
||||
virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const = 0;
|
||||
|
||||
virtual void IncrementAnimationConsumers() = 0;
|
||||
virtual void DecrementAnimationConsumers() = 0;
|
||||
@ -156,7 +149,6 @@ public:
|
||||
MOZ_ASSERT(!mProgressTracker);
|
||||
mProgressTracker = aProgressTracker;
|
||||
}
|
||||
virtual uint32_t SizeOfData() MOZ_OVERRIDE;
|
||||
|
||||
virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
|
@ -39,34 +39,17 @@ ImageWrapper::FrameRect(uint32_t aWhichFrame)
|
||||
return mInnerImage->FrameRect(aWhichFrame);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ImageWrapper::SizeOfData()
|
||||
size_t
|
||||
ImageWrapper::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return mInnerImage->SizeOfData();
|
||||
return mInnerImage->SizeOfSourceWithComputedFallback(aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
ImageWrapper::HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
ImageWrapper::SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return mInnerImage->HeapSizeOfSourceWithComputedFallback(aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
ImageWrapper::HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return mInnerImage->HeapSizeOfDecodedWithComputedFallback(aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
ImageWrapper::NonHeapSizeOfDecoded() const
|
||||
{
|
||||
return mInnerImage->NonHeapSizeOfDecoded();
|
||||
}
|
||||
|
||||
size_t
|
||||
ImageWrapper::OutOfProcessSizeOfDecoded() const
|
||||
{
|
||||
return mInnerImage->OutOfProcessSizeOfDecoded();
|
||||
return mInnerImage->SizeOfDecoded(aLocation, aMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -27,15 +27,8 @@ public:
|
||||
virtual already_AddRefed<ProgressTracker> GetProgressTracker() MOZ_OVERRIDE;
|
||||
virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
|
||||
|
||||
virtual uint32_t SizeOfData() MOZ_OVERRIDE;
|
||||
virtual size_t HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t NonHeapSizeOfDecoded() const MOZ_OVERRIDE;
|
||||
virtual size_t OutOfProcessSizeOfDecoded() const MOZ_OVERRIDE;
|
||||
|
||||
virtual size_t HeapSizeOfVectorImageDocument(nsACString* aDocURL = nullptr) const MOZ_OVERRIDE {
|
||||
return mInnerImage->HeapSizeOfVectorImageDocument(aDocURL);
|
||||
}
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
|
||||
virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
|
||||
|
@ -964,7 +964,7 @@ RasterImage::UpdateImageContainer()
|
||||
}
|
||||
|
||||
size_t
|
||||
RasterImage::HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
RasterImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// n == 0 is possible for two reasons.
|
||||
// - This is a zero-length image.
|
||||
@ -978,39 +978,17 @@ RasterImage::HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) co
|
||||
}
|
||||
|
||||
size_t
|
||||
RasterImage::SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
RasterImage::SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t n = 0;
|
||||
n += SurfaceCache::SizeOfSurfaces(ImageKey(this), aLocation, aMallocSizeOf);
|
||||
if (mFrameBlender) {
|
||||
n += mFrameBlender->SizeOfDecodedWithComputedFallbackIfHeap(aLocation,
|
||||
aMallocSizeOf);
|
||||
n += mFrameBlender->SizeOfDecoded(aLocation, aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t
|
||||
RasterImage::HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation::IN_PROCESS_HEAP,
|
||||
aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
RasterImage::NonHeapSizeOfDecoded() const
|
||||
{
|
||||
return SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation::IN_PROCESS_NONHEAP,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
size_t
|
||||
RasterImage::OutOfProcessSizeOfDecoded() const
|
||||
{
|
||||
return SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation::OUT_OF_PROCESS,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
RawAccessFrameRef
|
||||
RasterImage::InternalAddFrame(uint32_t aFrameNum,
|
||||
const nsIntRect& aFrameRect,
|
||||
|
@ -171,14 +171,9 @@ public:
|
||||
/* The total number of frames in this image. */
|
||||
uint32_t GetNumFrames() const;
|
||||
|
||||
virtual size_t HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t NonHeapSizeOfDecoded() const;
|
||||
virtual size_t OutOfProcessSizeOfDecoded() const;
|
||||
|
||||
virtual size_t HeapSizeOfVectorImageDocument(nsACString* aDocURL = nullptr) const MOZ_OVERRIDE {
|
||||
return 0;
|
||||
}
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
/* Triggers discarding. */
|
||||
void Discard(bool aForce = false, bool aNotify = true);
|
||||
|
@ -175,9 +175,8 @@ public:
|
||||
if (!aCachedSurface->mSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSum += aCachedSurface->mSurface->
|
||||
SizeOfExcludingThisWithComputedFallbackIfHeap(mLocation, mMallocSizeOf);
|
||||
mSum += aCachedSurface->mSurface->SizeOfExcludingThis(mLocation,
|
||||
mMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t Result() const { return mSum; }
|
||||
|
@ -366,71 +366,35 @@ VectorImage::FrameRect(uint32_t aWhichFrame)
|
||||
}
|
||||
|
||||
size_t
|
||||
VectorImage::HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// We're not storing the source data -- we just feed that directly to
|
||||
// our helper SVG document as we receive it, for it to parse.
|
||||
// So 0 is an appropriate return value here.
|
||||
// If implementing this, we'll need to restructure our callers to make sure
|
||||
// any amount we return is attributed to the vector images measure (i.e.
|
||||
// "explicit/images/{content,chrome}/vector/{used,unused}/...")
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
VectorImage::HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// If implementing this, we'll need to restructure our callers to make sure
|
||||
// any amount we return is attributed to the vector images measure (i.e.
|
||||
// "explicit/images/{content,chrome}/vector/{used,unused}/...")
|
||||
// XXX(seth): Same goes for the other *SizeOfDecoded() methods. We'll do this
|
||||
// in bug 921300 or one of its blockers. For now it seems worthwhile to get
|
||||
// this memory accounted for, even if it gets listed under 'raster'. It does
|
||||
// make some perverse sense, since we are after all reporting on raster data
|
||||
// here - it just happens to be computed from a vector document.
|
||||
return SurfaceCache::SizeOfSurfaces(ImageKey(this),
|
||||
gfxMemoryLocation::IN_PROCESS_HEAP,
|
||||
aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
VectorImage::NonHeapSizeOfDecoded() const
|
||||
{
|
||||
return SurfaceCache::SizeOfSurfaces(ImageKey(this),
|
||||
gfxMemoryLocation::IN_PROCESS_NONHEAP,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
size_t
|
||||
VectorImage::OutOfProcessSizeOfDecoded() const
|
||||
{
|
||||
return SurfaceCache::SizeOfSurfaces(ImageKey(this),
|
||||
gfxMemoryLocation::OUT_OF_PROCESS,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf);
|
||||
|
||||
size_t
|
||||
VectorImage::HeapSizeOfVectorImageDocument(nsACString* aDocURL) const
|
||||
VectorImage::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
nsIDocument* doc = mSVGDocumentWrapper->GetDocument();
|
||||
if (!doc) {
|
||||
if (aDocURL) {
|
||||
mURI->GetSpec(*aDocURL);
|
||||
}
|
||||
return 0; // No document, so no memory used for the document
|
||||
return 0; // No document, so no memory used for the document.
|
||||
}
|
||||
|
||||
if (aDocURL) {
|
||||
doc->GetDocumentURI()->GetSpec(*aDocURL);
|
||||
}
|
||||
|
||||
nsWindowSizes windowSizes(WindowsMallocSizeOf);
|
||||
nsWindowSizes windowSizes(aMallocSizeOf);
|
||||
doc->DocAddSizeOfIncludingThis(&windowSizes);
|
||||
|
||||
if (windowSizes.getTotalSize() == 0) {
|
||||
// MallocSizeOf fails on this platform. Because we also use this method for
|
||||
// determining the size of cache entries, we need to return something
|
||||
// reasonable here. Unfortunately, there's no way to estimate the document's
|
||||
// size accurately, so we just use a constant value of 100KB, which will
|
||||
// generally underestimate the true size.
|
||||
return 100 * 1024;
|
||||
}
|
||||
|
||||
return windowSizes.getTotalSize();
|
||||
}
|
||||
|
||||
size_t
|
||||
VectorImage::SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return SurfaceCache::SizeOfSurfaces(ImageKey(this), aLocation, aMallocSizeOf);
|
||||
}
|
||||
|
||||
nsresult
|
||||
VectorImage::OnImageDataComplete(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
|
@ -42,12 +42,9 @@ public:
|
||||
uint32_t aFlags);
|
||||
virtual nsIntRect FrameRect(uint32_t aWhichFrame) MOZ_OVERRIDE;
|
||||
|
||||
virtual size_t HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const;
|
||||
virtual size_t NonHeapSizeOfDecoded() const;
|
||||
virtual size_t OutOfProcessSizeOfDecoded() const;
|
||||
|
||||
virtual size_t HeapSizeOfVectorImageDocument(nsACString* aDocURL = nullptr) const MOZ_OVERRIDE;
|
||||
virtual size_t SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
virtual size_t SizeOfDecoded(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
|
@ -905,11 +905,9 @@ void imgFrame::SetCompositingFailed(bool val)
|
||||
mCompositingFailed = val;
|
||||
}
|
||||
|
||||
// If |aLocation| indicates this is heap memory, we try to measure things with
|
||||
// |aMallocSizeOf|. If that fails (because the platform doesn't support it) or
|
||||
// it's non-heap memory, we fall back to computing the size analytically.
|
||||
size_t
|
||||
imgFrame::SizeOfExcludingThisWithComputedFallbackIfHeap(gfxMemoryLocation aLocation, MallocSizeOf aMallocSizeOf) const
|
||||
imgFrame::SizeOfExcludingThis(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
// aMallocSizeOf is only used if aLocation==gfxMemoryLocation::IN_PROCESS_HEAP. It
|
||||
// should be nullptr otherwise.
|
||||
@ -921,13 +919,8 @@ imgFrame::SizeOfExcludingThisWithComputedFallbackIfHeap(gfxMemoryLocation aLocat
|
||||
size_t n = 0;
|
||||
|
||||
if (mPalettedImageData && aLocation == gfxMemoryLocation::IN_PROCESS_HEAP) {
|
||||
size_t n2 = aMallocSizeOf(mPalettedImageData);
|
||||
if (n2 == 0) {
|
||||
n2 = GetImageDataLength() + PaletteDataLength();
|
||||
}
|
||||
n += n2;
|
||||
n += aMallocSizeOf(mPalettedImageData);
|
||||
}
|
||||
|
||||
if (mImageSurface && aLocation == gfxMemoryLocation::IN_PROCESS_HEAP) {
|
||||
n += aMallocSizeOf(mImageSurface);
|
||||
}
|
||||
|
@ -131,9 +131,8 @@ public:
|
||||
|
||||
TemporaryRef<SourceSurface> CachedSurface();
|
||||
|
||||
size_t SizeOfExcludingThisWithComputedFallbackIfHeap(
|
||||
gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const;
|
||||
size_t SizeOfExcludingThis(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
uint8_t GetPaletteDepth() const { return mPaletteDepth; }
|
||||
uint32_t PaletteDataLength() const {
|
||||
|
@ -54,75 +54,39 @@ MOZ_DEFINE_MALLOC_SIZE_OF(ImagesMallocSizeOf)
|
||||
|
||||
class imgMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||
{
|
||||
~imgMemoryReporter() {}
|
||||
~imgMemoryReporter() { }
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aHandleReport,
|
||||
nsISupports *aData, bool aAnonymize)
|
||||
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData, bool aAnonymize)
|
||||
{
|
||||
nsresult rv;
|
||||
ImageSizes chrome;
|
||||
ImageSizes content;
|
||||
ImageSizes uncached;
|
||||
nsTArray<ImageMemoryCounter> chrome;
|
||||
nsTArray<ImageMemoryCounter> content;
|
||||
nsTArray<ImageMemoryCounter> uncached;
|
||||
|
||||
for (uint32_t i = 0; i < mKnownLoaders.Length(); i++) {
|
||||
mKnownLoaders[i]->mChromeCache.EnumerateRead(EntryImageSizes, &chrome);
|
||||
mKnownLoaders[i]->mCache.EnumerateRead(EntryImageSizes, &content);
|
||||
mKnownLoaders[i]->mChromeCache.EnumerateRead(DoRecordCounter, &chrome);
|
||||
mKnownLoaders[i]->mCache.EnumerateRead(DoRecordCounter, &content);
|
||||
MutexAutoLock lock(mKnownLoaders[i]->mUncachedImagesMutex);
|
||||
mKnownLoaders[i]->mUncachedImages.EnumerateEntries(EntryUncachedImageSizes, &uncached);
|
||||
mKnownLoaders[i]->
|
||||
mUncachedImages.EnumerateEntries(DoRecordCounterUncached, &uncached);
|
||||
}
|
||||
|
||||
// Note that we only need to anonymize content image URIs.
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, chrome.mRasterUsedImageInfo,
|
||||
"images/chrome/raster/used");
|
||||
rv = ReportCounterArray(aHandleReport, aData, chrome, "images/chrome");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, chrome.mRasterUnusedImageInfo,
|
||||
"images/chrome/raster/unused");
|
||||
rv = ReportCounterArray(aHandleReport, aData, content,
|
||||
"images/content", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, chrome.mVectorUsedImageDocInfo,
|
||||
"images/chrome/vector/used/documents");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, chrome.mVectorUnusedImageDocInfo,
|
||||
"images/chrome/vector/unused/documents");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, content.mRasterUsedImageInfo,
|
||||
"images/content/raster/used", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, content.mRasterUnusedImageInfo,
|
||||
"images/content/raster/unused", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, content.mVectorUsedImageDocInfo,
|
||||
"images/content/vector/used/documents", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, content.mVectorUnusedImageDocInfo,
|
||||
"images/content/vector/unused/documents", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The uncached images can contain both content and chrome images, so anonymize it.
|
||||
rv = ReportInfoArray(aHandleReport, aData, uncached.mRasterUsedImageInfo,
|
||||
"images/uncached/raster/used", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, uncached.mRasterUnusedImageInfo,
|
||||
"images/uncached/raster/unused", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, uncached.mVectorUsedImageDocInfo,
|
||||
"images/uncached/vector/used/documents", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportInfoArray(aHandleReport, aData, uncached.mVectorUnusedImageDocInfo,
|
||||
"images/uncached/vector/unused/documents", aAnonymize);
|
||||
// Uncached images may be content or chrome, so anonymize them.
|
||||
rv = ReportCounterArray(aHandleReport, aData, uncached,
|
||||
"images/uncached", aAnonymize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@ -132,7 +96,8 @@ public:
|
||||
{
|
||||
size_t n = 0;
|
||||
for (uint32_t i = 0; i < imgLoader::sMemReporter->mKnownLoaders.Length(); i++) {
|
||||
imgLoader::sMemReporter->mKnownLoaders[i]->mCache.EnumerateRead(EntryUsedUncompressedSize, &n);
|
||||
imgLoader::sMemReporter->mKnownLoaders[i]->
|
||||
mCache.EnumerateRead(DoRecordCounterUsedDecoded, &n);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@ -150,306 +115,342 @@ public:
|
||||
private:
|
||||
nsTArray<imgLoader*> mKnownLoaders;
|
||||
|
||||
struct RasterSizes
|
||||
struct MemoryCounter
|
||||
{
|
||||
size_t mRaw;
|
||||
size_t mUncompressedHeap;
|
||||
size_t mUncompressedNonheap;
|
||||
MemoryCounter()
|
||||
: mSource(0)
|
||||
, mDecodedHeap(0)
|
||||
, mDecodedNonHeap(0)
|
||||
{ }
|
||||
|
||||
RasterSizes()
|
||||
: mRaw(0)
|
||||
, mUncompressedHeap(0)
|
||||
, mUncompressedNonheap(0)
|
||||
{}
|
||||
void SetSource(size_t aCount) { mSource = aCount; }
|
||||
size_t Source() const { return mSource; }
|
||||
void SetDecodedHeap(size_t aCount) { mDecodedHeap = aCount; }
|
||||
size_t DecodedHeap() const { return mDecodedHeap; }
|
||||
void SetDecodedNonHeap(size_t aCount) { mDecodedNonHeap = aCount; }
|
||||
size_t DecodedNonHeap() const { return mDecodedNonHeap; }
|
||||
|
||||
void add(const RasterSizes &aOther)
|
||||
MemoryCounter& operator+=(const MemoryCounter& aOther)
|
||||
{
|
||||
mRaw += aOther.mRaw;
|
||||
mUncompressedHeap += aOther.mUncompressedHeap;
|
||||
mUncompressedNonheap += aOther.mUncompressedNonheap;
|
||||
mSource += aOther.mSource;
|
||||
mDecodedHeap += aOther.mDecodedHeap;
|
||||
mDecodedNonHeap += aOther.mDecodedNonHeap;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isNotable() const
|
||||
{
|
||||
const size_t NotableThreshold = 16 * 1024;
|
||||
size_t total = mRaw + mUncompressedHeap + mUncompressedNonheap;
|
||||
return total >= NotableThreshold;
|
||||
}
|
||||
private:
|
||||
size_t mSource;
|
||||
size_t mDecodedHeap;
|
||||
size_t mDecodedNonHeap;
|
||||
};
|
||||
|
||||
struct VectorDocSizes
|
||||
struct ImageMemoryCounter
|
||||
{
|
||||
size_t mSize;
|
||||
|
||||
VectorDocSizes()
|
||||
: mSize(0)
|
||||
{}
|
||||
|
||||
void add(const VectorDocSizes &aOther)
|
||||
ImageMemoryCounter(uint16_t aType, const nsACString& aURI, bool aIsUsed)
|
||||
: mURI(aURI)
|
||||
, mType(aType)
|
||||
, mIsUsed(aIsUsed)
|
||||
{
|
||||
mSize += aOther.mSize;
|
||||
MOZ_ASSERT(!mURI.IsEmpty(), "Should have a URI for all images");
|
||||
}
|
||||
|
||||
bool isNotable() const
|
||||
nsCString& URI() { return mURI; }
|
||||
const nsCString& URI() const { return mURI; }
|
||||
uint16_t Type() const { return mType; }
|
||||
MemoryCounter& Values() { return mValues; }
|
||||
const MemoryCounter& Values() const { return mValues; }
|
||||
bool IsUsed() const { return mIsUsed; }
|
||||
|
||||
bool IsNotable() const
|
||||
{
|
||||
const size_t NotableThreshold = 16 * 1024;
|
||||
size_t total = mSize;
|
||||
size_t total = mValues.Source() + mValues.DecodedHeap()
|
||||
+ mValues.DecodedNonHeap();
|
||||
return total >= NotableThreshold;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ImageSizes>
|
||||
struct ImageInfo
|
||||
{
|
||||
ImageSizes mSizes;
|
||||
private:
|
||||
nsCString mURI;
|
||||
uint16_t mType;
|
||||
MemoryCounter mValues;
|
||||
bool mIsUsed;
|
||||
};
|
||||
|
||||
struct ImageSizes
|
||||
struct MemoryTotal
|
||||
{
|
||||
nsTArray<ImageInfo<RasterSizes> > mRasterUsedImageInfo;
|
||||
nsTArray<ImageInfo<RasterSizes> > mRasterUnusedImageInfo;
|
||||
nsTArray<ImageInfo<VectorDocSizes> > mVectorUsedImageDocInfo;
|
||||
nsTArray<ImageInfo<VectorDocSizes> > mVectorUnusedImageDocInfo;
|
||||
};
|
||||
|
||||
// Definitions specialized for raster and vector images are below.
|
||||
template<typename Sizes>
|
||||
nsresult ReportSizes(nsIMemoryReporterCallback *aHandleReport,
|
||||
nsISupports *aData,
|
||||
const nsACString &aPathPrefix,
|
||||
const nsACString &aLocation,
|
||||
Sizes aSizes);
|
||||
|
||||
// This is used to report all images of a single kind, e.g. all
|
||||
// "chrome/raster/used" images.
|
||||
template <typename Sizes>
|
||||
nsresult ReportInfoArray(nsIMemoryReporterCallback *aHandleReport,
|
||||
nsISupports *aData,
|
||||
const nsTArray<ImageInfo<Sizes> > &aInfoArray,
|
||||
const char *aPathPartStr, bool aAnonymize = false)
|
||||
{
|
||||
nsresult rv;
|
||||
Sizes totalSizes;
|
||||
Sizes nonNotableSizes;
|
||||
|
||||
nsCString pathPart(aPathPartStr);
|
||||
nsCString explicitPathPrefix(aPathPartStr);
|
||||
explicitPathPrefix.Insert("explicit/", 0);
|
||||
|
||||
// Report notable images, and compute total and non-notable aggregate sizes.
|
||||
for (uint32_t i = 0; i < aInfoArray.Length(); i++) {
|
||||
ImageInfo<Sizes> info = aInfoArray[i];
|
||||
|
||||
if (aAnonymize) {
|
||||
info.mURI.Truncate();
|
||||
info.mURI.AppendPrintf("<anonymized-%u>", i);
|
||||
} else {
|
||||
// info.mURI can be a data: URI, and thus extremely long. Truncate if
|
||||
// necessary.
|
||||
static const size_t max = 256;
|
||||
if (info.mURI.Length() > max) {
|
||||
info.mURI.Truncate(max);
|
||||
info.mURI.AppendLiteral(" (truncated)");
|
||||
MemoryTotal& operator+=(const ImageMemoryCounter& aImageCounter)
|
||||
{
|
||||
if (aImageCounter.Type() == imgIContainer::TYPE_RASTER) {
|
||||
if (aImageCounter.IsUsed()) {
|
||||
mUsedRasterCounter += aImageCounter.Values();
|
||||
} else {
|
||||
mUnusedRasterCounter += aImageCounter.Values();
|
||||
}
|
||||
info.mURI.ReplaceChar('/', '\\');
|
||||
} else if (aImageCounter.Type() == imgIContainer::TYPE_VECTOR) {
|
||||
if (aImageCounter.IsUsed()) {
|
||||
mUsedVectorCounter += aImageCounter.Values();
|
||||
} else {
|
||||
mUnusedVectorCounter += aImageCounter.Values();
|
||||
}
|
||||
} else {
|
||||
MOZ_CRASH("Unexpected image type");
|
||||
}
|
||||
|
||||
totalSizes.add(info.mSizes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (!info.mSizes.isNotable()) {
|
||||
nonNotableSizes.add(info.mSizes);
|
||||
const MemoryCounter& UsedRaster() const { return mUsedRasterCounter; }
|
||||
const MemoryCounter& UnusedRaster() const { return mUnusedRasterCounter; }
|
||||
const MemoryCounter& UsedVector() const { return mUsedVectorCounter; }
|
||||
const MemoryCounter& UnusedVector() const { return mUnusedVectorCounter; }
|
||||
|
||||
private:
|
||||
MemoryCounter mUsedRasterCounter;
|
||||
MemoryCounter mUnusedRasterCounter;
|
||||
MemoryCounter mUsedVectorCounter;
|
||||
MemoryCounter mUnusedVectorCounter;
|
||||
};
|
||||
|
||||
|
||||
// Reports all images of a single kind, e.g. all used chrome images.
|
||||
nsresult ReportCounterArray(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
const nsTArray<ImageMemoryCounter>& aCounterArray,
|
||||
const char* aPathPrefix,
|
||||
bool aAnonymize = false)
|
||||
{
|
||||
nsresult rv;
|
||||
MemoryTotal summaryTotal;
|
||||
MemoryTotal nonNotableTotal;
|
||||
|
||||
// Report notable images, and compute total and non-notable aggregate sizes.
|
||||
for (uint32_t i = 0; i < aCounterArray.Length(); i++) {
|
||||
ImageMemoryCounter counter = aCounterArray[i];
|
||||
|
||||
if (aAnonymize) {
|
||||
counter.URI().Truncate();
|
||||
counter.URI().AppendPrintf("<anonymized-%u>", i);
|
||||
} else {
|
||||
// Report the notable image.
|
||||
rv = ReportSizes(aHandleReport, aData, explicitPathPrefix,
|
||||
info.mURI, info.mSizes);
|
||||
// The URI could be an extremely long data: URI. Truncate if needed.
|
||||
static const size_t max = 256;
|
||||
if (counter.URI().Length() > max) {
|
||||
counter.URI().Truncate(max);
|
||||
counter.URI().AppendLiteral(" (truncated)");
|
||||
}
|
||||
counter.URI().ReplaceChar('/', '\\');
|
||||
}
|
||||
|
||||
summaryTotal += counter;
|
||||
|
||||
if (counter.IsNotable()) {
|
||||
rv = ReportCounter(aHandleReport, aData, aPathPrefix, counter);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
nonNotableTotal += counter;
|
||||
}
|
||||
}
|
||||
|
||||
// Report non-notable images in aggregate.
|
||||
rv = ReportSizes(aHandleReport, aData, explicitPathPrefix,
|
||||
NS_LITERAL_CSTRING("<non-notable images>"),
|
||||
nonNotableSizes);
|
||||
rv = ReportTotal(aHandleReport, aData, /* aExplicit = */ true,
|
||||
aPathPrefix, "<non-notable images>/", nonNotableTotal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Report image totals in aggregate, without the "explicit/" prefix.
|
||||
rv = ReportSizes(aHandleReport, aData, pathPart, EmptyCString(),
|
||||
totalSizes);
|
||||
// Report a summary in aggregate, outside of the explicit tree.
|
||||
rv = ReportTotal(aHandleReport, aData, /* aExplicit = */ false,
|
||||
aPathPrefix, "", summaryTotal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PLDHashOperator EntryImageSizes(const nsACString&,
|
||||
imgCacheEntry *aEntry,
|
||||
void *aUserArg)
|
||||
static nsresult ReportCounter(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
const char* aPathPrefix,
|
||||
const ImageMemoryCounter& aCounter)
|
||||
{
|
||||
nsRefPtr<imgRequest> req = aEntry->GetRequest();
|
||||
Image *image = static_cast<Image*>(req->mImage.get());
|
||||
if (image) {
|
||||
ImageSizes *sizes = static_cast<ImageSizes*>(aUserArg);
|
||||
nsAutoCString pathPrefix(NS_LITERAL_CSTRING("explicit/"));
|
||||
pathPrefix.Append(aPathPrefix);
|
||||
pathPrefix.Append(aCounter.Type() == imgIContainer::TYPE_RASTER
|
||||
? "/raster/"
|
||||
: "/vector/");
|
||||
pathPrefix.Append(aCounter.IsUsed() ? "used/" : "unused/");
|
||||
pathPrefix.Append("image(");
|
||||
if (aCounter.URI().IsEmpty()) {
|
||||
pathPrefix.Append("<unknown URI>");
|
||||
} else {
|
||||
pathPrefix.Append(aCounter.URI());
|
||||
}
|
||||
pathPrefix.Append(")/");
|
||||
|
||||
nsRefPtr<ImageURL> imageURL(image->GetURI());
|
||||
nsAutoCString spec;
|
||||
imageURL->GetSpec(spec);
|
||||
ImageInfo<RasterSizes> rasterInfo;
|
||||
rasterInfo.mSizes.mRaw =
|
||||
image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf);
|
||||
rasterInfo.mSizes.mUncompressedHeap =
|
||||
image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf);
|
||||
rasterInfo.mSizes.mUncompressedNonheap = image->NonHeapSizeOfDecoded();
|
||||
rasterInfo.mURI = spec.get();
|
||||
if (!aEntry->HasNoProxies()) {
|
||||
sizes->mRasterUsedImageInfo.AppendElement(rasterInfo);
|
||||
} else {
|
||||
sizes->mRasterUnusedImageInfo.AppendElement(rasterInfo);
|
||||
}
|
||||
return ReportValues(aHandleReport, aData, pathPrefix, aCounter.Values());
|
||||
}
|
||||
|
||||
ImageInfo<VectorDocSizes> vectorInfo;
|
||||
vectorInfo.mSizes.mSize =
|
||||
image->HeapSizeOfVectorImageDocument(&vectorInfo.mURI);
|
||||
if (!vectorInfo.mURI.IsEmpty()) {
|
||||
if (!aEntry->HasNoProxies()) {
|
||||
sizes->mVectorUsedImageDocInfo.AppendElement(vectorInfo);
|
||||
} else {
|
||||
sizes->mVectorUnusedImageDocInfo.AppendElement(vectorInfo);
|
||||
}
|
||||
}
|
||||
static nsresult ReportTotal(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
bool aExplicit,
|
||||
const char* aPathPrefix,
|
||||
const char* aPathInfix,
|
||||
const MemoryTotal& aTotal)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsAutoCString pathPrefix;
|
||||
if (aExplicit) {
|
||||
pathPrefix.Append("explicit/");
|
||||
}
|
||||
pathPrefix.Append(aPathPrefix);
|
||||
|
||||
nsAutoCString rasterUsedPrefix(pathPrefix);
|
||||
rasterUsedPrefix.Append("/raster/used/");
|
||||
rasterUsedPrefix.Append(aPathInfix);
|
||||
rv = ReportValues(aHandleReport, aData, rasterUsedPrefix,
|
||||
aTotal.UsedRaster());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString rasterUnusedPrefix(pathPrefix);
|
||||
rasterUnusedPrefix.Append("/raster/unused/");
|
||||
rasterUnusedPrefix.Append(aPathInfix);
|
||||
rv = ReportValues(aHandleReport, aData, rasterUnusedPrefix,
|
||||
aTotal.UnusedRaster());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString vectorUsedPrefix(pathPrefix);
|
||||
vectorUsedPrefix.Append("/vector/used/");
|
||||
vectorUsedPrefix.Append(aPathInfix);
|
||||
rv = ReportValues(aHandleReport, aData, vectorUsedPrefix,
|
||||
aTotal.UsedVector());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString vectorUnusedPrefix(pathPrefix);
|
||||
vectorUnusedPrefix.Append("/vector/unused/");
|
||||
vectorUnusedPrefix.Append(aPathInfix);
|
||||
rv = ReportValues(aHandleReport, aData, vectorUnusedPrefix,
|
||||
aTotal.UnusedVector());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult ReportValues(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
const nsACString& aPathPrefix,
|
||||
const MemoryCounter& aCounter)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
rv = ReportValue(aHandleReport, aData, KIND_HEAP, aPathPrefix,
|
||||
"source",
|
||||
"Raster image source data and vector image documents.",
|
||||
aCounter.Source());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportValue(aHandleReport, aData, KIND_HEAP, aPathPrefix,
|
||||
"decoded-heap",
|
||||
"Decoded image data which is stored on the heap.",
|
||||
aCounter.DecodedHeap());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ReportValue(aHandleReport, aData, KIND_NONHEAP, aPathPrefix,
|
||||
"decoded-nonheap",
|
||||
"Decoded image data which isn't stored on the heap.",
|
||||
aCounter.DecodedNonHeap());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult ReportValue(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
int32_t aKind,
|
||||
const nsACString& aPathPrefix,
|
||||
const char* aPathSuffix,
|
||||
const char* aDescription,
|
||||
size_t aValue)
|
||||
{
|
||||
if (aValue == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoCString desc(aDescription);
|
||||
nsAutoCString path(aPathPrefix);
|
||||
path.Append(aPathSuffix);
|
||||
|
||||
return aHandleReport->Callback(EmptyCString(), path, aKind, UNITS_BYTES,
|
||||
aValue, desc, aData);
|
||||
}
|
||||
|
||||
static PLDHashOperator DoRecordCounter(const nsACString&,
|
||||
imgCacheEntry* aEntry,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsRefPtr<imgRequest> req = aEntry->GetRequest();
|
||||
RecordCounterForRequest(req,
|
||||
static_cast<nsTArray<ImageMemoryCounter>*>(aUserArg),
|
||||
!aEntry->HasNoProxies());
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator EntryUncachedImageSizes(nsPtrHashKey<imgRequest>* aEntry,
|
||||
static PLDHashOperator DoRecordCounterUncached(nsPtrHashKey<imgRequest>* aEntry,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsRefPtr<imgRequest> req = aEntry->GetKey();
|
||||
Image *image = static_cast<Image*>(req->mImage.get());
|
||||
if (image) {
|
||||
ImageSizes *sizes = static_cast<ImageSizes*>(aUserArg);
|
||||
|
||||
nsRefPtr<ImageURL> imageURL(image->GetURI());
|
||||
nsAutoCString spec;
|
||||
imageURL->GetSpec(spec);
|
||||
ImageInfo<RasterSizes> rasterInfo;
|
||||
rasterInfo.mSizes.mRaw =
|
||||
image->HeapSizeOfSourceWithComputedFallback(ImagesMallocSizeOf);
|
||||
rasterInfo.mSizes.mUncompressedHeap =
|
||||
image->HeapSizeOfDecodedWithComputedFallback(ImagesMallocSizeOf);
|
||||
rasterInfo.mSizes.mUncompressedNonheap = image->NonHeapSizeOfDecoded();
|
||||
rasterInfo.mURI = spec.get();
|
||||
if (req->HasConsumers()) {
|
||||
sizes->mRasterUsedImageInfo.AppendElement(rasterInfo);
|
||||
} else {
|
||||
sizes->mRasterUnusedImageInfo.AppendElement(rasterInfo);
|
||||
}
|
||||
|
||||
ImageInfo<VectorDocSizes> vectorInfo;
|
||||
vectorInfo.mSizes.mSize =
|
||||
image->HeapSizeOfVectorImageDocument(&vectorInfo.mURI);
|
||||
if (!vectorInfo.mURI.IsEmpty()) {
|
||||
if (req->HasConsumers()) {
|
||||
sizes->mVectorUsedImageDocInfo.AppendElement(vectorInfo);
|
||||
} else {
|
||||
sizes->mVectorUnusedImageDocInfo.AppendElement(vectorInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RecordCounterForRequest(req,
|
||||
static_cast<nsTArray<ImageMemoryCounter>*>(aUserArg),
|
||||
req->HasConsumers());
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
static PLDHashOperator EntryUsedUncompressedSize(const nsACString&,
|
||||
imgCacheEntry *aEntry,
|
||||
void *aUserArg)
|
||||
static void RecordCounterForRequest(imgRequest* aRequest,
|
||||
nsTArray<ImageMemoryCounter>* aArray,
|
||||
bool aIsUsed)
|
||||
{
|
||||
if (!aEntry->HasNoProxies()) {
|
||||
size_t *n = static_cast<size_t*>(aUserArg);
|
||||
nsRefPtr<imgRequest> req = aEntry->GetRequest();
|
||||
Image *image = static_cast<Image*>(req->mImage.get());
|
||||
if (image) {
|
||||
// Both this and EntryImageSizes measure
|
||||
// images/content/raster/used/uncompressed memory. This function's
|
||||
// measurement is secondary -- the result doesn't go in the "explicit"
|
||||
// tree -- so we use moz_malloc_size_of instead of ImagesMallocSizeOf
|
||||
// to prevent DMD from seeing it reported twice.
|
||||
*n += image->HeapSizeOfDecodedWithComputedFallback(moz_malloc_size_of);
|
||||
*n += image->NonHeapSizeOfDecoded();
|
||||
}
|
||||
auto image = static_cast<Image*>(aRequest->mImage.get());
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<ImageURL> imageURL(image->GetURI());
|
||||
nsAutoCString spec;
|
||||
imageURL->GetSpec(spec);
|
||||
|
||||
ImageMemoryCounter counter(image->GetType(), spec, aIsUsed);
|
||||
|
||||
counter.Values().SetSource(image->
|
||||
SizeOfSourceWithComputedFallback(ImagesMallocSizeOf));
|
||||
counter.Values().SetDecodedHeap(image->
|
||||
SizeOfDecoded(gfxMemoryLocation::IN_PROCESS_HEAP, ImagesMallocSizeOf));
|
||||
counter.Values().SetDecodedNonHeap(image->
|
||||
SizeOfDecoded(gfxMemoryLocation::IN_PROCESS_NONHEAP, nullptr));
|
||||
|
||||
aArray->AppendElement(counter);
|
||||
}
|
||||
|
||||
static PLDHashOperator DoRecordCounterUsedDecoded(const nsACString&,
|
||||
imgCacheEntry* aEntry,
|
||||
void* aUserArg)
|
||||
{
|
||||
if (aEntry->HasNoProxies()) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
nsRefPtr<imgRequest> req = aEntry->GetRequest();
|
||||
auto image = static_cast<Image*>(req->mImage.get());
|
||||
if (!image) {
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// Both this and EntryImageSizes measure images/content/raster/used/decoded
|
||||
// memory. This function's measurement is secondary -- the result doesn't
|
||||
// go in the "explicit" tree -- so we use moz_malloc_size_of instead of
|
||||
// ImagesMallocSizeOf to prevent DMD from seeing it reported twice.
|
||||
auto n = static_cast<size_t*>(aUserArg);
|
||||
*n += image->SizeOfDecoded(gfxMemoryLocation::IN_PROCESS_HEAP,
|
||||
moz_malloc_size_of);
|
||||
*n += image->SizeOfDecoded(gfxMemoryLocation::IN_PROCESS_NONHEAP, nullptr);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
};
|
||||
|
||||
// Specialisation of this method for raster images.
|
||||
template<>
|
||||
nsresult imgMemoryReporter::ReportSizes(
|
||||
nsIMemoryReporterCallback *aHandleReport, nsISupports *aData,
|
||||
const nsACString &aPathPrefix, const nsACString &aLocation,
|
||||
RasterSizes aSizes)
|
||||
{
|
||||
#define REPORT(_pathPrefix, _pathSuffix, _location, _kind, _amount, _desc) \
|
||||
do { \
|
||||
if (_amount > 0) { \
|
||||
nsCString path(_pathPrefix); \
|
||||
path.Append("/"); \
|
||||
if (!_location.IsEmpty()) { \
|
||||
path.Append("image("); \
|
||||
path.Append(_location); \
|
||||
path.Append(")/"); \
|
||||
} \
|
||||
path.Append(_pathSuffix); \
|
||||
nsresult rv; \
|
||||
rv = aHandleReport->Callback(EmptyCString(), path, _kind, UNITS_BYTES, \
|
||||
_amount, NS_LITERAL_CSTRING(_desc), aData);\
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
REPORT(aPathPrefix, "raw", aLocation, KIND_HEAP,
|
||||
aSizes.mRaw, "Compressed image data.");
|
||||
|
||||
REPORT(aPathPrefix, "uncompressed-heap", aLocation, KIND_HEAP,
|
||||
aSizes.mUncompressedHeap, "Uncompressed image data.");
|
||||
|
||||
REPORT(aPathPrefix, "uncompressed-nonheap", aLocation, KIND_NONHEAP,
|
||||
aSizes.mUncompressedNonheap, "Uncompressed image data.");
|
||||
#undef REPORT
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Specialisation of this method for vector images.
|
||||
template<>
|
||||
nsresult imgMemoryReporter::ReportSizes(
|
||||
nsIMemoryReporterCallback *aHandleReport, nsISupports *aData,
|
||||
const nsACString &aPathPrefix, const nsACString &aLocation,
|
||||
VectorDocSizes aSizes)
|
||||
{
|
||||
#define REPORT(_pathPrefix, _location, _amount, _desc) \
|
||||
do { \
|
||||
if (_amount > 0) { \
|
||||
nsCString path(_pathPrefix); \
|
||||
if (!_location.IsEmpty()) { \
|
||||
path.Append("/document("); \
|
||||
path.Append(_location); \
|
||||
path.Append(")"); \
|
||||
} \
|
||||
nsresult rv; \
|
||||
rv = aHandleReport->Callback(EmptyCString(), path, KIND_HEAP, \
|
||||
UNITS_BYTES, _amount, \
|
||||
NS_LITERAL_CSTRING(_desc), aData); \
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
REPORT(aPathPrefix, aLocation, aSizes.mSize,
|
||||
"Parsed vector image documents.");
|
||||
#undef REPORT
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(imgMemoryReporter, nsIMemoryReporter)
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsProgressNotificationProxy,
|
||||
|
@ -455,8 +455,10 @@ void imgRequest::SetIsInCache(bool incache)
|
||||
|
||||
void imgRequest::UpdateCacheEntrySize()
|
||||
{
|
||||
if (mCacheEntry)
|
||||
mCacheEntry->SetDataSize(mImage->SizeOfData());
|
||||
if (mCacheEntry) {
|
||||
size_t size = mImage->SizeOfSourceWithComputedFallback(moz_malloc_size_of);
|
||||
mCacheEntry->SetDataSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequest::SetCacheValidation(imgCacheEntry* aCacheEntry, nsIRequest* aRequest)
|
||||
|
@ -141,9 +141,6 @@ public:
|
||||
// Resize the cache entry to 0 if it exists
|
||||
void ResetCacheEntry();
|
||||
|
||||
// Update the cache entry size based on the image container
|
||||
void UpdateCacheEntrySize();
|
||||
|
||||
// OK to use on any thread.
|
||||
nsresult GetURI(ImageURL **aURI);
|
||||
nsresult GetCurrentURI(nsIURI **aURI);
|
||||
@ -183,6 +180,9 @@ private:
|
||||
// Returns whether we've got a reference to the cache entry.
|
||||
bool HasCacheEntry() const;
|
||||
|
||||
// Update the cache entry size based on the image container.
|
||||
void UpdateCacheEntrySize();
|
||||
|
||||
// Return the priority of the underlying network request, or return
|
||||
// PRIORITY_NORMAL if it doesn't support nsISupportsPriority.
|
||||
int32_t Priority() const;
|
||||
|
@ -776,12 +776,6 @@ void imgRequestProxy::OnDecodeComplete()
|
||||
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||
mListener->Notify(this, imgINotificationObserver::DECODE_COMPLETE, nullptr);
|
||||
}
|
||||
|
||||
if (GetOwner()) {
|
||||
// We finished the decode, and thus have the decoded frames. Update the cache
|
||||
// entry size to take this into account.
|
||||
GetOwner()->UpdateCacheEntrySize();
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::OnDiscard()
|
||||
@ -793,10 +787,6 @@ void imgRequestProxy::OnDiscard()
|
||||
nsCOMPtr<imgINotificationObserver> kungFuDeathGrip(mListener);
|
||||
mListener->Notify(this, imgINotificationObserver::DISCARD, nullptr);
|
||||
}
|
||||
if (GetOwner()) {
|
||||
// Update the cache entry size, since we just got rid of frame data.
|
||||
GetOwner()->UpdateCacheEntrySize();
|
||||
}
|
||||
}
|
||||
|
||||
void imgRequestProxy::OnUnlockedDraw()
|
||||
|
Loading…
Reference in New Issue
Block a user