[Libreoffice-commits] core.git: vcl/skia

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Thu Apr 16 14:40:20 UTC 2020


 vcl/skia/gdiimpl.cxx |   40 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 36 insertions(+), 4 deletions(-)

New commits:
commit ecf58d6e961d88a7e951988c3c3fbcdc24860bab
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Thu Apr 16 14:49:54 2020 +0200
Commit:     Luboš Luňák <l.lunak at 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.lunak at 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, &copy);
+            aPath.offset(-area.x(), -area.y());
+            surface->getCanvas()->drawPath(aPath, aPaint);
+            getDrawCanvas()->drawImageRect(surface->makeImageSnapshot(), size, area, &copy);
+        }
         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, &copy);
+            aPath.offset(-area.x(), -area.y());
+            surface->getCanvas()->drawPath(aPath, aPaint);
+            getDrawCanvas()->drawImageRect(surface->makeImageSnapshot(), size, area, &copy);
+        }
         if (mXorMode) // limit xor area update
             mXorExtents = aPath.getBounds();
     }


More information about the Libreoffice-commits mailing list