mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1533546 - disable Skia's global DWrite lock on Windows 10. r=jrmuizel
Differential Revision: https://phabricator.services.mozilla.com/D31328 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
e679d377e4
commit
0ab44c22e7
@ -42,17 +42,46 @@
|
||||
/* Note:
|
||||
* In versions 8 and 8.1 of Windows, some calls in DWrite are not thread safe.
|
||||
* The DWriteFactoryMutex protects the calls that are problematic.
|
||||
*
|
||||
* On DWrite 3 or above, which is only available on Windows 10, we don't enable
|
||||
* the locking to avoid thread contention.
|
||||
*/
|
||||
static SkSharedMutex DWriteFactoryMutex;
|
||||
|
||||
typedef SkAutoSharedMutexShared Shared;
|
||||
struct MaybeExclusive {
|
||||
MaybeExclusive(SkScalerContext_DW* ctx) : fEnabled(!ctx->isDWrite3()) {
|
||||
if (fEnabled) {
|
||||
DWriteFactoryMutex.acquire();
|
||||
}
|
||||
}
|
||||
~MaybeExclusive() {
|
||||
if (fEnabled) {
|
||||
DWriteFactoryMutex.release();
|
||||
}
|
||||
}
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
struct MaybeShared {
|
||||
MaybeShared(SkScalerContext_DW* ctx) : fEnabled(!ctx->isDWrite3()) {
|
||||
if (fEnabled) {
|
||||
DWriteFactoryMutex.acquireShared();
|
||||
}
|
||||
}
|
||||
~MaybeShared() {
|
||||
if (fEnabled) {
|
||||
DWriteFactoryMutex.releaseShared();
|
||||
}
|
||||
}
|
||||
bool fEnabled;
|
||||
};
|
||||
|
||||
static bool isLCD(const SkScalerContextRec& rec) {
|
||||
return SkMask::kLCD16_Format == rec.fMaskFormat;
|
||||
}
|
||||
|
||||
static bool is_hinted(DWriteFontTypeface* typeface) {
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
static bool is_hinted(SkScalerContext_DW* ctx, DWriteFontTypeface* typeface) {
|
||||
MaybeExclusive l(ctx);
|
||||
AutoTDWriteTable<SkOTTableMaximumProfile> maxp(typeface->fDWriteFontFace.get());
|
||||
if (!maxp.fExists) {
|
||||
return false;
|
||||
@ -122,8 +151,8 @@ static bool is_gridfit_only(GaspRange::Behavior flags) {
|
||||
return flags.raw.value == GaspRange::Behavior::Raw::GridfitMask;
|
||||
}
|
||||
|
||||
static bool has_bitmap_strike(DWriteFontTypeface* typeface, GaspRange range) {
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
static bool has_bitmap_strike(SkScalerContext_DW* ctx, DWriteFontTypeface* typeface, GaspRange range) {
|
||||
MaybeExclusive l(ctx);
|
||||
{
|
||||
AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWriteFontFace.get());
|
||||
if (!eblc.fExists) {
|
||||
@ -268,7 +297,7 @@ SkScalerContext_DW::SkScalerContext_DW(sk_sp<DWriteFontTypeface> typefaceRef,
|
||||
range = GaspRange(bitmapPPEM, bitmapPPEM, 0, GaspRange::Behavior());
|
||||
}
|
||||
}
|
||||
treatLikeBitmap = has_bitmap_strike(typeface, range);
|
||||
treatLikeBitmap = has_bitmap_strike(this, typeface, range);
|
||||
|
||||
axisAlignedBitmap = is_axis_aligned(fRec);
|
||||
}
|
||||
@ -304,7 +333,7 @@ SkScalerContext_DW::SkScalerContext_DW(sk_sp<DWriteFontTypeface> typefaceRef,
|
||||
// If the font has a gasp table version 1, use it to determine symmetric rendering.
|
||||
} else if ((get_gasp_range(typeface, SkScalarRoundToInt(gdiTextSize), &range) &&
|
||||
range.fVersion >= 1) ||
|
||||
realTextSize > SkIntToScalar(20) || !is_hinted(typeface)) {
|
||||
realTextSize > SkIntToScalar(20) || !is_hinted(this, typeface)) {
|
||||
fTextSizeRender = realTextSize;
|
||||
fTextureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
|
||||
fTextSizeMeasure = realTextSize;
|
||||
@ -397,7 +426,7 @@ bool SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
|
||||
if (DWRITE_MEASURING_MODE_GDI_CLASSIC == fMeasuringMode ||
|
||||
DWRITE_MEASURING_MODE_GDI_NATURAL == fMeasuringMode)
|
||||
{
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
HRBM(this->getDWriteTypeface()->fDWriteFontFace->GetGdiCompatibleGlyphMetrics(
|
||||
fTextSizeMeasure,
|
||||
1.0f, // pixelsPerDip
|
||||
@ -409,14 +438,14 @@ bool SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
|
||||
&gm),
|
||||
"Could not get gdi compatible glyph metrics.");
|
||||
} else {
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
HRBM(this->getDWriteTypeface()->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm),
|
||||
"Could not get design metrics.");
|
||||
}
|
||||
|
||||
DWRITE_FONT_METRICS dwfm;
|
||||
{
|
||||
Shared l(DWriteFactoryMutex);
|
||||
MaybeShared l(this);
|
||||
this->getDWriteTypeface()->fDWriteFontFace->GetMetrics(&dwfm);
|
||||
}
|
||||
SkScalar advanceX = fTextSizeMeasure * gm.advanceWidth / dwfm.designUnitsPerEm;
|
||||
@ -465,7 +494,7 @@ HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
|
||||
|
||||
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
|
||||
{
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
// IDWriteFactory2::CreateGlyphRunAnalysis is very bad at aliased glyphs.
|
||||
if (this->getDWriteTypeface()->fFactory2 &&
|
||||
(fGridFitMode == DWRITE_GRID_FIT_MODE_DISABLED ||
|
||||
@ -495,7 +524,7 @@ HRESULT SkScalerContext_DW::getBoundingBox(SkGlyph* glyph,
|
||||
}
|
||||
}
|
||||
{
|
||||
Shared l(DWriteFactoryMutex);
|
||||
MaybeShared l(this);
|
||||
HRM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, bbox),
|
||||
"Could not get texture bounds.");
|
||||
}
|
||||
@ -588,7 +617,7 @@ void SkScalerContext_DW::generateColorMetrics(SkGlyph* glyph) {
|
||||
HRVM(SkDWriteGeometrySink::Create(&path, &geometryToPath),
|
||||
"Could not create geometry to path converter.");
|
||||
{
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
HRVM(colorGlyph->glyphRun.fontFace->GetGlyphRunOutline(
|
||||
colorGlyph->glyphRun.fontEmSize,
|
||||
colorGlyph->glyphRun.glyphIndices,
|
||||
@ -947,7 +976,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
|
||||
{
|
||||
SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
|
||||
{
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
// IDWriteFactory2::CreateGlyphRunAnalysis is very bad at aliased glyphs.
|
||||
if (this->getDWriteTypeface()->fFactory2 &&
|
||||
(fGridFitMode == DWRITE_GRID_FIT_MODE_DISABLED ||
|
||||
@ -983,7 +1012,7 @@ const void* SkScalerContext_DW::drawDWMask(const SkGlyph& glyph,
|
||||
bbox.right = glyph.fLeft + glyph.fWidth;
|
||||
bbox.bottom = glyph.fTop + glyph.fHeight;
|
||||
{
|
||||
Shared l(DWriteFactoryMutex);
|
||||
MaybeShared l(this);
|
||||
HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
|
||||
&bbox,
|
||||
fBits.begin(),
|
||||
@ -1047,7 +1076,7 @@ void SkScalerContext_DW::generateColorGlyphImage(const SkGlyph& glyph) {
|
||||
HRVM(SkDWriteGeometrySink::Create(&path, &geometryToPath),
|
||||
"Could not create geometry to path converter.");
|
||||
{
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
HRVM(colorGlyph->glyphRun.fontFace->GetGlyphRunOutline(
|
||||
colorGlyph->glyphRun.fontEmSize,
|
||||
colorGlyph->glyphRun.glyphIndices,
|
||||
@ -1186,7 +1215,7 @@ bool SkScalerContext_DW::generatePath(SkGlyphID glyph, SkPath* path) {
|
||||
"Could not create geometry to path converter.");
|
||||
UINT16 glyphId = SkTo<UINT16>(glyph);
|
||||
{
|
||||
SkAutoExclusive l(DWriteFactoryMutex);
|
||||
MaybeExclusive l(this);
|
||||
//TODO: convert to<->from DIUs? This would make a difference if hinting.
|
||||
//It may not be needed, it appears that DirectWrite only hints at em size.
|
||||
HRBM(this->getDWriteTypeface()->fDWriteFontFace->GetGlyphRunOutline(
|
||||
|
@ -26,6 +26,10 @@ public:
|
||||
const SkDescriptor*);
|
||||
~SkScalerContext_DW() override;
|
||||
|
||||
// The IDWriteFontFace4 interface is only available in DWrite 3,
|
||||
// so checking if it was found is sufficient to detect DWrite 3.
|
||||
bool isDWrite3() { return bool(getDWriteTypeface()->fDWriteFontFace4); }
|
||||
|
||||
protected:
|
||||
unsigned generateGlyphCount() override;
|
||||
uint16_t generateCharToGlyph(SkUnichar uni) override;
|
||||
|
Loading…
Reference in New Issue
Block a user