vcl/skia/SkiaHelper.cxx |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

New commits:
commit 1d354e9b5083f0ecdab92dfa6853f3d1ed6f401d
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Sat Feb 8 17:48:57 2025 +0500
Commit:     Christian Lohmaier <lohmaier+libreoff...@googlemail.com>
CommitDate: Mon May 19 19:03:53 2025 +0200

    Related: tdf#164788 Force Skia software rendering after crash in test
    
    The minidumps in the bug give this call stack:
    
      KERNELBASE.dll!RaiseException()
      [Inline Frame] mergedlo.dll!SalAbort(const rtl::OUString &) Line 377
      mergedlo.dll!Application::Abort(const rtl::OUString & rErrorText) Line 300
      mergedlo.dll!desktop::Desktop::Exception(ExceptionCategory nCategory) 
Line 1237
      mergedlo.dll!VCLExceptionSignal_impl(void * __formal, oslSignalInfo * 
pInfo) Line 176
      [Inline Frame] sal3.dll!callSignalHandler(oslSignalInfo *) Line 47
      sal3.dll!`anonymous namespace'::signalHandlerFunction(_EXCEPTION_POINTERS 
* lpEP) Line 141
      KERNELBASE.dll!UnhandledExceptionFilter()
      ntdll.dll!RtlUserThreadStart$filt$0()
      ntdll.dll!__C_specific_handler()
      ntdll.dll!RtlpExecuteHandlerForException()
      ntdll.dll!RtlDispatchException()
      ntdll.dll!KiUserExceptionDispatch()
      skialo.dll!sk_gpu_test::FreeVulkanFeaturesStructs(const 
VkPhysicalDeviceFeatures2 * features) Line 885
      skialo.dll!skwindow::internal::VulkanWindowContext::initializeContext() 
Line 83
      
skialo.dll!skwindow::internal::VulkanWindowContext::VulkanWindowContext(const 
skwindow::DisplayParams & params, std::function<VkSurfaceKHR_T *(VkInstance_T 
*)> createVkSurface, std::function<bool (VkInstance_T *, VkPhysicalDevice_T *, 
unsigned int)> canPresent, void(*)()(*)(VkInstance_T *, const char *) instProc) 
Line 59
      skialo.dll!skwindow::MakeVulkanForWin(HWND__ * hwnd, const 
skwindow::DisplayParams & params) Line 72
      vclplug_winlo.dll!`anonymous namespace'::createVulkanWindowContext(bool 
__formal) Line 571
      [Inline Frame] mergedlo.dll!SkiaHelper::getTemporaryWindowContext() Line 
546
      mergedlo.dll!SkiaHelper::checkDeviceDenylisted(bool blockDisable) Line 253
      mergedlo.dll!SkiaHelper::isVCLSkiaEnabled() Line 408
      vclplug_winlo.dll!WinSalGraphics::WinSalGraphics(WinSalGraphics::Type 
eType, bool bScreen, HWND__ * hWnd, SalGeometryProvider * pProvider) Line 636
      vclplug_winlo.dll!WinSalFrame::AcquireGraphics() Line 1063
      mergedlo.dll!vcl::WindowOutputDevice::AcquireGraphics() Line 838
      mergedlo.dll!vcl::Window::ImplInit(vcl::Window * pParent, __int64 nStyle, 
SystemParentData * pSystemParentData) Line 1100
      mergedlo.dll!ImplBorderWindow::ImplInit(vcl::Window * pParent, __int64 
nStyle, BorderWindowStyle nTypeStyle, SystemParentData * pSystemParentData) 
Line 1566
      [Inline Frame] mergedlo.dll!ImplBorderWindow::{ctor}(vcl::Window *) Line 
1594
      [Inline Frame] 
