Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c8faa65 authored by John Reck's avatar John Reck Committed by Gerrit Code Review
Browse files

Merge "Only use the gainmap shader if we might need it" into main

parents 564f0514 6256c0f5
Loading
Loading
Loading
Loading
+3.41 MiB
Loading image diff...
+43 −0
Original line number Diff line number Diff line
@@ -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();
        }
    }
}
+32 −2
Original line number Diff line number Diff line
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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.