vcl/skia/gdiimpl.cxx | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-)
New commits: commit ecf58d6e961d88a7e951988c3c3fbcdc24860bab Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Thu Apr 16 14:49:54 2020 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Thu Apr 16 16:39:52 2020 +0200 workaround for intel Skia invert() problem (tdf#130430) Change-Id: I02c8cd7af2c35e8631932e3928d63c96dc0db255 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/92368 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx index e20d63018747..b4bda610e1b6 100644 --- a/vcl/skia/gdiimpl.cxx +++ b/vcl/skia/gdiimpl.cxx @@ -1105,6 +1105,12 @@ void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFl { preDraw(); SAL_INFO("vcl.skia.trace", "invert(" << this << "): " << rPoly << ":" << int(eFlags)); + // Intel Vulkan drivers (up to current 0.401.3889) have a problem + // with SkBlendMode::kDifference(?) and surfaces wider than 1024 pixels, resulting + // in drawing errors. Work that around by fetching the relevant part of the surface + // and drawing using CPU. + bool intelHack + = (isGPU() && SkiaHelper::getVendor() == DriverBlocklist::VendorIntel && !mXorMode); // TrackFrame just inverts a dashed path around the polygon if (eFlags == SalInvert::TrackFrame) { @@ -1123,8 +1129,21 @@ void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFl aPaint.setPathEffect(SkDashPathEffect::Make(intervals, SK_ARRAY_COUNT(intervals), 0)); aPaint.setColor(SkColorSetARGB(255, 255, 255, 255)); aPaint.setBlendMode(SkBlendMode::kDifference); - - getDrawCanvas()->drawPath(aPath, aPaint); + if (!intelHack) + getDrawCanvas()->drawPath(aPath, aPaint); + else + { + SkRect area; + aPath.getBounds().roundOut(&area); + SkRect size = SkRect::MakeWH(area.width(), area.height()); + sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(area.width(), area.height()); + SkPaint copy; + copy.setBlendMode(SkBlendMode::kSrc); + surface->getCanvas()->drawImageRect(mSurface->makeImageSnapshot(), area, size, ©); + aPath.offset(-area.x(), -area.y()); + surface->getCanvas()->drawPath(aPath, aPaint); + getDrawCanvas()->drawImageRect(surface->makeImageSnapshot(), size, area, ©); + } if (mXorMode) // limit xor area update mXorExtents = aPath.getBounds(); } @@ -1159,8 +1178,21 @@ void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFl // as the polygon (usually rectangle) aPaint.setShader(aBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat)); } - - getDrawCanvas()->drawPath(aPath, aPaint); + if (!intelHack) + getDrawCanvas()->drawPath(aPath, aPaint); + else + { + SkRect area; + aPath.getBounds().roundOut(&area); + SkRect size = SkRect::MakeWH(area.width(), area.height()); + sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(area.width(), area.height()); + SkPaint copy; + copy.setBlendMode(SkBlendMode::kSrc); + surface->getCanvas()->drawImageRect(mSurface->makeImageSnapshot(), area, size, ©); + aPath.offset(-area.x(), -area.y()); + surface->getCanvas()->drawPath(aPath, aPaint); + getDrawCanvas()->drawImageRect(surface->makeImageSnapshot(), size, area, ©); + } if (mXorMode) // limit xor area update mXorExtents = aPath.getBounds(); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits