diff options
author | 2023-11-16 19:05:21 +0000 | |
---|---|---|
committer | 2023-11-16 19:05:21 +0000 | |
commit | 08b76e9027dc01a674f5e5b9c9699fbd776dd441 (patch) | |
tree | 022df87a2036a54c519a3c934f7673d7f3eca210 | |
parent | dc90d17684081342ab1080617f25413295c872f6 (diff) | |
parent | 5c8faa654da42b78960e9563c5ad156835492a1e (diff) |
Merge "Only use the gainmap shader if we might need it" into main am: 5c8faa654d
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2833770
Change-Id: Id298bf47aac1869ab97cae1aec74a4feb476a0eb
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg | bin | 0 -> 3579758 bytes | |||
-rw-r--r-- | apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java | 43 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.cpp | 34 | ||||
-rw-r--r-- | libs/hwui/SkiaCanvas.h | 2 |
4 files changed, 77 insertions, 2 deletions
diff --git a/apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg b/apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg Binary files differnew file mode 100644 index 000000000000..d8b2d759e4c0 --- /dev/null +++ b/apct-tests/perftests/core/res/drawable-nodpi/fountain_night.jpg diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java index f84a0d037ca5..e5a06c9bd146 100644 --- a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java +++ b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java @@ -16,20 +16,29 @@ package android.graphics.perftests; +import static org.junit.Assert.assertTrue; + +import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.Color; +import android.graphics.ImageDecoder; import android.graphics.Paint; import android.graphics.RecordingCanvas; import android.graphics.RenderNode; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.LargeTest; +import com.android.perftests.core.R; + import org.junit.Rule; import org.junit.Test; +import java.io.IOException; + @LargeTest public class CanvasPerfTest { @Rule @@ -93,4 +102,38 @@ public class CanvasPerfTest { node.end(canvas); } } + + @Test + public void testCreateScaledBitmap() throws IOException { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final Context context = InstrumentationRegistry.getContext(); + Bitmap source = ImageDecoder.decodeBitmap( + ImageDecoder.createSource(context.getResources(), R.drawable.fountain_night), + (decoder, info, source1) -> { + decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); + }); + source.setGainmap(null); + + while (state.keepRunning()) { + Bitmap.createScaledBitmap(source, source.getWidth() / 2, source.getHeight() / 2, true) + .recycle(); + } + } + + @Test + public void testCreateScaledBitmapWithGainmap() throws IOException { + BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); + final Context context = InstrumentationRegistry.getContext(); + Bitmap source = ImageDecoder.decodeBitmap( + ImageDecoder.createSource(context.getResources(), R.drawable.fountain_night), + (decoder, info, source1) -> { + decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); + }); + assertTrue(source.hasGainmap()); + + while (state.keepRunning()) { + Bitmap.createScaledBitmap(source, source.getWidth() / 2, source.getHeight() / 2, true) + .recycle(); + } + } } diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 8394c3cd4175..ea9b6c90a65f 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -588,10 +588,40 @@ void SkiaCanvas::drawMesh(const Mesh& mesh, sk_sp<SkBlender> blender, const Pain // Canvas draw operations: Bitmaps // ---------------------------------------------------------------------------- +bool SkiaCanvas::useGainmapShader(Bitmap& bitmap) { + // If the bitmap doesn't have a gainmap, don't use the gainmap shader + if (!bitmap.hasGainmap()) return false; + + // If we don't have an owned canvas, then we're either hardware accelerated or drawing + // to a picture - use the gainmap shader out of caution. Ideally a picture canvas would + // use a drawable here instead to defer making that decision until the last possible + // moment + if (!mCanvasOwned) return true; + + auto info = mCanvasOwned->imageInfo(); + + // If it's an unknown colortype then it's not a bitmap-backed canvas + if (info.colorType() == SkColorType::kUnknown_SkColorType) return true; + + skcms_TransferFunction tfn; + info.colorSpace()->transferFn(&tfn); + + auto transferType = skcms_TransferFunction_getType(&tfn); + switch (transferType) { + case skcms_TFType_HLGish: + case skcms_TFType_HLGinvish: + case skcms_TFType_PQish: + return true; + case skcms_TFType_Invalid: + case skcms_TFType_sRGBish: + return false; + } +} + void SkiaCanvas::drawBitmap(Bitmap& bitmap, float left, float top, const Paint* paint) { auto image = bitmap.makeImage(); - if (bitmap.hasGainmap()) { + if (useGainmapShader(bitmap)) { Paint gainmapPaint = paint ? *paint : Paint(); sk_sp<SkShader> gainmapShader = uirenderer::MakeGainmapShader( image, bitmap.gainmap()->bitmap->makeImage(), bitmap.gainmap()->info, @@ -618,7 +648,7 @@ void SkiaCanvas::drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float s SkRect srcRect = SkRect::MakeLTRB(srcLeft, srcTop, srcRight, srcBottom); SkRect dstRect = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom); - if (bitmap.hasGainmap()) { + if (useGainmapShader(bitmap)) { Paint gainmapPaint = paint ? *paint : Paint(); sk_sp<SkShader> gainmapShader = uirenderer::MakeGainmapShader( image, bitmap.gainmap()->bitmap->makeImage(), bitmap.gainmap()->info, diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h index b785989f35cb..9cb50ed5b081 100644 --- a/libs/hwui/SkiaCanvas.h +++ b/libs/hwui/SkiaCanvas.h @@ -223,6 +223,8 @@ private: void drawPoints(const float* points, int count, const Paint& paint, SkCanvas::PointMode mode); + bool useGainmapShader(Bitmap& bitmap); + class Clip; std::unique_ptr<SkCanvas> mCanvasOwned; // Might own a canvas we allocated. |