[Libreoffice-commits] core.git: 140 commits - bin/update_pch compilerplugins/clang config_host/config_features.h.in config_host/config_skia.h.in config_host.mk.in configure.ac cui/source cui/uiconfig download.lst drawinglayer/source external/Module_external.mk external/skia include/sal include/svtools include/vcl Makefile.fetch officecfg/registry readlicense_oo/license RepositoryExternal.mk solenv/clang-format solenv/gbuild solenv/sanitizers svtools/source svtools/uiconfig vcl/backendtest vcl/inc vcl/Library_vcl.mk vcl/Library_vclplug_gen.mk vcl/Library_vclplug_win.mk vcl/opengl vcl/qa vcl/README.vars vcl/skia vcl/source vcl/unx vcl/win vcl/workben

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Wed Nov 27 08:57:59 UTC 2019


 Makefile.fetch                                             |    1 
 RepositoryExternal.mk                                      |   23 
 bin/update_pch                                             |   27 
 compilerplugins/clang/checkconfigmacros.cxx                |    3 
 config_host.mk.in                                          |    1 
 config_host/config_features.h.in                           |    5 
 config_host/config_skia.h.in                               |   45 
 configure.ac                                               |   25 
 cui/source/options/optgdlg.cxx                             |  139 +
 cui/source/options/optgdlg.hxx                             |    8 
 cui/uiconfig/ui/optviewpage.ui                             |   56 
 download.lst                                               |    2 
 drawinglayer/source/processor2d/vclhelperbufferdevice.cxx  |    2 
 drawinglayer/source/texture/texture3d.cxx                  |    3 
 external/Module_external.mk                                |    1 
 external/skia/Library_skia.mk                              |  966 ++++++++++
 external/skia/Makefile                                     |    7 
 external/skia/Module_skia.mk                               |   18 
 external/skia/README                                       |   25 
 external/skia/UnpackedTarball_skia.mk                      |   36 
 external/skia/fix-alpha-difference-copy.patch.1            |   13 
 external/skia/fix-ddi.patch                                |    9 
 external/skia/fix-pch.patch                                |   84 
 external/skia/fix-shader-locale.patch.1                    |   40 
 external/skia/inc/pch/precompiled_skia.cxx                 |   12 
 external/skia/inc/pch/precompiled_skia.hxx                 |  996 +++++++++++
 external/skia/lerp.patch                                   |   12 
 external/skia/libvulkan-name.patch.1                       |   13 
 external/skia/make-api-visible.patch.1                     |   51 
 external/skia/no-trace-resources-on-exit.patch.1           |   26 
 external/skia/share-grcontext.patch.1                      |  550 ++++++
 external/skia/source/SkMemory_malloc.cxx                   |   68 
 include/sal/log-areas.dox                                  |    1 
 include/svtools/restartdialog.hxx                          |    3 
 include/vcl/pdfwriter.hxx                                  |    2 
 include/vcl/skia/SkiaHelper.hxx                            |   39 
 include/vcl/virdev.hxx                                     |    9 
 officecfg/registry/schema/org/openoffice/Office/Common.xcs |   15 
 readlicense_oo/license/license.xml                         |   24 
 solenv/clang-format/blacklist                              |    9 
 solenv/gbuild/PrecompiledHeaders.mk                        |    2 
 solenv/sanitizers/ui/svt.suppr                             |    1 
 svtools/source/dialogs/restartdialog.cxx                   |    3 
 svtools/uiconfig/ui/restartdialog.ui                       |   15 
 vcl/Library_vcl.mk                                         |    6 
 vcl/Library_vclplug_gen.mk                                 |   13 
 vcl/Library_vclplug_win.mk                                 |    5 
 vcl/README.vars                                            |   14 
 vcl/backendtest/VisualBackendTest.cxx                      |  108 +
 vcl/backendtest/outputdevice/bitmap.cxx                    |   49 
 vcl/backendtest/outputdevice/common.cxx                    |  161 +
 vcl/backendtest/outputdevice/line.cxx                      |    2 
 vcl/backendtest/outputdevice/outputdevice.cxx              |    7 
 vcl/backendtest/outputdevice/polygon.cxx                   |   21 
 vcl/backendtest/outputdevice/polyline_b2d.cxx              |   79 
 vcl/backendtest/outputdevice/polypolygon.cxx               |   21 
 vcl/backendtest/outputdevice/polypolygon_b2d.cxx           |   22 
 vcl/backendtest/outputdevice/rectangle.cxx                 |   65 
 vcl/inc/ControlCacheKey.hxx                                |   15 
 vcl/inc/headless/svpgdi.hxx                                |    1 
 vcl/inc/opengl/RenderList.hxx                              |    2 
 vcl/inc/opengl/gdiimpl.hxx                                 |   17 
 vcl/inc/opengl/win/gdiimpl.hxx                             |   67 
 vcl/inc/opengl/win/winlayout.hxx                           |   51 
 vcl/inc/opengl/x11/cairotextrender.hxx                     |    2 
 vcl/inc/opengl/x11/gdiimpl.hxx                             |    4 
 vcl/inc/qt5/Qt5Graphics.hxx                                |    1 
 vcl/inc/qt5/Qt5SvpGraphics.hxx                             |    2 
 vcl/inc/quartz/salgdi.h                                    |    1 
 vcl/inc/salbmp.hxx                                         |   34 
 vcl/inc/salgdi.hxx                                         |    2 
 vcl/inc/salgdiimpl.hxx                                     |    5 
 vcl/inc/skia/gdiimpl.hxx                                   |  276 +++
 vcl/inc/skia/salbmp.hxx                                    |  106 +
 vcl/inc/skia/win/gdiimpl.hxx                               |   97 +
 vcl/inc/skia/win/winlayout.hxx                             |   48 
 vcl/inc/skia/x11/cairotextrender.hxx                       |   27 
 vcl/inc/skia/x11/gdiimpl.hxx                               |   40 
 vcl/inc/skia/x11/salvd.hxx                                 |   46 
 vcl/inc/strings.hrc                                        |    2 
 vcl/inc/test/outputdevice.hxx                              |   31 
 vcl/inc/unx/genpspgraphics.h                               |    2 
 vcl/inc/unx/gtk/gtkgdi.hxx                                 |    4 
 vcl/inc/unx/salgdi.h                                       |    6 
 vcl/inc/win/saldata.hxx                                    |   10 
 vcl/inc/win/salgdi.h                                       |   43 
 vcl/inc/win/wingdiimpl.hxx                                 |   56 
 vcl/inc/win/winlayout.hxx                                  |   91 -
 vcl/opengl/gdiimpl.cxx                                     |   20 
 vcl/opengl/salbmp.cxx                                      |  139 -
 vcl/opengl/win/gdiimpl.cxx                                 |   85 
 vcl/opengl/win/winlayout.cxx                               |   57 
 vcl/opengl/x11/cairotextrender.cxx                         |    4 
 vcl/qa/cppunit/BackendTest.cxx                             |  345 ++-
 vcl/qa/cppunit/BitmapTest.cxx                              |    6 
 vcl/qa/cppunit/svm/svmtest.cxx                             |   19 
 vcl/skia/README                                            |   35 
 vcl/skia/SkiaHelper.cxx                                    |  121 +
 vcl/skia/gdiimpl.cxx                                       | 1151 +++++++++++++
 vcl/skia/salbmp.cxx                                        |  425 ++++
 vcl/skia/win/gdiimpl.cxx                                   |  262 ++
 vcl/skia/win/winlayout.cxx                                 |   67 
 vcl/skia/x11/cairotextrender.cxx                           |   91 +
 vcl/skia/x11/gdiimpl.cxx                                   |  114 +
 vcl/skia/x11/salvd.cxx                                     |   86 
 vcl/source/app/svapp.cxx                                   |   16 
 vcl/source/bitmap/salbmp.cxx                               |  217 ++
 vcl/source/gdi/bitmap3.cxx                                 |    1 
 vcl/source/gdi/bitmapex.cxx                                |    2 
 vcl/source/gdi/salgdilayout.cxx                            |    9 
 vcl/source/outdev/bitmap.cxx                               |    2 
 vcl/unx/generic/app/saldisp.cxx                            |    1 
 vcl/unx/generic/app/salinst.cxx                            |    3 
 vcl/unx/generic/gdi/gdiimpl.cxx                            |   24 
 vcl/unx/generic/gdi/gdiimpl.hxx                            |    6 
 vcl/unx/generic/gdi/salbmp.cxx                             |   11 
 vcl/unx/generic/gdi/salgdi.cxx                             |   26 
 vcl/unx/generic/gdi/salgdi2.cxx                            |   20 
 vcl/unx/generic/gdi/salvd.cxx                              |   11 
 vcl/unx/generic/gdi/x11cairotextrender.cxx                 |    3 
 vcl/unx/generic/window/salframe.cxx                        |    1 
 vcl/win/app/salinst.cxx                                    |   12 
 vcl/win/gdi/gdiimpl.cxx                                    |   22 
 vcl/win/gdi/gdiimpl.hxx                                    |   10 
 vcl/win/gdi/salfont.cxx                                    |    6 
 vcl/win/gdi/salgdi.cxx                                     |   51 
 vcl/win/gdi/salgdi2.cxx                                    |   26 
 vcl/win/gdi/salnativewidgets-luna.cxx                      |   24 
 vcl/win/gdi/salvd.cxx                                      |    7 
 vcl/win/gdi/winlayout.cxx                                  |  134 -
 vcl/workben/vcldemo.cxx                                    |    2 
 131 files changed, 8086 insertions(+), 640 deletions(-)

New commits:
commit 1c2e5e47a4bdccc6682071c06b9e744bbeac6e52
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Nov 26 15:49:07 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:19 2019 +0100

    use idle priority in visualbackendtest
    
    At least Skia and OpenGL use POST_PAINT priority for flushing drawn
    contents to the screen. Using the higher REPAINT priority here could
    mean that actually showing the contents would not happen. Also,
    at least with Skia+Vulkan, it seems that Skia could queue commands
    indefinitely, eventually running out of resources.
    
    Change-Id: Ia3969bad18d710b006325a0fba11dc318ff93786

diff --git a/vcl/backendtest/VisualBackendTest.cxx b/vcl/backendtest/VisualBackendTest.cxx
index cab225918087..47b4149ef324 100644
--- a/vcl/backendtest/VisualBackendTest.cxx
+++ b/vcl/backendtest/VisualBackendTest.cxx
@@ -103,7 +103,7 @@ public:
         , mpVDev(VclPtr<VirtualDevice>::Create())
     {
         maUpdateTimer.SetInvokeHandler(LINK(this, VisualBackendTestWindow, updateHdl));
-        maUpdateTimer.SetPriority(TaskPriority::REPAINT);
+        maUpdateTimer.SetPriority(TaskPriority::DEFAULT_IDLE);
         if (mbAnimate)
         {
             maUpdateTimer.SetTimeout(1000.0);
commit 5e063cd7bb63772e6aab3a029dec13abcd748526
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Nov 26 12:15:27 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:19 2019 +0100

    always test Skia before OpenGL
    
    Skia/Vulkan as the newer technology should be preferred, currently Skia
    is not enabled by default, but that can change later. And this
    should be consistent, otherwise the about dialog can claim OpenGL is
    used while it's actually Skia that gets selected elsewhere.
    
    Change-Id: I185feb231c28a119a1152e92afb54a1e8c41af6f

diff --git a/vcl/qa/cppunit/BitmapTest.cxx b/vcl/qa/cppunit/BitmapTest.cxx
index 4db31a0f88fc..0ce45cf5641b 100644
--- a/vcl/qa/cppunit/BitmapTest.cxx
+++ b/vcl/qa/cppunit/BitmapTest.cxx
@@ -357,10 +357,10 @@ void BitmapTest::testConvert()
         //it would be nice to find and change the stride for quartz to be the same as everyone else
         CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(10), pReadAccess->GetScanlineSize());
 #else
+        if (!SkiaHelper::isVCLSkiaEnabled())
 #if HAVE_FEATURE_OPENGL
-        if (!OpenGLHelper::isVCLOpenGLEnabled())
+            if (!OpenGLHelper::isVCLOpenGLEnabled())
 #endif
-            if (!SkiaHelper::isVCLSkiaEnabled())
                 CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(12), pReadAccess->GetScanlineSize());
 #endif
         CPPUNIT_ASSERT(pReadAccess->HasPalette());
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 511e6dd5e598..df57b56ac327 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1148,11 +1148,6 @@ OUString Application::GetHWOSConfInfo()
     aDetails.append( "; " );
 
     aDetails.append( VclResId(SV_APP_UIRENDER) );
-#if HAVE_FEATURE_OPENGL
-    if ( OpenGLWrapper::isVCLOpenGLEnabled() )
-        aDetails.append( VclResId(SV_APP_GL) );
-    else
-#endif
 #if HAVE_FEATURE_SKIA
     if ( SkiaHelper::isVCLSkiaEnabled() )
     {
@@ -1168,6 +1163,11 @@ OUString Application::GetHWOSConfInfo()
     }
     else
 #endif
+#if HAVE_FEATURE_OPENGL
+    if ( OpenGLWrapper::isVCLOpenGLEnabled() )
+        aDetails.append( VclResId(SV_APP_GL) );
+    else
+#endif
         aDetails.append( VclResId(SV_APP_DEFAULT) );
     aDetails.append( "; " );
 
