[Libreoffice-commits] core.git: Branch 'feature/skia' - 5 commits - vcl/inc vcl/Library_vclplug_win.mk vcl/opengl vcl/skia vcl/unx vcl/win

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Wed Oct 16 14:34:34 UTC 2019


 vcl/Library_vclplug_win.mk            |    4 -
 vcl/inc/opengl/RenderList.hxx         |    2 
 vcl/inc/opengl/gdiimpl.hxx            |    1 
 vcl/inc/opengl/win/gdiimpl.hxx        |   41 ++++++++++-
 vcl/inc/opengl/win/winlayout.hxx      |   46 +++++++++++++
 vcl/inc/opengl/x11/gdiimpl.hxx        |    2 
 vcl/inc/skia/gdiimpl.hxx              |    3 
 vcl/inc/skia/win/gdiimpl.hxx          |   38 +++++++++-
 vcl/inc/skia/win/winlayout.hxx        |   32 +++++++++
 vcl/inc/win/saldata.hxx               |    4 -
 vcl/inc/win/salgdi.h                  |   40 +++++++----
 vcl/inc/win/salinst.h                 |    1 
 vcl/inc/win/wingdiimpl.hxx            |   56 ++++++++++++++++
 vcl/inc/win/winlayout.hxx             |   87 +++++++-----------------
 vcl/opengl/gdiimpl.cxx                |    6 -
 vcl/opengl/win/gdiimpl.cxx            |   67 ++++++++++++++++++-
 vcl/opengl/win/winlayout.cxx          |   56 ++++++++++++++++
 vcl/skia/gdiimpl.cxx                  |   19 ++++-
 vcl/skia/win/gdiimpl.cxx              |   64 +++++++++++++++++-
 vcl/skia/win/winlayout.cxx            |   26 +++++++
 vcl/unx/generic/gdi/gdiimpl.hxx       |    2 
 vcl/win/app/salinst.cxx               |   10 ++
 vcl/win/gdi/gdiimpl.cxx               |   11 ---
 vcl/win/gdi/gdiimpl.hxx               |    8 --
 vcl/win/gdi/salfont.cxx               |    7 +-
 vcl/win/gdi/salgdi.cxx                |   40 +++++------
 vcl/win/gdi/salnativewidgets-luna.cxx |    5 -
 vcl/win/gdi/winlayout.cxx             |  119 ++++++++++++++++++----------------
 28 files changed, 586 insertions(+), 211 deletions(-)

New commits:
commit bb2e8035308a838edb54a45f6c7638d77f1a9e1e
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Oct 16 16:12:15 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Oct 16 16:31:31 2019 +0200

    make Skia SkBitmap dumping function static
    
    So that it's usable also from the outside.
    
    Change-Id: I4d5184eb8a9dd452a94e5d5b7fe5ed7e329725a0

diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 68646a78d4bc..c4a1d74cc9ac 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -193,7 +193,7 @@ public:
 
 #ifdef DBG_UTIL
     void dump(const char* file) const;
-    void dump(const SkBitmap& bitmap, const char* file) const;
+    static void dump(const SkBitmap& bitmap, const char* file);
 #endif
 
 protected:
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 45e906816d55..6fbb82f8c1b5 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -572,7 +572,7 @@ void SkiaSalGraphicsImpl::dump(const char* file) const
     ostream.write(static_cast<const char*>(data->data()), data->size());
 }
 
-void SkiaSalGraphicsImpl::dump(const SkBitmap& bitmap, const char* file) const
+void SkiaSalGraphicsImpl::dump(const SkBitmap& bitmap, const char* file)
 {
     sk_sp<SkImage> image = SkImage::MakeFromBitmap(bitmap);
     sk_sp<SkData> data = image->encodeToData();
commit 7a767af1efe6038b0a231c979178ed5780c9a778
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Oct 16 16:11:05 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Oct 16 16:31:28 2019 +0200

    remove abort() from SkiaSalGraphicsImpl::invert()
    
    This gets called during LO startup.
    
    Change-Id: I98061df91d6503100ca7edf6058d50fc529180d4

diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 23248fc7ce79..45e906816d55 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -465,7 +465,7 @@ void SkiaSalGraphicsImpl::invert(long nX, long nY, long nWidth, long nHeight, Sa
     (void)nWidth;
     (void)nHeight;
     (void)nFlags;
-    abort();
+    // TODO
 }
 
 void SkiaSalGraphicsImpl::invert(sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags)
commit ec2ed64fa1f5f344f98da3bf2f3fdd74494ebd52
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Oct 16 16:08:51 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Oct 16 16:31:24 2019 +0200

    basic implementation of Skia text drawing on Windows
    
    Change-Id: If66e92aef04cd5bbeb22b8c5da65b7b9c77fed23

diff --git a/vcl/Library_vclplug_win.mk b/vcl/Library_vclplug_win.mk
index 1ac8211586df..8bf801ff188b 100644
--- a/vcl/Library_vclplug_win.mk
+++ b/vcl/Library_vclplug_win.mk
@@ -82,7 +82,8 @@ $(eval $(call gb_Library_add_exception_objects,vclplug_win,\
     vcl/win/window/salmenu \
     vcl/win/window/salobj \
     $(if $(filter SKIA,$(BUILD_TYPE)), \
-        vcl/skia/win/gdiimpl) \
+        vcl/skia/win/gdiimpl \
+        vcl/skia/win/winlayout) \
 ))
 
 $(eval $(call gb_Library_use_system_win32_libs,vclplug_win,\
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index 2d663496b518..142af9768387 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -72,8 +72,8 @@ public:
     using OpenGLSalGraphicsImpl::DrawMask;
     virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry) override;
 
+    virtual bool UseRenderNativeControl() const { return true; }
     virtual bool TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY) override;
-
     virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack,
                                      int nX, int nY , ControlCacheKey& aControlCacheKey) override;
 
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 96bc628e1dd6..68646a78d4bc 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -218,6 +218,7 @@ protected:
         return Color(255 - SkColorGetA(color), SkColorGetR(color), SkColorGetG(color),
                      SkColorGetB(color));
     }
+    void drawMask(const SalTwoRect& rPosAry, const SkBitmap& rBitmap, Color nMaskColor);
 
     SalGraphics& mParent;
     /// Pointer to the SalFrame or SalVirtualDevice
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index 4c47f02baa95..05cacb69d230 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -23,6 +23,26 @@ namespace sk_app
 class WindowContext;
 }
 
