[Libreoffice-commits] core.git: vcl/inc vcl/skia vcl/unx vcl/win

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Thu Mar 12 12:04:36 UTC 2020


 vcl/inc/skia/utils.hxx          |    5 +++--
 vcl/inc/skia/win/gdiimpl.hxx    |    2 ++
 vcl/inc/skia/x11/gdiimpl.hxx    |    2 ++
 vcl/skia/SkiaHelper.cxx         |   25 ++++++++++++++++++++++---
 vcl/skia/win/gdiimpl.cxx        |    8 ++------
 vcl/skia/x11/gdiimpl.cxx        |    9 +--------
 vcl/unx/generic/app/salinst.cxx |    6 ++++++
 vcl/win/app/salinst.cxx         |    3 +++
 8 files changed, 41 insertions(+), 19 deletions(-)

New commits:
commit a3d3e076def075f0a5bced48d89ca0d989a2467c
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Mar 12 12:04:08 2020 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Thu Mar 12 13:04:03 2020 +0100

    rework Skia setup
    
    Calls to SkiaHelper::isVCLSkiaEnabled() may be done from many places,
    even if LO uses a VCL plugin that doesn't use Skia, which leads
    to the Skia code not being prepared properly (and crashing/asserting).
    So make the SalInstance of those relevant VCL plugins call a setup
    function that is required for Skia actually getting enabled.
    Avoids crashes/asserts in the About dialog if the Skia UI checkbox
    is enabled but e.g. the KF5 VCL plugin is actually used.
    
    Change-Id: Ib56a5f32e88bd130a4c564031313f85e99898ba7
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/90376
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/inc/skia/utils.hxx b/vcl/inc/skia/utils.hxx
index cd6732a57a44..0a93b3b16863 100644
--- a/vcl/inc/skia/utils.hxx
+++ b/vcl/inc/skia/utils.hxx
@@ -43,9 +43,10 @@ inline sk_sp<SkSurface> createSkSurface(const Size& size, SkColorType type = kN3
     return createSkSurface(size.Width(), size.Height(), type);
 }
 
-/// This function is in the X11/Win backend libs, but needs to be used in SkiaHelper in the vcl lib.
+// Must be called in any VCL backend before any Skia functionality is used.
+// If not set, Skia will be disabled.
 VCL_DLLPUBLIC void
-    setCreateVulkanWindowContext(std::unique_ptr<sk_app::WindowContext> (*function)());
+    prepareSkia(std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContext)());
 
 #ifdef DBG_UTIL
 void prefillSurface(sk_sp<SkSurface>& surface);
diff --git a/vcl/inc/skia/win/gdiimpl.hxx b/vcl/inc/skia/win/gdiimpl.hxx
index 5e8aee2e4523..676e743151e7 100644
--- a/vcl/inc/skia/win/gdiimpl.hxx
+++ b/vcl/inc/skia/win/gdiimpl.hxx
@@ -81,6 +81,8 @@ public:
     virtual void DeferredTextDraw(const CompatibleDC::Texture* pTexture, Color nMaskColor,
                                   const SalTwoRect& rPosAry) override;
 
+    static void prepareSkia();
+
 protected:
     virtual void createWindowContext() override;
     virtual void performFlush() override;
diff --git a/vcl/inc/skia/x11/gdiimpl.hxx b/vcl/inc/skia/x11/gdiimpl.hxx
index 8cedf23d3e1b..acfe9f7ce192 100644
--- a/vcl/inc/skia/x11/gdiimpl.hxx
+++ b/vcl/inc/skia/x11/gdiimpl.hxx
@@ -31,6 +31,8 @@ public:
     virtual void DeInit() override;
     virtual void freeResources() override;
 
+    static void prepareSkia();
+
 private:
     virtual void createWindowContext() override;
     virtual void performFlush() override;
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index 50402cccf47c..4b21e6740603 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -102,7 +102,16 @@ static void checkDeviceBlacklisted(bool blockDisable = false)
     }
 }
 
-static bool supportsVCLSkia() { return !getenv("SAL_DISABLESKIA"); }
+static bool skiaSupportedByBackend = false;
+static bool supportsVCLSkia()
+{
+    if (!skiaSupportedByBackend)
+    {
+        SAL_INFO("vcl.skia", "Skia not supported by VCL backend, disabling");
+        return false;
+    }
+    return getenv("SAL_DISABLESKIA") == nullptr;
+}
 
 bool isVCLSkiaEnabled()
 {
@@ -222,7 +231,7 @@ void disableRenderMethod(RenderMethod method)
 static sk_app::VulkanWindowContext::SharedGrContext* sharedGrContext;
 
 static std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContextFunction)() = nullptr;