diff --git a/vcl/source/outdev/bitmap.cxx b/vcl/source/outdev/bitmap.cxx
index 0bce168579cc..7ab069c2f443 100644
--- a/vcl/source/outdev/bitmap.cxx
+++ b/vcl/source/outdev/bitmap.cxx
@@ -687,12 +687,10 @@ void OutputDevice::DrawDeviceAlphaBitmap( const Bitmap& rBmp, const AlphaMask& r
 
         // we need to make sure OpenGL never reaches this slow code path
 
+        assert(!SkiaHelper::isVCLSkiaEnabled());
 #if HAVE_FEATURE_OPENGL
         assert(!OpenGLHelper::isVCLOpenGLEnabled());
 #endif
-#if HAVE_FEATURE_SKIA
-        assert(!SkiaHelper::isVCLSkiaEnabled());
-#endif
         tools::Rectangle aBmpRect(Point(), rBmp.GetSizePixel());
         if (!aBmpRect.Intersection(tools::Rectangle(rSrcPtPixel, rSrcSizePixel)).IsEmpty())
         {
commit f448eb55d38db52d9b465ea2a4ba9170ebf7b4bf
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 22 12:58:50 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:19 2019 +0100

    fix SkiaSalGraphicsImpl::drawPolyLine()
    
    Code pretty much copy&pasted from the vcl/quartz version. Fixes
    e.g. Writer marks showing paper corners.
    
    Change-Id: I3c9d2ed00efe409abd0a730a6f7dc0ea2a31c90a

diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index b109b698914b..c222150478ec 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -620,16 +620,13 @@ bool SkiaSalGraphicsImpl::drawPolyPolygon(const basegfx::B2DHomMatrix& rObjectTo
     return true;
 }
 
-// TODO implement rObjectToDevice - need to take the matrix into account
 bool SkiaSalGraphicsImpl::drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDevice,
                                        const basegfx::B2DPolygon& rPolyLine, double fTransparency,
                                        const basegfx::B2DVector& rLineWidths,
                                        basegfx::B2DLineJoin eLineJoin,
                                        css::drawing::LineCap eLineCap, double fMiterMinimumAngle,
-                                       bool /*bPixelSnapHairline*/)
+                                       bool bPixelSnapHairline)
 {
-    //(void)bPixelSnapHairline; // TODO
-
     if (rPolyLine.count() == 0 || fTransparency < 0.0 || fTransparency >= 1.0
         || mLineColor == SALCOLOR_NONE)
         return true;
@@ -637,27 +634,22 @@ bool SkiaSalGraphicsImpl::drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDev
     preDraw();
     SAL_INFO("vcl.skia", "drawpolyline(" << this << "): " << rPolyLine << ":" << mLineColor);
 
-    basegfx::B2DVector aLineWidths(rLineWidths);
-    const bool bObjectToDeviceIsIdentity(rObjectToDevice.isIdentity());
-    const basegfx::B2DVector aDeviceLineWidths(
-        bObjectToDeviceIsIdentity ? rLineWidths : rObjectToDevice * rLineWidths);
-    const bool bCorrectLineWidth(!bObjectToDeviceIsIdentity && aDeviceLineWidths.getX() < 1.0
-                                 && aLineWidths.getX() >= 1.0);
-
-    // on-demand inverse of ObjectToDevice transformation
-    basegfx::B2DHomMatrix aObjectToDeviceInv;
+    // need to check/handle LineWidth when ObjectToDevice transformation is used
+    const basegfx::B2DVector aDeviceLineWidths(rObjectToDevice * rLineWidths);
+    const bool bCorrectLineWidth(aDeviceLineWidths.getX() < 1.0 && rLineWidths.getX() >= 1.0);
+    const basegfx::B2DVector aLineWidths(bCorrectLineWidth ? rLineWidths : aDeviceLineWidths);
 
-    if (bCorrectLineWidth)
-    {
-        if (aObjectToDeviceInv.isIdentity())
-        {
-            aObjectToDeviceInv = rObjectToDevice;
-            aObjectToDeviceInv.invert();
-        }
+    // Skia does not support B2DLineJoin::NONE; return false to use
+    // the fallback (own geometry preparation),
+    // linejoin-mode and thus the above only applies to "fat" lines.
+    if ((basegfx::B2DLineJoin::NONE == eLineJoin) && (aLineWidths.getX() > 1.3))
+        return false;
 
-        // calculate-back logical LineWidth for a hairline
-        aLineWidths = aObjectToDeviceInv * basegfx::B2DVector(1.0, 1.0);
-    }
+    // Transform to DeviceCoordinates, get DeviceLineWidth, execute PixelSnapHairline
+    basegfx::B2DPolygon aPolyLine(rPolyLine);
+    aPolyLine.transform(rObjectToDevice);
+    if (bPixelSnapHairline)
+        aPolyLine = basegfx::utils::snapPointsOfHorizontalOrVerticalEdges(aPolyLine);
 
     // Setup Line Join
     SkPaint::Join eSkLineJoin = SkPaint::kMiter_Join;
@@ -704,7 +696,7 @@ bool SkiaSalGraphicsImpl::drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDev
     aPaint.setAntiAlias(mParent.getAntiAliasB2DDraw());
 
     SkPath aPath;
-    addPolygonToPath(rPolyLine, aPath);
+    addPolygonToPath(aPolyLine, aPath);
     aPath.setFillType(SkPath::kEvenOdd_FillType);
     // Apply the same adjustment as toSkX()/toSkY() do. Do it here even in the non-GPU
     // case as it seems to produce better results.
commit 4b56c32512305b3c9385981f72e6ce4b609ecff6
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 22 15:12:57 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:19 2019 +0100

    don't fall back to raster if Skia is first asked for offscreen surface
    
    This is rare, but it may happen. Since now the code shared just one
    GrContext properly, this is not really a problem anymore (and the extra
    WindowContext creation shouldn't be hopefully noticeable either).
    
    Change-Id: I50887b7512e778b70870690a3f672b27cc7f2d21

diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index dfa7eb7a7320..b109b698914b 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -245,26 +245,22 @@ void SkiaSalGraphicsImpl::createOffscreenSurface()
         {
             mOffscreenGrContext = sk_app::VulkanWindowContext::getSharedGrContext();
             GrContext* grContext = mOffscreenGrContext.getGrContext();
-            // We may not get a GrContext if called before any onscreen window is created,
-            // but that happens very early, so this should be rare and insignificant.
-            // Unittests are an exception, they usually do not create any windows,
-            // so in that case do create GrContext that has no window associated.
+            // We may not get a GrContext if called before any onscreen window is created.
             if (!grContext)
             {
-                static bool isUnitTest = (getenv("LO_TESTNAME") != nullptr);
-                if (isUnitTest)
-                {
-                    // Create temporary WindowContext with no window. That will fail,
-                    // but it will initialize the shared GrContext.
-                    createWindowContext();
-                    // Keep a reference.
-                    sk_app::VulkanWindowContext::SharedGrContext context
-                        = sk_app::VulkanWindowContext::getSharedGrContext();
-                    // Destroy the temporary WindowContext.
-                    destroySurface();
-                    mOffscreenGrContext = context;
-                    grContext = mOffscreenGrContext.getGrContext();
-                }
+                SAL_INFO("vcl.skia",
+                         "creating Vulkan offscreen GPU surface before any window exists");
+                // Create temporary WindowContext with no window. That will fail,
+                // but it will initialize the shared GrContext.
+                createWindowContext();
+                // Keep a reference.
+                sk_app::VulkanWindowContext::SharedGrContext context
+                    = sk_app::VulkanWindowContext::getSharedGrContext();
+                // Destroy the temporary WindowContext.
+                destroySurface();
+                // Keep a reference until the surface is destroyed.
+                mOffscreenGrContext = context;
+                grContext = mOffscreenGrContext.getGrContext();
             }
             if (grContext)
             {
commit 19bac12d182eb8cb212c4993808348ccc43f6c73
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 22 12:36:31 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    do not require Vulkan devel package for Skia
    
    I don't see why this should use libvulkan.so, using libvulkan.so.1
    should do as well, and quite possibly any future libvulkan.so.2
    could be binary-incompatible anyway.
    
    Change-Id: I46be40da7fbfdcb59c947e6d088820e580cf4c44

diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk
index aabb1149a3ae..1d2da19c2b5b 100644
--- a/external/skia/UnpackedTarball_skia.mk
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -20,6 +20,7 @@ skia_patches := \
     fix-shader-locale.patch.1 \
     no-trace-resources-on-exit.patch.1 \
     fix-alpha-difference-copy.patch.1 \
+    libvulkan-name.patch.1 \
     share-grcontext.patch.1
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
diff --git a/external/skia/libvulkan-name.patch.1 b/external/skia/libvulkan-name.patch.1
new file mode 100644
index 000000000000..265d8daa11df
--- /dev/null
+++ b/external/skia/libvulkan-name.patch.1
@@ -0,0 +1,13 @@
+diff --git a/tools/gpu/vk/VkTestUtils.cpp b/tools/gpu/vk/VkTestUtils.cpp
+index 5b7e8c29ae..1580136b5c 100644
+--- a/tools/gpu/vk/VkTestUtils.cpp
++++ b/tools/gpu/vk/VkTestUtils.cpp
+@@ -13,7 +13,7 @@
+     #if defined _WIN32
+         #define SK_GPU_TOOLS_VK_LIBRARY_NAME "vulkan-1.dll"
+     #else
+-        #define SK_GPU_TOOLS_VK_LIBRARY_NAME "libvulkan.so"
++        #define SK_GPU_TOOLS_VK_LIBRARY_NAME "libvulkan.so.1"
+     #endif
+ #endif
+ 
commit e8b9dbbc78b3dc4124fbabfef54b686b2bec0843
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 22 12:30:16 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    use the native Skia color Type when using Vulkan
    
    Change-Id: Ie46d7d89b9aa149f48617ccdbe3a8c492759880f

diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index 3f706399f136..04e2586e7f7a 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -41,12 +41,7 @@ void X11SkiaSalGraphicsImpl::Init()
 void X11SkiaSalGraphicsImpl::createWindowContext()
 {
     sk_app::DisplayParams displayParams;
-    // Use a macro to hide an unreachable code warning.
-    // TODO The Skia Xlib code actually requires the non-native color type to work properly.
-#define GET_FORMAT                                                                                 \
-    kN32_SkColorType == kBGRA_8888_SkColorType ? kRGBA_8888_SkColorType : kBGRA_8888_SkColorType
-    displayParams.fColorType = GET_FORMAT;
-#undef GET_FORMAT
+    displayParams.fColorType = kN32_SkColorType;
     sk_app::window_context_factory::XlibWindowInfo winInfo;
     winInfo.fDisplay = mX11Parent.GetXDisplay();
     winInfo.fWindow = mX11Parent.GetDrawable();
@@ -68,6 +63,10 @@ void X11SkiaSalGraphicsImpl::createWindowContext()
     switch (SkiaHelper::renderMethodToUse())
     {
         case SkiaHelper::RenderRaster:
+            // TODO The Skia Xlib code actually requires the non-native color type to work properly.
+            displayParams.fColorType
+                = (displayParams.fColorType == kBGRA_8888_SkColorType ? kRGBA_8888_SkColorType
+                                                                      : kBGRA_8888_SkColorType);
             mWindowContext
                 = sk_app::window_context_factory::MakeRasterForXlib(winInfo, displayParams);
             mIsGPU = false;
commit 84f84f59ce7c83a99e4e340071d58b6557dbe91a
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Nov 21 12:17:13 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    revert BackendCapabilities::mbSupportsBitmap32 for Skia
    
    It appears that there are still some paths that do not expect
    bitmaps to be truly 32bit, so better revert to the old safe (and
    poor, complicated and inefficient) way of pretty much ignoring
    the alpha channel in SkiaSalBitmap, and let BitmapEx handle
    it by using an extra alpha bitmap.
    
    Change-Id: I4318c05f4ceafc5de48e19eeae5efe2abed2ec69

diff --git a/vcl/inc/unx/salinst.h b/vcl/inc/unx/salinst.h
index a84c659917cd..1b4b6c1af6f8 100644
--- a/vcl/inc/unx/salinst.h
+++ b/vcl/inc/unx/salinst.h
@@ -81,8 +81,6 @@ public:
 
     virtual void                AfterAppInit() override;
 
-    std::shared_ptr<vcl::BackendCapabilities> GetBackendCapabilities() override;
-
     // dtrans implementation
     virtual css::uno::Reference< css::uno::XInterface >
         CreateClipboard( const css::uno::Sequence< css::uno::Any >& i_rArguments ) override;
diff --git a/vcl/inc/win/salinst.h b/vcl/inc/win/salinst.h
index c06e51c84050..bcd3540ad8a9 100644
--- a/vcl/inc/win/salinst.h
+++ b/vcl/inc/win/salinst.h
@@ -73,7 +73,6 @@ 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/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 9910693d6336..fb0c3608028d 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -80,8 +80,16 @@ bool SkiaSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const Bitmap
     }
     if (colorType != kUnknown_SkColorType)
     {
+        // TODO
+        // As long as vcl::BackendCapabilities::mbSupportsBitmap32 is not set, we must use
+        // unpremultiplied alpha. This is because without mbSupportsBitmap32 set VCL uses
+        // an extra bitmap for the alpha channel and then merges the channels together
+        // into colors. kPremul_SkAlphaType would provide better performance, but
+        // without mbSupportsBitmap32 BitmapReadAccess::ImplSetAccessPointers() would use
+        // functions that merely read RGB without A, so the premultiplied values would
+        // not be converted back to unpremultiplied values.
         if (!mBitmap.tryAllocPixels(
-                SkImageInfo::Make(rSize.Width(), rSize.Height(), colorType, kPremul_SkAlphaType)))
+                SkImageInfo::Make(rSize.Width(), rSize.Height(), colorType, kUnpremul_SkAlphaType)))
         {
             return false;
         }
diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx
index 3ec713ca0e72..3c39a1addbd9 100644
--- a/vcl/unx/generic/app/salinst.cxx
+++ b/vcl/unx/generic/app/salinst.cxx
@@ -220,14 +220,4 @@ std::unique_ptr<GenPspGraphics> X11SalInstance::CreatePrintGraphics()
     return std::make_unique<GenPspGraphics>();
 }
 
-std::shared_ptr<vcl::BackendCapabilities> X11SalInstance::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: */
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index 7c7bfc6e76e0..1915fb6f6b97 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -1067,14 +1067,4 @@ 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 8f7e6f583953c6cdc9736d5dd120fddbde98ce8b
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Nov 21 12:09:17 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    patch Skia bug with copying data with different alpha type
    
    https://bugs.chromium.org/p/skia/issues/detail?id=9662
    
    Change-Id: Ic5208c2c817912cddbfae4b86e3b3647306262fb

diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk
index 1fab368cc34b..aabb1149a3ae 100644
--- a/external/skia/UnpackedTarball_skia.mk
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -19,6 +19,7 @@ skia_patches := \
     make-api-visible.patch.1 \
     fix-shader-locale.patch.1 \
     no-trace-resources-on-exit.patch.1 \
+    fix-alpha-difference-copy.patch.1 \
     share-grcontext.patch.1
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
diff --git a/external/skia/fix-alpha-difference-copy.patch.1 b/external/skia/fix-alpha-difference-copy.patch.1
new file mode 100644
index 000000000000..d9e992a770a7
--- /dev/null
+++ b/external/skia/fix-alpha-difference-copy.patch.1
@@ -0,0 +1,13 @@
+diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp
+index 89b107b939..042d8e65aa 100644
+--- a/src/core/SkBlitter_Sprite.cpp
++++ b/src/core/SkBlitter_Sprite.cpp
+@@ -178,7 +178,7 @@ SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
+     */
+     SkASSERT(allocator != nullptr);
+ 
+-    if (source.alphaType() == kUnpremul_SkAlphaType) {
++    if (source.alphaType() != dst.alphaType()) {
+         return nullptr;
+     }
+ 
commit d9879200ca3c0167b982ffecfa927bfac46b94c6
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Nov 20 15:37:11 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    handle properly true 32bit bitmaps in some places
    
    I.e. those created with vcl::BackendCapabilities::mbSupportsBitmap32 set.
    But there are quite possibly many more places that do not expect
    that the Bitmap itself would contain alpha.
    
    Change-Id: I83db37b3d346f42565f96b9bbf81c71b97b6bf8b

diff --git a/drawinglayer/source/texture/texture3d.cxx b/drawinglayer/source/texture/texture3d.cxx
index 3c5f7d5e29bf..8874d3425599 100644
--- a/drawinglayer/source/texture/texture3d.cxx
+++ b/drawinglayer/source/texture/texture3d.cxx
@@ -23,6 +23,7 @@
 
 #include <drawinglayer/texture/texture3d.hxx>
 #include <vcl/bitmapaccess.hxx>
+#include <vcl/BitmapTools.hxx>
 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
 #include <sal/log.hxx>
 
@@ -76,6 +77,8 @@ namespace drawinglayer
             mbIsAlpha(false),
             mbIsTransparent(maBitmapEx.IsTransparent())
         {
+            if(vcl::bitmap::convertBitmap32To24Plus8(maBitmapEx,maBitmapEx))
+                mbIsTransparent = maBitmapEx.IsTransparent();
             // #121194# Todo: use alpha channel, too (for 3d)
             maBitmap = maBitmapEx.GetBitmap();
 
diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx
index f37499dff0b8..b4d7c106b37c 100644
--- a/vcl/source/gdi/bitmapex.cxx
+++ b/vcl/source/gdi/bitmapex.cxx
@@ -689,6 +689,8 @@ sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const
     {
         if (nX >= 0 && nX < GetSizePixel().Width() && nY >= 0 && nY < GetSizePixel().Height())
         {
+            if (maBitmap.GetBitCount() == 32)
+                return GetPixelColor(nX, nY).GetTransparency();
             switch(meTransparent)
             {
                 case TransparentType::NONE:
diff --git a/vcl/unx/generic/window/salframe.cxx b/vcl/unx/generic/window/salframe.cxx
index 8ac555009541..8b8f029b1897 100644
--- a/vcl/unx/generic/window/salframe.cxx
+++ b/vcl/unx/generic/window/salframe.cxx
@@ -261,6 +261,7 @@ static void CreateNetWmAppIcon( sal_uInt16 nIcon, NetWmIconData& netwm_icon )
 
         if( aIcon.IsEmpty())
             continue;
+        vcl::bitmap::convertBitmap32To24Plus8(aIcon, aIcon);
         Bitmap icon = aIcon.GetBitmap();
         AlphaMask mask;
         switch( aIcon.GetTransparentType())
commit 6a0f8d88053bd7d33bc7d2032fb682f5579d10d0
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Nov 20 12:47:23 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    copy SkImage properly
    
    Change-Id: I61f082d8a8d8eead6c49bbf3da997462e7d9738e

diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index 1e5c554b49f2..9910693d6336 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -49,7 +49,9 @@ SkiaSalBitmap::SkiaSalBitmap(const SkImage& image)
     {
         SkCanvas canvas(mBitmap);
         // TODO makeNonTextureImage() ?
-        canvas.drawImage(&image, 0, 0);
+        SkPaint paint;
+        paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha
+        canvas.drawImage(&image, 0, 0, &paint);
     }
 }
 
commit c41d44286570c0b6da5e2a5901f5e2401037378e
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Nov 20 12:10:21 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    fix mistyped operator
    
    Change-Id: I10ca633d31163c968b0010983132942a1823a3f6

diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index de49400cd481..1e5c554b49f2 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -86,7 +86,7 @@ bool SkiaSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const Bitmap
 #ifdef DBG_UTIL
         // fill with random garbage
         sal_uInt8* buffer = static_cast<sal_uInt8*>(mBitmap.getPixels());
-        size_t size = mBitmap.rowBytes() & mBitmap.height();
+        size_t size = mBitmap.rowBytes() * mBitmap.height();
         for (size_t i = 0; i < size; i++)
             buffer[i] = (i & 0xFF);
 #endif
commit a082d7b36e6d88ac4a8a1bf772c084ea460d488a
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Nov 19 12:52:00 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    fix a VirtualDevice leak
    
    VclPtr is a smart ptr, but it does not own (and thus does not autodelete).
    
    Change-Id: I2d9b924852d01b118fb0bc2a583063da230ee065

diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index c377f4ee6526..ae753a40a39b 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -170,7 +170,7 @@ namespace
             if (maDeviceTemplates[pRetval]->isDisposed())
             {
                 maDeviceTemplates.erase(pRetval);
-                pRetval = nullptr;
+                pRetval.disposeAndClear();
             }
             else
             {
commit ce51719a2807887eebbe8fba4793e8d6e6c20a41
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Nov 12 17:28:14 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    fix Skia with --enable-pch=full
    
    Change-Id: I6bec47e373c042d1ffb3607bf5dca9dfe2509466

diff --git a/external/skia/fix-pch.patch b/external/skia/fix-pch.patch
index 1bd09f1bbc30..a991e80970e9 100644
--- a/external/skia/fix-pch.patch
+++ b/external/skia/fix-pch.patch
@@ -54,3 +54,31 @@
  #include <dwrite.h>
  #include <d2d1.h>
  
+--- skia/include/core/SkColor.h
++++ skia/include/core/SkColor.h
+@@ -396,6 +396,7 @@ using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;
+ 
+ template <> SK_API SkColor4f SkColor4f::FromColor(SkColor);
+ template <> SK_API SkColor   SkColor4f::toSkColor() const;
++template <> uint32_t SkColor4f::toBytes_RGBA() const;
+ 
+ namespace SkColors {
+ constexpr SkColor4f kTransparent = {0, 0, 0, 0};
+--- skia/include/private/SkColorData.h
++++ skia/include/private/SkColorData.h
+@@ -441,4 +441,6 @@ constexpr SkPMColor4f SK_PMColor4fILLEGAL = { SK_FloatNegativeInfinity,
+                                                   SK_FloatNegativeInfinity,
+                                                   SK_FloatNegativeInfinity };
+ 
++template <> uint32_t SkPMColor4f::toBytes_RGBA() const;
++
+ #endif
+--- skia/src/gpu/text/GrTextBlobCache.h
++++ skia/src/gpu/text/GrTextBlobCache.h
+@@ -188,4 +188,6 @@ private:
+     SkMessageBus<PurgeBlobMessage>::Inbox fPurgeBlobInbox;
+ };
+ 
++template<> SkMessageBus<GrTextBlobCache::PurgeBlobMessage>* SkMessageBus<GrTextBlobCache::PurgeBlobMessage>::Get();
++
+ #endif
commit 7e5e3b8b0831d9f6aff7481d1163a366e76141d7
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Nov 19 18:08:07 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:18 2019 +0100

    build Skia only on selected platforms
    
    Feel free to adjust your platform as necessary.
    
    Change-Id: I3003a643c39b6afeb3102f97280f20534b9c7f77

diff --git a/configure.ac b/configure.ac
index 20cde192061e..04f8330a9ac8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -590,6 +590,7 @@ case "$host_os" in
 solaris*)
     build_gstreamer_1_0=yes
     test_freetype=yes
+    build_skia=yes
     _os=SunOS
 
     dnl ===========================================================
@@ -616,6 +617,7 @@ linux-gnu*|k*bsd*-gnu*)
     build_gstreamer_1_0=yes
     test_kf5=yes
     test_gtk3_kde5=yes
+    build_skia=yes
     test_gdb_index=yes
     test_split_debug=yes
     if test "$enable_fuzzers" != yes; then
@@ -654,6 +656,7 @@ cygwin*|interix*)
     test_xrender=no
     test_freetype=no
     test_fontconfig=no
+    build_skia=yes
     _os=WINNT
 
     DLLPOST=".dll"
@@ -708,6 +711,7 @@ freebsd*)
     test_kf5=yes
     test_gtk3_kde5=yes
     test_freetype=yes
+    build_skia=yes
     AC_MSG_CHECKING([the FreeBSD operating system release])
     if test -n "$with_os_version"; then
         OSVERSION="$with_os_version"
@@ -735,6 +739,7 @@ freebsd*)
     test_kf5=yes
     test_gtk3_kde5=yes
     test_freetype=yes
+    build_skia=yes
     PTHREAD_LIBS="-pthread -lpthread"
     _os=NetBSD
     ;;
@@ -758,6 +763,7 @@ dragonfly*)
     test_kf5=yes
     test_gtk3_kde5=yes
     test_freetype=yes
+    build_skia=yes
     PTHREAD_LIBS="-pthread"
     _os=DragonFly
     ;;
@@ -10882,7 +10888,7 @@ AC_SUBST(POPPLER_LIBS)
 # Skia?
 AC_MSG_CHECKING([whether to build Skia])
 ENABLE_SKIA=
-if test "$enable_skia" != "no"; then
+if test "$enable_skia" != "no" -a "$build_skia" = "yes"; then
     AC_MSG_RESULT([yes])
     ENABLE_SKIA=TRUE
     AC_DEFINE(HAVE_FEATURE_SKIA)
commit c2709d9fe2711a3729225ec9168f7acf5a7ba23c
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Tue Nov 19 14:54:22 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    avoid some compiler warnings in Skia VCL code
    
    Mostly warnings from the 'casttovoid' Clang plugin, which is rather
    annoying here.
    
    Change-Id: I3d69697143f690211cdd26d1b9a4c0efe9397197

diff --git a/vcl/backendtest/outputdevice/common.cxx b/vcl/backendtest/outputdevice/common.cxx
index 34e37e771f1f..a7e857ffd1fd 100644
--- a/vcl/backendtest/outputdevice/common.cxx
+++ b/vcl/backendtest/outputdevice/common.cxx
@@ -262,7 +262,7 @@ TestResult OutputDeviceTestCommon::checkAALines(Bitmap& rBitmap)
     return checkHorizontalVerticalDiagonalLines(rBitmap, constLineColor, 30); // 30 color values threshold delta
 }
 
-void checkResult(TestResult eResult, TestResult & eTotal)
+static void checkResult(TestResult eResult, TestResult & eTotal)
 {
     if (eTotal == TestResult::Failed)
         return;
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 0036b2d89f7a..517bad0db5c8 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -251,7 +251,8 @@ protected:
     friend inline std::basic_ostream<charT, traits>&
     operator<<(std::basic_ostream<charT, traits>& stream, const SkiaSalGraphicsImpl* graphics)
     { // O - offscreen, G - GPU-based, R - raster
-        return stream << (void*)graphics << " " << Size(graphics->GetWidth(), graphics->GetHeight())
+        return stream << static_cast<const void*>(graphics) << " "
+                      << Size(graphics->GetWidth(), graphics->GetHeight())
                       << (graphics->isOffscreen() ? "O" : "") << (graphics->isGPU() ? "G" : "R");
     }
 
diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx
index c5922685c5b7..ed0f374162d6 100644
--- a/vcl/inc/skia/salbmp.hxx
+++ b/vcl/inc/skia/salbmp.hxx
@@ -83,8 +83,8 @@ private:
     operator<<(std::basic_ostream<charT, traits>& stream, const SkiaSalBitmap* bitmap)
     { // TODO GPU-based, once it's done
         // B - has SkBitmap, A - has alpha SkBitmap, D - has data buffer
-        return stream << (void*)bitmap << " " << bitmap->GetSize() << "/" << bitmap->mBitCount
-                      << (!bitmap->mBitmap.drawsNothing() ? "B" : "")
+        return stream << static_cast<const void*>(bitmap) << " " << bitmap->GetSize() << "/"
+                      << bitmap->mBitCount << (!bitmap->mBitmap.drawsNothing() ? "B" : "")
                       << (!bitmap->mAlphaBitmap.drawsNothing() ? "A" : "")
                       << (bitmap->mBuffer.get() ? "D" : "");
     }
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index 810e8f9b0b11..040f189be74f 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -103,8 +103,9 @@ static bool initRenderMethodToUse()
 SkiaHelper::RenderMethod SkiaHelper::renderMethodToUse()
 {
     static bool methodToUseInited = initRenderMethodToUse();
-    (void)methodToUseInited; // Used just to ensure thread-safe one-time init.
-    return methodToUse;
+    if (methodToUseInited) // Used just to ensure thread-safe one-time init.
+        return methodToUse;
+    abort();
 }
 
 void SkiaHelper::disableRenderMethod(RenderMethod method)
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 271f1a61321c..dfa7eb7a7320 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -439,10 +439,9 @@ void SkiaSalGraphicsImpl::SetFillColor() { mFillColor = SALCOLOR_NONE; }
 
 void SkiaSalGraphicsImpl::SetFillColor(Color nColor) { mFillColor = nColor; }
 
-void SkiaSalGraphicsImpl::SetXORMode(bool bSet, bool bInvertOnly)
+void SkiaSalGraphicsImpl::SetXORMode(bool, bool)
 {
-    (void)bSet;
-    (void)bInvertOnly;
+    // TODO
 }
 
 void SkiaSalGraphicsImpl::SetROPLineColor(SalROPColor nROPColor)
@@ -631,9 +630,9 @@ bool SkiaSalGraphicsImpl::drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDev
                                        const basegfx::B2DVector& rLineWidths,
                                        basegfx::B2DLineJoin eLineJoin,
                                        css::drawing::LineCap eLineCap, double fMiterMinimumAngle,
-                                       bool bPixelSnapHairline)
+                                       bool /*bPixelSnapHairline*/)
 {
-    (void)bPixelSnapHairline;
+    //(void)bPixelSnapHairline; // TODO
 
     if (rPolyLine.count() == 0 || fTransparency < 0.0 || fTransparency >= 1.0
         || mLineColor == SALCOLOR_NONE)
@@ -720,32 +719,22 @@ bool SkiaSalGraphicsImpl::drawPolyLine(const basegfx::B2DHomMatrix& rObjectToDev
     return true;
 }
 
-bool SkiaSalGraphicsImpl::drawPolyLineBezier(sal_uInt32 nPoints, const SalPoint* pPtAry,
-                                             const PolyFlags* pFlgAry)
+bool SkiaSalGraphicsImpl::drawPolyLineBezier(sal_uInt32, const SalPoint*, const PolyFlags*)
 {
-    (void)nPoints;
-    (void)pPtAry;
-    (void)pFlgAry;
+    // TODO?
     return false;
 }
 
-bool SkiaSalGraphicsImpl::drawPolygonBezier(sal_uInt32 nPoints, const SalPoint* pPtAry,
-                                            const PolyFlags* pFlgAry)
+bool SkiaSalGraphicsImpl::drawPolygonBezier(sal_uInt32, const SalPoint*, const PolyFlags*)
 {
-    (void)nPoints;
-    (void)pPtAry;
-    (void)pFlgAry;
+    // TODO?
     return false;
 }
 
-bool SkiaSalGraphicsImpl::drawPolyPolygonBezier(sal_uInt32 nPoly, const sal_uInt32* pPoints,
-                                                const SalPoint* const* pPtAry,
-                                                const PolyFlags* const* pFlgAry)
+bool SkiaSalGraphicsImpl::drawPolyPolygonBezier(sal_uInt32, const sal_uInt32*,
+                                                const SalPoint* const*, const PolyFlags* const*)
 {
-    (void)nPoly;
-    (void)pPoints;
-    (void)pPtAry;
-    (void)pFlgAry;
+    // TODO?
     return false;
 }
 
@@ -1005,15 +994,9 @@ void SkiaSalGraphicsImpl::invert(sal_uInt32 nPoints, const SalPoint* pPointArray
     invert(aPolygon, eFlags);
 }
 
-bool SkiaSalGraphicsImpl::drawEPS(long nX, long nY, long nWidth, long nHeight, void* pPtr,
-                                  sal_uInt32 nSize)
+bool SkiaSalGraphicsImpl::drawEPS(long, long, long, long, void*, sal_uInt32)
 {
-    (void)nX;
-    (void)nY;
-    (void)nWidth;
-    (void)nHeight;
-    (void)pPtr;
-    (void)nSize;
+    // TODO?
     return false;
 }
 
@@ -1122,11 +1105,9 @@ bool SkiaSalGraphicsImpl::drawAlphaRect(long nX, long nY, long nWidth, long nHei
     return true;
 }
 
-bool SkiaSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolygon,
-                                       const Gradient& rGradient)
+bool SkiaSalGraphicsImpl::drawGradient(const tools::PolyPolygon&, const Gradient&)
 {
-    (void)rPolygon;
-    (void)rGradient;
+    // TODO?
     return false;
 }
 
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index c1ff1f13e9e3..de49400cd481 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -164,15 +164,11 @@ bool SkiaSalBitmap::Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount)
     // TODO copy data
     SAL_INFO("vcl.skia", "copy(" << this << "): (" << &src << ")");
     abort();
