diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2017-12-28 00:35:23 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2017-12-28 13:04:30 +0100 |
commit | b0203670492d5af7f963e66ef702f36c87b6b694 (patch) | |
tree | 2c74d62962df05e3bdfcf2c80633e8e1d00dc9a8 /vcl/win | |
parent | b6e6c05b11c991757c640a2d46b1d2aa0e50960b (diff) |
Try to handle fonts orphaned from cache gracefully
ImplFontCache::Invalidate deletes unused entries (with zero ref
count), and keeps other entries, but clears everything (including
still used fonts) from its instance list. In the same time, those
fonts' mpFontCache pointers kept pointing to this cache object.
External clients released font instance by calling its cache's
Release method; this itself allows for broken invariants that
cache's mnRef0Count is equal to number of unused font instances
in its list. Also, those fonts never got released, leaking because
ImplFontCache only ever deletes objects in its list.
What is worse, sometimes font caches get deleted after invalidation
(see OutputDevice::ImplClearFontData). As the instance list of the
cache is empty at the point of delete, the cache destructor doesn't
delete those fonts that were orphaned at the moment of invalidation
(those fonts are still used by some client objects, so deleting
them is clearly wrong). But since the font instances still have
cache pointer referring the already deleted cache, releasing the
instances (by calling deleted cache's Release member function)
must lead do some weird results.
This patch moves the Acquire/Release to LogicalFontInstance, which
now checks if its cache pointer is valid, and if it is, the cache
is used to do the work (as before); otherwise, the font handles
its lifetime itself, and deletes itself when its reference counter
is zero. The cache invalidation clears the cache pointer of the
still-used instances.
Change-Id: I29811272dda814cbc81f14668d63e385ce772332
Reviewed-on: https://gerrit.libreoffice.org/47111
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'vcl/win')
-rw-r--r-- | vcl/win/gdi/salfont.cxx | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/vcl/win/gdi/salfont.cxx b/vcl/win/gdi/salfont.cxx index 9796ab928f3b..001518bf3e55 100644 --- a/vcl/win/gdi/salfont.cxx +++ b/vcl/win/gdi/salfont.cxx @@ -890,7 +890,7 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel mhFonts[ i ] = nullptr; if (mpWinFontEntry[i]) { - GetWinFontEntry(i)->mpFontCache->Release(GetWinFontEntry(i)); + GetWinFontEntry(i)->Release(); } mpWinFontEntry[i] = nullptr; mpWinFontData[i] = nullptr; @@ -902,13 +902,13 @@ void WinSalGraphics::SetFont( const FontSelectPattern* pFont, int nFallbackLevel assert(pFont->mpFontData); if (mpWinFontEntry[nFallbackLevel]) { - GetWinFontEntry(nFallbackLevel)->mpFontCache->Release(GetWinFontEntry(nFallbackLevel)); + GetWinFontEntry(nFallbackLevel)->Release(); } // WinSalGraphics::GetEmbedFontData does not set mpFontInstance // since it is interested in font file data only. if (pFont->mpFontInstance) { - pFont->mpFontInstance->mpFontCache->Acquire(pFont->mpFontInstance); + pFont->mpFontInstance->Acquire(); } mpWinFontEntry[ nFallbackLevel ] = reinterpret_cast<WinFontInstance*>( pFont->mpFontInstance ); mpWinFontData[ nFallbackLevel ] = static_cast<const WinFontFace*>( pFont->mpFontData ); |