summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-07-28 10:37:16 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-07-29 11:45:31 +0200
commit7a38f1817b0568cfbcda9a91dc86eafaba336871 (patch)
treee2cda33ed6a5c81389a09b42cb1f47c4b8ded864 /vcl
parentdf56a000a165da01a14b2fdf2ad66f371a452ce8 (diff)
optimize a bit more conversions to/from Skia bitmap formats
It turns out this doesn't really matter in practice, since if converting between pixel formats is where time is spent, something higher must be already wrong. But since I've already written this... Change-Id: I25451664d529a9226d2d81b2c424a4f4e5422ad5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99577 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/skia/SkiaHelper.cxx2
-rw-r--r--vcl/skia/salbmp.cxx85
2 files changed, 57 insertions, 30 deletions
diff --git a/vcl/skia/SkiaHelper.cxx b/vcl/skia/SkiaHelper.cxx
index b7d45ad61196..a3df4315b668 100644
--- a/vcl/skia/SkiaHelper.cxx
+++ b/vcl/skia/SkiaHelper.cxx
@@ -38,6 +38,7 @@ bool isVCLSkiaEnabled() { return false; }
#include <SkSurface.h>
#include <SkGraphics.h>
#include <skia_compiler.hxx>
+#include <skia_opts.hxx>
#ifdef DBG_UTIL
#include <fstream>
@@ -239,6 +240,7 @@ bool isVCLSkiaEnabled()
{
bRet = true;
SkGraphics::Init();
+ SkLoOpts::Init();
// don't actually block if denylisted, but log it if enabled, and also get the vendor id
checkDeviceDenylisted(true);
}
diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx
index dda47b46fa25..ed66eddbc3c5 100644
--- a/vcl/skia/salbmp.cxx
+++ b/vcl/skia/salbmp.cxx
@@ -37,6 +37,7 @@
#include <SkSwizzle.h>
#include <SkColorFilter.h>
#include <SkColorMatrix.h>
+#include <skia_opts.hxx>
#include <skia/utils.hxx>
#include <skia/zone.hxx>
@@ -450,7 +451,7 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
#endif
if (!bitmap.installPixels(
SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(), alphaType),
- data.release(), mPixelsSize.Width() * 4,
+ data.release(), mScanlineSize,
[](void* addr, void*) { delete[] static_cast<sal_uInt8*>(addr); }, nullptr))
abort();
bitmap.setImmutable();
@@ -461,13 +462,18 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
std::unique_ptr<uint32_t[]> data(
new uint32_t[mPixelsSize.Height() * mPixelsSize.Width()]);
uint32_t* dest = data.get();
- for (long y = 0; y < mPixelsSize.Height(); ++y)
+ // SkConvertRGBToRGBA() also works as BGR to BGRA (the function extends 3 bytes to 4
+ // by adding 0xFF alpha, so position of B and R doesn't matter).
+ if (mPixelsSize.Width() * 3 == mScanlineSize)
+ SkConvertRGBToRGBA(dest, mBuffer.get(), mPixelsSize.Height() * mPixelsSize.Width());
+ else
{
- const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
- // This also works as BGR to BGRA (the function extends 3 bytes to 4
- // by adding 0xFF alpha, so position of B and R doesn't matter).
- SkExtendRGBToRGBA(dest, src, mPixelsSize.Width());
- dest += mPixelsSize.Width();
+ for (long y = 0; y < mPixelsSize.Height(); ++y)
+ {
+ const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
+ SkConvertRGBToRGBA(dest, src, mPixelsSize.Width());
+ dest += mPixelsSize.Width();
+ }
}
if (!bitmap.installPixels(
SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(),
@@ -486,11 +492,17 @@ SkBitmap SkiaSalBitmap::GetAsSkBitmap() const
std::unique_ptr<uint32_t[]> data(
new uint32_t[mPixelsSize.Height() * mPixelsSize.Width()]);
uint32_t* dest = data.get();
- for (long y = 0; y < mPixelsSize.Height(); ++y)
+ if (mPixelsSize.Width() * 1 == mScanlineSize)
+ SkConvertGrayToRGBA(dest, mBuffer.get(),
+ mPixelsSize.Height() * mPixelsSize.Width());
+ else
{
- const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
- SkExtendGrayToRGBA(dest, src, mPixelsSize.Width());
- dest += mPixelsSize.Width();
+ for (long y = 0; y < mPixelsSize.Height(); ++y)
+ {
+ const sal_uInt8* src = mBuffer.get() + mScanlineSize * y;
+ SkConvertGrayToRGBA(dest, src, mPixelsSize.Width());
+ dest += mPixelsSize.Width();
+ }
}
if (!bitmap.installPixels(
SkImageInfo::MakeS32(mPixelsSize.Width(), mPixelsSize.Height(),
@@ -826,37 +838,50 @@ void SkiaSalBitmap::EnsureBitmapData()
assert(mBuffer != nullptr);
if (mBitCount == 32)
{
- for (long y = 0; y < mSize.Height(); ++y)
+ if (int(bitmap.rowBytes()) == mScanlineSize)
+ memcpy(mBuffer.get(), bitmap.getPixels(), mSize.Height() * mScanlineSize);
+ else
{
- const uint8_t* src = static_cast<uint8_t*>(bitmap.getAddr(0, y));
- sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
- memcpy(dest, src, mScanlineSize);
+ for (long y = 0; y < mSize.Height(); ++y)
+ {
+ const uint8_t* src = static_cast<uint8_t*>(bitmap.getAddr(0, y));
+ sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
+ memcpy(dest, src, mScanlineSize);
+ }
}
}
else if (mBitCount == 24) // non-paletted
{
- for (long y = 0; y < mSize.Height(); ++y)
+ if (int(bitmap.rowBytes()) == mSize.Width() * 4 && mSize.Width() * 3 == mScanlineSize)
{
- const uint8_t* src = static_cast<uint8_t*>(bitmap.getAddr(0, y));
- sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
- for (long x = 0; x < mSize.Width(); ++x)
+ SkConvertRGBAToRGB(mBuffer.get(), bitmap.getAddr32(0, 0),
+ mSize.Height() * mSize.Width());
+ }
+ else
+ {
+ for (long y = 0; y < mSize.Height(); ++y)
{
- *dest++ = *src++;
- *dest++ = *src++;
- *dest++ = *src++;
- ++src; // skip alpha
+ const uint32_t* src = bitmap.getAddr32(0, y);
+ sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
+ SkConvertRGBAToRGB(dest, src, mSize.Width());
}
}
}
else if (mBitCount == 8 && mPalette.IsGreyPalette8Bit())
- {
- for (long y = 0; y < mSize.Height(); ++y)
+ { // no actual data conversion, use one color channel as the gray value
+ if (int(bitmap.rowBytes()) == mSize.Width() * 4 && mSize.Width() * 1 == mScanlineSize)
{
- const uint8_t* src = static_cast<uint8_t*>(bitmap.getAddr(0, y));
- sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
- // no actual data conversion, use one color channel as the gray value
- for (long x = 0; x < mSize.Width(); ++x)
- dest[x] = src[x * 4];
+ SkConvertRGBAToGrayFast(mBuffer.get(), bitmap.getAddr32(0, 0),
+ mSize.Height() * mSize.Width());
+ }
+ else
+ {
+ for (long y = 0; y < mSize.Height(); ++y)
+ {
+ const uint32_t* src = bitmap.getAddr32(0, y);
+ sal_uInt8* dest = mBuffer.get() + mScanlineSize * y;
+ SkConvertRGBAToGrayFast(dest, src, mSize.Width());
+ }
}
}
else