diff options
author | Khaled Hosny <khaledhosny@eglug.org> | 2016-12-15 02:47:13 +0200 |
---|---|---|
committer | Khaled Hosny <khaledhosny@eglug.org> | 2016-12-16 05:56:44 +0000 |
commit | d85003a8af8b454b34eea0ac67c8dd9184a0b6d3 (patch) | |
tree | f40faab2322af0e6eef856c990d3bf6246919abf /vcl | |
parent | 641b3461dd57b73807f7f55fa2d9b08fb777ed20 (diff) |
tdf#104159: Re-enable OpenGL glyph caching on Windows
Reviewed-on: https://gerrit.libreoffice.org/32026
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Khaled Hosny <khaledhosny@eglug.org>
(cherry picked from commit 9cf20b5f0473db0b4dd2dcf607b7884f40762995)
Change-Id: Icafec05a8cf4428d806efcb286addf3042fcf021
Reviewed-on: https://gerrit.libreoffice.org/32066
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Khaled Hosny <khaledhosny@eglug.org>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/CommonSalLayout.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/win/salgdi.h | 3 | ||||
-rw-r--r-- | vcl/inc/win/winlayout.hxx | 2 | ||||
-rw-r--r-- | vcl/source/gdi/CommonSalLayout.cxx | 1 | ||||
-rw-r--r-- | vcl/win/gdi/winlayout.cxx | 95 |
5 files changed, 90 insertions, 14 deletions
diff --git a/vcl/inc/CommonSalLayout.hxx b/vcl/inc/CommonSalLayout.hxx index e5345d77a65b..e2f3a114eee1 100644 --- a/vcl/inc/CommonSalLayout.hxx +++ b/vcl/inc/CommonSalLayout.hxx @@ -45,6 +45,7 @@ class CommonSalLayout : public GenericSalLayout #ifdef _WIN32 HDC mhDC; HFONT mhFont; + WinFontInstance& mrWinFontInstance; double mnAveWidthFactor; #elif defined(MACOSX) || defined(IOS) const CoreTextStyle& mrCoreTextStyle; @@ -65,6 +66,8 @@ public: #if defined(_WIN32) explicit CommonSalLayout(HDC, WinFontInstance&, const WinFontFace&); const FontSelectPattern& getFontSelData() const { return mrFontSelData; }; + HFONT getHFONT() const { return mhFont; } + WinFontInstance& getWinFontInstance() const { return mrWinFontInstance; } #elif defined(MACOSX) || defined(IOS) explicit CommonSalLayout(const CoreTextStyle&); const CoreTextStyle& getFontData() const { return mrCoreTextStyle; }; diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 305005540841..14310f90411e 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -236,6 +236,9 @@ private: LogicalFontInstance* GetWinFontEntry(int nFallbackLevel); + bool CacheGlyphs(const CommonSalLayout& rLayout); + bool DrawCachedGlyphs(const CommonSalLayout& rLayout); + public: HDC getHDC() const { return mhLocalDC; } void setHDC(HDC aNew) { mhLocalDC = aNew; } diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx index 7b15e7e4f5f3..8ceebeac3882 100644 --- a/vcl/inc/win/winlayout.hxx +++ b/vcl/inc/win/winlayout.hxx @@ -193,7 +193,7 @@ public: private: GlyphCache maGlyphCache; public: - bool CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics); + bool CacheGlyphToAtlas(bool bRealGlyphIndices, HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics); GlyphCache& GetGlyphCache() { diff --git a/vcl/source/gdi/CommonSalLayout.cxx b/vcl/source/gdi/CommonSalLayout.cxx index dbc3fa89695c..8ab8eb3abf9c 100644 --- a/vcl/source/gdi/CommonSalLayout.cxx +++ b/vcl/source/gdi/CommonSalLayout.cxx @@ -181,6 +181,7 @@ CommonSalLayout::CommonSalLayout(HDC hDC, WinFontInstance& rWinFontInstance, con : mrFontSelData(rWinFontInstance.maFontSelData) , mhDC(hDC) , mhFont(static_cast<HFONT>(GetCurrentObject(hDC, OBJ_FONT))) +, mrWinFontInstance(rWinFontInstance) , mnAveWidthFactor(1.0f) , mpVertGlyphs(nullptr) { diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx index c693b31c9fb2..2d351758b2c6 100644 --- a/vcl/win/gdi/winlayout.cxx +++ b/vcl/win/gdi/winlayout.cxx @@ -66,7 +66,7 @@ inline int WinFontInstance::GetCachedGlyphWidth( int nCharCode ) const return it->second; } -bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, const WinLayout& rLayout, SalGraphics& rGraphics) +bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics) { if (nGlyphIndex == DROPPED_OUTGLYPH) return true; @@ -77,17 +77,17 @@ bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, std::vector<uint32_t> aCodePointsOrGlyphIndices(1); aCodePointsOrGlyphIndices[0] = nGlyphIndex; - HDC hDC = CreateCompatibleDC(rLayout.mhDC); - if (hDC == nullptr) + HDC hNewDC = CreateCompatibleDC(hDC); + if (hNewDC == nullptr) { SAL_WARN("vcl.gdi", "CreateCompatibleDC failed: " << WindowsErrorString(GetLastError())); return false; } - HFONT hOrigFont = static_cast<HFONT>(SelectObject(hDC, rLayout.mhFont)); + HFONT hOrigFont = static_cast<HFONT>(SelectObject(hNewDC, hFont)); if (hOrigFont == nullptr) { SAL_WARN("vcl.gdi", "SelectObject failed: " << WindowsErrorString(GetLastError())); - DeleteDC(hDC); + DeleteDC(hNewDC); return false; } @@ -96,26 +96,26 @@ bool WinFontInstance::CacheGlyphToAtlas(bool bRealGlyphIndices, int nGlyphIndex, if (!pTxt) return false; - if (!pTxt->BindFont(hDC)) + if (!pTxt->BindFont(hNewDC)) { SAL_WARN("vcl.gdi", "Binding of font failed. The font might not be supported by Direct Write."); - DeleteDC(hDC); + DeleteDC(hNewDC); return false; } // Bail for non-horizontal text. { wchar_t sFaceName[200]; - int nFaceNameLen = GetTextFaceW(hDC, SAL_N_ELEMENTS(sFaceName), sFaceName); + int nFaceNameLen = GetTextFaceW(hNewDC, SAL_N_ELEMENTS(sFaceName), sFaceName); if (!nFaceNameLen) SAL_WARN("vcl.gdi", "GetTextFace failed: " << WindowsErrorString(GetLastError())); LOGFONTW aLogFont; - GetObjectW(rLayout.mhFont, sizeof(LOGFONTW), &aLogFont); + GetObjectW(hFont, sizeof(LOGFONTW), &aLogFont); - SelectObject(hDC, hOrigFont); - DeleteDC(hDC); + SelectObject(hNewDC, hOrigFont); + DeleteDC(hNewDC); if (sFaceName[0] == '@' || aLogFont.lfOrientation != 0 || aLogFont.lfEscapement != 0) { @@ -1160,7 +1160,7 @@ bool SimpleWinLayout::CacheGlyphs(SalGraphics& rGraphics) const if (!mrWinFontEntry.GetGlyphCache().IsGlyphCached(nCodePoint)) { - if (!mrWinFontEntry.CacheGlyphToAtlas(false, nCodePoint, *this, rGraphics)) + if (!mrWinFontEntry.CacheGlyphToAtlas(false, mhDC, mhFont, nCodePoint, rGraphics)) return false; } } @@ -2409,7 +2409,7 @@ bool UniscribeLayout::CacheGlyphs(SalGraphics& rGraphics) const int nCodePoint = mpOutGlyphs[i]; if (!mrWinFontEntry.GetGlyphCache().IsGlyphCached(nCodePoint)) { - if (!mrWinFontEntry.CacheGlyphToAtlas(true, nCodePoint, *this, rGraphics)) + if (!mrWinFontEntry.CacheGlyphToAtlas(true, mhDC, mhFont, nCodePoint, rGraphics)) return false; } } @@ -3778,6 +3778,70 @@ LogicalFontInstance* WinFontFace::CreateFontInstance( FontSelectPattern& rFSD ) return pFontInstance; } +bool WinSalGraphics::CacheGlyphs(const CommonSalLayout& rLayout) +{ + static bool bDoGlyphCaching = (std::getenv("SAL_DISABLE_GLYPH_CACHING") == nullptr); + if (!bDoGlyphCaching) + return false; + + HDC hDC = getHDC(); + HFONT hFONT = rLayout.getHFONT(); + WinFontInstance& rFont = rLayout.getWinFontInstance(); + + int nStart = 0; + Point aPos(0, 0); + sal_GlyphId nGlyph; + while (rLayout.GetNextGlyphs(1, &nGlyph, aPos, nStart)) + { + if (!rFont.GetGlyphCache().IsGlyphCached(nGlyph)) + { + if (!rFont.CacheGlyphToAtlas(true, hDC, hFONT, nGlyph, *this)) + return false; + } + } + + return true; +} + +bool WinSalGraphics::DrawCachedGlyphs(const CommonSalLayout& rLayout) +{ + HDC hDC = getHDC(); + + Rectangle aRect; + rLayout.GetBoundRect(*this, aRect); + + COLORREF color = GetTextColor(hDC); + SalColor salColor = MAKE_SALCOLOR(GetRValue(color), GetGValue(color), GetBValue(color)); + + WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get()); + if (!pImpl) + return false; + + WinFontInstance& rFont = rLayout.getWinFontInstance(); + + int nStart = 0; + Point aPos(0, 0); + sal_GlyphId nGlyph; + while (rLayout.GetNextGlyphs(1, &nGlyph, aPos, nStart)) + { + OpenGLGlyphDrawElement& rElement(rFont.GetGlyphCache().GetDrawElement(nGlyph)); + OpenGLTexture& rTexture = rElement.maTexture; + + if (!rTexture) + return false; + + SalTwoRect a2Rects(0, 0, + rTexture.GetWidth(), rTexture.GetHeight(), + aPos.X() - rElement.getExtraOffset() + rElement.maLeftOverhangs, + aPos.Y() - rElement.mnBaselineOffset - rElement.getExtraOffset(), + rTexture.GetWidth(), rTexture.GetHeight()); + + pImpl->DeferredTextDraw(rTexture, salColor, a2Rects); + } + + return true; +} + void WinSalGraphics::DrawTextLayout(const CommonSalLayout& rLayout, HDC hDC, bool bUseDWrite) { Point aPos(0, 0); @@ -3796,6 +3860,11 @@ void WinSalGraphics::DrawSalLayout(const CommonSalLayout& rLayout) // no OpenGL, just classic rendering DrawTextLayout(rLayout, hDC, false); } + else if (CacheGlyphs(rLayout) && + DrawCachedGlyphs(rLayout)) + { + // Nothing + } else { // We have to render the text to a hidden texture, and draw it. |