Commit 47354b33 authored by Jonathan Kew's avatar Jonathan Kew
Browse files

Bug 1824200 - Make mFTFace an atomic pointer. r=lsalzman, a=dsmith

parent 28fb0f59
Loading
Loading
Loading
Loading
+33 −17
Original line number Diff line number Diff line
@@ -336,7 +336,8 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
                                               SlantStyleRange aStyle,
                                               RefPtr<SharedFTFace>&& aFace)
    : gfxFT2FontEntryBase(aFaceName),
      mFTFace(std::move(aFace)),
      mFontPattern(CreatePatternForFace(aFace->GetFace())),
      mFTFace(aFace.forget().take()),
      mFTFaceInitialized(true),
      mIgnoreFcCharmap(true),
      mHasVariationsInitialized(false) {
@@ -344,8 +345,6 @@ gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
  mStyleRange = aStyle;
  mStretchRange = aStretch;
  mIsDataUserFont = true;

  mFontPattern = CreatePatternForFace(mFTFace->GetFace());
}

gfxFontconfigFontEntry::gfxFontconfigFontEntry(const nsACString& aFaceName,
@@ -405,12 +404,17 @@ gfxFontconfigFontEntry::~gfxFontconfigFontEntry() {
    // InitializeVarFuncs must have been called in order for mMMVar to be
    // non-null here, so we don't need to do it again.
    if (sDoneVar) {
      MOZ_ASSERT(mFTFace, "How did mMMVar get set without a face?");
      (*sDoneVar)(mFTFace->GetFace()->glyph->library, mMMVar);
      auto ftFace = GetFTFace();
      MOZ_ASSERT(ftFace, "How did mMMVar get set without a face?");
      (*sDoneVar)(ftFace->GetFace()->glyph->library, mMMVar);
    } else {
      free(mMMVar);
    }
  }
  if (mFTFaceInitialized) {
    auto face = mFTFace.exchange(nullptr);
    NS_IF_RELEASE(face);
  }
}

nsresult gfxFontconfigFontEntry::ReadCMAP(FontInfoData* aFontInfoData) {
@@ -923,9 +927,12 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
  RefPtr<UnscaledFontFontconfig> unscaledFont =
      mUnscaledFontCache.Lookup(file, index);
  if (!unscaledFont) {
    unscaledFont = mFTFace->GetData() ? new UnscaledFontFontconfig(mFTFace)
    // Here, we use the original mFTFace, not a potential clone with variation
    // settings applied.
    auto ftFace = GetFTFace();
    unscaledFont = ftFace->GetData() ? new UnscaledFontFontconfig(ftFace)
                                     : new UnscaledFontFontconfig(
                                            std::move(file), index, mFTFace);
                                           std::move(file), index, ftFace);
    mUnscaledFontCache.Add(unscaledFont);
  }

@@ -936,17 +943,25 @@ gfxFont* gfxFontconfigFontEntry::CreateFontInstance(
  return newFont;
}

const RefPtr<SharedFTFace>& gfxFontconfigFontEntry::GetFTFace() {
SharedFTFace* gfxFontconfigFontEntry::GetFTFace() {
  if (!mFTFaceInitialized) {
    RefPtr<SharedFTFace> face = CreateFaceForPattern(mFontPattern);
    if (face) {
      if (mFTFace.compareExchange(nullptr, face.get())) {
        Unused << face.forget();  // The reference is now owned by mFTFace.
        mFTFaceInitialized = true;
    mFTFace = CreateFaceForPattern(mFontPattern);
      } else {
        // We lost a race to set mFTFace! Just discard our new face.
      }
    }
  }
  return mFTFace;
}

FTUserFontData* gfxFontconfigFontEntry::GetUserFontData() {
  if (mFTFace && mFTFace->GetData()) {
    return static_cast<FTUserFontData*>(mFTFace->GetData());
  auto face = GetFTFace();
  if (face && face->GetData()) {
    return static_cast<FTUserFontData*>(face->GetData());
  }
  return nullptr;
}
@@ -972,9 +987,9 @@ bool gfxFontconfigFontEntry::HasVariations() {
      mHasVariations = true;
    }
  } else {
    if (GetFTFace()) {
    if (auto ftFace = GetFTFace()) {
      mHasVariations =
          mFTFace->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
          ftFace->GetFace()->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
    }
  }

@@ -990,10 +1005,11 @@ FT_MM_Var* gfxFontconfigFontEntry::GetMMVar() {
  if (!sGetVar) {
    return nullptr;
  }
  if (!GetFTFace()) {
  auto ftFace = GetFTFace();
  if (!ftFace) {
    return nullptr;
  }
  if (FT_Err_Ok != (*sGetVar)(mFTFace->GetFace(), &mMMVar)) {
  if (FT_Err_Ok != (*sGetVar)(ftFace->GetFace(), &mMMVar)) {
    mMMVar = nullptr;
  }
  return mMMVar;
+7 −4
Original line number Diff line number Diff line
@@ -94,7 +94,7 @@ class gfxFontconfigFontEntry final : public gfxFT2FontEntryBase {
  nsresult ReadCMAP(FontInfoData* aFontInfoData = nullptr) override;
  bool TestCharacterMap(uint32_t aCh) override;

  const RefPtr<mozilla::gfx::SharedFTFace>& GetFTFace();
  mozilla::gfx::SharedFTFace* GetFTFace();
  FTUserFontData* GetUserFontData();

  FT_MM_Var* GetMMVar() override;
@@ -120,9 +120,12 @@ class gfxFontconfigFontEntry final : public gfxFT2FontEntryBase {
  // pattern for a single face of a family
  RefPtr<FcPattern> mFontPattern;

  // FTFace - initialized when needed
  RefPtr<mozilla::gfx::SharedFTFace> mFTFace;
  bool mFTFaceInitialized;
  // FTFace - initialized when needed. Once mFTFaceInitialized is true,
  // the face can be accessed without locking.
  // Note that mFTFace owns a reference to the SharedFTFace, but is not
  // a RefPtr because we need it to be an atomic.
  mozilla::Atomic<mozilla::gfx::SharedFTFace*> mFTFace;
  mozilla::Atomic<bool> mFTFaceInitialized;

  // Whether TestCharacterMap should check the actual cmap rather than asking
  // fontconfig about character coverage.