summaryrefslogtreecommitdiff
path: root/vcl/skia
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/skia')
-rw-r--r--vcl/skia/SkiaHelper.cxx32
-rw-r--r--vcl/skia/gdiimpl.cxx21
-rw-r--r--vcl/skia/osx/gdiimpl.cxx10
-rw-r--r--vcl/skia/salbmp.cxx4
-rw-r--r--vcl/skia/win/gdiimpl.cxx14
-rw-r--r--vcl/skia/x11/gdiimpl.cxx18
-rw-r--r--vcl/skia/x11/salvd.cxx20
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();