--- a/image/src/DynamicImage.cpp
+++ b/image/src/DynamicImage.cpp
@@ -38,51 +38,27 @@ DynamicImage::GetProgressTracker()
nsIntRect
DynamicImage::FrameRect(uint32_t aWhichFrame)
{
gfxIntSize size(mDrawable->Size());
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
+DynamicImage::SizeOfDecoded(gfxMemoryLocation aLocation,
+ MallocSizeOf aMallocSizeOf) const
{
- return 0;
-}
-
-size_t
-DynamicImage::OutOfProcessSizeOfDecoded() const
-{
- return 0;
-}
-
-size_t
-DynamicImage::HeapSizeOfVectorImageDocument(nsACString* aDocURL) const
-{
+ // We don't know the answer since gfxDrawable doesn't expose this information.
return 0;
}
void
DynamicImage::IncrementAnimationConsumers()
{ }
void
--- a/image/src/DynamicImage.h
+++ b/image/src/DynamicImage.h
@@ -32,22 +32,19 @@ public:
}
// Inherited methods from Image.
virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
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;
#ifdef DEBUG
virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE;
#endif
virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
--- a/image/src/FrameBlender.cpp
+++ b/image/src/FrameBlender.cpp
@@ -558,36 +558,33 @@ FrameBlender::Discard()
// timers are cancelled.
NS_ABORT_IF_FALSE(!mAnim, "Asked to discard for animated image!");
// Delete all the decoded frames, then clear the array.
ClearFrames();
}
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);
}
}
return n;
}
void
FrameBlender::ResetAnimation()
--- a/image/src/FrameBlender.h
+++ b/image/src/FrameBlender.h
@@ -67,18 +67,18 @@ public:
*/
void SetLoopCount(int32_t aLoopCount);
int32_t GetLoopCount() const;
void Discard();
void SetSize(nsIntSize aSize) { mSize = aSize; }
- size_t SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
- MallocSizeOf aMallocSizeOf) const;
+ size_t SizeOfDecoded(gfxMemoryLocation aLocation,
+ MallocSizeOf aMallocSizeOf) const;
void ResetAnimation();
// "Blend" method indicates how the current image is combined with the
// previous image.
enum FrameBlendMethod {
// All color components of the frame, including alpha, overwrite the current
// contents of the frame's output buffer region
--- a/image/src/Image.cpp
+++ b/image/src/Image.cpp
@@ -19,31 +19,16 @@ ImageResource::ImageResource(ImageURL* a
mAnimationConsumers(0),
mAnimationMode(kNormalAnimMode),
mInitialized(false),
mAnimating(false),
mError(false)
{
}
-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)
{
// By default we don't know
eDecoderType rv = eDecoderType_unknown;
// PNG
--- a/image/src/Image.h
+++ b/image/src/Image.h
@@ -2,16 +2,17 @@
/* 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/. */
#ifndef MOZILLA_IMAGELIB_IMAGE_H_
#define MOZILLA_IMAGELIB_IMAGE_H_
#include "mozilla/MemoryReporting.h"
+#include "gfx2DGlue.h" // for gfxMemoryLocation
#include "imgIContainer.h"
#include "ProgressTracker.h"
#include "ImageURL.h"
#include "nsStringFwd.h"
class nsIRequest;
class nsIInputStream;
@@ -67,35 +68,27 @@ public:
virtual void SetProgressTracker(ProgressTracker* aProgressTracker) {}
/**
* The rectangle defining the location and size of the given frame.
*/
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;
#ifdef DEBUG
virtual uint32_t GetAnimationConsumers() = 0;
#endif
/**
@@ -151,17 +144,16 @@ public:
MOZ_ASSERT(progressTracker);
return progressTracker.forget();
}
void SetProgressTracker(ProgressTracker* aProgressTracker) MOZ_OVERRIDE MOZ_FINAL {
MOZ_ASSERT(aProgressTracker);
MOZ_ASSERT(!mProgressTracker);
mProgressTracker = aProgressTracker;
}
- virtual uint32_t SizeOfData() MOZ_OVERRIDE;
virtual void IncrementAnimationConsumers() MOZ_OVERRIDE;
virtual void DecrementAnimationConsumers() MOZ_OVERRIDE;
#ifdef DEBUG
virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE { return mAnimationConsumers; }
#endif
virtual void SetInnerWindowID(uint64_t aInnerWindowId) MOZ_OVERRIDE {
--- a/image/src/ImageWrapper.cpp
+++ b/image/src/ImageWrapper.cpp
@@ -34,44 +34,27 @@ ImageWrapper::GetProgressTracker()
}
nsIntRect
ImageWrapper::FrameRect(uint32_t aWhichFrame)
{
return mInnerImage->FrameRect(aWhichFrame);
}
-uint32_t
-ImageWrapper::SizeOfData()
+size_t
+ImageWrapper::SizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
{
- return mInnerImage->SizeOfData();
-}
-
-size_t
-ImageWrapper::HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
-{
- return mInnerImage->HeapSizeOfSourceWithComputedFallback(aMallocSizeOf);
+ return mInnerImage->SizeOfSourceWithComputedFallback(aMallocSizeOf);
}
size_t
-ImageWrapper::HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) const
-{
- return mInnerImage->HeapSizeOfDecodedWithComputedFallback(aMallocSizeOf);
-}
-
-size_t
-ImageWrapper::NonHeapSizeOfDecoded() const
+ImageWrapper::SizeOfDecoded(gfxMemoryLocation aLocation,
+ MallocSizeOf aMallocSizeOf) const
{
- return mInnerImage->NonHeapSizeOfDecoded();
-}
-
-size_t
-ImageWrapper::OutOfProcessSizeOfDecoded() const
-{
- return mInnerImage->OutOfProcessSizeOfDecoded();
+ return mInnerImage->SizeOfDecoded(aLocation, aMallocSizeOf);
}
void
ImageWrapper::IncrementAnimationConsumers()
{
MOZ_ASSERT(NS_IsMainThread(), "Main thread only to encourage serialization "
"with DecrementAnimationConsumers");
mInnerImage->IncrementAnimationConsumers();
--- a/image/src/ImageWrapper.h
+++ b/image/src/ImageWrapper.h
@@ -22,25 +22,18 @@ public:
NS_DECL_IMGICONTAINER
// Inherited methods from Image.
virtual nsresult Init(const char* aMimeType, uint32_t aFlags) MOZ_OVERRIDE;
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;
#ifdef DEBUG
virtual uint32_t GetAnimationConsumers() MOZ_OVERRIDE;
#endif
virtual nsresult OnImageDataAvailable(nsIRequest* aRequest,
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -959,63 +959,41 @@ RasterImage::UpdateImageContainer()
if (!image) {
return;
}
mImageContainer->SetCurrentImage(image);
}
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.
// - We're on a platform where moz_malloc_size_of always returns 0.
// In either case the fallback works appropriately.
size_t n = mSourceData.SizeOfExcludingThis(aMallocSizeOf);
if (n == 0) {
n = mSourceData.Length();
}
return n;
}
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,
uint32_t aDecodeFlags,
SurfaceFormat aFormat,
uint8_t aPaletteDepth,
imgFrame* aPreviousFrame)
{
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -166,24 +166,19 @@ public:
static NS_METHOD WriteToRasterImage(nsIInputStream* aIn, void* aClosure,
const char* aFromRawSegment,
uint32_t aToOffset, uint32_t aCount,
uint32_t* aWriteCount);
/* 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);
void ForceDiscard() { Discard(/* aForce = */ true); }
/* Callbacks for decoders */
/** Sets the size and inherent orientation of the container. This should only
* be called by the decoder. This function may be called multiple times, but
--- a/image/src/SurfaceCache.cpp
+++ b/image/src/SurfaceCache.cpp
@@ -170,19 +170,18 @@ public:
void Add(CachedSurface* aCachedSurface)
{
MOZ_ASSERT(aCachedSurface, "Should have a CachedSurface");
if (!aCachedSurface->mSurface) {
return;
}
-
- mSum += aCachedSurface->mSurface->
- SizeOfExcludingThisWithComputedFallbackIfHeap(mLocation, mMallocSizeOf);
+ mSum += aCachedSurface->mSurface->SizeOfExcludingThis(mLocation,
+ mMallocSizeOf);
}
size_t Result() const { return mSum; }
private:
gfxMemoryLocation mLocation;
MallocSizeOf mMallocSizeOf;
size_t mSum;
--- a/image/src/VectorImage.cpp
+++ b/image/src/VectorImage.cpp
@@ -361,79 +361,43 @@ VectorImage::Init(const char* aMimeType,
nsIntRect
VectorImage::FrameRect(uint32_t aWhichFrame)
{
return nsIntRect::GetMaxSizedIntRect();
}
size_t
-VectorImage::HeapSizeOfSourceWithComputedFallback(MallocSizeOf aMallocSizeOf) const
+VectorImage::SizeOfSourceWithComputedFallback(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;
-}
+ nsIDocument* doc = mSVGDocumentWrapper->GetDocument();
+ if (!doc) {
+ return 0; // No document, so no memory used for the document.
+ }
+
+ nsWindowSizes windowSizes(aMallocSizeOf);
+ doc->DocAddSizeOfIncludingThis(&windowSizes);
-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);
+ 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::NonHeapSizeOfDecoded() const
-{
- return SurfaceCache::SizeOfSurfaces(ImageKey(this),
- gfxMemoryLocation::IN_PROCESS_NONHEAP,
- nullptr);
-}
-
-size_t
-VectorImage::OutOfProcessSizeOfDecoded() const
+VectorImage::SizeOfDecoded(gfxMemoryLocation aLocation,
+ MallocSizeOf aMallocSizeOf) const
{
- return SurfaceCache::SizeOfSurfaces(ImageKey(this),
- gfxMemoryLocation::OUT_OF_PROCESS,
- nullptr);
-}
-
-MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf);
-
-size_t
-VectorImage::HeapSizeOfVectorImageDocument(nsACString* aDocURL) const
-{
- nsIDocument* doc = mSVGDocumentWrapper->GetDocument();
- if (!doc) {
- if (aDocURL) {
- mURI->GetSpec(*aDocURL);
- }
- return 0; // No document, so no memory used for the document
- }
-
- if (aDocURL) {
- doc->GetDocumentURI()->GetSpec(*aDocURL);
- }
-
- nsWindowSizes windowSizes(WindowsMallocSizeOf);
- doc->DocAddSizeOfIncludingThis(&windowSizes);
- return windowSizes.getTotalSize();
+ return SurfaceCache::SizeOfSurfaces(ImageKey(this), aLocation, aMallocSizeOf);
}
nsresult
VectorImage::OnImageDataComplete(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus,
bool aLastPart)
{
--- a/image/src/VectorImage.h
+++ b/image/src/VectorImage.h
@@ -37,22 +37,19 @@ public:
// (no public constructor - use ImageFactory)
// Methods inherited from Image
nsresult Init(const char* aMimeType,
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,
nsIInputStream* aInStr,
uint64_t aSourceOffset,
uint32_t aCount) MOZ_OVERRIDE;
virtual nsresult OnImageDataComplete(nsIRequest* aRequest,
nsISupports* aContext,
--- a/image/src/imgFrame.cpp
+++ b/image/src/imgFrame.cpp
@@ -900,39 +900,32 @@ bool imgFrame::GetCompositingFailed() co
return mCompositingFailed;
}
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.
NS_ABORT_IF_FALSE(
(aLocation == gfxMemoryLocation::IN_PROCESS_HEAP && aMallocSizeOf) ||
(aLocation != gfxMemoryLocation::IN_PROCESS_HEAP && !aMallocSizeOf),
"mismatch between aLocation and aMallocSizeOf");
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);
}
if (mOptSurface && aLocation == gfxMemoryLocation::IN_PROCESS_HEAP) {
n += aMallocSizeOf(mOptSurface);
}
if (mVBuf && aLocation == gfxMemoryLocation::IN_PROCESS_HEAP) {
--- a/image/src/imgFrame.h
+++ b/image/src/imgFrame.h
@@ -126,19 +126,18 @@ public:
bool IsSinglePixel()
{
return mSinglePixel;
}
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 {
if (!mPaletteDepth)
return 0;
return ((1 << mPaletteDepth) * sizeof(uint32_t));
}
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -49,95 +49,60 @@
using namespace mozilla;
using namespace mozilla::image;
using namespace mozilla::net;
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");
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = ReportInfoArray(aHandleReport, aData, chrome.mRasterUnusedImageInfo,
- "images/chrome/raster/unused");
- 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);
+ rv = ReportCounterArray(aHandleReport, aData, chrome, "images/chrome");
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);
+ rv = ReportCounterArray(aHandleReport, aData, content,
+ "images/content", 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;
}
static int64_t ImagesContentUsedUncompressedDistinguishedAmount()
{
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;
}
void RegisterLoader(imgLoader* aLoader)
{
mKnownLoaders.AppendElement(aLoader);
}
@@ -145,316 +110,353 @@ public:
void UnregisterLoader(imgLoader* aLoader)
{
mKnownLoaders.RemoveElement(aLoader);
}
private:
nsTArray<imgLoader*> mKnownLoaders;
- struct RasterSizes
+ struct MemoryCounter
{
- size_t mRaw;
- size_t mUncompressedHeap;
- size_t mUncompressedNonheap;
-
- RasterSizes()
- : mRaw(0)
- , mUncompressedHeap(0)
- , mUncompressedNonheap(0)
- {}
-
- void add(const RasterSizes &aOther)
+ MemoryCounter()
+ : mSource(0)
+ , mDecodedHeap(0)
+ , mDecodedNonHeap(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; }
+
+ 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
+ private:
+ size_t mSource;
+ size_t mDecodedHeap;
+ size_t mDecodedNonHeap;
+ };
+
+ struct ImageMemoryCounter
+ {
+ ImageMemoryCounter(uint16_t aType, const nsACString& aURI, bool aIsUsed)
+ : mURI(aURI)
+ , mType(aType)
+ , mIsUsed(aIsUsed)
+ {
+ MOZ_ASSERT(!mURI.IsEmpty(), "Should have a URI for all images");
+ }
+
+ 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 = mRaw + mUncompressedHeap + mUncompressedNonheap;
- return total >= NotableThreshold;
- }
- };
-
- struct VectorDocSizes
- {
- size_t mSize;
-
- VectorDocSizes()
- : mSize(0)
- {}
-
- void add(const VectorDocSizes &aOther)
- {
- mSize += aOther.mSize;
- }
-
- 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;
- };
-
- struct ImageSizes
- {
- nsTArray<ImageInfo<RasterSizes> > mRasterUsedImageInfo;
- nsTArray<ImageInfo<RasterSizes> > mRasterUnusedImageInfo;
- nsTArray<ImageInfo<VectorDocSizes> > mVectorUsedImageDocInfo;
- nsTArray<ImageInfo<VectorDocSizes> > mVectorUnusedImageDocInfo;
+ uint16_t mType;
+ MemoryCounter mValues;
+ bool mIsUsed;
};
- // 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)
+ struct MemoryTotal
+ {
+ MemoryTotal& operator+=(const ImageMemoryCounter& aImageCounter)
+ {
+ if (aImageCounter.Type() == imgIContainer::TYPE_RASTER) {
+ if (aImageCounter.IsUsed()) {
+ mUsedRasterCounter += aImageCounter.Values();
+ } else {
+ mUnusedRasterCounter += aImageCounter.Values();
+ }
+ } else if (aImageCounter.Type() == imgIContainer::TYPE_VECTOR) {
+ if (aImageCounter.IsUsed()) {
+ mUsedVectorCounter += aImageCounter.Values();
+ } else {
+ mUnusedVectorCounter += aImageCounter.Values();
+ }
+ } else {
+ MOZ_CRASH("Unexpected image type");
+ }
+
+ return *this;
+ }
+
+ 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;
- Sizes totalSizes;
- Sizes nonNotableSizes;
-
- nsCString pathPart(aPathPartStr);
- nsCString explicitPathPrefix(aPathPartStr);
- explicitPathPrefix.Insert("explicit/", 0);
+ MemoryTotal summaryTotal;
+ MemoryTotal nonNotableTotal;
// 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];
+ for (uint32_t i = 0; i < aCounterArray.Length(); i++) {
+ ImageMemoryCounter counter = aCounterArray[i];
if (aAnonymize) {
- info.mURI.Truncate();
- info.mURI.AppendPrintf("<anonymized-%u>", i);
+ counter.URI().Truncate();
+ counter.URI().AppendPrintf("<anonymized-%u>", i);
} else {
- // info.mURI can be a data: URI, and thus extremely long. Truncate if
- // necessary.
+ // The URI could be an extremely long data: URI. Truncate if needed.
static const size_t max = 256;
- if (info.mURI.Length() > max) {
- info.mURI.Truncate(max);
- info.mURI.AppendLiteral(" (truncated)");
+ if (counter.URI().Length() > max) {
+ counter.URI().Truncate(max);
+ counter.URI().AppendLiteral(" (truncated)");
}
- info.mURI.ReplaceChar('/', '\\');
+ counter.URI().ReplaceChar('/', '\\');
}
- totalSizes.add(info.mSizes);
-
- if (!info.mSizes.isNotable()) {
- nonNotableSizes.add(info.mSizes);
+ summaryTotal += counter;
+
+ if (counter.IsNotable()) {
+ rv = ReportCounter(aHandleReport, aData, aPathPrefix, counter);
+ NS_ENSURE_SUCCESS(rv, rv);
} else {
- // Report the notable image.
- rv = ReportSizes(aHandleReport, aData, explicitPathPrefix,
- info.mURI, info.mSizes);
- NS_ENSURE_SUCCESS(rv, rv);
+ 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)
+ {
+ 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(")/");
+
+ return ReportValues(aHandleReport, aData, pathPrefix, aCounter.Values());
+ }
+
+ 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();
- 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 (!aEntry->HasNoProxies()) {
- sizes->mRasterUsedImageInfo.AppendElement(rasterInfo);
- } else {
- sizes->mRasterUnusedImageInfo.AppendElement(rasterInfo);
- }
-
- 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);
- }
- }
- }
-
+ 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,
+ moz_malloc_size_of);
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,
nsIProgressEventSink,
nsIChannelEventSink,
nsIInterfaceRequestor)
NS_IMETHODIMP
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -450,18 +450,20 @@ void imgRequest::AdjustPriority(imgReque
void imgRequest::SetIsInCache(bool incache)
{
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgRequest::SetIsCacheable", "incache", incache);
mIsInCache = 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)
{
/* get the expires info */
if (aCacheEntry) {
nsCOMPtr<nsICachingChannel> cacheChannel(do_QueryInterface(aRequest));
if (cacheChannel) {
--- a/image/src/imgRequest.h
+++ b/image/src/imgRequest.h
@@ -136,19 +136,16 @@ public:
already_AddRefed<ProgressTracker> GetProgressTracker();
// Get the current principal of the image. No AddRefing.
inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
// 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);
nsresult GetImageErrorCode(void);
private:
friend class imgCacheEntry;
@@ -178,16 +175,19 @@ private:
// Reset the cache entry after we've dropped our reference to it. Used by the
// imgLoader when our cache entry is re-requested after we've dropped our
// reference to it.
void SetCacheEntry(imgCacheEntry *entry);
// 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;
// Adjust the priority of the underlying network request by the given delta
// on behalf of the given proxy.
void AdjustPriority(imgRequestProxy *aProxy, int32_t aDelta);
--- a/image/src/imgRequestProxy.cpp
+++ b/image/src/imgRequestProxy.cpp
@@ -771,37 +771,27 @@ void imgRequestProxy::OnDecodeComplete()
{
LOG_FUNC(GetImgLog(), "imgRequestProxy::OnDecodeComplete");
if (mListener && !mCanceled) {
// Hold a ref to the listener while we call it, just in case.
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()
{
LOG_FUNC(GetImgLog(), "imgRequestProxy::OnDiscard");
if (mListener && !mCanceled) {
// Hold a ref to the listener while we call it, just in case.
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()
{
LOG_FUNC(GetImgLog(), "imgRequestProxy::OnUnlockedDraw");
if (mListener && !mCanceled) {
// Hold a ref to the listener while we call it, just in case.