From 16fc984bda55febdbc54bae7b34c5dc07dca7b41 Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Fri, 2 Oct 2020 18:50:08 +0200 Subject: clean up handling of erased state in SkiaSalBitmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that e.g. ResetToSkImage() does not keep the erase state. Change-Id: I67e15c7f26c804437b15c394bf1aa4bbc38dfed1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/103887 Tested-by: Jenkins Reviewed-by: Luboš Luňák --- vcl/inc/skia/salbmp.hxx | 9 ++++++--- vcl/skia/salbmp.cxx | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/vcl/inc/skia/salbmp.hxx b/vcl/inc/skia/salbmp.hxx index 00cd76ffd10e..6f74ac04b6f9 100644 --- a/vcl/inc/skia/salbmp.hxx +++ b/vcl/inc/skia/salbmp.hxx @@ -93,8 +93,8 @@ public: bool unittestHasEraseColor() const { return mEraseColorSet; } private: - // Reset the cached images allocated in GetSkImage()/GetAlphaSkImage(). - void ResetCachedData(); + // Reset the state to pixel data (resets cached images allocated in GetSkImage()/GetAlphaSkImage()). + void ResetToBuffer(); // Sets the data only as SkImage (will be converted as needed). void ResetToSkImage(sk_sp image); // Resets all data that does not match mSize. @@ -111,7 +111,10 @@ private: void CreateBitmapData(); // Should be called whenever mPixelsSize or mBitCount is set/changed. bool ComputeScanlineSize(); - void EraseInternal(); + // Sets bitmap to be erased on demand. + void EraseInternal(const Color& color); + // Sets pixels to the erase color. + void PerformErase(); SkBitmap GetAsSkBitmap() const; bool ConserveMemory() const; void verify() const diff --git a/vcl/skia/salbmp.cxx b/vcl/skia/salbmp.cxx index e8f67b0585ed..7bce30b6b637 100644 --- a/vcl/skia/salbmp.cxx +++ b/vcl/skia/salbmp.cxx @@ -282,7 +282,7 @@ void SkiaSalBitmap::ReleaseBuffer(BitmapBuffer* pBuffer, BitmapAccessMode nMode) --mWriteAccessCount; #endif mPalette = pBuffer->maPalette; - ResetCachedData(); + ResetToBuffer(); InvalidateChecksum(); } // Are there any more ground movements underneath us ? @@ -316,6 +316,13 @@ bool SkiaSalBitmap::Scale(const double& rScaleX, const double& rScaleY, BmpScale SAL_INFO("vcl.skia.trace", "scale(" << this << "): " << mSize << "/" << mBitCount << "->" << newSize << ":" << static_cast(nScaleFlag)); + if (mEraseColorSet) + { // Simple. + mSize = mPixelsSize = newSize; + EraseInternal(mEraseColor); + return true; + } + // The idea here is that the actual scaling will be delayed until the result // is actually needed. Usually the scaled bitmap will be drawn somewhere, // so delaying will mean the scaling can be done as a part of GetSkImage(). @@ -355,8 +362,10 @@ bool SkiaSalBitmap::Scale(const double& rScaleX, const double& rScaleY, BmpScale // by mSize != mPixelsSize mSize = newSize; // Do not reset cached data if mImage is possibly the only data we have. - if (mBuffer) - ResetCachedData(); + if (mImage) + ResetToSkImage(mImage); + else + ResetToBuffer(); // The rest will be handled when the scaled bitmap is actually needed, // such as in EnsureBitmapData() or GetSkImage(). return true; @@ -417,6 +426,7 @@ bool SkiaSalBitmap::InterpretAs8Bit() mBitCount = 8; ComputeScanlineSize(); mPalette = Bitmap::GetGreyPalette(256); + EraseInternal(mEraseColor); SAL_INFO("vcl.skia.trace", "interpretas8bit(" << this << ") with erase color"); return true; } @@ -447,10 +457,16 @@ bool SkiaSalBitmap::Erase(const Color& color) // Optimized variant, just remember the color and apply it when needed, // which may save having to do format conversions (e.g. GetSkImage() // may directly erase the SkImage). + EraseInternal(color); + SAL_INFO("vcl.skia.trace", "erase(" << this << ")"); + return true; +} + +void SkiaSalBitmap::EraseInternal(const Color& color) +{ ResetAllData(); mEraseColorSet = true; mEraseColor = color; - return true; } SkBitmap SkiaSalBitmap::GetAsSkBitmap() const @@ -810,7 +826,7 @@ bool SkiaSalBitmap::IsFullyOpaqueAsAlpha() const return SkColorGetA(fromEraseColorToAlphaImageColor(mEraseColor)) == 0; } -void SkiaSalBitmap::EraseInternal() +void SkiaSalBitmap::PerformErase() { if (mPixelsSize.IsEmpty()) return; @@ -851,7 +867,7 @@ void SkiaSalBitmap::EnsureBitmapData() CreateBitmapData(); // Unset now, so that repeated call will return mBuffer. mEraseColorSet = false; - EraseInternal(); + PerformErase(); verify(); SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << ") from erase color " << mEraseColor); @@ -908,7 +924,7 @@ void SkiaSalBitmap::EnsureBitmapData() if (ConserveMemory()) { SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << "): dropping images"); - ResetCachedData(); + ResetToBuffer(); } SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << "): from alpha image"); return; @@ -1035,7 +1051,7 @@ void SkiaSalBitmap::EnsureBitmapData() if (ConserveMemory()) { SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << "): dropping images"); - ResetCachedData(); + ResetToBuffer(); } SAL_INFO("vcl.skia.trace", "ensurebitmapdata(" << this << ")"); } @@ -1057,13 +1073,14 @@ void SkiaSalBitmap::EnsureBitmapUniqueData() } } -void SkiaSalBitmap::ResetCachedData() +void SkiaSalBitmap::ResetToBuffer() { SkiaZone zone; // This should never be called to drop mImage if that's the only data we have. assert(mBuffer || !mImage); mImage.reset(); mAlphaImage.reset(); + mEraseColorSet = false; } void SkiaSalBitmap::ResetToSkImage(sk_sp image) @@ -1072,6 +1089,7 @@ void SkiaSalBitmap::ResetToSkImage(sk_sp image) mBuffer.reset(); mImage = image; mAlphaImage.reset(); + mEraseColorSet = false; } void SkiaSalBitmap::ResetAllData() @@ -1080,12 +1098,14 @@ void SkiaSalBitmap::ResetAllData() mBuffer.reset(); mImage.reset(); mAlphaImage.reset(); + mEraseColorSet = false; } void SkiaSalBitmap::ResetCachedDataBySize() { SkiaZone zone; assert(mSize == mPixelsSize); + assert(!mEraseColorSet); if (mImage && (mImage->width() != mSize.getWidth() || mImage->height() != mSize.getHeight())) mImage.reset(); if (mAlphaImage -- cgit