-void setCreateVulkanWindowContext(std::unique_ptr<sk_app::WindowContext> (*function)())
+static void setCreateVulkanWindowContext(std::unique_ptr<sk_app::WindowContext> (*function)())
 {
     createVulkanWindowContextFunction = function;
 }
@@ -248,7 +257,8 @@ GrContext* getSharedGrContext()
     if (done)
         return nullptr;
     done = true;
-    assert(createVulkanWindowContextFunction);
+    if (createVulkanWindowContextFunction == nullptr)
+        return nullptr; // not initialized properly (e.g. used from a VCL backend with no Skia support)
     std::unique_ptr<sk_app::WindowContext> tmpContext = createVulkanWindowContextFunction();
     // Set up using the shared context created by the call above, if successful.
     context = sk_app::VulkanWindowContext::getSharedGrContext();
@@ -302,6 +312,15 @@ void cleanup()
     sharedGrContext = nullptr;
 }
 
+// Skia should not be used from VCL backends that do not actually support it, as there will be setup missing.
+// The code here (that is in the vcl lib) needs a function for creating Vulkan context that is
+// usually available only in the backend libs.
+void prepareSkia(std::unique_ptr<sk_app::WindowContext> (*createVulkanWindowContext)())
+{
+    setCreateVulkanWindowContext(createVulkanWindowContext);
+    skiaSupportedByBackend = true;
+}
+
 #ifdef DBG_UTIL
 void prefillSurface(sk_sp<SkSurface>& surface)
 {
diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx
index 3c034856e7aa..84aed4f05b92 100644
--- a/vcl/skia/win/gdiimpl.cxx
+++ b/vcl/skia/win/gdiimpl.cxx
@@ -299,12 +299,8 @@ std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext()
     sk_app::DisplayParams displayParams;
     return sk_app::window_context_factory::MakeVulkanForWin(nullptr, displayParams);
 }
-
-struct SetFunction
-{
-    SetFunction() { SkiaHelper::setCreateVulkanWindowContext(createVulkanWindowContext); }
-};
-SetFunction setFunction;
 }
 
+void WinSkiaSalGraphicsImpl::prepareSkia() { SkiaHelper::prepareSkia(createVulkanWindowContext); }
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx
index c587b143ef69..fe4553814758 100644
--- a/vcl/skia/x11/gdiimpl.cxx
+++ b/vcl/skia/x11/gdiimpl.cxx
@@ -130,13 +130,6 @@ std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext()
         1, SkiaHelper::RenderVulkan);
 }
 
-namespace
-{
-struct SetFunction
-{
-    SetFunction() { SkiaHelper::setCreateVulkanWindowContext(createVulkanWindowContext); }
-};
-SetFunction setFunction;
-}
+void X11SkiaSalGraphicsImpl::prepareSkia() { SkiaHelper::prepareSkia(createVulkanWindowContext); }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/unx/generic/app/salinst.cxx b/vcl/unx/generic/app/salinst.cxx
index bf4a71d5f6fc..20dbeb844dfb 100644
--- a/vcl/unx/generic/app/salinst.cxx
+++ b/vcl/unx/generic/app/salinst.cxx
@@ -35,6 +35,9 @@
 #include <config_features.h>
 #include <vcl/skia/SkiaHelper.hxx>
 #include <config_skia.h>
+#if HAVE_FEATURE_SKIA
+#include <skia/x11/gdiimpl.hxx>
+#endif
 
 // plugin factory function
 extern "C"
@@ -69,6 +72,9 @@ X11SalInstance::X11SalInstance(std::unique_ptr<SalYieldMutex> pMutex)
 {
     ImplSVData* pSVData = ImplGetSVData();
     pSVData->maAppData.mxToolkitName = OUString("x11");
+#if HAVE_FEATURE_SKIA
+    X11SkiaSalGraphicsImpl::prepareSkia();
+#endif
 }
 
 X11SalInstance::~X11SalInstance()
diff --git a/vcl/win/app/salinst.cxx b/vcl/win/app/salinst.cxx
index e97e8cbe4cdc..5a10de216f96 100644
--- a/vcl/win/app/salinst.cxx
+++ b/vcl/win/app/salinst.cxx
@@ -402,6 +402,9 @@ WinSalInstance::WinSalInstance()
 {
     ImplSVData* pSVData = ImplGetSVData();
     pSVData->maAppData.mxToolkitName = OUString("win");
+#if HAVE_FEATURE_SKIA
+    WinSkiaSalGraphicsImpl::prepareSkia();
+#endif
 }
 
 WinSalInstance::~WinSalInstance()


More information about the Libreoffice-commits mailing list