From dc7ba8870e6bbcf3e4c8fd79ff249116449fffbd Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Sun, 26 Aug 2007 23:44:00 +0000 Subject: [PATCH] Bug 390234. Coalesce glyph runs after sorting them, gets them into the canonical form. Also add debug code to help track down textrun-cache related crashers. r=vlad git-svn-id: svn://10.0.0.236/trunk@233130 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/gfx/thebes/public/gfxFont.h | 5 ++++ mozilla/gfx/thebes/src/gfxFont.cpp | 24 ++++++++++++++++++- .../gfx/thebes/src/gfxTextRunWordCache.cpp | 18 +++++++++++++- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/mozilla/gfx/thebes/public/gfxFont.h b/mozilla/gfx/thebes/public/gfxFont.h index 3cafe0d4824..d71ba6cd5b5 100644 --- a/mozilla/gfx/thebes/public/gfxFont.h +++ b/mozilla/gfx/thebes/public/gfxFont.h @@ -1113,6 +1113,11 @@ public: PRPackedBool mPartIsEndOfLigature; }; +#ifdef DEBUG + // number of entries referencing this textrun in the gfxTextRunWordCache + PRUint32 mCachedWords; +#endif + private: // **** general helpers **** diff --git a/mozilla/gfx/thebes/src/gfxFont.cpp b/mozilla/gfx/thebes/src/gfxFont.cpp index 606c5d24e09..246572fb9fd 100644 --- a/mozilla/gfx/thebes/src/gfxFont.cpp +++ b/mozilla/gfx/thebes/src/gfxFont.cpp @@ -1489,8 +1489,23 @@ gfxTextRun::AddGlyphRun(gfxFont *aFont, PRUint32 aUTF16Offset, PRBool aForceNewR void gfxTextRun::SortGlyphRuns() { + if (mGlyphRuns.Length() <= 1) + return; + + nsTArray runs(mGlyphRuns); GlyphRunOffsetComparator comp; - mGlyphRuns.Sort(comp); + runs.Sort(comp); + + // Now copy back, coalescing adjacent glyph runs that have the same font + mGlyphRuns.Clear(); + PRUint32 i; + for (i = 0; i < runs.Length(); ++i) { + // a GlyphRun with the same font as the previous GlyphRun can just + // be skipped; the last GlyphRun will cover its character range. + if (i == 0 || runs[i].mFont != runs[i - 1].mFont) { + mGlyphRuns.AppendElement(runs[i]); + } + } } PRUint32 @@ -1653,8 +1668,15 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, PRUint32 aStart, } GlyphRunIterator iter(aSource, aStart, aLength); +#ifdef DEBUG + gfxFont *lastFont = nsnull; +#endif while (iter.NextRun()) { gfxFont *font = iter.GetGlyphRun()->mFont; + NS_ASSERTION(font != lastFont, "Glyphruns not coalesced?"); +#ifdef DEBUG + lastFont = font; +#endif PRUint32 start = iter.GetStringStart(); PRUint32 end = iter.GetStringEnd(); NS_ASSERTION(aSource->IsClusterStart(start), diff --git a/mozilla/gfx/thebes/src/gfxTextRunWordCache.cpp b/mozilla/gfx/thebes/src/gfxTextRunWordCache.cpp index 9786ef0f747..b5c49f062df 100644 --- a/mozilla/gfx/thebes/src/gfxTextRunWordCache.cpp +++ b/mozilla/gfx/thebes/src/gfxTextRunWordCache.cpp @@ -243,6 +243,9 @@ TextRunWordCache::LookupWord(gfxTextRun *aTextRun, gfxFont *aFirstFont, if (fontEntry->mTextRun) { existingEntry = fontEntry; } else { +#ifdef DEBUG + ++aTextRun->mCachedWords; +#endif PR_LOG(gWordCacheLog, PR_LOG_DEBUG, ("%p(%d-%d,%d): added using font", aTextRun, aStart, aEnd - aStart, aHash)); key.mFontOrGroup = aTextRun->GetFontGroup(); CacheHashEntry *groupEntry = mCache.GetEntry(key); @@ -368,7 +371,10 @@ TextRunWordCache::MakeTextRun(const PRUnichar *aText, PRUint32 aLength, nsAutoPtr textRun; textRun = new gfxTextRun(aParams, aText, aLength, aFontGroup, aFlags); if (!textRun || !textRun->GetCharacterGlyphs()) - return nsnull; + return nsnull; +#ifdef DEBUG + textRun->mCachedWords = 0; +#endif gfxFont *font = aFontGroup->GetFontAt(0); nsresult rv = textRun->AddGlyphRun(font, 0); @@ -442,6 +448,9 @@ TextRunWordCache::MakeTextRun(const PRUint8 *aText, PRUint32 aLength, textRun = new gfxTextRun(aParams, aText, aLength, aFontGroup, aFlags); if (!textRun || !textRun->GetCharacterGlyphs()) return nsnull; +#ifdef DEBUG + textRun->mCachedWords = 0; +#endif gfxFont *font = aFontGroup->GetFontAt(0); nsresult rv = textRun->AddGlyphRun(font, 0); @@ -519,6 +528,9 @@ TextRunWordCache::RemoveWord(gfxTextRun *aTextRun, PRUint32 aStart, // XXX would like to use RawRemoveEntry here plus some extra method // that conditionally shrinks the hashtable mCache.RemoveEntry(key); +#ifdef DEBUG + --aTextRun->mCachedWords; +#endif PR_LOG(gWordCacheLog, PR_LOG_DEBUG, ("%p(%d-%d,%d): removed using %s", aTextRun, aStart, length, aHash, key.mFontOrGroup == aTextRun->GetFontGroup() ? "fontgroup" : "font")); @@ -543,6 +555,10 @@ TextRunWordCache::RemoveTextRun(gfxTextRun *aTextRun) } } RemoveWord(aTextRun, wordStart, i, hash); +#ifdef DEBUG + NS_ASSERTION(aTextRun->mCachedWords == 0, + "Textrun was not completely removed from the cache!"); +#endif } static PRBool