+class SkiaCompatibleDC : public CompatibleDC
+{
+public:
+    SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height);
+
+    virtual std::unique_ptr<Texture> getTexture() override;
+
+    virtual bool copyToTexture(Texture& aTexture) override;
+
+    struct Texture;
+};
+
+struct SkiaCompatibleDC::Texture : public CompatibleDC::Texture
+{
+    SkBitmap bitmap; // TODO SkBitmap, SkSurface, SkImage?
+    virtual bool isValid() const { return !bitmap.drawsNothing(); }
+    virtual int GetWidth() const { return bitmap.width(); }
+    virtual int GetHeight() const { return bitmap.height(); }
+};
+
 class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl, public WinSalGraphicsImplBase
 {
 private:
@@ -37,12 +57,20 @@ public:
 
     virtual void freeResources() override;
 
+    virtual bool UseRenderNativeControl() const override { return true; }
     virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX,
                                               int nY) override;
-
     virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX,
                                              int nY, ControlCacheKey& aControlCacheKey) override;
 
+    virtual bool UseTextDraw() const override { return true; }
+    virtual void PreDrawText() override;
+    virtual void PostDrawText() override;
+    virtual void DrawMask(CompatibleDC::Texture* rTexture, Color nMaskColor,
+                          const SalTwoRect& rPosAry) override;
+    virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor,
+                                  const SalTwoRect& rPosAry) override;
+
 protected:
     virtual void createSurface() override;
     virtual void performFlush() override;
diff --git a/vcl/inc/skia/win/winlayout.hxx b/vcl/inc/skia/win/winlayout.hxx
new file mode 100644
index 000000000000..2455c39d06e8
--- /dev/null
+++ b/vcl/inc/skia/win/winlayout.hxx
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_SKIA_WIN_WINLAYOUT_HXX
+#define INCLUDED_VCL_INC_SKIA_WIN_WINLAYOUT_HXX
+
+#include <win/winlayout.hxx>
+
+struct SkiaGlobalWinGlyphCache : public GlobalWinGlyphCache
+{
+    virtual bool AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, int nHeight) override;
+};
+
+#endif // INCLUDED_VCL_INC_SKIA_WIN_WINLAYOUT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx
index d283f4c2bb5c..2264eecf353d 100644
--- a/vcl/inc/win/wingdiimpl.hxx
+++ b/vcl/inc/win/wingdiimpl.hxx
@@ -21,22 +21,34 @@ class WinSalGraphicsImplBase
 public:
     virtual ~WinSalGraphicsImplBase(){};
 
