mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 22:04:36 +00:00
bug 688125 - part 2 - add memory reporting for fonts in the gfxFontCache. r=njn
This commit is contained in:
parent
c278b0a18f
commit
5ffe5203cf
@ -762,3 +762,20 @@ gfxDWriteFont::MeasureGlyphWidth(PRUint16 aGlyph)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gfxDWriteFont::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
gfxFont::SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
aSizes->mFontInstances += aMallocSizeOf(mMetrics) +
|
||||
mGlyphWidths.SizeOfExcludingThis(nsnull, aMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
gfxDWriteFont::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
@ -92,6 +92,11 @@ public:
|
||||
|
||||
virtual mozilla::TemporaryRef<mozilla::gfx::GlyphRenderingOptions> GetGlyphRenderingOptions();
|
||||
|
||||
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
friend class gfxDWriteShaper;
|
||||
|
||||
|
@ -661,3 +661,20 @@ gfxFT2Font::FillGlyphDataForChar(PRUint32 ch, CachedGlyphData *gd)
|
||||
gd->rsbDelta = face->glyph->rsb_delta;
|
||||
gd->xAdvance = face->glyph->advance.x;
|
||||
}
|
||||
|
||||
void
|
||||
gfxFT2Font::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
gfxFont::SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
aSizes->mFontInstances +=
|
||||
mCharGlyphCache.SizeOfExcludingThis(nsnull, aMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
gfxFT2Font::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
@ -96,6 +96,11 @@ public: // new functions
|
||||
return &entry->mData;
|
||||
}
|
||||
|
||||
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
virtual bool ShapeWord(gfxContext *aContext,
|
||||
gfxShapedWord *aShapedWord,
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsILanguageAtomService.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "gfxFont.h"
|
||||
@ -1048,6 +1047,52 @@ gfxFontFamily::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
* shaped-word caches to free up memory.
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryMultiReporter)
|
||||
|
||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf, "font-cache")
|
||||
|
||||
NS_IMETHODIMP
|
||||
gfxFontCache::MemoryReporter::GetName(nsACString &aName)
|
||||
{
|
||||
aName.AssignLiteral("font-cache");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
gfxFontCache::MemoryReporter::CollectReports
|
||||
(nsIMemoryMultiReporterCallback* aCb,
|
||||
nsISupports* aClosure)
|
||||
{
|
||||
FontCacheSizes sizes;
|
||||
|
||||
gfxFontCache::GetCache()->SizeOfIncludingThis(&FontCacheMallocSizeOf,
|
||||
&sizes);
|
||||
|
||||
aCb->Callback(EmptyCString(),
|
||||
NS_LITERAL_CSTRING("explicit/gfx/font-cache"),
|
||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||
sizes.mFontInstances,
|
||||
NS_LITERAL_CSTRING("Memory used for active font instances."),
|
||||
aClosure);
|
||||
|
||||
aCb->Callback(EmptyCString(),
|
||||
NS_LITERAL_CSTRING("explicit/gfx/font-shaped-words"),
|
||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||
sizes.mShapedWords,
|
||||
NS_LITERAL_CSTRING("Memory used to cache shaped glyph data."),
|
||||
aClosure);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
gfxFontCache::MemoryReporter::GetExplicitNonHeap(PRInt64* aAmount)
|
||||
{
|
||||
// This reporter only measures heap memory.
|
||||
*aAmount = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Observer for the memory-pressure notification, to trigger
|
||||
// flushing of the shaped-word caches
|
||||
class MemoryPressureObserver : public nsIObserver,
|
||||
@ -1079,7 +1124,11 @@ gfxFontCache::Init()
|
||||
{
|
||||
NS_ASSERTION(!gGlobalCache, "Where did this come from?");
|
||||
gGlobalCache = new gfxFontCache();
|
||||
return gGlobalCache ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
if (!gGlobalCache) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_RegisterMemoryMultiReporter(new MemoryReporter);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1240,6 +1289,39 @@ gfxFontCache::ClearCachedWordsForFont(HashEntry* aHashEntry, void* aUserData)
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
/*static*/
|
||||
size_t
|
||||
gfxFontCache::SizeOfFontEntryExcludingThis(HashEntry* aHashEntry,
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
void* aUserArg)
|
||||
{
|
||||
HashEntry *entry = static_cast<HashEntry*>(aHashEntry);
|
||||
FontCacheSizes *sizes = static_cast<FontCacheSizes*>(aUserArg);
|
||||
entry->mFont->SizeOfExcludingThis(aMallocSizeOf, sizes);
|
||||
|
||||
// The font records its size in the |sizes| parameter, so we return zero
|
||||
// here to the hashtable enumerator.
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontCache::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
// TODO: add the overhead of the expiration tracker (generation arrays)
|
||||
|
||||
mFonts.SizeOfExcludingThis(SizeOfFontEntryExcludingThis,
|
||||
aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
||||
void
|
||||
gfxFontCache::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
||||
void
|
||||
gfxFont::RunMetrics::CombineWith(const RunMetrics& aOther, bool aOtherIsOnLeft)
|
||||
{
|
||||
@ -2589,10 +2671,40 @@ gfxFont::SynthesizeSpaceWidth(PRUint32 aCh)
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ size_t
|
||||
gfxFont::WordCacheEntrySizeOfExcludingThis(CacheHashEntry* aHashEntry,
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
void* aUserArg)
|
||||
{
|
||||
return aMallocSizeOf(aHashEntry->mShapedWord.get());
|
||||
}
|
||||
|
||||
void
|
||||
gfxFont::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
for (PRUint32 i = 0; i < mGlyphExtentsArray.Length(); ++i) {
|
||||
aSizes->mFontInstances +=
|
||||
mGlyphExtentsArray[i]->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
aSizes->mShapedWords +=
|
||||
mWordCache.SizeOfExcludingThis(WordCacheEntrySizeOfExcludingThis,
|
||||
aMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
gfxFont::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
||||
gfxGlyphExtents::~gfxGlyphExtents()
|
||||
{
|
||||
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
|
||||
gGlyphExtentsWidthsTotalSize += mContainedGlyphWidths.ComputeSize();
|
||||
gGlyphExtentsWidthsTotalSize +=
|
||||
mContainedGlyphWidths.SizeOfExcludingThis(&FontCacheMallocSizeOf);
|
||||
gGlyphExtentsCount++;
|
||||
#endif
|
||||
MOZ_COUNT_DTOR(gfxGlyphExtents);
|
||||
@ -2636,21 +2748,19 @@ gfxGlyphExtents::GlyphWidths::~GlyphWidths()
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRUint32
|
||||
gfxGlyphExtents::GlyphWidths::ComputeSize()
|
||||
gfxGlyphExtents::GlyphWidths::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
PRUint32 i;
|
||||
PRUint32 size = mBlocks.Capacity()*sizeof(PtrBits);
|
||||
PRUint32 size = mBlocks.SizeOfExcludingThis(aMallocSizeOf);
|
||||
for (i = 0; i < mBlocks.Length(); ++i) {
|
||||
PtrBits bits = mBlocks[i];
|
||||
if (bits && !(bits & 0x1)) {
|
||||
size += BLOCK_SIZE*sizeof(PRUint16);
|
||||
size += aMallocSizeOf(reinterpret_cast<void*>(bits));
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
gfxGlyphExtents::GlyphWidths::Set(PRUint32 aGlyphID, PRUint16 aWidth)
|
||||
@ -2702,6 +2812,19 @@ gfxGlyphExtents::SetTightGlyphExtents(PRUint32 aGlyphID, const gfxRect& aExtents
|
||||
entry->height = aExtentsAppUnits.Height();
|
||||
}
|
||||
|
||||
size_t
|
||||
gfxGlyphExtents::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) +
|
||||
mTightGlyphExtents.SizeOfExcludingThis(nsnull, aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
gfxGlyphExtents::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
gfxFontGroup::gfxFontGroup(const nsAString& aFamilies, const gfxFontStyle *aStyle, gfxUserFontSet *aUserFontSet)
|
||||
: mFamilies(aFamilies), mStyle(*aStyle), mUnderlineOffset(UNDERLINE_OFFSET_NOT_SET)
|
||||
{
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
typedef struct _cairo_scaled_font cairo_scaled_font_t;
|
||||
|
||||
@ -742,6 +743,15 @@ struct gfxTextRange {
|
||||
* completely, with all its words, and avoid the cost of aging the words
|
||||
* individually. That only happens with longer-lived fonts.
|
||||
*/
|
||||
struct FontCacheSizes {
|
||||
FontCacheSizes()
|
||||
: mFontInstances(0), mShapedWords(0)
|
||||
{ }
|
||||
|
||||
size_t mFontInstances; // memory used by instances of gfxFont subclasses
|
||||
size_t mShapedWords; // memory used by the per-font shapedWord caches
|
||||
};
|
||||
|
||||
class THEBES_API gfxFontCache MOZ_FINAL : public nsExpirationTracker<gfxFont,3> {
|
||||
public:
|
||||
enum {
|
||||
@ -795,7 +805,20 @@ public:
|
||||
mFonts.EnumerateEntries(ClearCachedWordsForFont, nsnull);
|
||||
}
|
||||
|
||||
void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
class MemoryReporter
|
||||
: public nsIMemoryMultiReporter
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMEMORYMULTIREPORTER
|
||||
};
|
||||
|
||||
void DestroyFont(gfxFont *aFont);
|
||||
|
||||
static gfxFontCache *gGlobalCache;
|
||||
@ -828,6 +851,10 @@ protected:
|
||||
gfxFont* mFont;
|
||||
};
|
||||
|
||||
static size_t SizeOfFontEntryExcludingThis(HashEntry* aHashEntry,
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
void* aUserArg);
|
||||
|
||||
nsTHashtable<HashEntry> mFonts;
|
||||
|
||||
static PLDHashOperator ClearCachedWordsForFont(HashEntry* aHashEntry, void*);
|
||||
@ -999,6 +1026,9 @@ public:
|
||||
|
||||
PRUint32 GetAppUnitsPerDevUnit() { return mAppUnitsPerDevUnit; }
|
||||
|
||||
size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
||||
private:
|
||||
class HashEntry : public nsUint32HashKey {
|
||||
public:
|
||||
@ -1035,9 +1065,7 @@ private:
|
||||
return widths[indexInBlock];
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRUint32 ComputeSize();
|
||||
#endif
|
||||
PRUint32 SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
||||
~GlyphWidths();
|
||||
|
||||
@ -1056,7 +1084,7 @@ private:
|
||||
|
||||
nsTArray<PtrBits> mBlocks;
|
||||
};
|
||||
|
||||
|
||||
GlyphWidths mContainedGlyphWidths;
|
||||
nsTHashtable<HashEntry> mTightGlyphExtents;
|
||||
PRUint32 mAppUnitsPerDevUnit;
|
||||
@ -1493,6 +1521,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
// Call the appropriate shaper to generate glyphs for aText and store
|
||||
// them into aShapedWord.
|
||||
@ -1577,6 +1610,11 @@ protected:
|
||||
nsAutoPtr<gfxShapedWord> mShapedWord;
|
||||
};
|
||||
|
||||
static size_t
|
||||
WordCacheEntrySizeOfExcludingThis(CacheHashEntry* aHashEntry,
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
void* aUserArg);
|
||||
|
||||
nsTHashtable<CacheHashEntry> mWordCache;
|
||||
|
||||
static PLDHashOperator AgeCacheEntry(CacheHashEntry *aEntry, void *aUserData);
|
||||
|
@ -560,3 +560,20 @@ gfxGDIFont::GetGlyphWidth(gfxContext *aCtx, PRUint16 aGID)
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
gfxGDIFont::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
gfxFont::SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
aSizes->mFontInstances += aMallocSizeOf(mMetrics) +
|
||||
mGlyphWidths.SizeOfExcludingThis(nsnull, aMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
gfxGDIFont::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
@ -88,6 +88,11 @@ public:
|
||||
// get hinted glyph width in pixels as 16.16 fixed-point value
|
||||
virtual PRInt32 GetGlyphWidth(gfxContext *aCtx, PRUint16 aGID);
|
||||
|
||||
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
virtual void CreatePlatformShaper();
|
||||
|
||||
|
@ -509,3 +509,19 @@ gfxMacFont::GetScaledFont()
|
||||
return mAzureFont;
|
||||
}
|
||||
|
||||
void
|
||||
gfxMacFont::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
gfxFont::SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
// mCGFont is shared with the font entry, so not counted here;
|
||||
// and we don't have APIs to measure the cairo mFontFace object
|
||||
}
|
||||
|
||||
void
|
||||
gfxMacFont::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const
|
||||
{
|
||||
aSizes->mFontInstances += aMallocSizeOf(this);
|
||||
SizeOfExcludingThis(aMallocSizeOf, aSizes);
|
||||
}
|
||||
|
@ -81,6 +81,11 @@ public:
|
||||
|
||||
mozilla::RefPtr<mozilla::gfx::ScaledFont> GetScaledFont();
|
||||
|
||||
virtual void SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
virtual void SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf,
|
||||
FontCacheSizes* aSizes) const;
|
||||
|
||||
protected:
|
||||
virtual void CreatePlatformShaper();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user