mergedlo.dll!VclPtrInstance<ImplBorderWindow>::{ctor}(vcl::Window * &) Line 280
      mergedlo.dll!WorkWindow::ImplInit(vcl::Window * pParent, __int64 nStyle, 
SystemParentData * pSystemParentData) Line 51
      [Inline Frame] mergedlo.dll!IntroWindow::{ctor}() Line 35
      mergedlo.dll!`anonymous 
namespace'::SplashScreenWindow::SplashScreenWindow(`anonymous-namespace'::SplashScreen
 * pSplash) Line 125
      [Inline Frame] mergedlo.dll!VclPtr<`anonymous 
namespace'::SplashScreenWindow>::Create(`anonymous-namespace'::SplashScreen * 
&&) Line 129
      [Inline Frame] mergedlo.dll!`anonymous-namespace'::SplashScreen::{ctor}() 
Line 145
      
mergedlo.dll!desktop_SplashScreen_get_implementation(com::sun::star::uno::XComponentContext
 * __formal, const com::sun::star::uno::Sequence<com::sun::star::uno::Any> & 
__formal) Line 616
      [Inline Frame] 
cppuhelper3MSC.dll!std::_Func_class<com::sun::star::uno::XInterface 
*,com::sun::star::uno::XComponentContext 
*,com::sun::star::uno::Sequence<com::sun::star::uno::Any> const 
&>::operator()(com::sun::star::uno::XComponentContext * <_Args_0>, const 
com::sun::star::uno::Sequence<com::sun::star::uno::Any> &) Line 869
      
cppuhelper3MSC.dll!cppuhelper::ServiceManager::Data::Implementation::doCreateInstanceWithArguments(const
 com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
context, const com::sun::star::uno::Sequence<com::sun::star::uno::Any> & 
arguments) Line 717
      
cppuhelper3MSC.dll!cppuhelper::ServiceManager::Data::Implementation::createInstanceWithArguments(const
 com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
context, bool singletonRequest, const 
com::sun::star::uno::Sequence<com::sun::star::uno::Any> & arguments) Line 689
      
cppuhelper3MSC.dll!cppuhelper::ServiceManager::createInstanceWithArgumentsAndContext(const
 rtl::OUString & ServiceSpecifier, const 
com::sun::star::uno::Sequence<com::sun::star::uno::Any> & Arguments, const 
com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> & 
Context) Line 1013
      mergedlo.dll!desktop::Desktop::OpenSplashScreen() Line 2516
      mergedlo.dll!desktop::Desktop::Main() Line 1356
      mergedlo.dll!ImplSVMain() Line 228
      [Inline Frame] mergedlo.dll!SVMain() Line 246
      mergedlo.dll!soffice_main() Line 121
      [Inline Frame] soffice.bin!sal_main() Line 51
      soffice.bin!main(int argc, char * * argv) Line 49
      [Inline Frame] soffice.bin!invoke_main() Line 78
      soffice.bin!__scrt_common_main_seh() Line 288
      kernel32.dll!BaseThreadInitThunk()
      ntdll.dll!RtlUserThreadStart()
    
    The crash happened inside checkDeviceDenylisted. Let's try to wrap
    the dangerous code into a pair of configuration changes: first to
    force software rendering in Skia - this change will stay in case
    the HW check crashes for some reason; and after the check, second
    to restore the original value.
    
    If similar problems can happen also in case of Metal, then it can
    be also done inside the '#ifdef SK_METAL'.
    
    Change-Id: I163a0a16e0edc6b542dfc3e25ee862f38cffa863
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181290
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit 9735a9377b3013943e6a245b5afef57de738a0f6)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185497
    Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com>

diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index bd9c5a2c21b2..b8e9f7a89373 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -42,6 +42,9 @@ bool isAlphaMaskBlendingEnabled() { return false; }
 #include <list>
 #include <o3tl/lru_map.hxx>
 
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+
 #include <SkBitmap.h>
 #include <SkCanvas.h>
 #include <include/codec/SkEncodedImageFormat.h>
@@ -158,6 +161,25 @@ static std::string_view vendorAsString(uint32_t vendor)
     return DriverBlocklist::GetVendorNameFromId(vendor);
 }
 
+// returns old value
+static bool setForceSkiaRaster(bool val)
+{
+    const bool oldValue = 
officecfg::Office::Common::VCL::ForceSkiaRaster::get();
+    if (oldValue != val && 
!officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly())
+    {
+        auto batch(comphelper::ConfigurationChanges::create());
+        officecfg::Office::Common::VCL::ForceSkiaRaster::set(val, batch);
+        batch->commit();
+
+        // make sure the change is written to the configuration
+        if (auto xFlushable{ css::configuration::theDefaultProvider::get(
+                                 comphelper::getProcessComponentContext())
+                                 .query<css::util::XFlushable>() })
+            xFlushable->flush();
+    }
+    return oldValue;
+}
+
 // Note that this function also logs system information about Vulkan.
 static bool isVulkanDenylisted(const VkPhysicalDeviceProperties& props)
 {
@@ -236,6 +258,11 @@ static void checkDeviceDenylisted(bool blockDisable = 
false)
         case RenderVulkan:
         {
 #ifdef SK_VULKAN
+            // Temporarily change config to force software rendering. If the 
following HW check
+            // crashes, this config change will stay active, and will make 
sure to avoid use of
+            // faulty HW/driver on the nest start
+            const bool oldForceSkiaRasterValue = setForceSkiaRaster(true);
+
             // First try if a GrDirectContext already exists.
             std::unique_ptr<skwindow::WindowContext> temporaryWindowContext;
             GrDirectContext* grDirectContext
@@ -268,6 +295,9 @@ static void checkDeviceDenylisted(bool blockDisable = false)
                 disableRenderMethod(RenderVulkan);
                 useRaster = true;
             }
+
+            // The check succeeded; restore the original value
+            setForceSkiaRaster(oldForceSkiaRasterValue);
 #else
             SAL_WARN("vcl.skia", "Vulkan support not built in");
             (void)blockDisable;

Reply via email to