summaryrefslogtreecommitdiff
path: root/vcl/win/gdi
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2019-10-15 16:17:26 +0200
committerLuboš Luňák <l.lunak@collabora.com>2019-11-27 09:55:08 +0100
commitb6cbf5dbd067c63f94872e31f2332e95edc201dd (patch)
treec169fd52f259038dca208c2bcc6904f38163fb1b /vcl/win/gdi
parent8fa83a3265e25b164cb11d598f1fbb49a7b8fbf1 (diff)
refactor Windows OpenGLGlyphCache stuff to be reusable for Skia
Basically just remove 'OpenGL' from names of most of the classes, turn them into base classes that have OpenGL subclasses that actually implement the functionality. Change-Id: Idf1f347cebc2a417bda37d6955201c775ecb0890
Diffstat (limited to 'vcl/win/gdi')
-rw-r--r--vcl/win/gdi/gdiimpl.cxx4
-rw-r--r--vcl/win/gdi/gdiimpl.hxx10
-rw-r--r--vcl/win/gdi/salgdi.cxx36
-rw-r--r--vcl/win/gdi/winlayout.cxx99
4 files changed, 69 insertions, 80 deletions
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index 79621f53bf60..f63258b83dd2 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -2576,12 +2576,12 @@ bool WinSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
return false;
}
-bool WinSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey& /*rControlCacheKey*/, int /*nX*/, int /*nY*/)
+bool WinSalGraphicsImpl::TryRenderCachedNativeControl(const ControlCacheKey& /*rControlCacheKey*/, int /*nX*/, int /*nY*/)
{
return false;
}
-bool WinSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& /*rWhite*/, OpenGLCompatibleDC& /*rBlack*/,
+bool WinSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& /*rWhite*/, CompatibleDC& /*rBlack*/,
int /*nX*/, int /*nY*/ , ControlCacheKey& /*aControlCacheKey*/)
{
return false;
diff --git a/vcl/win/gdi/gdiimpl.hxx b/vcl/win/gdi/gdiimpl.hxx
index bc4a6ac27414..d7d37557565c 100644
--- a/vcl/win/gdi/gdiimpl.hxx
+++ b/vcl/win/gdi/gdiimpl.hxx
@@ -22,6 +22,7 @@
#include <salgdiimpl.hxx>
#include <win/salgdi.h>
+#include <win/wingdiimpl.hxx>
#include <vcl/gradient.hxx>
@@ -30,7 +31,7 @@
class WinSalGraphics;
-class WinSalGraphicsImpl : public SalGraphicsImpl
+class WinSalGraphicsImpl : public SalGraphicsImpl, public WinSalGraphicsImplBase
{
private:
@@ -238,10 +239,11 @@ public:
virtual bool drawGradient(const tools::PolyPolygon& rPolygon,
const Gradient& rGradient) override;
- virtual bool TryRenderCachedNativeControl(ControlCacheKey& rControlCacheKey, int nX, int nY);
+ virtual bool TryRenderCachedNativeControl(const ControlCacheKey& rControlCacheKey,
+ int nX, int nY) override;
- virtual bool RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack,
- int nX, int nY , ControlCacheKey& aControlCacheKey);
+ virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack,
+ int nX, int nY , ControlCacheKey& aControlCacheKey) override;
};
#endif // INCLUDED_VCL_WIN_GDI_GDIIMPL_HXX
diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx
index 6da451de36aa..29c6f83e11f6 100644
--- a/vcl/win/gdi/salgdi.cxx
+++ b/vcl/win/gdi/salgdi.cxx
@@ -547,21 +547,30 @@ void ImplClearHDCCache( SalData* pData )
}
}
-OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height)
+std::unique_ptr< CompatibleDC > CompatibleDC::create(SalGraphics &rGraphics, int x, int y, int width, int height)
+{
+ if (OpenGLHelper::isVCLOpenGLEnabled())
+ return std::make_unique< OpenGLCompatibleDC >( rGraphics, x, y, width, height );
+ return std::unique_ptr< CompatibleDC >( new CompatibleDC( rGraphics, x, y, width, height ));
+}
+
+CompatibleDC::CompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height, bool disable)
: mhBitmap(nullptr)
, mpData(nullptr)
, maRects(0, 0, width, height, x, y, width, height)
+ , mpImpl(nullptr)
{
WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics);
- mpImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(rWinGraphics.mpImpl.get());
- if (!mpImpl)
+ if( disable )
{
// we avoid the OpenGL drawing, instead we draw directly to the DC
mhCompatibleDC = rWinGraphics.getHDC();
return;
}
+ mpImpl = dynamic_cast<WinSalGraphicsImplBase*>(rWinGraphics.GetImpl());
+ assert(mpImpl != nullptr);
mhCompatibleDC = CreateCompatibleDC(rWinGraphics.getHDC());
// move the origin so that we always paint at 0,0 - to keep the bitmap
@@ -573,7 +582,7 @@ OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int
mhOrigBitmap = static_cast<HBITMAP>(SelectObject(mhCompatibleDC, mhBitmap));
}
-OpenGLCompatibleDC::~OpenGLCompatibleDC()
+CompatibleDC::~CompatibleDC()
{
if (mpImpl)
{
@@ -583,7 +592,7 @@ OpenGLCompatibleDC::~OpenGLCompatibleDC()
}
}
-void OpenGLCompatibleDC::fill(sal_uInt32 color)
+void CompatibleDC::fill(sal_uInt32 color)
{
if (!mpData)
return;
@@ -593,23 +602,6 @@ void OpenGLCompatibleDC::fill(sal_uInt32 color)
*p++ = color;
}
-OpenGLTexture* OpenGLCompatibleDC::getTexture()
-{
- if (!mpImpl)
- return nullptr;
-
- // turn what's in the mpData into a texture
- return new OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData);
-}
-
-bool OpenGLCompatibleDC::copyToTexture(OpenGLTexture& aTexture)
-{
- if (!mpImpl)
- return false;
-
- return aTexture.CopyData(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData));
-}
-
WinSalGraphics::WinSalGraphics(WinSalGraphics::Type eType, bool bScreen, HWND hWnd, SalGeometryProvider *pProvider):
mhLocalDC(nullptr),
mbPrinter(eType == WinSalGraphics::PRINTER),
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 7fa273a79c97..9305f38e9dd9 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -26,12 +26,13 @@
#include <comphelper/windowserrorstring.hxx>
#include <comphelper/scopeguard.hxx>
-#include <opengl/texture.hxx>
#include <opengl/win/gdiimpl.hxx>
+#include <opengl/win/winlayout.hxx>
#include <vcl/opengl/OpenGLHelper.hxx>
#include <win/salgdi.h>
#include <win/saldata.hxx>
+#include <win/wingdiimpl.hxx>
#include <outdev.h>
#include <win/DWriteTextRenderer.hxx>
@@ -51,18 +52,18 @@
#include <shlwapi.h>
#include <winver.h>
-GlobalOpenGLGlyphCache * GlobalOpenGLGlyphCache::get()
+GlobalWinGlyphCache * GlobalWinGlyphCache::get()
{
SalData *data = GetSalData();
- if (!data->m_pGlobalOpenGLGlyphCache)
- data->m_pGlobalOpenGLGlyphCache.reset(new GlobalOpenGLGlyphCache);
- return data->m_pGlobalOpenGLGlyphCache.get();
+ if (!data->m_pGlobalWinGlyphCache) // TODO SKIA
+ data->m_pGlobalWinGlyphCache.reset(new OpenGLGlobalWinGlyphCache);
+ return data->m_pGlobalWinGlyphCache.get();
}
bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex,
SalGraphics& rGraphics, const GenericSalLayout& rLayout)
{
- OpenGLGlyphDrawElement aElement;
+ WinGlyphDrawElement aElement;
ScopedHDC aHDC(CreateCompatibleDC(hDC));
@@ -144,14 +145,14 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex,
aElement.maLocation.SetBottom(bounds.getHeight() + aElement.getExtraSpace());
nPos = aEnds[0];
- OpenGLCompatibleDC aDC(rGraphics, 0, 0, nBitmapWidth, nBitmapHeight);
+ std::unique_ptr<CompatibleDC> aDC(CompatibleDC::create(rGraphics, 0, 0, nBitmapWidth, nBitmapHeight));
- SetTextColor(aDC.getCompatibleHDC(), RGB(0, 0, 0));
- SetBkColor(aDC.getCompatibleHDC(), RGB(255, 255, 255));
+ SetTextColor(aDC->getCompatibleHDC(), RGB(0, 0, 0));
+ SetBkColor(aDC->getCompatibleHDC(), RGB(255, 255, 255));
- aDC.fill(RGB(0xff, 0xff, 0xff));
+ aDC->fill(RGB(0xff, 0xff, 0xff));
- pTxt->BindDC(aDC.getCompatibleHDC(), tools::Rectangle(0, 0, nBitmapWidth, nBitmapHeight));
+ pTxt->BindDC(aDC->getCompatibleHDC(), tools::Rectangle(0, 0, nBitmapWidth, nBitmapHeight));
auto pRT = pTxt->GetRenderTarget();
ID2D1SolidColorBrush* pBrush = nullptr;
@@ -193,12 +194,12 @@ bool WinFontInstance::CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex,
return false;
}
- if (!OpenGLGlyphCache::ReserveTextureSpace(aElement, nBitmapWidth, nBitmapHeight))
+ if (!GlobalWinGlyphCache::get()->AllocateTexture(aElement, nBitmapWidth, nBitmapHeight))
return false;
- if (!aDC.copyToTexture(aElement.maTexture))
+ if (!aDC->copyToTexture(*aElement.maTexture.get()))
return false;
- maOpenGLGlyphCache.PutDrawElementInCache(aElement, nGlyphIndex);
+ maWinGlyphCache.PutDrawElementInCache(std::move(aElement), nGlyphIndex);
return true;
}
@@ -457,7 +458,7 @@ bool WinSalGraphics::CacheGlyphs(const GenericSalLayout& rLayout)
const GlyphItem* pGlyph;
while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart))
{
- if (!rFont.GetOpenGLGlyphCache().IsGlyphCached(pGlyph->glyphId()))
+ if (!rFont.GetWinGlyphCache().IsGlyphCached(pGlyph->glyphId()))
{
if (!rFont.CacheGlyphToAtlas(hDC, hFONT, pGlyph->glyphId(), *this, rLayout))
return false;
@@ -489,19 +490,19 @@ bool WinSalGraphics::DrawCachedGlyphs(const GenericSalLayout& rLayout)
const GlyphItem* pGlyph;
while (rLayout.GetNextGlyph(&pGlyph, aPos, nStart))
{
- OpenGLGlyphDrawElement& rElement(rFont.GetOpenGLGlyphCache().GetDrawElement(pGlyph->glyphId()));
- OpenGLTexture& rTexture = rElement.maTexture;
+ WinGlyphDrawElement& rElement(rFont.GetWinGlyphCache().GetDrawElement(pGlyph->glyphId()));
+ const CompatibleDC::Texture* texture = rElement.maTexture.get();
- if (!rTexture)
+ if (!texture || !texture->isValid())
return false;
SalTwoRect a2Rects(0, 0,
- rTexture.GetWidth(), rTexture.GetHeight(),
+ texture->GetWidth(), texture->GetHeight(),
aPos.X() - rElement.getExtraOffset() + rElement.maLeftOverhangs,
aPos.Y() - rElement.mnBaselineOffset - rElement.getExtraOffset(),
- rTexture.GetWidth(), rTexture.GetHeight());
+ texture->GetWidth(), texture->GetHeight());
- pImpl->DeferredTextDraw(rTexture, salColor, a2Rects);
+ pImpl->DeferredTextDraw(texture, salColor, a2Rects);
}
return true;
@@ -519,14 +520,14 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
const WinFontInstance* pWinFont = static_cast<const WinFontInstance*>(&rLayout.GetFont());
const HFONT hLayoutFont = pWinFont->GetHFONT();
- // TODO SKIA
- bool bUseOpenGL = OpenGLHelper::isVCLOpenGLEnabled() && !mbPrinter;
+ WinSalGraphicsImplBase* pImpl = dynamic_cast<WinSalGraphicsImplBase*>(mpImpl.get());
+ bool bUseClassic = !pImpl->UseTextDraw() || mbPrinter;
// Our DirectWrite renderer is incomplete, skip it for vertical text where glyphs are not
// rotated.
bool bForceGDI = rLayout.GetFont().GetFontSelectPattern().mbVertical;
- if (!bUseOpenGL)
+ if (bUseClassic)
{
// no OpenGL, just classic rendering
const HFONT hOrigFont = ::SelectFont(hDC, hLayoutFont);
@@ -568,45 +569,39 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& rLayout)
tools::Rectangle aRect;
rLayout.GetBoundRect(aRect);
- // TODO SKIA
- WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get());
-
- if (pImpl)
- {
- pImpl->PreDraw();
+ pImpl->PreDrawText();
- OpenGLCompatibleDC aDC(*this, aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight());
+ std::unique_ptr<CompatibleDC> aDC(CompatibleDC::create(*this, aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight()));
- // we are making changes to the DC, make sure we got a new one
- assert(aDC.getCompatibleHDC() != hDC);
+ // we are making changes to the DC, make sure we got a new one
+ assert(aDC->getCompatibleHDC() != hDC);
- RECT aWinRect = { aRect.Left(), aRect.Top(), aRect.Left() + aRect.GetWidth(), aRect.Top() + aRect.GetHeight() };
- ::FillRect(aDC.getCompatibleHDC(), &aWinRect, static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));
+ RECT aWinRect = { aRect.Left(), aRect.Top(), aRect.Left() + aRect.GetWidth(), aRect.Top() + aRect.GetHeight() };
+ ::FillRect(aDC->getCompatibleHDC(), &aWinRect, static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH)));
- // setup the hidden DC with black color and white background, we will
- // use the result of the text drawing later as a mask only
- const HFONT hOrigFont = ::SelectFont(aDC.getCompatibleHDC(), hLayoutFont);
+ // setup the hidden DC with black color and white background, we will
+ // use the result of the text drawing later as a mask only
+ const HFONT hOrigFont = ::SelectFont(aDC->getCompatibleHDC(), hLayoutFont);
- ::SetTextColor(aDC.getCompatibleHDC(), RGB(0, 0, 0));
- ::SetBkColor(aDC.getCompatibleHDC(), RGB(255, 255, 255));
+ ::SetTextColor(aDC->getCompatibleHDC(), RGB(0, 0, 0));
+ ::SetBkColor(aDC->getCompatibleHDC(), RGB(255, 255, 255));
- UINT nTextAlign = ::GetTextAlign(hDC);
- ::SetTextAlign(aDC.getCompatibleHDC(), nTextAlign);
+ UINT nTextAlign = ::GetTextAlign(hDC);
+ ::SetTextAlign(aDC->getCompatibleHDC(), nTextAlign);
- COLORREF color = ::GetTextColor(hDC);
- Color salColor(GetRValue(color), GetGValue(color), GetBValue(color));
+ COLORREF color = ::GetTextColor(hDC);
+ Color salColor(GetRValue(color), GetGValue(color), GetBValue(color));
- // the actual drawing
- DrawTextLayout(rLayout, aDC.getCompatibleHDC(), !bForceGDI);
+ // the actual drawing
+ DrawTextLayout(rLayout, aDC->getCompatibleHDC(), !bForceGDI);
- std::unique_ptr<OpenGLTexture> xTexture(aDC.getTexture());
- if (xTexture)
- pImpl->DrawMask(*xTexture, salColor, aDC.getTwoRect());
+ std::unique_ptr<CompatibleDC::Texture> xTexture(aDC->getTexture());
+ if (xTexture)
+ pImpl->DrawMask(xTexture.get(), salColor, aDC->getTwoRect());
- ::SelectFont(aDC.getCompatibleHDC(), hOrigFont);
+ ::SelectFont(aDC->getCompatibleHDC(), hOrigFont);
- pImpl->PostDraw();
- }
+ pImpl->PostDrawText();
}
}