summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2021-03-01 19:38:42 +0100
committerLuboš Luňák <l.lunak@collabora.com>2021-03-03 11:07:16 +0100
commitd4159496056741302718ac1e85f450985fd11580 (patch)
treefd9dfd3b836b9a399c71fc4ad08431abafc7c867 /vcl
parentf5c7ec8c99bd7f831fa5e1b00bd5ac01b1a03a8b (diff)
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@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/skia/utils.hxx9
-rw-r--r--vcl/qa/cppunit/skia/skia.cxx20
-rw-r--r--vcl/skia/gdiimpl.cxx31
3 files changed, 57 insertions, 3 deletions
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)
{