diff options
Diffstat (limited to 'vcl/skia')
-rw-r--r-- | vcl/skia/SkiaHelper.cxx | 32 | ||||
-rw-r--r-- | vcl/skia/gdiimpl.cxx | 21 | ||||
-rw-r--r-- | vcl/skia/osx/gdiimpl.cxx | 10 | ||||
-rw-r--r-- | vcl/skia/salbmp.cxx | 4 | ||||
-rw-r--r-- | vcl/skia/win/gdiimpl.cxx | 14 | ||||
-rw-r--r-- | vcl/skia/x11/gdiimpl.cxx | 18 | ||||
-rw-r--r-- | vcl/skia/x11/salvd.cxx | 20 |
7 files changed, 91 insertions, 28 deletions
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx index bd9c5a2c21b2..fdff5e464380 100644 --- a/vcl/skia/SkiaHelper.cxx +++ b/vcl/skia/SkiaHelper.cxx @@ -42,13 +42,16 @@ 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> #include <SkPaint.h> #include <SkSurface.h> #include <SkGraphics.h> -#include <GrDirectContext.h> +#include <ganesh/GrDirectContext.h> #include <SkRuntimeEffect.h> #include <SkStream.h> #include <SkTileMode.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; diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index 579a2d98d7fa..de46b67ef073 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -37,7 +37,7 @@ #include <SkRegion.h> #include <SkPathEffect.h> #include <SkDashPathEffect.h> -#include <GrBackendSurface.h> +#include <ganesh/GrBackendSurface.h> #include <SkTextBlob.h> #include <SkRSXform.h> @@ -245,8 +245,14 @@ public: : Idle(get_debug_name(pGraphics)) , mpGraphics(pGraphics) { +#ifdef MACOSX + // tdf#165277 Skia needs to flush immediately before POST_PAINT + // tasks on macOS + SetPriority(TaskPriority::SKIA_FLUSH); +#else // We don't want to be swapping before we've painted. SetPriority(TaskPriority::POST_PAINT); +#endif } #ifndef NDEBUG virtual ~SkiaFlushIdle() { free(debugname); } @@ -273,11 +279,12 @@ public: // tdf#157312 and tdf#163945 Lower Skia flush timer priority on macOS // On macOS, flushing with Skia/Metal is noticeably slower than // with Skia/Raster. So lower the flush timer priority to - // TaskPriority::POST_PAINT so that the flush timer runs less + // TaskPriority::SKIA_FLUSH so that the flush timer runs less // frequently but each pass copies a more up-to-date offscreen // surface. - // TODO: fix tdf#163734 on macOS - SetPriority(TaskPriority::POST_PAINT); + // tdf#165277 Skia needs to flush immediately before POST_PAINT + // tasks on macOS + SetPriority(TaskPriority::SKIA_FLUSH); #else SetPriority(TaskPriority::HIGHEST); #endif @@ -316,7 +323,13 @@ void SkiaSalGraphicsImpl::createSurface() // We don't want to be swapping before we've painted. mFlush->Stop(); +#ifdef MACOSX + // tdf#165277 Skia needs to flush immediately before POST_PAINT + // tasks on macOS + mFlush->SetPriority(TaskPriority::SKIA_FLUSH); +#else mFlush->SetPriority(TaskPriority::POST_PAINT); +#endif } void SkiaSalGraphicsImpl::createWindowSurface(bool forceRaster) diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx index 7fa95e8d9fab..8043fb2e2b72 100644 --- a/vcl/skia/osx/gdiimpl.cxx +++ b/vcl/skia/osx/gdiimpl.cxx @@ -72,8 +72,8 @@ void AquaSkiaSalGraphicsImpl::createWindowSurfaceInternal(bool forceRaster) assert(!mWindowContext); assert(!mSurface); SkiaZone zone; - skwindow::DisplayParams displayParams; - displayParams.fColorType = kN32_SkColorType; + skwindow::DisplayParamsBuilder displayParams; + displayParams.colorType(kN32_SkColorType); skwindow::MacWindowInfo macWindow; macWindow.fMainView = mrShared.mpFrame->mpNSView; mScaling = getWindowScaling(); @@ -86,7 +86,7 @@ void AquaSkiaSalGraphicsImpl::createWindowSurfaceInternal(bool forceRaster) mSurface = createSkSurface(GetWidth() * mScaling, GetHeight() * mScaling); break; case RenderMetal: - mWindowContext = skwindow::MakeGaneshMetalForMac(macWindow, displayParams); + mWindowContext = skwindow::MakeGaneshMetalForMac(macWindow, displayParams.build()); // Like with other GPU contexts, create a proxy offscreen surface (see // flushSurfaceToWindowContext()). Here it's additionally needed because // it appears that Metal surfaces cannot be read from, which would break things @@ -411,10 +411,10 @@ namespace { std::unique_ptr<skwindow::WindowContext> createMetalWindowContext(bool /*temporary*/) { - skwindow::DisplayParams displayParams; + skwindow::DisplayParamsBuilder displayParams; skwindow::MacWindowInfo macWindow; macWindow.fMainView = nullptr; - return skwindow::MakeGaneshMetalForMac(macWindow, displayParams); + return skwindow::MakeGaneshMetalForMac(macWindow, displayParams.build()); } } diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx index ca1bcf863241..6dee8b0b5252 100644 --- a/vcl/skia/salbmp.cxx +++ b/vcl/skia/salbmp.cxx @@ -312,6 +312,7 @@ BitmapBuffer* SkiaSalBitmap::AcquireBuffer(BitmapAccessMode nMode) default: abort(); } + buffer->meDirection = ScanlineDirection::TopDown; // Refcount all read/write accesses, to catch problems with existing accesses while // a bitmap changes, and also to detect when we can free mBuffer if wanted. // Write mode implies also reading. It would be probably a good idea to count even @@ -1146,10 +1147,11 @@ void SkiaSalBitmap::PerformErase() if (!ImplFastEraseBitmap(*bitmapBuffer, fastColor)) { FncSetPixel setPixel = BitmapReadAccess::SetPixelFunction(bitmapBuffer->meFormat); + assert(bitmapBuffer->meDirection == ScanlineDirection::TopDown); // Set first scanline, copy to others. Scanline scanline = bitmapBuffer->mpBits; for (tools::Long x = 0; x < bitmapBuffer->mnWidth; ++x) - setPixel(scanline, x, mEraseColor, bitmapBuffer->maColorMask); + setPixel(scanline, x, mEraseColor); for (tools::Long y = 1; y < bitmapBuffer->mnHeight; ++y) memcpy(scanline + y * bitmapBuffer->mnScanlineSize, scanline, bitmapBuffer->mnScanlineSize); diff --git a/vcl/skia/win/gdiimpl.cxx b/vcl/skia/win/gdiimpl.cxx index 8de57dba2b89..8ce4c33e57d0 100644 --- a/vcl/skia/win/gdiimpl.cxx +++ b/vcl/skia/win/gdiimpl.cxx @@ -104,18 +104,20 @@ void WinSkiaSalGraphicsImpl::createWindowSurfaceInternal(bool forceRaster) assert(!mWindowContext); assert(!mSurface); SkiaZone zone; - skwindow::DisplayParams displayParams; assert(GetWidth() > 0 && GetHeight() > 0); - displayParams.fSurfaceProps = *surfaceProps(); + skwindow::DisplayParamsBuilder aDispParamBuilder; + aDispParamBuilder.surfaceProps(*surfaceProps()); switch (forceRaster ? RenderRaster : renderMethodToUse()) { case RenderRaster: - mWindowContext = skwindow::MakeRasterForWin(mWinParent.gethWnd(), displayParams); + mWindowContext + = skwindow::MakeRasterForWin(mWinParent.gethWnd(), aDispParamBuilder.build()); if (mWindowContext) mSurface = mWindowContext->getBackbufferSurface(); break; case RenderVulkan: - mWindowContext = skwindow::MakeVulkanForWin(mWinParent.gethWnd(), displayParams); + mWindowContext + = skwindow::MakeVulkanForWin(mWinParent.gethWnd(), aDispParamBuilder.build()); // See flushSurfaceToWindowContext(). if (mWindowContext) mSurface = createSkSurface(GetWidth(), GetHeight()); @@ -416,8 +418,8 @@ namespace std::unique_ptr<skwindow::WindowContext> createVulkanWindowContext(bool /*temporary*/) { SkiaZone zone; - skwindow::DisplayParams displayParams; - return skwindow::MakeVulkanForWin(nullptr, displayParams); + skwindow::DisplayParamsBuilder displayParams; + return skwindow::MakeVulkanForWin(nullptr, displayParams.build()); } } diff --git a/vcl/skia/x11/gdiimpl.cxx b/vcl/skia/x11/gdiimpl.cxx index 34df45fa7d09..103aa7329c6a 100644 --- a/vcl/skia/x11/gdiimpl.cxx +++ b/vcl/skia/x11/gdiimpl.cxx @@ -67,14 +67,14 @@ X11SkiaSalGraphicsImpl::createWindowContext(Display* display, Drawable drawable, RenderMethod renderMethod, bool temporary) { SkiaZone zone; - skwindow::DisplayParams displayParams; - displayParams.fColorType = kN32_SkColorType; + skwindow::DisplayParamsBuilder displayParamsBuilder; + displayParamsBuilder.colorType(kN32_SkColorType); #if defined LINUX // WORKAROUND: VSync causes freezes that can even temporarily freeze the entire desktop. // This happens even with the latest 450.66 drivers despite them claiming a fix for vsync. // https://forums.developer.nvidia.com/t/hangs-freezes-when-vulkan-v-sync-vk-present-mode-fifo-khr-is-enabled/67751 if (getVendor() == DriverBlocklist::VendorNVIDIA) - displayParams.fDisableVsync = true; + displayParamsBuilder.disableVsync(true); #endif skwindow::XlibWindowInfo winInfo; assert(display); @@ -103,17 +103,19 @@ X11SkiaSalGraphicsImpl::createWindowContext(Display* display, Drawable drawable, switch (renderMethod) { case RenderRaster: + { // Make sure we ask for color type that matches the X11 visual. If red mask // is larger value than blue mask, then on little endian this means blue is first. // This should also preferably match SK_R32_SHIFT set in config_skia.h, as that // improves performance, the common setup seems to be BGRA (possibly because of // choosing OpenGL-capable visual). - displayParams.fColorType - = (visual->red_mask > visual->blue_mask ? kBGRA_8888_SkColorType - : kRGBA_8888_SkColorType); - return skwindow::MakeRasterForXlib(winInfo, displayParams); + displayParamsBuilder.colorType(visual->red_mask > visual->blue_mask + ? kBGRA_8888_SkColorType + : kRGBA_8888_SkColorType); + return skwindow::MakeRasterForXlib(winInfo, displayParamsBuilder.build()); + } case RenderVulkan: - return skwindow::MakeGaneshVulkanForXlib(winInfo, displayParams); + return skwindow::MakeGaneshVulkanForXlib(winInfo, displayParamsBuilder.build()); case RenderMetal: abort(); break; diff --git a/vcl/skia/x11/salvd.cxx b/vcl/skia/x11/salvd.cxx index 8979f36d32b3..c128bae50413 100644 --- a/vcl/skia/x11/salvd.cxx +++ b/vcl/skia/x11/salvd.cxx @@ -30,7 +30,7 @@ void X11SalGraphics::Init(X11SkiaSalVirtualDevice* pDevice) } X11SkiaSalVirtualDevice::X11SkiaSalVirtualDevice(const SalGraphics& rGraphics, tools::Long nDX, - tools::Long nDY, const SystemGraphicsData* pData, + tools::Long nDY, std::unique_ptr<X11SalGraphics> pNewGraphics) : mpGraphics(std::move(pNewGraphics)) , mbGraphics(false) @@ -38,9 +38,23 @@ X11SkiaSalVirtualDevice::X11SkiaSalVirtualDevice(const SalGraphics& rGraphics, t { assert(mpGraphics); + mpDisplay = vcl_sal::getSalDisplay(GetGenericUnixSalData()); + mnXScreen = static_cast<const X11SalGraphics&>(rGraphics).GetScreenNumber(); + mnWidth = nDX; + mnHeight = nDY; + mpGraphics->Init(this); +} + +X11SkiaSalVirtualDevice::X11SkiaSalVirtualDevice(const SalGraphics& rGraphics, tools::Long nDX, + tools::Long nDY, + const SystemGraphicsData& /*rData*/, + std::unique_ptr<X11SalGraphics> pNewGraphics) + : mpGraphics(std::move(pNewGraphics)) + , mbGraphics(false) + , mnXScreen(0) +{ // TODO Check where a VirtualDevice is created from SystemGraphicsData - assert(pData == nullptr); - (void)pData; + assert(false); mpDisplay = vcl_sal::getSalDisplay(GetGenericUnixSalData()); mnXScreen = static_cast<const X11SalGraphics&>(rGraphics).GetScreenNumber(); |