-    virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX,
-                                              int nY)
-        = 0;
-
-    virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX,
-                                             int nY, ControlCacheKey& aControlCacheKey)
-        = 0;
+    // If true is returned, the following functions are used for drawing controls.
+    virtual bool UseRenderNativeControl() const { return false; }
+    virtual bool TryRenderCachedNativeControl(const ControlCacheKey& /*rControlCacheKey*/,
+                                              int /*nX*/, int /*nY*/)
+    {
+        abort();
+    };
+    virtual bool RenderAndCacheNativeControl(CompatibleDC& /*rWhite*/, CompatibleDC& /*rBlack*/,
+                                             int /*nX*/, int /*nY*/,
+                                             ControlCacheKey& /*aControlCacheKey*/)
+    {
+        abort();
+    };
 
     // If true is returned, the following functions are used for text rendering.
     virtual bool UseTextDraw() const { return false; }
     virtual void PreDrawText() {}
     virtual void PostDrawText() {}
     virtual void DrawMask(CompatibleDC::Texture* /*rTexture*/, Color /*nMaskColor*/,
-                          const SalTwoRect& /*rPosAry*/){};
+                          const SalTwoRect& /*rPosAry*/)
+    {
+        abort();
+    };
     virtual void DeferredTextDraw(const CompatibleDC::Texture* /*pTexture*/, Color /*nMaskColor*/,
-                                  const SalTwoRect& /*rPosAry*/){};
+                                  const SalTwoRect& /*rPosAry*/)
+    {
+        abort();
+    };
 };
 
 #endif // INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 7d1745882f8a..aed6956b7ceb 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -75,22 +75,26 @@ protected:
 public:
     WinGlyphCache()
     {
-        GlobalWinGlyphCache::get()->maWinGlyphCaches.insert(this);
+        if(GlobalWinGlyphCache* c = GlobalWinGlyphCache::get())
+            c->maWinGlyphCaches.insert(this);
     }
 
     virtual ~WinGlyphCache()
     {
-        GlobalWinGlyphCache::get()->maWinGlyphCaches.erase(this);
+        if(GlobalWinGlyphCache* c = GlobalWinGlyphCache::get())
+            c->maWinGlyphCaches.erase(this);
     }
 
     void PutDrawElementInCache(WinGlyphDrawElement&& rElement, int nGlyphIndex)
     {
+        assert(GlobalWinGlyphCache::get());
         assert(!IsGlyphCached(nGlyphIndex));
         maWinTextureCache[nGlyphIndex] = std::move( rElement );
     }
 
     WinGlyphDrawElement& GetDrawElement(int nGlyphIndex)
     {
+        assert(GlobalWinGlyphCache::get());
         assert(IsGlyphCached(nGlyphIndex));
         return maWinTextureCache[nGlyphIndex];
     }
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 246826b5f124..23248fc7ce79 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -412,14 +412,23 @@ void SkiaSalGraphicsImpl::drawMask(const SalTwoRect& rPosAry, const SalBitmap& r
                                    Color nMaskColor)
 {
     assert(dynamic_cast<const SkiaSalBitmap*>(&rSalBitmap));
+    drawMask(rPosAry, static_cast<const SkiaSalBitmap&>(rSalBitmap).GetSkBitmap(), nMaskColor);
+}
+
+void SkiaSalGraphicsImpl::drawMask(const SalTwoRect& rPosAry, const SkBitmap& rBitmap,
+                                   Color nMaskColor)
+{
     SkBitmap tmpBitmap;
-    if (!tmpBitmap.tryAllocN32Pixels(rSalBitmap.GetSize().Width(), rSalBitmap.GetSize().Height()))
+    if (!tmpBitmap.tryAllocN32Pixels(rBitmap.width(), rBitmap.height()))
         abort();
     SkCanvas canvas(tmpBitmap);
     SkPaint paint;
     paint.setBlendMode(SkBlendMode::kSrc);
-    canvas.drawBitmap(static_cast<const SkiaSalBitmap&>(rSalBitmap).GetSkBitmap(), 0, 0, &paint);
-    tmpBitmap.eraseColor(toSkColor(nMaskColor));
+    canvas.drawBitmap(rBitmap, 0, 0, &paint);
+    // TODO what is this function supposed to do exactly?
+    // Text drawing on Windows doesn't work if this is uncommented.
+    //    tmpBitmap.eraseColor(toSkColor(nMaskColor));
+    (void)nMaskColor;
     mSurface->getCanvas()->drawBitmapRect(
         tmpBitmap,
         SkRect::MakeXYWH(rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight),
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index ccfd59572424..b8894ad98216 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -99,4 +99,63 @@ bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, C
     return false; // TODO
 }
 
+void WinSkiaSalGraphicsImpl::PreDrawText() {}
+
+void WinSkiaSalGraphicsImpl::PostDrawText() { scheduleFlush(); }
+
+void WinSkiaSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pTexture,
+                                              Color aMaskColor, const SalTwoRect& rPosAry)
+{
+    assert(dynamic_cast<const SkiaCompatibleDC::Texture*>(pTexture));
+    drawMask(rPosAry, static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap, aMaskColor);
+}
+
+void WinSkiaSalGraphicsImpl::DrawMask(CompatibleDC::Texture* pTexture, Color nMaskColor,
+                                      const SalTwoRect& rPosAry)
+{
+    assert(dynamic_cast<SkiaCompatibleDC::Texture*>(pTexture));
+    drawMask(rPosAry, static_cast<const SkiaCompatibleDC::Texture*>(pTexture)->bitmap, nMaskColor);
+}
+
+SkiaCompatibleDC::SkiaCompatibleDC(SalGraphics& rGraphics, int x, int y, int width, int height)
+    : CompatibleDC(rGraphics, x, y, width, height, false)
+{
+}
+
+std::unique_ptr<CompatibleDC::Texture> SkiaCompatibleDC::getTexture()
+{
+    auto ret = std::make_unique<SkiaCompatibleDC::Texture>();
+    // TODO is this correct?
+    // TODO make copy of data?
+    if (!ret->bitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
+                                                     kBGRA_8888_SkColorType, kUnpremul_SkAlphaType),
+                                   mpData, maRects.mnSrcWidth * 4))
+        abort();
+    return ret;
+}
+
+bool SkiaCompatibleDC::copyToTexture(CompatibleDC::Texture& aTexture)
+{
+    assert(mpImpl);
+    assert(dynamic_cast<SkiaCompatibleDC::Texture*>(&aTexture));
+    SkBitmap tmpBitmap;
+    if (!tmpBitmap.installPixels(SkImageInfo::Make(maRects.mnSrcWidth, maRects.mnSrcHeight,
+                                                   kBGRA_8888_SkColorType, kUnpremul_SkAlphaType),
+                                 mpData, maRects.mnSrcWidth * 4))
+        abort();
+    SkBitmap& bitmap = static_cast<SkiaCompatibleDC::Texture&>(aTexture).bitmap;
+    SkPaint paint;
+    paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
+    SkCanvas canvas(bitmap);
+    // The data we got is upside-down.
+    SkMatrix matrix;
+    matrix.preTranslate(0, maRects.mnSrcHeight);
+    matrix.setConcat(matrix, SkMatrix::MakeScale(1, -1));
+    canvas.concat(matrix);
+    canvas.drawBitmapRect(tmpBitmap,
+                          SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight),
+                          SkRect::MakeXYWH(0, 0, maRects.mnSrcWidth, maRects.mnSrcHeight), &paint);
+    return true;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/win/winlayout.cxx b/vcl/skia/win/winlayout.cxx
new file mode 100644
index 000000000000..bd232c1d2bbf
--- /dev/null
+++ b/vcl/skia/win/winlayout.cxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <skia/win/winlayout.hxx>
+
+#include <skia/win/gdiimpl.hxx>
+
+bool SkiaGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, int nWidth,
+                                              int nHeight)
+{
+    assert(rElement.maTexture.get() == nullptr);
+    SkiaCompatibleDC::Texture* texture = new SkiaCompatibleDC::Texture;
+    rElement.maTexture.reset(texture);
+    if (!texture->bitmap.tryAllocN32Pixels(nWidth, nHeight))
+        return false;
+    // TODO prune cache
+    return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index 9741152180f8..d8b4d0905a2c 100644
--- a/vcl/win/gdi/gdiimpl.cxx
+++ b/vcl/win/gdi/gdiimpl.cxx
@@ -2576,15 +2576,4 @@ bool WinSalGraphicsImpl::drawGradient(const tools::PolyPolygon& /*rPolygon*/,
     return false;
 }
 
-bool WinSalGraphicsImpl::TryRenderCachedNativeControl(const ControlCacheKey& /*rControlCacheKey*/, int /*nX*/, int /*nY*/)
-{
-    return false;
-}
-
-bool WinSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& /*rWhite*/, CompatibleDC& /*rBlack*/,
-        int /*nX*/, int /*nY*/ , ControlCacheKey& /*aControlCacheKey*/)
-{
-    return false;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/win/gdi/gdiimpl.hxx b/vcl/win/gdi/gdiimpl.hxx
index d7d37557565c..63eecf521750 100644
--- a/vcl/win/gdi/gdiimpl.hxx
+++ b/vcl/win/gdi/gdiimpl.hxx
@@ -238,12 +238,6 @@ public:
 
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon,
             const Gradient& rGradient) override;
-
-    virtual bool TryRenderCachedNativeControl(const ControlCacheKey& rControlCacheKey,
-                        int nX, int nY) override;
-
-    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/salfont.cxx b/vcl/win/gdi/salfont.cxx
index 45f6e7722b0d..edb917b97b86 100644
--- a/vcl/win/gdi/salfont.cxx
+++ b/vcl/win/gdi/salfont.cxx
@@ -61,6 +61,8 @@
 #include <impfontmetricdata.hxx>
 #include <impglyphitem.hxx>
 
+#include <vcl/skia/SkiaHelper.hxx>
+
 using namespace vcl;
 
 static const int MAXFONTHEIGHT = 2048;
