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;