vcl/skia/salbmp.cxx | 84 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 31 deletions(-)
New commits: commit 21719933e7632a504bf7c03e97a62b01bb938d6a Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Fri Apr 3 17:55:30 2020 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Apr 7 11:53:30 2020 +0200 optimize SkiaSalBitmap::GetAlphaSkImage() This is again used by the ugly separate-alpha-outdev hack. So try to avoid pixel operations. Change-Id: I2956f03272b58831493b1eb4901a8ab5a3e587be Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91771 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx index f9fae9dd83e8..dd723b9ee55e 100644 --- a/vcl/skia/salbmp.cxx +++ b/vcl/skia/salbmp.cxx @@ -505,8 +505,42 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const assert(mSize == mPixelsSize); // data has already been scaled if needed return mAlphaImage; } + if (mImage) + { + SkiaZone zone; + sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize, kAlpha_8_SkColorType); + assert(surface); + SkPaint paint; + paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha + // Move the R channel value to the alpha channel. This seems to be the only + // way to reinterpret data in SkImage as an alpha SkImage without accessing the pixels. + // NOTE: The matrix is 4x5 organized as columns (i.e. each line is a column, not a row). + constexpr SkColorMatrix redToAlpha(0, 0, 0, 0, 0, // R column + 0, 0, 0, 0, 0, // G column + 0, 0, 0, 0, 0, // B column + 1, 0, 0, 0, 0); // A column + paint.setColorFilter(SkColorFilters::Matrix(redToAlpha)); + bool scaling = mImage->width() != mSize.Width() || mImage->height() != mSize.Height(); + if (scaling) + { + assert(!mBuffer); // This code should be only called if only mImage holds data. + paint.setFilterQuality(mScaleQuality); + } + surface->getCanvas()->drawImageRect(mImage, + SkRect::MakeWH(mImage->width(), mImage->height()), + SkRect::MakeWH(mSize.Width(), mSize.Height()), &paint); + if (scaling) + SAL_INFO("vcl.skia.trace", "getalphaskimage(" << this << "): image scaled " + << Size(mImage->width(), mImage->height()) + << "->" << mSize << ":" + << static_cast<int>(mScaleQuality)); + else + SAL_INFO("vcl.skia.trace", "getalphaskbitmap(" << this << ") from image"); + SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this); + thisPtr->mAlphaImage = surface->makeImageSnapshot(); + return mAlphaImage; + } SkiaZone zone; - // TODO can we convert directly mImage -> mAlphaImage? EnsureBitmapData(); assert(mSize == mPixelsSize); // data has already been scaled if needed SkBitmap alphaBitmap; @@ -522,40 +556,28 @@ const sk_sp<SkImage>& SkiaSalBitmap::GetAlphaSkImage() const [](void* addr, void*) { delete[] static_cast<sal_uInt8*>(addr); }, nullptr)) abort(); alphaBitmap.setImmutable(); + sk_sp<SkImage> image = SkiaHelper::createSkImage(alphaBitmap); + assert(image); + const_cast<sk_sp<SkImage>&>(mAlphaImage) = image; } else { - SkBitmap originalBitmap = GetAsSkBitmap(); - // To make things more interesting, some LO code creates masks as 24bpp, - // so we first need to convert to 8bit to be able to convert that to 8bit alpha. - SkBitmap* convertedBitmap = nullptr; - const SkBitmap* bitmap8 = &originalBitmap; - if (originalBitmap.colorType() != kGray_8_SkColorType) - { - convertedBitmap = new SkBitmap; - if (!convertedBitmap->tryAllocPixels(SkImageInfo::Make( - mSize.Width(), mSize.Height(), kGray_8_SkColorType, kOpaque_SkAlphaType))) - abort(); - SkCanvas canvas(*convertedBitmap); - SkPaint paint; - paint.setBlendMode(SkBlendMode::kSrc); // copy and convert depth - canvas.drawBitmap(originalBitmap, 0, 0, &paint); - convertedBitmap->setImmutable(); - bitmap8 = convertedBitmap; - } - // Skia uses a bitmap as an alpha channel only if it's set as kAlpha_8_SkColorType. - // So create such SkBitmap and make it share bitmap8's data. - alphaBitmap.setInfo( - bitmap8->info().makeColorType(kAlpha_8_SkColorType).makeAlphaType(kPremul_SkAlphaType), - bitmap8->rowBytes()); - alphaBitmap.setPixelRef(sk_ref_sp(bitmap8->pixelRef()), bitmap8->pixelRefOrigin().x(), - bitmap8->pixelRefOrigin().y()); - delete convertedBitmap; - alphaBitmap.setImmutable(); + sk_sp<SkSurface> surface = SkiaHelper::createSkSurface(mSize, kAlpha_8_SkColorType); + assert(surface); + SkPaint paint; + paint.setBlendMode(SkBlendMode::kSrc); // set as is, including alpha + // Move the R channel value to the alpha channel. This seems to be the only + // way to reinterpret data in SkImage as an alpha SkImage without accessing the pixels. + // NOTE: The matrix is 4x5 organized as columns (i.e. each line is a column, not a row). + constexpr SkColorMatrix redToAlpha(0, 0, 0, 0, 0, // R column + 0, 0, 0, 0, 0, // G column + 0, 0, 0, 0, 0, // B column + 1, 0, 0, 0, 0); // A column + paint.setColorFilter(SkColorFilters::Matrix(redToAlpha)); + surface->getCanvas()->drawBitmap(GetAsSkBitmap(), 0, 0, &paint); + SkiaSalBitmap* thisPtr = const_cast<SkiaSalBitmap*>(this); + thisPtr->mAlphaImage = surface->makeImageSnapshot(); } - sk_sp<SkImage> image = SkiaHelper::createSkImage(alphaBitmap); - assert(image); - const_cast<sk_sp<SkImage>&>(mAlphaImage) = image; SAL_INFO("vcl.skia.trace", "getalphaskbitmap(" << this << ")"); return mAlphaImage; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits