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

Luboš Luňák (via logerrit) logerrit at kemper.freedesktop.org
Wed Mar 3 10:08:00 UTC 2021


 vcl/inc/skia/utils.hxx       |    9 ++++++++-
 vcl/qa/cppunit/skia/skia.cxx |   20 ++++++++++++++++++++
 vcl/skia/gdiimpl.cxx         |   31 +++++++++++++++++++++++++++++--
 3 files changed, 57 insertions(+), 3 deletions(-)

New commits:
commit d4159496056741302718ac1e85f450985fd11580
Author:     Luboš Luňák <l.lunak at collabora.com>
AuthorDate: Mon Mar 1 19:38:42 2021 +0100
Commit:     Luboš Luňák <l.lunak at collabora.com>
CommitDate: Wed Mar 3 11:07:16 2021 +0100

    do not smoothscale if not changing pixel size
    
    Flipping or rotating are simple operations in this regard. This saves
    some CPU time in raster mode, and for the upcoming chrome/m90 release
    this also prevents a failure in
    BackendTest::testDrawTransformedBitmapExAlpha() when rotating.
    
    Change-Id: I51890ac19b0bd5312fcf9c7bb8fe519dc10dc007
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111771
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lunak at collabora.com>

diff --git a/vcl/inc/skia/utils.hxx b/vcl/inc/skia/utils.hxx
index 7da858ab1fff..b5412e9f9479 100644
--- a/vcl/inc/skia/utils.hxx
+++ b/vcl/inc/skia/utils.hxx
@@ -26,6 +26,7 @@
 #include <driverblocklist.hxx>
 
 #include <SkRegion.h>
+#include <SkSurface.h>
 #include <tools/sk_app/VulkanWindowContext.h>
 
 namespace SkiaHelper
@@ -94,7 +95,13 @@ inline DriverBlocklist::DeviceVendor getVendor()
     return DriverBlocklist::GetVendorFromId(vendorId);
 }
 
-} // namespace
+} // namespace SkiaHelper
+
+// For unittests.
+namespace SkiaTests
+{
+VCL_DLLPUBLIC bool matrixNeedsHighQuality(const SkMatrix& matrix);
+}
 
 template <typename charT, typename traits>
 inline std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& stream,
diff --git a/vcl/qa/cppunit/skia/skia.cxx b/vcl/qa/cppunit/skia/skia.cxx
index a84cb7d19907..6b18967f0590 100644
--- a/vcl/qa/cppunit/skia/skia.cxx
+++ b/vcl/qa/cppunit/skia/skia.cxx
@@ -17,6 +17,7 @@
 #include <vcl/skia/SkiaHelper.hxx>
 
 #include <skia/salbmp.hxx>
+#include <skia/utils.hxx>
 #include <bitmap/BitmapWriteAccess.hxx>
 
 // This tests backends that use Skia (i.e. intentionally not the svp one, which is the default.)
@@ -37,6 +38,7 @@ public:
     void testInterpretAs8Bit();
     void testAlphaBlendWith();
     void testBitmapCopyOnWrite();
+    void testMatrixQuality();
     void testTdf137329();
 
     CPPUNIT_TEST_SUITE(SkiaTest);
@@ -45,6 +47,7 @@ public:
     CPPUNIT_TEST(testInterpretAs8Bit);
     CPPUNIT_TEST(testAlphaBlendWith);
     CPPUNIT_TEST(testBitmapCopyOnWrite);
+    CPPUNIT_TEST(testMatrixQuality);
     CPPUNIT_TEST(testTdf137329);
     CPPUNIT_TEST_SUITE_END();
 
@@ -307,8 +310,25 @@ void SkiaTest::testBitmapCopyOnWrite()
     CPPUNIT_ASSERT(bitmap.unittestGetAlphaImage() != oldAlphaImage);
 }
 
+void SkiaTest::testMatrixQuality()
+{
+    if (!SkiaHelper::isVCLSkiaEnabled())
+        return;
+    // Not changing the size (but possibly rotated/flipped) does not need high quality transformations.
+    CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix()));
+    CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(90)));
+    CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(180)));
+    CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(270)));
+    CPPUNIT_ASSERT(!SkiaTests::matrixNeedsHighQuality(SkMatrix::Scale(1, -1)));
+    CPPUNIT_ASSERT(SkiaTests::matrixNeedsHighQuality(SkMatrix::Scale(0, -1)));
+    CPPUNIT_ASSERT(SkiaTests::matrixNeedsHighQuality(SkMatrix::Scale(2, 1)));
+    CPPUNIT_ASSERT(SkiaTests::matrixNeedsHighQuality(SkMatrix::RotateDeg(89)));
+}
+
 void SkiaTest::testTdf137329()
 {
+    if (!SkiaHelper::isVCLSkiaEnabled())
+        return;
     // Draw a filled polygon in the entire device, with AA enabled.
     // All pixels in the device should be black, even those at edges (i.e. not affected by AA).
     ScopedVclPtr<VirtualDevice> device = VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT);
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index d8ddf48536c0..c511b2ef2f45 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -1766,6 +1766,33 @@ bool SkiaSalGraphicsImpl::hasFastDrawTransformedBitmap() const
     return true;
 }
 
+// Whether applying matrix needs image smoothing for the transformation.
+static bool matrixNeedsHighQuality(const SkMatrix& matrix)
+{
+    if (matrix.isIdentity())
+        return false;
+    if (matrix.isScaleTranslate())
+    {
+        if (abs(matrix.getScaleX()) == 1 && abs(matrix.getScaleY()) == 1)
+            return false; // Only at most flipping and keeping the size.
+        return true;
+    }
+    assert(!matrix.hasPerspective()); // we do not use this
+    if (matrix.getScaleX() == 0 && matrix.getScaleY() == 0)
+    {
+        // Rotating 90 or 270 degrees while keeping the size.
+        if ((matrix.getSkewX() == 1 && matrix.getSkewY() == -1)
+            || (matrix.getSkewX() == -1 && matrix.getSkewY() == 1))
+            return false;
+    }
+    return true;
+}
+
+namespace SkiaTests
+{
+bool matrixNeedsHighQuality(const SkMatrix& matrix) { return ::matrixNeedsHighQuality(matrix); }
+}
+
 bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
                                                 const basegfx::B2DPoint& rX,
                                                 const basegfx::B2DPoint& rY,
@@ -1816,7 +1843,7 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
         SkAutoCanvasRestore autoRestore(canvas, true);
         canvas->concat(matrix);
         SkPaint paint;
-        if (!matrix.isTranslate())
+        if (matrixNeedsHighQuality(matrix))
             paint.setFilterQuality(kHigh_SkFilterQuality);
         if (fAlpha == 1.0)
             canvas->drawImage(imageToDraw, 0, 0, &paint);
@@ -1842,7 +1869,7 @@ bool SkiaSalGraphicsImpl::drawTransformedBitmap(const basegfx::B2DPoint& rNull,
         SkAutoCanvasRestore autoRestore(canvas, true);
         canvas->concat(matrix);
         SkPaint paint;
-        if (!matrix.isTranslate())
+        if (matrixNeedsHighQuality(matrix))
             paint.setFilterQuality(kHigh_SkFilterQuality);
         if (pSkiaAlphaBitmap)
         {


More information about the Libreoffice-commits mailing list