-    return true;
 }
 
-bool SkiaSalBitmap::Create(const css::uno::Reference<css::rendering::XBitmapCanvas>& rBitmapCanvas,
-                           Size& rSize, bool bMask)
+bool SkiaSalBitmap::Create(const css::uno::Reference<css::rendering::XBitmapCanvas>&, Size&, bool)
 {
-    (void)rBitmapCanvas;
-    (void)rSize;
-    (void)bMask;
+    // TODO?
     return false;
 }
 
@@ -187,9 +183,9 @@ Size SkiaSalBitmap::GetSize() const { return mSize; }
 
 sal_uInt16 SkiaSalBitmap::GetBitCount() const { return mBitCount; }
 
-BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode nMode)
+BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode /*nMode*/)
 {
-    (void)nMode; // TODO
+    //(void)nMode; // TODO
     if (mBitmap.drawsNothing() && !mBuffer)
         return nullptr;
     BitmapBuffer* buffer = new BitmapBuffer;
@@ -257,27 +253,23 @@ void SkiaSalBitmap::ReleaseBuffer(BitmapBuffer* pBuffer, BitmapAccessMode nMode)
     delete pBuffer;
 }
 
-bool SkiaSalBitmap::GetSystemData(BitmapSystemData& rData)
+bool SkiaSalBitmap::GetSystemData(BitmapSystemData&)
 {
-    (void)rData;
+    // TODO?
     return false;
 }
 
 bool SkiaSalBitmap::ScalingSupported() const { return false; }
 
-bool SkiaSalBitmap::Scale(const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag)
+bool SkiaSalBitmap::Scale(const double&, const double&, BmpScaleFlag)
 {
-    (void)rScaleX;
-    (void)rScaleY;
-    (void)nScaleFlag;
+    // TODO?
     return false;
 }
 
-bool SkiaSalBitmap::Replace(const Color& rSearchColor, const Color& rReplaceColor, sal_uInt8 nTol)
+bool SkiaSalBitmap::Replace(const Color&, const Color&, sal_uInt8)
 {
-    (void)rSearchColor;
-    (void)rReplaceColor;
-    (void)nTol;
+    // TODO?
     return false;
 }
 
@@ -298,10 +290,10 @@ const SkBitmap& SkiaSalBitmap::GetSkBitmap() const
             // Convert 24bpp RGB/BGR to 32bpp RGBA/BGRA.
             std::unique_ptr<sal_uInt8[]> data(new sal_uInt8[mSize.Height() * mSize.Width() * 4]);
             sal_uInt8* dest = data.get();
-            for (int y = 0; y < mSize.Height(); ++y)
+            for (long y = 0; y < mSize.Height(); ++y)
             {
                 const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
-                for (int x = 0; x < mSize.Width(); ++x)
+                for (long x = 0; x < mSize.Width(); ++x)
                 {
                     *dest++ = *src++;
                     *dest++ = *src++;
diff --git a/vcl/source/bitmap/salbmp.cxx b/vcl/source/bitmap/salbmp.cxx
index 28a46ccc262b..c9aca589edba 100644
--- a/vcl/source/bitmap/salbmp.cxx
+++ b/vcl/source/bitmap/salbmp.cxx
@@ -148,7 +148,7 @@ std::unique_ptr< sal_uInt8[] > SalBitmap::convertDataBitCount( const sal_uInt8*
 {
     assert( bitCount == 1 || bitCount == 4 || bitCount == 8 );
     static const int bpp[] = { 1, 3, 3, 4, 4 };
-    std::unique_ptr< sal_uInt8[] > data( new sal_uInt8[width * height * bpp[ (int)type ]] );
+    std::unique_ptr< sal_uInt8[] > data( new sal_uInt8[width * height * bpp[ static_cast<int>(type) ]] );
     std::unique_ptr<ImplPixelFormat> pSrcFormat(ImplPixelFormat::GetFormat(bitCount, palette));
 
     const sal_uInt8* pSrcData = src;
commit 5ce6f448ae3d00707202a2d52cf3d718431297f8
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Nov 18 16:40:25 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    solve the Skia lerp() conflict differently
    
    New versions of libstdc++ provide lerp() in the global namespace,
    older ones don't, but it depends on the libstdc++ version and not
    the c++ version. Since the function is local, just "rename" it.
    
    Change-Id: I37896190c620350739fba9b8ce6544f945519244

diff --git a/external/skia/lerp.patch b/external/skia/lerp.patch
index c87a965e7caf..2062c21f2df0 100644
--- a/external/skia/lerp.patch
+++ b/external/skia/lerp.patch
@@ -1,14 +1,12 @@
---- skia/src/shaders/SkPerlinNoiseShader.cpp.sav	2019-07-29 14:37:30.429563360 +0200
-+++ skia/src/shaders/SkPerlinNoiseShader.cpp	2019-07-29 16:45:29.736231751 +0200
-@@ -573,9 +573,11 @@ static SkScalar fade(SkScalar t) {
+diff --git a/src/shaders/SkPerlinNoiseShader.cpp b/src/shaders/SkPerlinNoiseShader.cpp
+index 812dc1694f..60b8d617c6 100644
+--- a/src/shaders/SkPerlinNoiseShader.cpp
++++ b/src/shaders/SkPerlinNoiseShader.cpp
+@@ -573,6 +573,7 @@ static SkScalar fade(SkScalar t) {
      return t * t * t * (t * (t * 6 - 15) + 10);
  }
  
-+#if __cplusplus <= 201703L
++#define lerp skia_lerp
  static SkScalar lerp(SkScalar t, SkScalar a, SkScalar b) {
      return a + t * (b - a);
  }
-+#endif
- 
- static SkScalar grad(int hash, SkScalar x, SkScalar y, SkScalar z) {
-     int h = hash & 15;
commit c8fd10fecabf04aab30cd8e911739873d5e32a2a
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Nov 18 13:52:09 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    avoid unused parameter warning in non-debug build
    
    Change-Id: I3ea06a872d5348f7681602a6d68ff69990f2cd7e

diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 1090c33b73e0..0f253a797097 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -59,6 +59,7 @@ public:
     {
         // This ensures that all backends return a valid name.
         assert(!name.isEmpty());
+        (void)name;
         return false;
     }
 
commit 48c92ecb2ee04a25fd14f818b1fb7d752cde58c1
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Nov 18 12:24:59 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    make about dialog differentiate between Skia with Vulkan or raster
    
    Since they are technically still two different rendering implementations.
    
    Change-Id: I83c324b384b7acfcc84e729271d00b995327eec6

diff --git a/vcl/inc/strings.hrc b/vcl/inc/strings.hrc
index d8f73a587722..e378b54814bd 100644
--- a/vcl/inc/strings.hrc
+++ b/vcl/inc/strings.hrc
@@ -125,7 +125,8 @@
 #define SV_APP_OSVERSION                             NC_("SV_APP_OSVERSION", "OS: ")
 #define SV_APP_UIRENDER                              NC_("SV_APP_UIRENDER", "UI render: ")
 #define SV_APP_GL                                    NC_("SV_APP_GL", "GL")
-#define SV_APP_SKIA                                  NC_("SV_APP_SKIA", "Skia")
+#define SV_APP_SKIA_VULKAN                           NC_("SV_APP_SKIA_VULKAN", "Skia/Vulkan")
+#define SV_APP_SKIA_RASTER                           NC_("SV_APP_SKIA_RASTER", "Skia/Raster")
 #define SV_APP_DEFAULT                               NC_("SV_APP_DEFAULT", "default")
 
 #define SV_MSGBOX_INFO                               NC_("SV_MSGBOX_INFO", "Information")
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 4b97754bebbe..511e6dd5e598 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -1153,9 +1153,21 @@ OUString Application::GetHWOSConfInfo()
         aDetails.append( VclResId(SV_APP_GL) );
     else
 #endif
+#if HAVE_FEATURE_SKIA
     if ( SkiaHelper::isVCLSkiaEnabled() )
-        aDetails.append( VclResId(SV_APP_SKIA) );
+    {
+        switch(SkiaHelper::renderMethodToUse())
+        {
+            case SkiaHelper::RenderVulkan:
+                aDetails.append( VclResId(SV_APP_SKIA_VULKAN) );
+                break;
+            case SkiaHelper::RenderRaster:
+                aDetails.append( VclResId(SV_APP_SKIA_RASTER) );
+                break;
+        }
+    }
     else
+#endif
         aDetails.append( VclResId(SV_APP_DEFAULT) );
     aDetails.append( "; " );
 
commit c019d96dddaa7abc13cc94299dff6a858c50e58f
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Nov 18 12:10:36 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    make sure Skia invert with TrackFrame doesn't paint outside
    
    According to Tomaž that's a requirement and that is what the test
    for it tests. This is easy to implement with additional clipping.
    
    Change-Id: Ia54489e20ce58ae0624183f2989036e6938cd44f

diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 6dfda5d02d35..1090c33b73e0 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -465,8 +465,7 @@ public:
 
     CPPUNIT_TEST(testDrawInvertWithRectangle);
     CPPUNIT_TEST(testDrawInvertN50WithRectangle);
-    // AFAIK this test (itself) is broken.
-    // CPPUNIT_TEST(testDrawInvertTrackFrameWithRectangle);
+    CPPUNIT_TEST(testDrawInvertTrackFrameWithRectangle);
 
     CPPUNIT_TEST(testDrawBezierWithPolylineB2D);
     CPPUNIT_TEST(testDrawBezierAAWithPolylineB2D);
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 948c85df72e4..271f1a61321c 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -920,6 +920,11 @@ void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFl
         SkPath aPath;
         addPolygonToPath(rPoly, aPath);
         aPath.setFillType(SkPath::kEvenOdd_FillType);
+        // TrackFrame is not supposed to paint outside of the polygon (usually rectangle),
+        // but wider stoke width usually results in that, so ensure the requirement
+        // by clipping.
+        SkAutoCanvasRestore autoRestore(mSurface->getCanvas(), true);
+        mSurface->getCanvas()->clipRect(aPath.getBounds(), SkClipOp::kIntersect, false);
         SkPaint aPaint;
         aPaint.setStrokeWidth(2);
         float intervals[] = { 4.0f, 4.0f };
commit ed270e4755727da81ee16d210d24575885abc6b7
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 15 17:22:38 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    disable Skia resource leak checking on exit
    
    This is normally enabled in Skia debug builds and it asserts if there
    is a problem, which there is with a number of our unittests that leak
    something (usually a VirtualDevice). Those are non-trivial to find
    and don't matter in practice (or if they do they should be fixed
    for all VCL backends), so just disable the Skia check.
    
    Change-Id: I0a0721d8a3f0f961e14513574f4b3cc88ec1e62c

diff --git a/external/skia/UnpackedTarball_skia.mk b/external/skia/UnpackedTarball_skia.mk
index c3988042a012..1fab368cc34b 100644
--- a/external/skia/UnpackedTarball_skia.mk
+++ b/external/skia/UnpackedTarball_skia.mk
@@ -18,6 +18,7 @@ skia_patches := \
     fix-ddi.patch \
     make-api-visible.patch.1 \
     fix-shader-locale.patch.1 \
+    no-trace-resources-on-exit.patch.1 \
     share-grcontext.patch.1
 
 $(eval $(call gb_UnpackedTarball_set_patchlevel,skia,1))
diff --git a/external/skia/no-trace-resources-on-exit.patch.1 b/external/skia/no-trace-resources-on-exit.patch.1
new file mode 100644
index 000000000000..7a8567938eba
--- /dev/null
+++ b/external/skia/no-trace-resources-on-exit.patch.1
@@ -0,0 +1,26 @@
+diff --git a/src/gpu/vk/GrVkCommandPool.h b/src/gpu/vk/GrVkCommandPool.h
+index fd44d62e94..f9e90f185f 100644
+--- a/src/gpu/vk/GrVkCommandPool.h
++++ b/src/gpu/vk/GrVkCommandPool.h
+@@ -41,7 +41,7 @@ public:
+     // returns true if close() has not been called
+     bool isOpen() const { return fOpen; }
+ 
+-#ifdef SK_DEBUG
++#ifdef SK_TRACE_VK_RESOURCES
+     void dumpInfo() const override {
+         SkDebugf("GrVkCommandPool: %p (%d refs)\n", fCommandPool, this->getRefCnt());
+     }
+diff --git a/src/gpu/vk/GrVkResource.h b/src/gpu/vk/GrVkResource.h
+index 7b9949ba1b..4e8fb48c7c 100644
+--- a/src/gpu/vk/GrVkResource.h
++++ b/src/gpu/vk/GrVkResource.h
+@@ -17,7 +17,7 @@ class GrVkGpu;
+ 
+ // uncomment to enable tracing of resource refs
+ #ifdef SK_DEBUG
+-#define SK_TRACE_VK_RESOURCES
++//#define SK_TRACE_VK_RESOURCES
+ #endif
+ 
+ /** \class GrVkResource
commit 39a7992b4de5323e7cda1ced3154ebab61e81339
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 15 17:20:44 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    fix memory leak
    
    Change-Id: I6148159737edd4fe225d1140606064cdb77ef615

diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index e109cf6a76eb..39efe91e51c7 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -74,7 +74,7 @@ class VCL_DLLPUBLIC PDFOutputStream
 
 class VCL_DLLPUBLIC PDFWriter
 {
-    VclPtr<PDFWriterImpl> xImplementation;
+    ScopedVclPtr<PDFWriterImpl> xImplementation;
 
     PDFWriter(const PDFWriter&) = delete;
     PDFWriter& operator=(const PDFWriter&) = delete;
commit a2033ddb7243d756feae6b9b089b92c4f847e78a
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Fri Nov 15 14:42:05 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    make Skia GPU offscreen surfaces work with unittests
    
    Skia is now patched to be able to create also invalid
    sk_app::WindowContext that will just initialize the shared GrContext.
    And always use that GrContext, even for tests, because some tests
    first create a offscreen surfaces and only later create windows,
    which before this patch led to mixing GrContext instances.
    
    Change-Id: Ic79c0719f98f6ac48527c2ea2a9a9a69412adeff

diff --git a/external/skia/Library_skia.mk b/external/skia/Library_skia.mk
index 7d84762a621d..ed24d30fa93f 100644
--- a/external/skia/Library_skia.mk
+++ b/external/skia/Library_skia.mk
@@ -62,7 +62,6 @@ ifeq ($(OS),LINUX)
 $(eval $(call gb_Library_add_libs,skia,\
     -lm \
     -ldl \
-    -lGLU \
     -lGLX \
     -lGL \
     -lX11-xcb \
@@ -814,12 +813,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
 ))
 
 $(eval $(call gb_Library_add_generated_exception_objects,skia,\
-    UnpackedTarball/skia/tools/gpu/GrContextFactory \
-    UnpackedTarball/skia/tools/gpu/TestContext \
-    UnpackedTarball/skia/tools/gpu/gl/GLTestContext \
-    UnpackedTarball/skia/tools/gpu/gl/command_buffer/GLTestContext_command_buffer \
-    UnpackedTarball/skia/tools/gpu/mock/MockTestContext \
-    UnpackedTarball/skia/tools/gpu/vk/VkTestContext \
     UnpackedTarball/skia/tools/gpu/vk/VkTestUtils \
     UnpackedTarball/skia/tools/sk_app/GLWindowContext \
     UnpackedTarball/skia/tools/sk_app/VulkanWindowContext \
@@ -848,7 +841,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
 ))
 
 $(eval $(call gb_Library_add_generated_exception_objects,skia,\
-    UnpackedTarball/skia/tools/gpu/gl/win/CreatePlatformGLTestContext_win \
     UnpackedTarball/skia/tools/sk_app/win/GLWindowContext_win \
     UnpackedTarball/skia/tools/sk_app/win/RasterWindowContext_win \
     UnpackedTarball/skia/tools/sk_app/win/VulkanWindowContext_win \
@@ -871,7 +863,6 @@ $(eval $(call gb_Library_add_generated_exception_objects,skia,\
 ))
 
 $(eval $(call gb_Library_add_generated_exception_objects,skia,\
-    UnpackedTarball/skia/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx \
     UnpackedTarball/skia/tools/sk_app/unix/GLWindowContext_unix \
     UnpackedTarball/skia/tools/sk_app/unix/RasterWindowContext_unix \
     UnpackedTarball/skia/tools/sk_app/unix/VulkanWindowContext_unix \
diff --git a/external/skia/make-api-visible.patch.1 b/external/skia/make-api-visible.patch.1
index 3c2ff873eabb..2bf3a0f3d73a 100644
--- a/external/skia/make-api-visible.patch.1
+++ b/external/skia/make-api-visible.patch.1
@@ -1,29 +1,3 @@
-diff --git a/tools/gpu/GrContextFactory.h b/tools/gpu/GrContextFactory.h
-index d1b7fd5fa0..1b0bc249d2 100644
---- a/tools/gpu/GrContextFactory.h
-+++ b/tools/gpu/GrContextFactory.h
-@@ -26,7 +26,7 @@ class ContextInfo;
-  * factory is destroyed (though the caller can always grab a ref on the returned
-  * Gr and GL contexts to make them outlive the factory).
-  */
--class GrContextFactory : SkNoncopyable {
-+class SK_API GrContextFactory : SkNoncopyable {
- public:
-     // The availability of context types is subject to platform and build configuration
-     // restrictions.
-diff --git a/tools/gpu/gl/GLTestContext.cpp b/tools/gpu/gl/GLTestContext.cpp
-index d4aa605188..5d246f9737 100644
---- a/tools/gpu/gl/GLTestContext.cpp
-+++ b/tools/gpu/gl/GLTestContext.cpp
-@@ -298,7 +298,7 @@ void GLTestContext::teardown() {
- void GLTestContext::testAbandon() {
-     INHERITED::testAbandon();
-     if (fGL) {
--        fGL->abandon();
-+//        fGL->abandon();
-     }
- }
- 
 diff --git a/tools/sk_app/unix/WindowContextFactory_unix.h b/tools/sk_app/unix/WindowContextFactory_unix.h
 index 47310970d5..e02e6eb5b7 100644
 --- a/tools/sk_app/unix/WindowContextFactory_unix.h
diff --git a/external/skia/share-grcontext.patch.1 b/external/skia/share-grcontext.patch.1
index 357c3a885880..ed81e772aa20 100644
--- a/external/skia/share-grcontext.patch.1
+++ b/external/skia/share-grcontext.patch.1
@@ -1,13 +1,168 @@
-diff --git a/tools/sk_app/VulkanWindowContext.cpp b/tools/sk_app/VulkanWindowContext.cpp
-index 793c88c158..21164cac67 100644
---- a/tools/sk_app/VulkanWindowContext.cpp
-+++ b/tools/sk_app/VulkanWindowContext.cpp
-@@ -1,4 +1,3 @@
+--- ./tools/sk_app/VulkanWindowContext.h.sav	2019-11-14 16:46:31.218722399 +0100
++++ ./tools/sk_app/VulkanWindowContext.h	2019-11-15 11:58:46.656455921 +0100
+@@ -23,14 +23,30 @@ class GrRenderTarget;
+ 
+ namespace sk_app {
+ 
+-class VulkanWindowContext : public WindowContext {
++class SK_API VulkanWindowContext : public WindowContext {
++    struct Shared;
+ public:
+     ~VulkanWindowContext() override;
+ 
++    class SharedGrContext {
++    public:
++        SharedGrContext() {}
++        GrContext* getGrContext() { return shared ? shared->fContext.get() : nullptr; }
++        ~SharedGrContext() { shared.reset(); checkDestroyShared(); }
++        bool operator!() const { return !shared; }
++        void reset() { shared.reset(); }
++    private:
++        friend class VulkanWindowContext;
++        SharedGrContext(sk_sp<Shared>& sh ) : shared( sh ) {}
++        sk_sp<Shared> shared;
++    };
++
++    static SharedGrContext getSharedGrContext() { return SharedGrContext( fGlobalShared ); }
++
+     sk_sp<SkSurface> getBackbufferSurface() override;
+     void swapBuffers() override;
+ 
+-    bool isValid() override { return fDevice != VK_NULL_HANDLE; }
++    bool isValid() override { return fSurface != VK_NULL_HANDLE; }
+ 
+     void resize(int w, int h) override {
+         this->createSwapchain(w, h, fDisplayParams);
+@@ -53,6 +69,7 @@ public:
+ private:
+     void initializeContext();
+     void destroyContext();
++    static void checkDestroyShared();
+ 
+     struct BackbufferInfo {
+         uint32_t        fImageIndex;          // image this is associated with
+@@ -64,11 +81,6 @@ private:
+     void createBuffers(VkFormat format, SkColorType colorType);
+     void destroyBuffers();
+ 
+-    VkInstance fInstance = VK_NULL_HANDLE;
+-    VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
+-    VkDevice fDevice = VK_NULL_HANDLE;
+-    VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
 -
- /*
-  * Copyright 2015 Google Inc.
-  *
-@@ -24,8 +23,10 @@
+     // Create functions
+     CreateVkSurfaceFn fCreateVkSurfaceFn;
+     CanPresentFn      fCanPresentFn;
+@@ -90,20 +102,41 @@ private:
+     PFN_vkAcquireNextImageKHR fAcquireNextImageKHR = nullptr;
+     PFN_vkQueuePresentKHR fQueuePresentKHR = nullptr;
+ 
+-    PFN_vkDestroyInstance fDestroyInstance = nullptr;
+     PFN_vkDeviceWaitIdle fDeviceWaitIdle = nullptr;
+-    PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugReportCallbackEXT = nullptr;
+     PFN_vkQueueWaitIdle fQueueWaitIdle = nullptr;
+-    PFN_vkDestroyDevice fDestroyDevice = nullptr;
+     PFN_vkGetDeviceQueue fGetDeviceQueue = nullptr;
+ 
++    // We need to use just one GrContext, so share all the relevant data.
++    struct Shared : public SkRefCnt
++    {
++    PFN_vkDestroyInstance fDestroyInstance = nullptr;
++    PFN_vkDestroyDevice fDestroyDevice = nullptr;
++    PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugReportCallbackEXT = nullptr;
++
++    VkInstance fInstance = VK_NULL_HANDLE;
++    VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
++    VkDevice fDevice = VK_NULL_HANDLE;
++    VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
++
+     sk_sp<const GrVkInterface> fInterface;
+ 
+-    VkSurfaceKHR      fSurface;
+-    VkSwapchainKHR    fSwapchain;
++    // Original code had this as a function-local variable, but that seems wrong.
++    // It should exist as long as the context exists.
++    VkPhysicalDeviceFeatures2 features;
++
+     uint32_t          fGraphicsQueueIndex;
+     VkQueue           fGraphicsQueue;
+     uint32_t          fPresentQueueIndex;
++
++    sk_sp<GrContext> fContext;
++    };
++
++    sk_sp<Shared> fShared;
++
++    static sk_sp<Shared> fGlobalShared;
++
++    VkSurfaceKHR      fSurface;
++    VkSwapchainKHR    fSwapchain;
+     VkQueue           fPresentQueue;
+ 
+     uint32_t               fImageCount;
+--- ./tools/sk_app/unix/VulkanWindowContext_unix.cpp.sav	2019-10-21 12:03:51.753745188 +0200
++++ ./tools/sk_app/unix/VulkanWindowContext_unix.cpp	2019-11-15 12:08:01.605967642 +0100
+@@ -30,7 +30,7 @@ std::unique_ptr<WindowContext> MakeVulka
+         return nullptr;
+     }
+ 
+-    auto createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR {
++    VulkanWindowContext::CreateVkSurfaceFn createVkSurface = [&info, instProc](VkInstance instance) -> VkSurfaceKHR {
+         static PFN_vkCreateXcbSurfaceKHR createXcbSurfaceKHR = nullptr;
+         if (!createXcbSurfaceKHR) {
+             createXcbSurfaceKHR =
+@@ -54,6 +54,9 @@ std::unique_ptr<WindowContext> MakeVulka
+ 
+         return surface;
+     };
++    // Allow creating just the shared context, without an associated window.
++    if(info.fWindow == None)
++        createVkSurface = nullptr;
+ 
+     auto canPresent = [&info, instProc](VkInstance instance, VkPhysicalDevice physDev,
+                               uint32_t queueFamilyIndex) {
+@@ -76,7 +79,7 @@ std::unique_ptr<WindowContext> MakeVulka
+     };
+     std::unique_ptr<WindowContext> ctx(
+             new VulkanWindowContext(displayParams, createVkSurface, canPresent, instProc, devProc));
+-    if (!ctx->isValid()) {
++    if (!ctx->isValid() && createVkSurface != nullptr) {
+         return nullptr;
+     }
+     return ctx;
+--- ./tools/sk_app/win/VulkanWindowContext_win.cpp.sav	2019-10-21 12:03:51.753745188 +0200
++++ ./tools/sk_app/win/VulkanWindowContext_win.cpp	2019-11-15 12:08:21.466022257 +0100
+@@ -30,7 +30,7 @@ std::unique_ptr<WindowContext> MakeVulka
+         return nullptr;
+     }
+ 
+-    auto createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
++    VulkanWindowContext::CreateVkSurfaceFn createVkSurface = [hwnd, instProc] (VkInstance instance) -> VkSurfaceKHR {
+         static PFN_vkCreateWin32SurfaceKHR createWin32SurfaceKHR = nullptr;
+         if (!createWin32SurfaceKHR) {
+             createWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)
+@@ -54,6 +54,9 @@ std::unique_ptr<WindowContext> MakeVulka
+ 
+         return surface;
+     };
++    // Allow creating just the shared context, without an associated window.
++    if(hwnd == nullptr)
++        createVkSurface = nullptr;
+ 
+     auto canPresent = [instProc] (VkInstance instance, VkPhysicalDevice physDev,
+                                   uint32_t queueFamilyIndex) {
+@@ -71,7 +74,7 @@ std::unique_ptr<WindowContext> MakeVulka
+ 
+     std::unique_ptr<WindowContext> ctx(
+             new VulkanWindowContext(params, createVkSurface, canPresent, instProc, devProc));
+-    if (!ctx->isValid()) {
++    if (!ctx->isValid() && createVkSurface != nullptr) {
+         return nullptr;
+     }
+     return ctx;
+--- ./tools/sk_app/VulkanWindowContext.cpp.sav	2019-11-14 16:46:31.218722399 +0100
++++ ./tools/sk_app/VulkanWindowContext.cpp	2019-11-15 11:58:46.656455921 +0100
+@@ -24,8 +24,10 @@
  #undef CreateSemaphore
  #endif
  
@@ -20,7 +175,7 @@ index 793c88c158..21164cac67 100644
  
  namespace sk_app {
  
-@@ -49,6 +50,14 @@ VulkanWindowContext::VulkanWindowContext(const DisplayParams& params,
+@@ -49,6 +51,14 @@ VulkanWindowContext::VulkanWindowContext
  }
  
  void VulkanWindowContext::initializeContext() {
@@ -35,7 +190,7 @@ index 793c88c158..21164cac67 100644
      // any config code here (particularly for msaa)?
  
      PFN_vkGetInstanceProcAddr getInstanceProc = fGetInstanceProcAddr;
-@@ -62,24 +71,25 @@ void VulkanWindowContext::initializeContext() {
+@@ -62,24 +72,25 @@ void VulkanWindowContext::initializeCont
      };
      GrVkBackendContext backendContext;
      GrVkExtensions extensions;
@@ -71,7 +226,7 @@ index 793c88c158..21164cac67 100644
  
      PFN_vkGetPhysicalDeviceProperties localGetPhysicalDeviceProperties =
              reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
-@@ -87,21 +97,31 @@ void VulkanWindowContext::initializeContext() {
+@@ -87,21 +98,31 @@ void VulkanWindowContext::initializeCont
                                              backendContext.fInstance,
                                              VK_NULL_HANDLE));
      if (!localGetPhysicalDeviceProperties) {
@@ -108,7 +263,7 @@ index 793c88c158..21164cac67 100644
      GET_PROC(DestroySurfaceKHR);
      GET_PROC(GetPhysicalDeviceSurfaceSupportKHR);
      GET_PROC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
-@@ -109,7 +129,6 @@ void VulkanWindowContext::initializeContext() {
+@@ -109,7 +130,6 @@ void VulkanWindowContext::initializeCont
      GET_PROC(GetPhysicalDeviceSurfacePresentModesKHR);
      GET_DEV_PROC(DeviceWaitIdle);
      GET_DEV_PROC(QueueWaitIdle);
@@ -116,12 +271,15 @@ index 793c88c158..21164cac67 100644
      GET_DEV_PROC(CreateSwapchainKHR);
      GET_DEV_PROC(DestroySwapchainKHR);
      GET_DEV_PROC(GetSwapchainImagesKHR);
-@@ -117,46 +136,40 @@ void VulkanWindowContext::initializeContext() {
+@@ -117,46 +137,44 @@ void VulkanWindowContext::initializeCont
      GET_DEV_PROC(QueuePresentKHR);
      GET_DEV_PROC(GetDeviceQueue);
  
 -    fContext = GrContext::MakeVulkan(backendContext, fDisplayParams.fGrContextOptions);
--
++    // No actual window, used just to create the shared GrContext.
++    if(fCreateVkSurfaceFn == nullptr)
++        return;
+ 
 -    fSurface = fCreateVkSurfaceFn(fInstance);
 +    fSurface = fCreateVkSurfaceFn(fShared->fInstance);
      if (VK_NULL_HANDLE == fSurface) {
@@ -130,6 +288,9 @@ index 793c88c158..21164cac67 100644
          return;
      }
  
++    // create presentQueue
++    fGetDeviceQueue(fShared->fDevice, fShared->fPresentQueueIndex, 0, &fPresentQueue);
++
      VkBool32 supported;
 -    VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fPhysicalDevice, fPresentQueueIndex,
 +    VkResult res = fGetPhysicalDeviceSurfaceSupportKHR(fShared->fPhysicalDevice, fShared->fPresentQueueIndex,
@@ -145,11 +306,10 @@ index 793c88c158..21164cac67 100644
 -        sk_gpu_test::FreeVulkanFeaturesStructs(&features);
          return;
      }
- 
-     // create presentQueue
+-
+-    // create presentQueue
 -    fGetDeviceQueue(fDevice, fPresentQueueIndex, 0, &fPresentQueue);
 -    sk_gpu_test::FreeVulkanFeaturesStructs(&features);
-+    fGetDeviceQueue(fShared->fDevice, fShared->fPresentQueueIndex, 0, &fPresentQueue);
  }
  
  bool VulkanWindowContext::createSwapchain(int width, int height,
@@ -168,7 +328,7 @@ index 793c88c158..21164cac67 100644
                                                nullptr);
      if (VK_SUCCESS != res) {
          return false;
-@@ -164,14 +177,14 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+@@ -164,14 +182,14 @@ bool VulkanWindowContext::createSwapchai
  
      SkAutoMalloc surfaceFormatAlloc(surfaceFormatCount * sizeof(VkSurfaceFormatKHR));
      VkSurfaceFormatKHR* surfaceFormats = (VkSurfaceFormatKHR*)surfaceFormatAlloc.get();
@@ -185,7 +345,7 @@ index 793c88c158..21164cac67 100644
                                                     nullptr);
      if (VK_SUCCESS != res) {
          return false;
-@@ -179,7 +192,7 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+@@ -179,7 +197,7 @@ bool VulkanWindowContext::createSwapchai
  
      SkAutoMalloc presentModeAlloc(presentModeCount * sizeof(VkPresentModeKHR));
      VkPresentModeKHR* presentModes = (VkPresentModeKHR*)presentModeAlloc.get();
@@ -194,7 +354,7 @@ index 793c88c158..21164cac67 100644
                                                     presentModes);
      if (VK_SUCCESS != res) {
          return false;
-@@ -286,8 +299,8 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+@@ -286,8 +304,8 @@ bool VulkanWindowContext::createSwapchai
      swapchainCreateInfo.imageArrayLayers = 1;
      swapchainCreateInfo.imageUsage = usageFlags;
  
@@ -205,7 +365,7 @@ index 793c88c158..21164cac67 100644
          swapchainCreateInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT;
          swapchainCreateInfo.queueFamilyIndexCount = 2;
          swapchainCreateInfo.pQueueFamilyIndices = queueFamilies;
-@@ -303,18 +316,18 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+@@ -303,18 +321,18 @@ bool VulkanWindowContext::createSwapchai
      swapchainCreateInfo.clipped = true;
      swapchainCreateInfo.oldSwapchain = fSwapchain;
  
@@ -227,7 +387,7 @@ index 793c88c158..21164cac67 100644
      }
  
      this->createBuffers(swapchainCreateInfo.imageFormat, colorType);
-@@ -323,10 +336,10 @@ bool VulkanWindowContext::createSwapchain(int width, int height,
+@@ -323,10 +341,10 @@ bool VulkanWindowContext::createSwapchai
  }
  
  void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType) {
@@ -240,7 +400,7 @@ index 793c88c158..21164cac67 100644
  
      // set up initial image layouts and create surfaces
      fImageLayouts = new VkImageLayout[fImageCount];
-@@ -341,7 +354,7 @@ void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType)
+@@ -341,7 +359,7 @@ void VulkanWindowContext::createBuffers(
          info.fImageTiling = VK_IMAGE_TILING_OPTIMAL;
          info.fFormat = format;
          info.fLevelCount = 1;
@@ -249,7 +409,7 @@ index 793c88c158..21164cac67 100644
  
          if (fSampleCount == 1) {
              GrBackendRenderTarget backendRT(fWidth, fHeight, fSampleCount, info);
-@@ -372,8 +385,8 @@ void VulkanWindowContext::createBuffers(VkFormat format, SkColorType colorType)
+@@ -372,8 +390,8 @@ void VulkanWindowContext::createBuffers(
      fBackbuffers = new BackbufferInfo[fImageCount + 1];
      for (uint32_t i = 0; i < fImageCount + 1; ++i) {
          fBackbuffers[i].fImageIndex = -1;
@@ -260,7 +420,7 @@ index 793c88c158..21164cac67 100644
                                              nullptr, &fBackbuffers[i].fRenderSemaphore));
      }
      fCurrentBackbufferIndex = fImageCount;
-@@ -384,8 +397,8 @@ void VulkanWindowContext::destroyBuffers() {
+@@ -384,8 +402,8 @@ void VulkanWindowContext::destroyBuffers
      if (fBackbuffers) {
          for (uint32_t i = 0; i < fImageCount + 1; ++i) {
              fBackbuffers[i].fImageIndex = -1;
@@ -271,7 +431,7 @@ index 793c88c158..21164cac67 100644
                                          fBackbuffers[i].fRenderSemaphore,
                                          nullptr));
          }
-@@ -410,41 +423,55 @@ VulkanWindowContext::~VulkanWindowContext() {
+@@ -410,41 +428,55 @@ VulkanWindowContext::~VulkanWindowContex
  void VulkanWindowContext::destroyContext() {
      if (this->isValid()) {
          fQueueWaitIdle(fPresentQueue);
@@ -340,7 +500,7 @@ index 793c88c158..21164cac67 100644
  }
  
  VulkanWindowContext::BackbufferInfo* VulkanWindowContext::getAvailableBackbuffer() {
-@@ -470,34 +497,34 @@ sk_sp<SkSurface> VulkanWindowContext::getBackbufferSurface() {
+@@ -470,34 +502,34 @@ sk_sp<SkSurface> VulkanWindowContext::ge
      semaphoreInfo.pNext = nullptr;
      semaphoreInfo.flags = 0;
      VkSemaphore semaphore;
@@ -381,119 +541,10 @@ index 793c88c158..21164cac67 100644
              return nullptr;
          }
      }
-@@ -541,4 +568,6 @@ void VulkanWindowContext::swapBuffers() {
+@@ -541,4 +573,6 @@ void VulkanWindowContext::swapBuffers()
      fQueuePresentKHR(fPresentQueue, &presentInfo);
  }
  
 +SK_API sk_sp<VulkanWindowContext::Shared> VulkanWindowContext::fGlobalShared;
 +
  }   //namespace sk_app
-diff --git a/tools/sk_app/VulkanWindowContext.h b/tools/sk_app/VulkanWindowContext.h
-index 2db9e79ae6..7950dc159b 100644
---- a/tools/sk_app/VulkanWindowContext.h
-+++ b/tools/sk_app/VulkanWindowContext.h
-@@ -1,4 +1,3 @@
--
- /*
-  * Copyright 2016 Google Inc.
-  *
-@@ -23,14 +22,30 @@ class GrRenderTarget;
- 
- namespace sk_app {
- 
--class VulkanWindowContext : public WindowContext {
-+class SK_API VulkanWindowContext : public WindowContext {
-+    struct Shared;
- public:
-     ~VulkanWindowContext() override;
- 
-+    class SharedGrContext {
-+    public:
-+        SharedGrContext() {}
-+        GrContext* getGrContext() { return shared ? shared->fContext.get() : nullptr; }
-+        ~SharedGrContext() { shared.reset(); checkDestroyShared(); }
-+        bool operator!() const { return !shared; }
-+        void reset() { shared.reset(); }
-+    private:
-+        friend class VulkanWindowContext;
-+        SharedGrContext(sk_sp<Shared>& sh ) : shared( sh ) {}
-+        sk_sp<Shared> shared;
-+    };
-+
-+    static SharedGrContext getSharedGrContext() { return SharedGrContext( fGlobalShared ); }
-+
-     sk_sp<SkSurface> getBackbufferSurface() override;
-     void swapBuffers() override;
- 
--    bool isValid() override { return fDevice != VK_NULL_HANDLE; }
-+    bool isValid() override { return fShared && fShared->fDevice != VK_NULL_HANDLE; }
- 
-     void resize(int w, int h) override {
-         this->createSwapchain(w, h, fDisplayParams);
-@@ -53,6 +68,7 @@ public:
- private:
-     void initializeContext();
-     void destroyContext();
-+    static void checkDestroyShared();
- 
-     struct BackbufferInfo {
-         uint32_t        fImageIndex;          // image this is associated with
-@@ -64,11 +80,6 @@ private:
-     void createBuffers(VkFormat format, SkColorType colorType);
-     void destroyBuffers();
- 
--    VkInstance fInstance = VK_NULL_HANDLE;
--    VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
--    VkDevice fDevice = VK_NULL_HANDLE;
--    VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
--
-     // Create functions
-     CreateVkSurfaceFn fCreateVkSurfaceFn;
-     CanPresentFn      fCanPresentFn;
-@@ -90,20 +101,41 @@ private:
-     PFN_vkAcquireNextImageKHR fAcquireNextImageKHR = nullptr;
-     PFN_vkQueuePresentKHR fQueuePresentKHR = nullptr;
- 
--    PFN_vkDestroyInstance fDestroyInstance = nullptr;
-     PFN_vkDeviceWaitIdle fDeviceWaitIdle = nullptr;
--    PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugReportCallbackEXT = nullptr;
-     PFN_vkQueueWaitIdle fQueueWaitIdle = nullptr;
--    PFN_vkDestroyDevice fDestroyDevice = nullptr;
-     PFN_vkGetDeviceQueue fGetDeviceQueue = nullptr;
- 
-+    // We need to use just one GrContext, so share all the relevant data.
-+    struct Shared : public SkRefCnt
-+    {
-+    PFN_vkDestroyInstance fDestroyInstance = nullptr;
-+    PFN_vkDestroyDevice fDestroyDevice = nullptr;
-+    PFN_vkDestroyDebugReportCallbackEXT fDestroyDebugReportCallbackEXT = nullptr;
-+
-+    VkInstance fInstance = VK_NULL_HANDLE;
-+    VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE;
-+    VkDevice fDevice = VK_NULL_HANDLE;
-+    VkDebugReportCallbackEXT fDebugCallback = VK_NULL_HANDLE;
-+
-     sk_sp<const GrVkInterface> fInterface;
- 
--    VkSurfaceKHR      fSurface;
--    VkSwapchainKHR    fSwapchain;
-+    // Original code had this as a function-local variable, but that seems wrong.
-+    // It should exist as long as the context exists.
-+    VkPhysicalDeviceFeatures2 features;
-+
-     uint32_t          fGraphicsQueueIndex;
-     VkQueue           fGraphicsQueue;
-     uint32_t          fPresentQueueIndex;
-+
-+    sk_sp<GrContext> fContext;
-+    };
-+
-+    sk_sp<Shared> fShared;
-+
-+    static sk_sp<Shared> fGlobalShared;
-+
-+    VkSurfaceKHR      fSurface;
-+    VkSwapchainKHR    fSwapchain;
-     VkQueue           fPresentQueue;
- 
-     uint32_t               fImageCount;
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 7c41e98a91b5..0036b2d89f7a 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -211,6 +211,8 @@ protected:
     void destroySurface();
     // Reimplemented for X11.
     virtual bool avoidRecreateByResize() const { return false; }
+    void createWindowSurface();
+    virtual void createWindowContext() = 0;
     void createOffscreenSurface();
 
     void privateDrawAlphaRect(long nX, long nY, long nWidth, long nHeight, double nTransparency,
@@ -256,11 +258,12 @@ protected:
     SalGraphics& mParent;
     /// Pointer to the SalFrame or SalVirtualDevice
     SalGeometryProvider* mProvider;
+    std::unique_ptr<sk_app::WindowContext> mWindowContext;
+    sk_app::VulkanWindowContext::SharedGrContext mOffscreenGrContext;
     // The Skia surface that is target of all the rendering.
     sk_sp<SkSurface> mSurface;
     bool mIsGPU; // whether the surface is GPU-backed
     // Keep reference to shared GrContext.
-    sk_app::VulkanWindowContext::SharedGrContext mOffscreenGrContext;
     vcl::Region mClipRegion;
     Color mLineColor;
     Color mFillColor;
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index 321f35f24366..75531ae9a164 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -21,10 +21,6 @@
 #include <svdata.hxx>
 
 class ControlCacheKey;
-namespace sk_app
-{
-class WindowContext;
-}
 
 class SkiaCompatibleDC : public CompatibleDC
 {
@@ -79,11 +75,8 @@ public:
                                   const SalTwoRect& rPosAry) override;
 
 protected:
-    virtual void createSurface() override;
+    virtual void createWindowContext() override;
     virtual void performFlush() override;
-
-private:
-    std::unique_ptr<sk_app::WindowContext> mWindowContext;
 };
 
 typedef std::pair<ControlCacheKey, SkBitmap> SkiaControlCachePair;
diff --git a/vcl/inc/skia/x11/gdiimpl.hxx b/vcl/inc/skia/x11/gdiimpl.hxx
index 1dc5064e6667..4d88740b8ba9 100644
--- a/vcl/inc/skia/x11/gdiimpl.hxx
+++ b/vcl/inc/skia/x11/gdiimpl.hxx
@@ -16,11 +16,6 @@
 #include <unx/x11/x11gdiimpl.h>
 #include <skia/gdiimpl.hxx>
 
-namespace sk_app
-{
-class WindowContext;
-}
-
 class VCL_PLUGIN_PUBLIC X11SkiaSalGraphicsImpl : public SkiaSalGraphicsImpl, public X11GraphicsImpl
 {
 private:
@@ -35,12 +30,9 @@ public:
     virtual void freeResources() override;
 
 protected:
-    virtual void createSurface() override;
+    virtual void createWindowContext() override;
     virtual void performFlush() override;
     virtual bool avoidRecreateByResize() const override;
-
-private:
-    std::unique_ptr<sk_app::WindowContext> mWindowContext;
 };
 
 #endif // INCLUDED_VCL_INC_SKIA_X11_GDIIMPL_HXX
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index caed9fb33431..948c85df72e4 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -31,7 +31,6 @@
 #include <SkRegion.h>
 #include <SkDashPathEffect.h>
 #include <GrBackendSurface.h>
-#include <GrContextFactory.h>
 
 #include <basegfx/polygon/b2dpolygontools.hxx>
 
@@ -182,6 +181,7 @@ SkiaSalGraphicsImpl::SkiaSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvid
 SkiaSalGraphicsImpl::~SkiaSalGraphicsImpl()
 {
     assert(!mSurface);
+    assert(!mWindowContext);
     assert(!mOffscreenGrContext);
 }
 
@@ -191,6 +191,17 @@ void SkiaSalGraphicsImpl::recreateSurface()
 {
     destroySurface();
     createSurface();
+}
+
+void SkiaSalGraphicsImpl::createSurface()
+{
+    if (isOffscreen())
+        createOffscreenSurface();
+    else
+        createWindowSurface();
+#ifdef DBG_UTIL
+    prefillSurface();
+#endif
     mSurface->getCanvas()->save(); // see SetClipRegion()
     mClipRegion = vcl::Region(tools::Rectangle(0, 0, GetWidth(), GetHeight()));
 
@@ -199,20 +210,35 @@ void SkiaSalGraphicsImpl::recreateSurface()
     mFlush->SetPriority(TaskPriority::POST_PAINT);
 }
 
-void SkiaSalGraphicsImpl::createSurface()
+void SkiaSalGraphicsImpl::createWindowSurface()
 {
-    // Create raster surface. Subclasses will create GPU-backed surfaces as appropriate.
-    mSurface = SkSurface::MakeRasterN32Premul(GetWidth(), GetHeight());
-    mIsGPU = false;
-#ifdef DBG_UTIL
-    prefillSurface();
-#endif
+    assert(!isOffscreen());
+    assert(!mSurface);
+    assert(!mWindowContext);
+    createWindowContext();
+    if (mWindowContext)
+        mSurface = mWindowContext->getBackbufferSurface();
+    if (!mSurface)
+    {
+        switch (SkiaHelper::renderMethodToUse())
+        {
+            case SkiaHelper::RenderVulkan:
+                SAL_WARN("vcl.skia", "cannot create Vulkan GPU window surface, disabling Vulkan");
+                // fall back to raster
+                SkiaHelper::disableRenderMethod(SkiaHelper::RenderVulkan);
+                destroySurface(); // destroys also WindowContext
+                return createWindowSurface(); // try again
+            case SkiaHelper::RenderRaster:
+                abort(); // this should not really happen
+        }
+    }
 }
 
 void SkiaSalGraphicsImpl::createOffscreenSurface()
 {
     assert(isOffscreen());
-    destroySurface();
+    assert(!mSurface);
+    assert(!mWindowContext);
     switch (SkiaHelper::renderMethodToUse())
     {
         case SkiaHelper::RenderVulkan:
@@ -228,11 +254,16 @@ void SkiaSalGraphicsImpl::createOffscreenSurface()
                 static bool isUnitTest = (getenv("LO_TESTNAME") != nullptr);
                 if (isUnitTest)
                 {
-                    static vcl::DeleteOnDeinit<sk_gpu_test::GrContextFactory> factory(
-                        new sk_gpu_test::GrContextFactory);
-                    // The factory owns the context.
-                    grContext
-                        = factory.get()->get(sk_gpu_test::GrContextFactory::kVulkan_ContextType);
+                    // Create temporary WindowContext with no window. That will fail,
+                    // but it will initialize the shared GrContext.
+                    createWindowContext();
+                    // Keep a reference.
+                    sk_app::VulkanWindowContext::SharedGrContext context
+                        = sk_app::VulkanWindowContext::getSharedGrContext();
+                    // Destroy the temporary WindowContext.
+                    destroySurface();
+                    mOffscreenGrContext = context;
+                    grContext = mOffscreenGrContext.getGrContext();
                 }
             }
             if (grContext)
@@ -241,7 +272,7 @@ void SkiaSalGraphicsImpl::createOffscreenSurface()
                     grContext, SkBudgeted::kNo,
                     SkImageInfo::MakeN32Premul(GetWidth(), GetHeight()));
                 mIsGPU = true;
-                assert(mSurface.get());
+                assert(mSurface);
 #ifdef DBG_UTIL
                 prefillSurface();
 #endif
@@ -254,7 +285,10 @@ void SkiaSalGraphicsImpl::createOffscreenSurface()
         default:
             break;
     }
-    return SkiaSalGraphicsImpl::createSurface(); // create a raster one
+    // Create raster surface. Subclasses will create GPU-backed surfaces as appropriate.
+    mSurface = SkSurface::MakeRasterN32Premul(GetWidth(), GetHeight());
+    assert(mSurface);
+    mIsGPU = false;
 }
 
 void SkiaSalGraphicsImpl::destroySurface()
@@ -266,6 +300,7 @@ void SkiaSalGraphicsImpl::destroySurface()
         // if this fails, something forgot to use SkAutoCanvasRestore
         assert(mSurface->getCanvas()->getTotalMatrix().isIdentity());
     }
+    // TODO Is this still needed?
     // If we use e.g. Vulkan, we must destroy the surface before the context,
     // otherwise destroying the surface will reference the context. This is
     // handled by calling destroySurface() before destroying the context.
@@ -276,6 +311,7 @@ void SkiaSalGraphicsImpl::destroySurface()
     if (mSurface)
         mSurface->flush();
     mSurface.reset();
+    mWindowContext.reset();
     mIsGPU = false;
     mOffscreenGrContext.reset();
 }
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index cba8bed29355..dd63f4d6121e 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -43,43 +43,26 @@ void WinSkiaSalGraphicsImpl::Init()
     SkiaSalGraphicsImpl::Init();
 }
 
-void WinSkiaSalGraphicsImpl::createSurface()
+void WinSkiaSalGraphicsImpl::createWindowContext()
 {
-    if (isOffscreen())
-        return createOffscreenSurface();
-    destroySurface();
     // When created, Init() gets called with size (0,0), which is invalid size
     // for Skia. Creating the actual surface is delayed, so the size should be always
     // valid here, but better check.
-    assert(GetWidth() != 0 && GetHeight() != 0);
+    assert((GetWidth() != 0 && GetHeight() != 0) || isOffscreen());
     sk_app::DisplayParams displayParams;
     switch (SkiaHelper::renderMethodToUse())
     {
         case SkiaHelper::RenderRaster:
             mWindowContext = sk_app::window_context_factory::MakeRasterForWin(mWinParent.gethWnd(),
                                                                               displayParams);
-            assert(SkToBool(mWindowContext));
-            mSurface = mWindowContext->getBackbufferSurface();
-            assert(mSurface.get());
             mIsGPU = false;
             break;
         case SkiaHelper::RenderVulkan:
             mWindowContext = sk_app::window_context_factory::MakeVulkanForWin(mWinParent.gethWnd(),
                                                                               displayParams);
-            if (mWindowContext)
-                mSurface = mWindowContext->getBackbufferSurface();
-            if (!mSurface)
-            {
-                SAL_WARN("vcl.skia", "cannot create Vulkan GPU surface, disabling Vulkan");
-                SkiaHelper::disableRenderMethod(SkiaHelper::RenderVulkan);
-                return createSurface(); // try again
-            }
             mIsGPU = true;
             break;
     }
-#ifdef DBG_UTIL
-    prefillSurface();
-#endif
 }
 
 void WinSkiaSalGraphicsImpl::DeInit()
diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index e679fa8dbb2d..3f706399f136 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -38,11 +38,8 @@ void X11SkiaSalGraphicsImpl::Init()
     SkiaSalGraphicsImpl::Init();
 }
 
-void X11SkiaSalGraphicsImpl::createSurface()
+void X11SkiaSalGraphicsImpl::createWindowContext()
 {
-    if (isOffscreen())
-        return createOffscreenSurface();
-    destroySurface();
     sk_app::DisplayParams displayParams;
     // Use a macro to hide an unreachable code warning.
     // TODO The Skia Xlib code actually requires the non-native color type to work properly.
@@ -53,7 +50,10 @@ void X11SkiaSalGraphicsImpl::createSurface()
     sk_app::window_context_factory::XlibWindowInfo winInfo;
     winInfo.fDisplay = mX11Parent.GetXDisplay();
     winInfo.fWindow = mX11Parent.GetDrawable();
-    assert(winInfo.fDisplay && winInfo.fWindow != None);
+    assert(winInfo.fDisplay);
+    // Allow window being None if offscreen, this is used to temporarily create GrContext
+    // for an offscreen surface.
+    assert(winInfo.fWindow != None || isOffscreen());
     winInfo.fFBConfig = nullptr; // not used
     winInfo.fVisualInfo = const_cast<SalVisual*>(&mX11Parent.GetVisual());
 #ifdef DBG_UTIL
@@ -70,28 +70,14 @@ void X11SkiaSalGraphicsImpl::createSurface()
         case SkiaHelper::RenderRaster:
             mWindowContext
                 = sk_app::window_context_factory::MakeRasterForXlib(winInfo, displayParams);
-            assert(SkToBool(mWindowContext));
-            mSurface = mWindowContext->getBackbufferSurface();
-            assert(mSurface.get());
             mIsGPU = false;
             break;
         case SkiaHelper::RenderVulkan:
             mWindowContext
                 = sk_app::window_context_factory::MakeVulkanForXlib(winInfo, displayParams);
-            if (mWindowContext)
-                mSurface = mWindowContext->getBackbufferSurface();
-            if (!mSurface)
-            {
-                SAL_WARN("vcl.skia", "cannot create Vulkan GPU surface, disabling Vulkan");
-                SkiaHelper::disableRenderMethod(SkiaHelper::RenderVulkan);
-                return createSurface(); // try again
-            }
             mIsGPU = true;
             break;
     }
-#ifdef DBG_UTIL
-    prefillSurface();
-#endif
 }
 
 bool X11SkiaSalGraphicsImpl::avoidRecreateByResize() const
commit 6292a51f9666edc8aa6f6d89caf07695387c86e8
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Nov 13 17:24:42 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:17 2019 +0100

    add invert() tests to visualbackendtest
    
    They already exist and are used by the unittest. And the TrackFrame
    test actually appears to expect incorrect results (or otherwise pretty
    much all backends implement the operation incorrectly).
    
    Change-Id: I26867a2d1b0f01b5e836131932b422cb8823fb5b

diff --git a/vcl/backendtest/VisualBackendTest.cxx b/vcl/backendtest/VisualBackendTest.cxx
index 4110082a6985..cab225918087 100644
--- a/vcl/backendtest/VisualBackendTest.cxx
+++ b/vcl/backendtest/VisualBackendTest.cxx
@@ -90,7 +90,7 @@ class VisualBackendTestWindow : public WorkWindow
 private:
     Timer maUpdateTimer;
     std::vector<std::chrono::high_resolution_clock::time_point> mTimePoints;
-    static constexpr unsigned char gnNumberOfTests = 7;
+    static constexpr unsigned char gnNumberOfTests = 8;
     unsigned char mnTest;
     bool mbAnimate;
     ScopedVclPtr<VirtualDevice> mpVDev;
@@ -391,6 +391,43 @@ public:
         }
     }
 
+    static void testInvert(vcl::RenderContext& rRenderContext, int nWidth, int nHeight)
+    {
+        tools::Rectangle aRectangle;
+        size_t index = 0;
+
+        std::vector<tools::Rectangle> aRegions = setupRegions(2, 2, nWidth, nHeight);
+
+        aRectangle = aRegions[index++];
+        {
+            vcl::test::OutputDeviceTestRect aOutDevTest;
+            Bitmap aBitmap = aOutDevTest.setupInvert_NONE();
+            assertAndSetBackground(vcl::test::OutputDeviceTestRect::checkInvertRectangle(aBitmap), aRectangle, rRenderContext);
+            drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+        }
+        aRectangle = aRegions[index++];
+        {
+            vcl::test::OutputDeviceTestRect aOutDevTest;
+            Bitmap aBitmap = aOutDevTest.setupInvert_N50();
+            assertAndSetBackground(vcl::test::OutputDeviceTestRect::checkInvertN50Rectangle(aBitmap), aRectangle, rRenderContext);
+            drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+        }
+        aRectangle = aRegions[index++];
+        {
+            vcl::test::OutputDeviceTestRect aOutDevTest;
+            Bitmap aBitmap = aOutDevTest.setupInvert_TrackFrame();
+            assertAndSetBackground(vcl::test::OutputDeviceTestRect::checkInvertTrackFrameRectangle(aBitmap), aRectangle, rRenderContext);
+            drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+        }
+        aRectangle = aRegions[index++];
+        {
+            vcl::test::OutputDeviceTestAnotherOutDev aOutDevTest;
+            Bitmap aBitmap = aOutDevTest.setupXOR();
+            assertAndSetBackground(vcl::test::OutputDeviceTestAnotherOutDev::checkXOR(aBitmap), aRectangle, rRenderContext);
+            drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
+        }
+    }
+
     virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/) override
     {
         if (mnTest % gnNumberOfTests == gnNumberOfTests - 1)
@@ -487,7 +524,11 @@ public:
         }
         else if (mnTest % gnNumberOfTests == 5)
         {
-            std::vector<tools::Rectangle> aRegions = setupRegions(3, 2, nWidth, nHeight);
+            testInvert(rRenderContext, nWidth, nHeight);
+        }
+        else if (mnTest % gnNumberOfTests == 6)
+        {
+            std::vector<tools::Rectangle> aRegions = setupRegions(3, 1, nWidth, nHeight);
 
             aRectangle = aRegions[index++];
             {
@@ -498,13 +539,6 @@ public:
             }
             aRectangle = aRegions[index++];
             {
-                vcl::test::OutputDeviceTestAnotherOutDev aOutDevTest;
-                Bitmap aBitmap = aOutDevTest.setupXOR();
-                assertAndSetBackground(vcl::test::OutputDeviceTestAnotherOutDev::checkXOR(aBitmap), aRectangle, rRenderContext);
-                drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
-            }
-            aRectangle = aRegions[index++];
-            {
                 vcl::test::OutputDeviceTestGradient aOutDevTest;
                 Bitmap aBitmap = aOutDevTest.setupLinearGradient();
                 drawBitmapScaledAndCentered(aRectangle, aBitmap, rRenderContext);
diff --git a/vcl/qa/cppunit/BackendTest.cxx b/vcl/qa/cppunit/BackendTest.cxx
index 01a81c0f17f3..6dfda5d02d35 100644
--- a/vcl/qa/cppunit/BackendTest.cxx
+++ b/vcl/qa/cppunit/BackendTest.cxx
@@ -465,7 +465,8 @@ public:
 
     CPPUNIT_TEST(testDrawInvertWithRectangle);
     CPPUNIT_TEST(testDrawInvertN50WithRectangle);
-    //    CPPUNIT_TEST(testDrawInvertTrackFrameWithRectangle); TODO SKIA
+    // AFAIK this test (itself) is broken.
+    // CPPUNIT_TEST(testDrawInvertTrackFrameWithRectangle);
 
     CPPUNIT_TEST(testDrawBezierWithPolylineB2D);
     CPPUNIT_TEST(testDrawBezierAAWithPolylineB2D);
commit f670aee88e4630b6cf8ce9f0c077d4dd75791c2e
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Nov 14 11:26:58 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:16 2019 +0100

    do not use Xlib for accessing something that is not an X window
    
    Change-Id: I8986064e581fdb9876068ae3b9736b9716554fb6

diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index 7eb02a51169e..e679fa8dbb2d 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -96,7 +96,7 @@ void X11SkiaSalGraphicsImpl::createSurface()
 
 bool X11SkiaSalGraphicsImpl::avoidRecreateByResize() const
 {
-    if (!mSurface)
+    if (!mSurface || isOffscreen())
         return false;
     // Skia's WindowContext uses actual dimensions of the X window, which due to X11 being
     // asynchronous may be temporarily different from what VCL thinks are the dimensions.
commit acd64ae866bdf6d8171c4508a5a42b4c20d4bf3d
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Nov 13 13:58:58 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:16 2019 +0100

    remove no-longer-needed Skia workaround for GPU offscreen drawing
    
    Change-Id: I044a9a31af71c4c624f08a0813bc59472f4c728a

diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index cb2beb2667a0..caed9fb33431 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -739,11 +739,6 @@ void SkiaSalGraphicsImpl::copyBits(const SalTwoRect& rPosAry, SalGraphics* pSrcG
         assert(dynamic_cast<SkiaSalGraphicsImpl*>(pSrcGraphics->GetImpl()));
         src = static_cast<SkiaSalGraphicsImpl*>(pSrcGraphics->GetImpl());
         src->checkSurface();
-        // TODO Without this flush() Skia asserts if both src and destination are
-        // GPU-backed SkSurface that come from different GrContext (e.g. when
-        // src comes from SkiaVulkanGrContext and target is a window). I don't
-        // know if it's a Skia bug or our GrContext usage is incorrect.
-        src->mSurface->flush();
     }
     else
         src = this;
commit 241730a71bcde0aca285c9e28d3811693e259dce
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Wed Nov 13 13:27:57 2019 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Nov 27 09:55:16 2019 +0100

    make Skia VCL backend fall back to raster if vulkan doesn't work
    
    Change-Id: Ic446f6f85e5ebc2e50cb51a3ed1e732b8976a193

diff --git a/external/skia/share-grcontext.patch.1 b/external/skia/share-grcontext.patch.1
index 0492bd948240..357c3a885880 100644
--- a/external/skia/share-grcontext.patch.1
+++ b/external/skia/share-grcontext.patch.1
@@ -426,7 +426,7 @@ index 2db9e79ae6..7950dc159b 100644
      void swapBuffers() override;
  
 -    bool isValid() override { return fDevice != VK_NULL_HANDLE; }
-+    bool isValid() override { return fShared->fDevice != VK_NULL_HANDLE; }
++    bool isValid() override { return fShared && fShared->fDevice != VK_NULL_HANDLE; }
  
      void resize(int w, int h) override {
          this->createSwapchain(w, h, fDisplayParams);
diff --git a/include/vcl/skia/SkiaHelper.hxx b/include/vcl/skia/SkiaHelper.hxx
index 77e9fab5797a..d27cffd650f3 100644
--- a/include/vcl/skia/SkiaHelper.hxx
+++ b/include/vcl/skia/SkiaHelper.hxx
@@ -12,6 +12,8 @@
 
 #include <vcl/dllapi.h>
 
+#include <config_features.h>
+
 // All member functions static and VCL_DLLPUBLIC. Basically a glorified namespace.
 struct VCL_DLLPUBLIC SkiaHelper
 {
@@ -19,6 +21,17 @@ struct VCL_DLLPUBLIC SkiaHelper
 
 public:
     static bool isVCLSkiaEnabled();
+
+#if HAVE_FEATURE_SKIA
+    // Which Skia backend to use.
+    enum RenderMethod
+    {
+        RenderRaster,
+        RenderVulkan
+    };
+    static RenderMethod renderMethodToUse();
+    static void disableRenderMethod(RenderMethod method);
+#endif
 };
 
 #endif
diff --git a/vcl/inc/skia/gdiimpl.hxx b/vcl/inc/skia/gdiimpl.hxx
index 195b5d877eed..7c41e98a91b5 100644
--- a/vcl/inc/skia/gdiimpl.hxx
+++ b/vcl/inc/skia/gdiimpl.hxx
@@ -241,14 +241,6 @@ protected:
     SkScalar toSkX(long x) const { return mIsGPU ? x + 0.5 : x; }
     SkScalar toSkY(long y) const { return mIsGPU ? y + 0.5 : y; }
 
-    // Which Skia backend to use.
-    enum RenderMethod
-    {
-        RenderRaster,
-        RenderVulkan
-    };
-    static RenderMethod renderMethodToUse();
-
 #ifdef DBG_UTIL
     void prefillSurface();
 #endif
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index bc643bd546b1..810e8f9b0b11 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -13,8 +13,6 @@
 #include <desktop/crashreport.hxx>
 #include <officecfg/Office/Common.hxx>
 
-#include <config_features.h>
-
 #if !HAVE_FEATURE_SKIA
 bool SkiaHelper::isVCLSkiaEnabled() { return false; }
 
@@ -86,6 +84,37 @@ bool SkiaHelper::isVCLSkiaEnabled()
     return bRet;
 }
 
+static SkiaHelper::RenderMethod methodToUse = SkiaHelper::RenderRaster;
+
+static bool initRenderMethodToUse()
+{
+    if (const char* env = getenv("SAL_SKIA"))
+    {
+        if (strcmp(env, "raster") == 0)
+        {
+            methodToUse = SkiaHelper::RenderRaster;
+            return true;
+        }
+    }
+    methodToUse = SkiaHelper::RenderVulkan;
+    return true;
+}
+
+SkiaHelper::RenderMethod SkiaHelper::renderMethodToUse()
+{
+    static bool methodToUseInited = initRenderMethodToUse();
+    (void)methodToUseInited; // Used just to ensure thread-safe one-time init.
+    return methodToUse;
+}
+
+void SkiaHelper::disableRenderMethod(RenderMethod method)
+{
+    if (renderMethodToUse() != method)
+        return;
+    // Choose a fallback, right now always raster.
+    methodToUse = RenderRaster;
+}
+
 #endif // HAVE_FEATURE_SKIA
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index ac47d254cc03..cb2beb2667a0 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -24,6 +24,7 @@
 #include <vcl/idle.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/lazydelete.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
 
 #include <SkCanvas.h>
 #include <SkPath.h>
@@ -168,20 +169,6 @@ public:
     }
 };
 
-SkiaSalGraphicsImpl::RenderMethod SkiaSalGraphicsImpl::renderMethodToUse()
-{
-    static RenderMethod method = [] {
-        if (const char* env = getenv("SAL_SKIA"))
-        {
-            if (strcmp(env, "raster") == 0)
-                return RenderRaster;
-        }
-        return RenderVulkan;
-    }();
-
-    return method;
-}
-
 SkiaSalGraphicsImpl::SkiaSalGraphicsImpl(SalGraphics& rParent, SalGeometryProvider* pProvider)
     : mParent(rParent)
     , mProvider(pProvider)
@@ -226,9 +213,9 @@ void SkiaSalGraphicsImpl::createOffscreenSurface()
 {
     assert(isOffscreen());
     destroySurface();
-    switch (renderMethodToUse())
+    switch (SkiaHelper::renderMethodToUse())
     {
-        case RenderVulkan:
+        case SkiaHelper::RenderVulkan:
         {
             mOffscreenGrContext = sk_app::VulkanWindowContext::getSharedGrContext();
             GrContext* grContext = mOffscreenGrContext.getGrContext();
@@ -260,7 +247,8 @@ void SkiaSalGraphicsImpl::createOffscreenSurface()
 #endif
                 return;
             }
-            SAL_WARN("vcl.skia", "cannot create Vulkan GPU offscreen surface");
+            SAL_WARN("vcl.skia", "cannot create Vulkan offscreen GPU surface, disabling Vulkan");
+            SkiaHelper::disableRenderMethod(SkiaHelper::RenderVulkan);
             break;
         }
         default:
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 8f30c3486dac..cba8bed29355 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -9,12 +9,13 @@
 
 #include <skia/win/gdiimpl.hxx>
 
-#include <tools/sk_app/win/WindowContextFactory_win.h>
-#include <tools/sk_app/WindowContext.h>
 #include <win/saldata.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
 
 #include <SkColorFilter.h>
 #include <SkPixelRef.h>
+#include <tools/sk_app/win/WindowContextFactory_win.h>
+#include <tools/sk_app/WindowContext.h>
 
 WinSkiaSalGraphicsImpl::WinSkiaSalGraphicsImpl(WinSalGraphics& rGraphics,
                                                SalGeometryProvider* mpProvider)
@@ -52,22 +53,30 @@ void WinSkiaSalGraphicsImpl::createSurface()
     // valid here, but better check.
     assert(GetWidth() != 0 && GetHeight() != 0);
     sk_app::DisplayParams displayParams;
-    switch (renderMethodToUse())
+    switch (SkiaHelper::renderMethodToUse())
     {
-        case RenderRaster:
+        case SkiaHelper::RenderRaster:
             mWindowContext = sk_app::window_context_factory::MakeRasterForWin(mWinParent.gethWnd(),
                                                                               displayParams);
+            assert(SkToBool(mWindowContext));
+            mSurface = mWindowContext->getBackbufferSurface();
+            assert(mSurface.get());

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list