mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Bug 923302 - Add explicit memory reporting for SurfaceCache. r=njn
--HG-- extra : rebase_source : 08187da628ee01f41a2722913ddd0461c446808c
This commit is contained in:
parent
e9226a8d8c
commit
1c2757be11
@ -1010,10 +1010,13 @@ size_t
|
||||
RasterImage::SizeOfDecodedWithComputedFallbackIfHeap(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return mFrameBlender
|
||||
? mFrameBlender->SizeOfDecodedWithComputedFallbackIfHeap(aLocation,
|
||||
aMallocSizeOf)
|
||||
: 0;
|
||||
size_t n = 0;
|
||||
n += SurfaceCache::SizeOfSurfaces(ImageKey(this), aLocation, aMallocSizeOf);
|
||||
if (mFrameBlender) {
|
||||
n += mFrameBlender->SizeOfDecodedWithComputedFallbackIfHeap(aLocation,
|
||||
aMallocSizeOf);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -54,7 +54,7 @@ static StaticRefPtr<SurfaceCacheImpl> sInstance;
|
||||
// SurfaceCache Implementation
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
/**
|
||||
* Cost models the cost of storing a surface in the cache. Right now, this is
|
||||
* simply an estimate of the size of the surface in bytes, but in the future it
|
||||
* may be worth taking into account the cost of rematerializing the surface as
|
||||
@ -67,7 +67,7 @@ static Cost ComputeCost(const IntSize& aSize)
|
||||
return aSize.width * aSize.height * 4; // width * height * 4 bytes (32bpp)
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Since we want to be able to make eviction decisions based on cost, we need to
|
||||
* be able to look up the CachedSurface which has a certain cost as well as the
|
||||
* cost associated with a certain CachedSurface. To make this possible, in data
|
||||
@ -108,7 +108,7 @@ private:
|
||||
Cost mCost;
|
||||
};
|
||||
|
||||
/*
|
||||
/**
|
||||
* A CachedSurface associates a surface with a key that uniquely identifies that
|
||||
* surface.
|
||||
*/
|
||||
@ -158,6 +158,34 @@ public:
|
||||
nsExpirationState* GetExpirationState() { return &mExpirationState; }
|
||||
Lifetime GetLifetime() const { return mLifetime; }
|
||||
|
||||
// A helper type used by SurfaceCacheImpl::SizeOfSurfacesSum.
|
||||
struct SizeOfSurfacesSum
|
||||
{
|
||||
SizeOfSurfacesSum(gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf)
|
||||
: mLocation(aLocation)
|
||||
, mMallocSizeOf(aMallocSizeOf)
|
||||
, mSum(0)
|
||||
{ }
|
||||
|
||||
void Add(CachedSurface* aCachedSurface)
|
||||
{
|
||||
if (!aCachedSurface || !aCachedSurface->mSurface) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSum += aCachedSurface->mSurface->
|
||||
SizeOfExcludingThisWithComputedFallbackIfHeap(mLocation, mMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t Result() const { return mSum; }
|
||||
|
||||
private:
|
||||
gfxMemoryLocation mLocation;
|
||||
MallocSizeOf mMallocSizeOf;
|
||||
size_t mSum;
|
||||
};
|
||||
|
||||
private:
|
||||
nsExpirationState mExpirationState;
|
||||
nsRefPtr<imgFrame> mSurface;
|
||||
@ -522,38 +550,53 @@ public:
|
||||
NS_IMETHOD
|
||||
CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||
nsISupports* aData,
|
||||
bool aAnonymize)
|
||||
bool aAnonymize) MOZ_OVERRIDE
|
||||
{
|
||||
// We have explicit memory reporting for the surface cache which is more
|
||||
// accurate than the cost metrics we report here, but these metrics are
|
||||
// still useful to report, since they control the cache's behavior.
|
||||
nsresult rv;
|
||||
|
||||
rv = MOZ_COLLECT_REPORT("imagelib-surface-cache-total",
|
||||
rv = MOZ_COLLECT_REPORT("imagelib-surface-cache-estimated-total",
|
||||
KIND_OTHER, UNITS_BYTES,
|
||||
SizeOfSurfacesEstimate(),
|
||||
"Total memory used by the imagelib surface cache.");
|
||||
(mMaxCost - mAvailableCost),
|
||||
"Estimated total memory used by the imagelib "
|
||||
"surface cache.");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = MOZ_COLLECT_REPORT("imagelib-surface-cache-locked",
|
||||
rv = MOZ_COLLECT_REPORT("imagelib-surface-cache-estimated-locked",
|
||||
KIND_OTHER, UNITS_BYTES,
|
||||
SizeOfLockedSurfacesEstimate(),
|
||||
"Memory used by locked surfaces in the imagelib "
|
||||
"surface cache.");
|
||||
mLockedCost,
|
||||
"Estimated memory used by locked surfaces in the "
|
||||
"imagelib surface cache.");
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX(seth): This is currently only an estimate and, since we don't know
|
||||
// which surfaces are in GPU memory and which aren't, it's reported as
|
||||
// KIND_OTHER and will also show up in heap-unclassified. Bug 923302 will
|
||||
// make this nicer.
|
||||
Cost SizeOfSurfacesEstimate() const
|
||||
size_t SizeOfSurfaces(const ImageKey aImageKey,
|
||||
gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf)
|
||||
{
|
||||
return mMaxCost - mAvailableCost;
|
||||
nsRefPtr<ImageSurfaceCache> cache = GetImageCache(aImageKey);
|
||||
if (!cache) {
|
||||
return 0; // No surfaces for this image.
|
||||
}
|
||||
|
||||
// Sum the size of all surfaces in the per-image cache.
|
||||
CachedSurface::SizeOfSurfacesSum sum(aLocation, aMallocSizeOf);
|
||||
cache->ForEach(DoSizeOfSurfacesSum, &sum);
|
||||
|
||||
return sum.Result();
|
||||
}
|
||||
|
||||
Cost SizeOfLockedSurfacesEstimate() const
|
||||
static PLDHashOperator DoSizeOfSurfacesSum(const SurfaceKey&,
|
||||
CachedSurface* aSurface,
|
||||
void* aSum)
|
||||
{
|
||||
return mLockedCost;
|
||||
auto sum = static_cast<CachedSurface::SizeOfSurfacesSum*>(aSum);
|
||||
sum->Add(aSurface);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -597,7 +640,9 @@ private:
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD Observe(nsISupports*, const char* aTopic, const char16_t*)
|
||||
NS_IMETHOD Observe(nsISupports*,
|
||||
const char* aTopic,
|
||||
const char16_t*) MOZ_OVERRIDE
|
||||
{
|
||||
if (sInstance && strcmp(aTopic, "memory-pressure") == 0) {
|
||||
sInstance->DiscardAll();
|
||||
@ -756,5 +801,18 @@ SurfaceCache::DiscardAll()
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ size_t
|
||||
SurfaceCache::SizeOfSurfaces(const ImageKey aImageKey,
|
||||
gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!sInstance) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sInstance->SizeOfSurfaces(aImageKey, aLocation, aMallocSizeOf);
|
||||
}
|
||||
|
||||
} // namespace image
|
||||
} // namespace mozilla
|
||||
|
@ -11,13 +11,15 @@
|
||||
#ifndef MOZILLA_IMAGELIB_SURFACECACHE_H_
|
||||
#define MOZILLA_IMAGELIB_SURFACECACHE_H_
|
||||
|
||||
#include "mozilla/Maybe.h" // for Maybe
|
||||
#include "mozilla/HashFunctions.h" // for HashGeneric and AddToHash
|
||||
#include "gfxPoint.h" // for gfxSize
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "mozilla/gfx/Point.h" // for mozilla::gfx::IntSize
|
||||
#include "mozilla/gfx/2D.h" // for SourceSurface
|
||||
#include "SVGImageContext.h" // for SVGImageContext
|
||||
#include "mozilla/Maybe.h" // for Maybe
|
||||
#include "mozilla/MemoryReporting.h" // for MallocSizeOf
|
||||
#include "mozilla/HashFunctions.h" // for HashGeneric and AddToHash
|
||||
#include "gfx2DGlue.h" // for gfxMemoryLocation
|
||||
#include "gfxPoint.h" // for gfxSize
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "mozilla/gfx/Point.h" // for mozilla::gfx::IntSize
|
||||
#include "mozilla/gfx/2D.h" // for SourceSurface
|
||||
#include "SVGImageContext.h" // for SVGImageContext
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
@ -293,6 +295,23 @@ struct SurfaceCache
|
||||
*/
|
||||
static void DiscardAll();
|
||||
|
||||
/**
|
||||
* Computes the size of the surfaces stored for the given image at the given
|
||||
* memory location.
|
||||
*
|
||||
* This is intended for use with memory reporting.
|
||||
*
|
||||
* @param aImageKey The image to report memory usage for.
|
||||
* @param aLocation The location (heap, nonheap, etc.) of the memory to
|
||||
* report on.
|
||||
* @param aMallocSizeOf A fallback malloc memory reporting function. This
|
||||
* should be null unless we're reporting on in-process
|
||||
* heap memory.
|
||||
*/
|
||||
static size_t SizeOfSurfaces(const ImageKey aImageKey,
|
||||
gfxMemoryLocation aLocation,
|
||||
MallocSizeOf aMallocSizeOf);
|
||||
|
||||
private:
|
||||
virtual ~SurfaceCache() = 0; // Forbid instantiation.
|
||||
};
|
||||
|
@ -384,25 +384,30 @@ VectorImage::HeapSizeOfDecodedWithComputedFallback(MallocSizeOf aMallocSizeOf) c
|
||||
// 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;
|
||||
// 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
|
||||
{
|
||||
// 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;
|
||||
return SurfaceCache::SizeOfSurfaces(ImageKey(this),
|
||||
gfxMemoryLocation::IN_PROCESS_NONHEAP,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
size_t
|
||||
VectorImage::OutOfProcessSizeOfDecoded() 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}/...")
|
||||
return 0;
|
||||
return SurfaceCache::SizeOfSurfaces(ImageKey(this),
|
||||
gfxMemoryLocation::OUT_OF_PROCESS,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf);
|
||||
|
Loading…
Reference in New Issue
Block a user