@@ -781,8 +783,9 @@ void ImplGetLogFontFromFontSelect( HDC hDC,
     static BYTE nDefaultQuality = NONANTIALIASED_QUALITY;
     if (nDefaultQuality == NONANTIALIASED_QUALITY)
     {
-        // TODO SKIA
-        if (OpenGLWrapper::isVCLOpenGLEnabled())
+        if (SkiaHelper::isVCLSkiaEnabled())
+            nDefaultQuality = ANTIALIASED_QUALITY;
+        else if (OpenGLWrapper::isVCLOpenGLEnabled())
             nDefaultQuality = ANTIALIASED_QUALITY;
         else
             nDefaultQuality = DEFAULT_QUALITY;
diff --git a/vcl/win/gdi/salgdi.cxx b/vcl/win/gdi/salgdi.cxx
index 3ccc64b4633e..3ce04dd95c6e 100644
--- a/vcl/win/gdi/salgdi.cxx
+++ b/vcl/win/gdi/salgdi.cxx
@@ -549,6 +549,10 @@ void ImplClearHDCCache( SalData* pData )
 
 std::unique_ptr< CompatibleDC > CompatibleDC::create(SalGraphics &rGraphics, int x, int y, int width, int height)
 {
+#if HAVE_FEATURE_SKIA
+    if (SkiaHelper::isVCLSkiaEnabled())
+        return std::make_unique< SkiaCompatibleDC >( rGraphics, x, y, width, height );
+#endif
     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 ));
diff --git a/vcl/win/gdi/salnativewidgets-luna.cxx b/vcl/win/gdi/salnativewidgets-luna.cxx
index a4b6640ca88d..7da5b223481d 100644
--- a/vcl/win/gdi/salnativewidgets-luna.cxx
+++ b/vcl/win/gdi/salnativewidgets-luna.cxx
@@ -1159,8 +1159,9 @@ bool WinSalGraphics::drawNativeControl( ControlType nType,
     tools::Rectangle cacheRect = rControlRegion;
     Size keySize = cacheRect.GetSize();
 
-    // TODO SKIA
-    WinOpenGLSalGraphicsImpl* pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get());
+    WinSalGraphicsImplBase* pImpl = dynamic_cast<WinSalGraphicsImplBase*>(mpImpl.get());
+    if( !pImpl->UseRenderNativeControl())
+        pImpl = nullptr;
 
     // tdf#95618 - A few controls render outside the region they're given.
     if (pImpl && nType == ControlType::TabItem)
diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index ccc744a0a991..d6baa6586b9e 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <config_features.h>
+
 #include <memory>
 #include <osl/module.h>
 #include <osl/file.h>
@@ -33,6 +35,11 @@
 #include <win/saldata.hxx>
 #include <win/wingdiimpl.hxx>
 #include <outdev.h>
+#include <vcl/opengl/OpenGLHelper.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
+#if HAVE_FEATURE_SKIA
+#include <skia/win/winlayout.hxx>
+#endif
 
 #include <win/DWriteTextRenderer.hxx>
 #include <win/scoped_gdi.hxx>
@@ -53,8 +60,16 @@
 GlobalWinGlyphCache * GlobalWinGlyphCache::get()
 {
     SalData *data = GetSalData();
-    if (!data->m_pGlobalWinGlyphCache) // TODO SKIA
-        data->m_pGlobalWinGlyphCache.reset(new OpenGLGlobalWinGlyphCache);
+    if (!data->m_pGlobalWinGlyphCache)
+    {
+#if HAVE_FEATURE_SKIA
+        if (SkiaHelper::isVCLSkiaEnabled())
+            data->m_pGlobalWinGlyphCache.reset(new SkiaGlobalWinGlyphCache);
+        else
+#endif
+        if (OpenGLHelper::isVCLOpenGLEnabled())
+            data->m_pGlobalWinGlyphCache.reset(new OpenGLGlobalWinGlyphCache);
+    }
     return data->m_pGlobalWinGlyphCache.get();
 }
 
@@ -435,9 +450,8 @@ bool WinSalGraphics::DrawCachedGlyphs(const GenericSalLayout& rLayout)
     COLORREF color = GetTextColor(hDC);
     Color salColor(GetRValue(color), GetGValue(color), GetBValue(color));
 
-    // TODO SKIA
-    WinOpenGLSalGraphicsImpl *pImpl = dynamic_cast<WinOpenGLSalGraphicsImpl*>(mpImpl.get());
-    if (!pImpl)
+    WinSalGraphicsImplBase *pImpl = dynamic_cast<WinSalGraphicsImplBase*>(mpImpl.get());
+    if (!pImpl->UseTextDraw())
         return false;
 
     WinFontInstance& rFont = *static_cast<WinFontInstance*>(&rLayout.GetFont());
commit 1d30e451c1da1c2cdbc15d9efc3c112e3de23809
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Oct 16 16:00:46 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Oct 16 16:31:21 2019 +0200

    use SupportsBitmap32 also for Skia on Windows
    
    Change-Id: Ic40b76f152767d25c3645de2cb013c3af4ae93a4

diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h
index bcd3540ad8a9..c06e51c84050 100644
--- a/vcl/inc/win/salinst.h
+++ b/vcl/inc/win/salinst.h
@@ -73,6 +73,7 @@ public:
     virtual void                AddToRecentDocumentList(const OUString& rFileUrl, const OUString& rMimeType, const OUString& rDocumentService) override;
 
     virtual OUString            getOSVersion() override;
+    virtual std::shared_ptr<vcl::BackendCapabilities> GetBackendCapabilities() override;
 
     static int WorkaroundExceptionHandlingInUSER32Lib(int nExcept, LPEXCEPTION_POINTERS pExceptionInfo);
 };
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index f904be4c6eb7..1dde24c85464 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -1067,4 +1067,14 @@ OUString WinSalInstance::getOSVersion()
     return aVer.makeStringAndClear();
 }
 
+std::shared_ptr<vcl::BackendCapabilities> WinSalInstance::GetBackendCapabilities()
+{
+    auto pBackendCapabilities = SalInstance::GetBackendCapabilities();
+#if HAVE_FEATURE_SKIA
+    if( SkiaHelper::isVCLSkiaEnabled())
+        pBackendCapabilities->mbSupportsBitmap32 = true;
+#endif
+    return pBackendCapabilities;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit c00c38359d4be60107d6653d2df2aab9755f07fe
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Oct 15 16:17:26 2019 +0200
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Oct 16 16:31:17 2019 +0200

    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

diff --git a/vcl/Library_vclplug_win.mk b/vcl/Library_vclplug_win.mk
index 19b7a2d6f87f..1ac8211586df 100644
--- a/vcl/Library_vclplug_win.mk
+++ b/vcl/Library_vclplug_win.mk
@@ -60,6 +60,7 @@ $(eval $(call gb_Library_use_externals,vclplug_win,\
 
 $(eval $(call gb_Library_add_exception_objects,vclplug_win,\
     vcl/opengl/win/gdiimpl \
+    vcl/opengl/win/winlayout \
     vcl/win/app/saldata \
     vcl/win/app/salinfo \
     vcl/win/app/salinst \
diff --git a/vcl/inc/opengl/RenderList.hxx b/vcl/inc/opengl/RenderList.hxx
index e4df834755d6..06dd03b4d7d1 100644
--- a/vcl/inc/opengl/RenderList.hxx
+++ b/vcl/inc/opengl/RenderList.hxx
@@ -150,7 +150,7 @@ public:
         return maRenderEntries;
     }
 
-    void addDrawTextureWithMaskColor(OpenGLTexture const & rTexture, Color nColor, const SalTwoRect& r2Rect);
+    VCL_DLLPUBLIC void addDrawTextureWithMaskColor(OpenGLTexture const & rTexture, Color nColor, const SalTwoRect& r2Rect);
 
     void addDrawPixel(long nX, long nY, Color nColor);
 
diff --git a/vcl/inc/opengl/gdiimpl.hxx b/vcl/inc/opengl/gdiimpl.hxx
index e90e55458d12..b0b1de88b185 100644
--- a/vcl/inc/opengl/gdiimpl.hxx
+++ b/vcl/inc/opengl/gdiimpl.hxx
@@ -141,7 +141,6 @@ public:
     void DrawLinearGradient( const Gradient& rGradient, const tools::Rectangle& rRect );
     void DrawAxialGradient( const Gradient& rGradient, const tools::Rectangle& rRect );
     void DrawRadialGradient( const Gradient& rGradient, const tools::Rectangle& rRect );
-    void DeferredTextDraw(OpenGLTexture const & rTexture, const Color nMaskColor, const SalTwoRect& rPosAry);
 
     void FlushDeferredDrawing();
     void FlushLinesOrTriangles(DrawShaderType eType, RenderParameters const & rParameters);
diff --git a/vcl/inc/opengl/win/gdiimpl.hxx b/vcl/inc/opengl/win/gdiimpl.hxx
index 6382e0441bdb..2d663496b518 100644
--- a/vcl/inc/opengl/win/gdiimpl.hxx
+++ b/vcl/inc/opengl/win/gdiimpl.hxx
@@ -16,11 +16,34 @@
 #include <opengl/gdiimpl.hxx>
 #include <svdata.hxx>
 #include <win/salgdi.h>
+#include <win/wingdiimpl.hxx>
 #include <o3tl/lru_map.hxx>
 #include <vcl/opengl/OpenGLContext.hxx>
 #include <ControlCacheKey.hxx>
 
-class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl
+class OpenGLCompatibleDC : public CompatibleDC
+{
+public:
+    OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height);
+
+    virtual std::unique_ptr<Texture> getTexture() override;
+    // overload, caller must delete
+    OpenGLTexture* getOpenGLTexture();
+
+    virtual bool copyToTexture(Texture& aTexture) override;
+
+    struct Texture;
+};
+
+struct OpenGLCompatibleDC::Texture : public CompatibleDC::Texture
+{
+    OpenGLTexture texture;
+    virtual bool isValid() const { return !!texture; }
+    virtual int GetWidth() const { return texture.GetWidth(); }
+    virtual int GetHeight() const { return texture.GetHeight(); }
+};
+
+class WinOpenGLSalGraphicsImpl : public OpenGLSalGraphicsImpl, public WinSalGraphicsImplBase
 {
     friend class WinLayout;
 private:
@@ -42,11 +65,17 @@ public:
     virtual void Init() override;
     virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) override;
 
+    virtual bool UseTextDraw() const override { return true; }
+    virtual void PreDrawText() override;
+    virtual void PostDrawText() override;
+    virtual void DrawMask( CompatibleDC::Texture* rTexture, Color nMaskColor, const SalTwoRect& rPosAry ) override;
+    using OpenGLSalGraphicsImpl::DrawMask;
+    virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry) override;
 
-    bool TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY);
+    virtual bool TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY) override;
 
-    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;
 
 };
 
diff --git a/vcl/inc/opengl/win/winlayout.hxx b/vcl/inc/opengl/win/winlayout.hxx
new file mode 100644
index 000000000000..c6ce77bdad4e
--- /dev/null
+++ b/vcl/inc/opengl/win/winlayout.hxx
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX
+#define INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX
+
+#include <win/winlayout.hxx>
+#include <opengl/PackedTextureAtlas.hxx>
+
+struct OpenGLGlobalWinGlyphCache : public GlobalWinGlyphCache
+{
+    OpenGLGlobalWinGlyphCache()
+        : maPackedTextureAtlas(2048, 2048)
+    {
+    }
+
+    PackedTextureAtlasManager maPackedTextureAtlas;
+
+    virtual bool AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, int nHeight) override;
+};
+
+class OpenGLWinGlyphCache : public WinGlyphCache
+{
+public:
+    void RemoveTextures(std::vector<GLuint>& rTextureIDs);
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_WIN_WINLAYOUT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/x11/gdiimpl.hxx b/vcl/inc/opengl/x11/gdiimpl.hxx
index 2fdd32dc44da..334530306258 100644
--- a/vcl/inc/opengl/x11/gdiimpl.hxx
+++ b/vcl/inc/opengl/x11/gdiimpl.hxx
@@ -32,8 +32,6 @@ protected:
     virtual rtl::Reference<OpenGLContext> CreateWinContext() override;
 
 public:
-    // implementation of X11GraphicsImpl
-
     virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) override;
 
     virtual void Init() override;
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index 621d8d4b4a78..4c47f02baa95 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -15,6 +15,7 @@
 
 #include <skia/gdiimpl.hxx>
 #include <win/salgdi.h>
+#include <win/wingdiimpl.hxx>
 
 class ControlCacheKey;
 namespace sk_app
@@ -22,7 +23,7 @@ namespace sk_app
 class WindowContext;
 }
 
-class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl
+class WinSkiaSalGraphicsImpl : public SkiaSalGraphicsImpl, public WinSalGraphicsImplBase
 {
 private:
     WinSalGraphics& mWinParent;
@@ -36,10 +37,11 @@ public:
 
     virtual void freeResources() override;
 
-    bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX, int nY);
+    virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX,
+                                              int nY) override;
 
-    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;
 
 protected:
     virtual void createSurface() override;
diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx
index dd08b7553734..e9889e6653d1 100644
--- a/vcl/inc/win/saldata.hxx
+++ b/vcl/inc/win/saldata.hxx
@@ -38,7 +38,7 @@ class WinSalFrame;
 class WinSalVirtualDevice;
 class WinSalPrinter;
 namespace vcl { class Font; }
-struct GlobalOpenGLGlyphCache;
+struct GlobalWinGlyphCache;
 struct HDCCache;
 struct TempFontItem;
 class TextOutRenderer;
@@ -122,7 +122,7 @@ public:
     std::unique_ptr<TextOutRenderer> m_pD2DWriteTextOutRenderer;
     // tdf#107205 need 2 instances because D2DWrite can't rotate text
     std::unique_ptr<TextOutRenderer> m_pExTextOutRenderer;
-    std::unique_ptr<GlobalOpenGLGlyphCache> m_pGlobalOpenGLGlyphCache;
+    std::unique_ptr<GlobalWinGlyphCache> m_pGlobalWinGlyphCache;
     std::unique_ptr<TheTextureCache> m_pTextureCache;
 };
 
diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h
index d6d8dea14c24..f7fb206624b5 100644
--- a/vcl/inc/win/salgdi.h
+++ b/vcl/inc/win/salgdi.h
@@ -45,10 +45,9 @@
 class FontSelectPattern;
 class WinFontInstance;
 class ImplFontAttrCache;
-class OpenGLTexture;
 class PhysicalFontCollection;
 class SalGraphicsImpl;
-class WinOpenGLSalGraphicsImpl;
+class WinSalGraphicsImplBase;
 class ImplFontMetricData;
 
 #define RGB_TO_PALRGB(nRGB)         ((nRGB)|0x02000000)
@@ -95,11 +94,12 @@ private:
 
 /** Class that creates (and destroys) a compatible Device Context.
 
-This is to be used for GDI drawing into a DIB that we later use as a texture for OpenGL drawing.
+This is to be used for GDI drawing into a DIB that we later use for a different
+drawing method, such as a texture for OpenGL drawing or surface for Skia drawing.
 */
-class OpenGLCompatibleDC
+class CompatibleDC
 {
-private:
+protected:
     /// The compatible DC that we create for our purposes.
     HDC mhCompatibleDC;
 
@@ -115,12 +115,16 @@ private:
     /// Mapping between the GDI position and OpenGL, to use for OpenGL drawing.
     SalTwoRect maRects;
 
-    /// The OpenGL-based SalGraphicsImpl where we will draw.  If null, we ignore the drawing, it means it happened directly to the DC...
-    WinOpenGLSalGraphicsImpl *mpImpl;
+    /// The SalGraphicsImpl where we will draw.  If null, we ignore the drawing, it means it happened directly to the DC...
+    WinSalGraphicsImplBase *mpImpl;
+
+    // If 'disable' is true, this class is a simple wrapper for drawing directly. Subclasses should use true.
+    CompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height, bool disable=true);
 
 public:
-    OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height);
-    ~OpenGLCompatibleDC();
+    static std::unique_ptr< CompatibleDC > create(SalGraphics &rGraphics, int x, int y, int width, int height);
+
+    virtual ~CompatibleDC();
 
     HDC getCompatibleHDC() { return mhCompatibleDC; }
 
@@ -131,11 +135,22 @@ public:
     /// Reset the DC with the defined color.
     void fill(sal_uInt32 color);
 
-    /// Obtain the texture; the caller must delete it after use.
-    OpenGLTexture* getTexture();
+    /// Base texture class (OpenGL and Skia will provide their implementations).
+    struct Texture;
+
+    /// Obtain the texture.
+    virtual std::unique_ptr<Texture> getTexture() { abort(); };
 
     /// Copy bitmap data to the texture. Texture must be initialized and the correct size to hold the bitmap.
-    bool copyToTexture(OpenGLTexture& aTexture);
+    virtual bool copyToTexture(Texture& /*aTexture*/) { abort(); };
+};
+
+struct CompatibleDC::Texture
+{
+    virtual ~Texture() = 0 {};
+    virtual bool isValid() const = 0;
+    virtual int GetWidth() const = 0;
+    virtual int GetHeight() const = 0;
 };
 
 class WinSalGraphics : public SalGraphics
@@ -143,7 +158,6 @@ class WinSalGraphics : public SalGraphics
     friend class WinSalGraphicsImpl;
     friend class WinOpenGLSalGraphicsImpl;
     friend class ScopedFont;
-    friend class OpenGLCompatibleDC;
 
 protected:
     std::unique_ptr<SalGraphicsImpl> mpImpl;
diff --git a/vcl/inc/win/wingdiimpl.hxx b/vcl/inc/win/wingdiimpl.hxx
new file mode 100644
index 000000000000..d283f4c2bb5c
--- /dev/null
+++ b/vcl/inc/win/wingdiimpl.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX
+#define INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX
+
+#include <win/salgdi.h>
+#include <ControlCacheKey.hxx>
+
+class ControlCacheKey;
+
+// Base class for some functionality that OpenGL/Skia/GDI backends must each implement.
+class WinSalGraphicsImplBase
+{
+public:
+    virtual ~WinSalGraphicsImplBase(){};
+
+    virtual bool TryRenderCachedNativeControl(ControlCacheKey const& rControlCacheKey, int nX,
+                                              int nY)
+        = 0;
+
+    virtual bool RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack, int nX,
+                                             int nY, ControlCacheKey& aControlCacheKey)
+        = 0;
+
+    // If true is returned, the following functions are used for text rendering.
+    virtual bool UseTextDraw() const { return false; }
+    virtual void PreDrawText() {}
+    virtual void PostDrawText() {}
+    virtual void DrawMask(CompatibleDC::Texture* /*rTexture*/, Color /*nMaskColor*/,
+                          const SalTwoRect& /*rPosAry*/){};
+    virtual void DeferredTextDraw(const CompatibleDC::Texture* /*pTexture*/, Color /*nMaskColor*/,
+                                  const SalTwoRect& /*rPosAry*/){};
+};
+
+#endif // INCLUDED_VCL_INC_WIN_WINGDIIMPL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/win/winlayout.hxx b/vcl/inc/win/winlayout.hxx
index 991c68f15b66..7d1745882f8a 100644
--- a/vcl/inc/win/winlayout.hxx
+++ b/vcl/inc/win/winlayout.hxx
@@ -26,8 +26,6 @@
 #include <svsys.h>
 #include <win/salgdi.h>
 
-#include <opengl/PackedTextureAtlas.hxx>
-
 class WinFontInstance;
 
 namespace
@@ -38,11 +36,11 @@ const int GLYPH_SPACE_RATIO = 8;
 const int GLYPH_OFFSET_RATIO = GLYPH_SPACE_RATIO * 2;
 }
 
-struct OpenGLGlyphDrawElement
+struct WinGlyphDrawElement
 {
     tools::Rectangle maLocation;
     int maLeftOverhangs;
-    OpenGLTexture maTexture;
+    std::unique_ptr<CompatibleDC::Texture> maTexture;
     int mnBaselineOffset;
     int mnHeight;
     bool mbVertical;
@@ -58,87 +56,48 @@ struct OpenGLGlyphDrawElement
     }
 };
 
-class OpenGLGlyphCache;
+class WinGlyphCache;
 
-struct GlobalOpenGLGlyphCache
+struct GlobalWinGlyphCache
 {
-    GlobalOpenGLGlyphCache()
-        : maPackedTextureAtlas(2048, 2048)
-    {}
+    std::unordered_set<WinGlyphCache*> maWinGlyphCaches;
 
-    PackedTextureAtlasManager maPackedTextureAtlas;
-    std::unordered_set<OpenGLGlyphCache*> maOpenGLGlyphCaches;
+    static GlobalWinGlyphCache * get();
 
-    static GlobalOpenGLGlyphCache * get();
+    virtual bool AllocateTexture(WinGlyphDrawElement& rElement, int nWidth, int nHeight) = 0;
 };
 
