Bug 1777475 - Add locking to the gfxGlyphExtents class. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D150750
This commit is contained in:
Jonathan Kew 2022-06-30 14:52:38 +00:00
Родитель a30e2f2d3b
Коммит a18e1814b0
2 изменённых файлов: 25 добавлений и 6 удалений

Просмотреть файл

@ -37,6 +37,7 @@ bool gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont* aFont,
DrawTarget* aDrawTarget,
uint32_t aGlyphID,
gfxRect* aExtents) {
AutoReadLock lock(mLock);
HashEntry* entry = mTightGlyphExtents.GetEntry(aGlyphID);
if (!entry) {
// Some functions higher up in the call chain deliberately pass in a
@ -50,7 +51,11 @@ bool gfxGlyphExtents::GetTightGlyphExtentsAppUnits(gfxFont* aFont,
#ifdef DEBUG_TEXT_RUN_STORAGE_METRICS
++gGlyphExtentsSetupLazyTight;
#endif
// We need to temporarily release the read lock, as SetupGlyphExtents will
// take a write lock internally when it wants to set the new entry.
mLock.ReadUnlock();
aFont->SetupGlyphExtents(aDrawTarget, aGlyphID, true, this);
mLock.ReadLock();
entry = mTightGlyphExtents.GetEntry(aGlyphID);
if (!entry) {
NS_WARNING("Could not get glyph extents");
@ -122,8 +127,11 @@ void gfxGlyphExtents::GlyphWidths::Set(uint32_t aGlyphID, uint16_t aWidth) {
void gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID,
const gfxRect& aExtentsAppUnits) {
AutoWriteLock lock(mLock);
HashEntry* entry = mTightGlyphExtents.PutEntry(aGlyphID);
if (!entry) return;
if (!entry) {
return;
}
entry->x = aExtentsAppUnits.X();
entry->y = aExtentsAppUnits.Y();
entry->width = aExtentsAppUnits.Width();
@ -131,6 +139,7 @@ void gfxGlyphExtents::SetTightGlyphExtents(uint32_t aGlyphID,
}
size_t gfxGlyphExtents::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const {
AutoReadLock lock(mLock);
return mContainedGlyphWidths.SizeOfExcludingThis(aMallocSizeOf) +
mTightGlyphExtents.ShallowSizeOfExcludingThis(aMallocSizeOf);
}

Просмотреть файл

@ -12,6 +12,7 @@
#include "nsHashKeys.h"
#include "nsTArray.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/RWLock.h"
class gfxContext;
@ -39,29 +40,36 @@ class gfxGlyphExtents {
public:
explicit gfxGlyphExtents(int32_t aAppUnitsPerDevUnit)
: mAppUnitsPerDevUnit(aAppUnitsPerDevUnit) {
: mAppUnitsPerDevUnit(aAppUnitsPerDevUnit),
mLock("gfxGlyphExtents lock") {
MOZ_COUNT_CTOR(gfxGlyphExtents);
}
~gfxGlyphExtents();
enum { INVALID_WIDTH = 0xFFFF };
void NotifyGlyphsChanged() { mTightGlyphExtents.Clear(); }
void NotifyGlyphsChanged() {
mozilla::AutoWriteLock lock(mLock);
mTightGlyphExtents.Clear();
}
// returns INVALID_WIDTH => not a contained glyph
// Otherwise the glyph has no before-bearing or vertical bearings,
// and the result is its width measured from the baseline origin, in
// appunits.
uint16_t GetContainedGlyphWidthAppUnits(uint32_t aGlyphID) const {
mozilla::AutoReadLock lock(mLock);
return mContainedGlyphWidths.Get(aGlyphID);
}
bool IsGlyphKnown(uint32_t aGlyphID) const {
mozilla::AutoReadLock lock(mLock);
return mContainedGlyphWidths.Get(aGlyphID) != INVALID_WIDTH ||
mTightGlyphExtents.GetEntry(aGlyphID) != nullptr;
}
bool IsGlyphKnownWithTightExtents(uint32_t aGlyphID) const {
mozilla::AutoReadLock lock(mLock);
return mTightGlyphExtents.GetEntry(aGlyphID) != nullptr;
}
@ -72,6 +80,7 @@ class gfxGlyphExtents {
uint32_t aGlyphID, gfxRect* aExtents);
void SetContainedGlyphWidthAppUnits(uint32_t aGlyphID, uint16_t aWidth) {
mozilla::AutoWriteLock lock(mLock);
mContainedGlyphWidths.Set(aGlyphID, aWidth);
}
void SetTightGlyphExtents(uint32_t aGlyphID, const gfxRect& aExtentsAppUnits);
@ -140,9 +149,10 @@ class gfxGlyphExtents {
nsTArray<uintptr_t> mBlocks;
};
GlyphWidths mContainedGlyphWidths;
nsTHashtable<HashEntry> mTightGlyphExtents;
int32_t mAppUnitsPerDevUnit;
GlyphWidths mContainedGlyphWidths GUARDED_BY(mLock);
nsTHashtable<HashEntry> mTightGlyphExtents GUARDED_BY(mLock);
const int32_t mAppUnitsPerDevUnit;
mutable mozilla::RWLock mLock;
private:
// not implemented: