diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-07-28 10:37:16 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2020-07-29 11:45:31 +0200 |
commit | 7a38f1817b0568cfbcda9a91dc86eafaba336871 (patch) | |
tree | e2cda33ed6a5c81389a09b42cb1f47c4b8ded864 /vcl | |
parent | df56a000a165da01a14b2fdf2ad66f371a452ce8 (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.cxx | 2 | ||||
-rw-r--r-- | vcl/skia/salbmp.cxx | 85 |
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 |