-class OpenGLGlyphCache
+class WinGlyphCache
 {
-private:
-    std::unordered_map<int, OpenGLGlyphDrawElement> maOpenGLTextureCache;
+protected:
+    std::unordered_map<int, WinGlyphDrawElement> maWinTextureCache;
 
 public:
-    OpenGLGlyphCache()
-    {
-        GlobalOpenGLGlyphCache::get()->maOpenGLGlyphCaches.insert(this);
-    }
-
-    ~OpenGLGlyphCache()
-    {
-        GlobalOpenGLGlyphCache::get()->maOpenGLGlyphCaches.erase(this);
-    }
-
-    static bool ReserveTextureSpace(OpenGLGlyphDrawElement& rElement, int nWidth, int nHeight)
+    WinGlyphCache()
     {
-        GlobalOpenGLGlyphCache* pGlobalOpenGLGlyphCache = GlobalOpenGLGlyphCache::get();
-        rElement.maTexture = pGlobalOpenGLGlyphCache->maPackedTextureAtlas.Reserve(nWidth, nHeight);
-        if (!rElement.maTexture)
-            return false;
-        std::vector<GLuint> aTextureIDs = pGlobalOpenGLGlyphCache->maPackedTextureAtlas.ReduceTextureNumber(8);
-        if (!aTextureIDs.empty())
-        {
-            for (auto& pOpenGLGlyphCache: pGlobalOpenGLGlyphCache->maOpenGLGlyphCaches)
-            {
-                pOpenGLGlyphCache->RemoveTextures(aTextureIDs);
-            }
-        }
-        return true;
+        GlobalWinGlyphCache::get()->maWinGlyphCaches.insert(this);
     }
 
-    void RemoveTextures(std::vector<GLuint>& rTextureIDs)
+    virtual ~WinGlyphCache()
     {
-        auto it = maOpenGLTextureCache.begin();
-
-        while (it != maOpenGLTextureCache.end())
-        {
-            GLuint nTextureID = it->second.maTexture.Id();
-
-            if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end())
-            {
-                it = maOpenGLTextureCache.erase(it);
-            }
-            else
-            {
-                ++it;
-            }
-        }
+        GlobalWinGlyphCache::get()->maWinGlyphCaches.erase(this);
     }
 
-    void PutDrawElementInCache(const OpenGLGlyphDrawElement& rElement, int nGlyphIndex)
+    void PutDrawElementInCache(WinGlyphDrawElement&& rElement, int nGlyphIndex)
     {
         assert(!IsGlyphCached(nGlyphIndex));
-        maOpenGLTextureCache[nGlyphIndex] = rElement;
+        maWinTextureCache[nGlyphIndex] = std::move( rElement );
     }
 
-    OpenGLGlyphDrawElement& GetDrawElement(int nGlyphIndex)
+    WinGlyphDrawElement& GetDrawElement(int nGlyphIndex)
     {
         assert(IsGlyphCached(nGlyphIndex));
-        return maOpenGLTextureCache[nGlyphIndex];
+        return maWinTextureCache[nGlyphIndex];
     }
 
     bool IsGlyphCached(int nGlyphIndex) const
     {
-        return maOpenGLTextureCache.find(nGlyphIndex) != maOpenGLTextureCache.end();
+        return maWinTextureCache.find(nGlyphIndex) != maWinTextureCache.end();
     }
 };
 
@@ -166,7 +125,7 @@ public:
     const WinFontFace * GetFontFace() const { return static_cast<const WinFontFace *>(LogicalFontInstance::GetFontFace()); }
 
     bool CacheGlyphToAtlas(HDC hDC, HFONT hFont, int nGlyphIndex, SalGraphics& rGraphics, const GenericSalLayout& rLayout);
-    OpenGLGlyphCache& GetOpenGLGlyphCache() { return maOpenGLGlyphCache; }
+    WinGlyphCache& GetWinGlyphCache() { return maWinGlyphCache; }
 
     bool GetGlyphOutline(sal_GlyphId, basegfx::B2DPolyPolygon&, bool) const override;
 
@@ -179,7 +138,7 @@ private:
     WinSalGraphics *m_pGraphics;
     HFONT m_hFont;
     float m_fScale;
-    OpenGLGlyphCache maOpenGLGlyphCache;
+    WinGlyphCache maWinGlyphCache;
 };
 
 class TextOutRenderer
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index 30d2299978ea..0f0e40dd7eaa 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -1324,12 +1324,6 @@ void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, Color nMaskColor, co
     mpProgram->Clean();
 }
 
-void OpenGLSalGraphicsImpl::DeferredTextDraw(OpenGLTexture const & rTexture, Color aMaskColor, const SalTwoRect& rPosAry)
-{
-    mpRenderList->addDrawTextureWithMaskColor(rTexture, aMaskColor, rPosAry);
-    PostBatchDraw();
-}
-
 void OpenGLSalGraphicsImpl::FlushLinesOrTriangles(DrawShaderType eType, RenderParameters const & rParameters)
 {
     if (!UseProgram("combinedVertexShader", "combinedFragmentShader", "#define USE_VERTEX_COLORS"))
diff --git a/vcl/opengl/win/gdiimpl.cxx b/vcl/opengl/win/gdiimpl.cxx
index b0d1188519c2..d71a03714198 100644
--- a/vcl/opengl/win/gdiimpl.cxx
+++ b/vcl/opengl/win/gdiimpl.cxx
@@ -756,6 +756,37 @@ ControlCacheType & TheTextureCache::get() {
     return data->m_pTextureCache->cache;
 }
 
+OpenGLCompatibleDC::OpenGLCompatibleDC(SalGraphics &rGraphics, int x, int y, int width, int height)
+: CompatibleDC( rGraphics, x, y, width, height, false )
+{
+}
+
+OpenGLTexture* OpenGLCompatibleDC::getOpenGLTexture()
+{
+    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);
+}
+
+std::unique_ptr<CompatibleDC::Texture> OpenGLCompatibleDC::getTexture()
+{
+    auto ret = std::make_unique<OpenGLCompatibleDC::Texture>();
+    ret->texture = OpenGLTexture(maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, mpData);
+    return ret;
+}
+
+bool OpenGLCompatibleDC::copyToTexture(CompatibleDC::Texture& aTexture)
+{
+    if (!mpImpl)
+        return false;
+
+    assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(&aTexture));
+    return static_cast<OpenGLCompatibleDC::Texture&>(aTexture).texture.CopyData(
+        maRects.mnSrcWidth, maRects.mnSrcHeight, GL_BGRA, GL_UNSIGNED_BYTE, reinterpret_cast<sal_uInt8*>(mpData));
+}
+
 bool WinOpenGLSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const & rControlCacheKey, int nX, int nY)
 {
     static bool gbCacheEnabled = !getenv("SAL_WITHOUT_WIDGET_CACHE");
@@ -801,8 +832,8 @@ bool WinOpenGLSalGraphicsImpl::RenderCompatibleDC(OpenGLCompatibleDC& rWhite, Op
 
     PreDraw();
 
-    rCombo.mpTexture.reset(rWhite.getTexture());
-    rCombo.mpMask.reset(rBlack.getTexture());
+    rCombo.mpTexture.reset(rWhite.getOpenGLTexture());
+    rCombo.mpMask.reset(rBlack.getOpenGLTexture());
 
     bRet = RenderTextureCombo(rCombo, nX, nY);
 
@@ -810,12 +841,16 @@ bool WinOpenGLSalGraphicsImpl::RenderCompatibleDC(OpenGLCompatibleDC& rWhite, Op
     return bRet;
 }
 
-bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite, OpenGLCompatibleDC& rBlack,
+bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack,
                                                            int nX, int nY , ControlCacheKey& aControlCacheKey)
 {
+    assert(dynamic_cast<OpenGLCompatibleDC*>(&rWhite));
+    assert(dynamic_cast<OpenGLCompatibleDC*>(&rBlack));
+
     std::unique_ptr<TextureCombo> pCombo(new TextureCombo);
 
-    bool bResult = RenderCompatibleDC(rWhite, rBlack, nX, nY, *pCombo);
+    bool bResult = RenderCompatibleDC(static_cast<OpenGLCompatibleDC&>(rWhite),
+        static_cast<OpenGLCompatibleDC&>(rBlack), nX, nY, *pCombo);
     if (!bResult)
         return false;
 
@@ -828,4 +863,28 @@ bool WinOpenGLSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& r
     return bResult;
 }
 
+void WinOpenGLSalGraphicsImpl::PreDrawText()
+{
+    PreDraw();
+}
+
+void WinOpenGLSalGraphicsImpl::PostDrawText()
+{
+    PostDraw();
+}
+
+void WinOpenGLSalGraphicsImpl::DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color aMaskColor, const SalTwoRect& rPosAry)
+{
+    assert(dynamic_cast<const OpenGLCompatibleDC::Texture*>(pTexture));
+    mpRenderList->addDrawTextureWithMaskColor(
+        static_cast<const OpenGLCompatibleDC::Texture*>(pTexture)->texture, aMaskColor, rPosAry);
+    PostBatchDraw();
+}
+
+void WinOpenGLSalGraphicsImpl::DrawMask( CompatibleDC::Texture* pTexture, Color nMaskColor, const SalTwoRect& rPosAry )
+{
+    assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(pTexture));
+    DrawMask( static_cast<OpenGLCompatibleDC::Texture*>(pTexture)->texture, nMaskColor, rPosAry );
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/win/winlayout.cxx b/vcl/opengl/win/winlayout.cxx
new file mode 100644
index 000000000000..ddc72c8b28cf
--- /dev/null
+++ b/vcl/opengl/win/winlayout.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <opengl/win/winlayout.hxx>
+
+#include <opengl/win/gdiimpl.hxx>
+
+bool OpenGLGlobalWinGlyphCache::AllocateTexture(WinGlyphDrawElement& rElement, int nWidth,
+                                                int nHeight)
+{
+    assert(rElement.maTexture.get() == nullptr);
+    OpenGLCompatibleDC::Texture* texture = new OpenGLCompatibleDC::Texture;
+    rElement.maTexture.reset(texture);
+    texture->texture = maPackedTextureAtlas.Reserve(nWidth, nHeight);
+    if (!texture->texture)
+        return false;
+    std::vector<GLuint> aTextureIDs = maPackedTextureAtlas.ReduceTextureNumber(8);
+    if (!aTextureIDs.empty())
+    {
+        for (auto& pWinGlyphCache : maWinGlyphCaches)
+        {
+            assert(dynamic_cast<OpenGLWinGlyphCache*>(pWinGlyphCache));
+            static_cast<OpenGLWinGlyphCache*>(pWinGlyphCache)->RemoveTextures(aTextureIDs);
+        }
+    }
+    return true;
+}
+
+void OpenGLWinGlyphCache::RemoveTextures(std::vector<GLuint>& rTextureIDs)
+{
+    auto it = maWinTextureCache.begin();
+
+    while (it != maWinTextureCache.end())
+    {
+        assert(dynamic_cast<OpenGLCompatibleDC::Texture*>(it->second.maTexture.get()));
+        GLuint nTextureID
+            = static_cast<OpenGLCompatibleDC::Texture*>(it->second.maTexture.get())->texture.Id();
+
+        if (std::find(rTextureIDs.begin(), rTextureIDs.end(), nTextureID) != rTextureIDs.end())
+        {
+            it = maWinTextureCache.erase(it);
+        }
+        else
+        {
+            ++it;
+        }
+    }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 0763334f0ebf..ccfd59572424 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -87,9 +87,8 @@ bool WinSkiaSalGraphicsImpl::TryRenderCachedNativeControl(ControlCacheKey const&
     return false; // TODO
 }
 
-// TODO OpenGLCompatibleDC?
-bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(OpenGLCompatibleDC& rWhite,
-                                                         OpenGLCompatibleDC& rBlack, int nX, int nY,
+bool WinSkiaSalGraphicsImpl::RenderAndCacheNativeControl(CompatibleDC& rWhite, CompatibleDC& rBlack,
+                                                         int nX, int nY,
                                                          ControlCacheKey& aControlCacheKey)
 {
     (void)rWhite;
diff --git a/vcl/unx/generic/gdi/gdiimpl.hxx b/vcl/unx/generic/gdi/gdiimpl.hxx
index 315ed4094f8b..edacdac787c5 100644
--- a/vcl/unx/generic/gdi/gdiimpl.hxx
+++ b/vcl/unx/generic/gdi/gdiimpl.hxx
@@ -283,8 +283,6 @@ public:
     virtual bool drawGradient(const tools::PolyPolygon& rPolygon, const Gradient& rGradient) override;
 
 public:
-    // implementation of X11GraphicsImpl
-
     void Init() override;
 };
 
diff --git a/vcl/win/gdi/gdiimpl.cxx b/vcl/win/gdi/gdiimpl.cxx
index 95fd346af1a5..9741152180f8 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 a20c7b27b59e..3ccc64b4633e 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 9c89a240ead0..ccc744a0a991 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -25,12 +25,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>
@@ -49,18 +50,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));
 
@@ -142,14 +143,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;
@@ -191,12 +192,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;
 }
@@ -414,7 +415,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;
@@ -446,19 +447,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;
@@ -476,14 +477,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);
@@ -525,45 +526,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();
     }
 }
 


More information about the Libreoffice-commits mailing list